/* ldap_passwd_s.c - replacement function for ldap_passwd_s() Parts of this file were based on parts of the pam_ldap library (taken from _update_authtok() in pam_ldap.c). Copyright (C) 1998-2004 Luke Howard Copyright (C) 2009, 2010 Arthur de Jong This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include "compat/ldap_compat.h" #include "compat/attrs.h" #ifndef LDAP_EXOP_MODIFY_PASSWD #ifdef LDAP_EXOP_X_MODIFY_PASSWD #define LDAP_EXOP_MODIFY_PASSWD LDAP_EXOP_X_MODIFY_PASSWD #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID #define LDAP_TAG_EXOP_MODIFY_PASSWD_OLD LDAP_TAG_EXOP_X_MODIFY_PASSWD_OLD #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW #else /* not LDAP_EXOP_X_MODIFY_PASSWD */ #define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1" #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U) #define LDAP_TAG_EXOP_MODIFY_PASSWD_OLD ((ber_tag_t) 0x81U) #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U) #endif /* not LDAP_EXOP_X_MODIFY_PASSWD */ #endif /* not LDAP_EXOP_MODIFY_PASSWD */ #ifndef LBER_USE_DER #define LBER_USE_DER 1 #endif /* not LBER_USE_DER */ #ifndef HAVE_BER_MEMFREE #define ber_memfree free #endif /* not HAVE_BER_MEMFREE */ #if !HAVE_DECL_LDAP_EXTENDED_OPERATION_S /* we define this ourselves here because some LDAP header versions don't seem to define this */ extern int ldap_extended_operation_s(LDAP *ld,LDAP_CONST char *reqoid, struct berval *reqdata,LDAPControl **serverctrls,LDAPControl **clientctrls, char **retoidp,struct berval **retdatap); #endif /* not HAVE_DECL_LDAP_EXTENDED_OPERATION_S */ /* Replacement for password modification. user is the DN of the entry to change, oldpw is the old password (may not always be needed?), newpw is the new password to set and newpasswd is sometimes returned (though not by us). See RFC 3062 for details.*/ int ldap_passwd_s(LDAP *ld,struct berval *user,struct berval *oldpw, struct berval *newpw,struct berval UNUSED(*newpasswd), LDAPControl **sctrls,LDAPControl **cctrls) { #ifndef HAVE_LDAP_EXTENDED_OPERATION_S return LDAP_OPERATIONS_ERROR; #else /* HAVE_LDAP_EXTENDED_OPERATION_S */ int rc; BerElement *ber; struct berval *bv; char *retoid; struct berval *retdata; /* set up request data */ ber=ber_alloc_t(LBER_USE_DER); if (ber==NULL) return LDAP_NO_MEMORY; ber_printf(ber,"{"); ber_printf(ber,"tO",LDAP_TAG_EXOP_MODIFY_PASSWD_ID,user); if (oldpw!=NULL) ber_printf(ber,"tO",LDAP_TAG_EXOP_MODIFY_PASSWD_OLD,oldpw); ber_printf(ber,"tO",LDAP_TAG_EXOP_MODIFY_PASSWD_NEW,newpw); ber_printf(ber,"N}"); rc=ber_flatten(ber,&bv); ber_free(ber,1); if (rc<0) return LDAP_NO_MEMORY; /* perform the operation */ rc=ldap_extended_operation_s(ld,LDAP_EXOP_MODIFY_PASSWD,bv,sctrls,cctrls, &retoid,&retdata); /* free data */ ber_bvfree(bv); if (rc==LDAP_SUCCESS) { ber_bvfree(retdata); ber_memfree(retoid); } /* return result code */ return rc; #endif /* HAVE_LDAP_EXTENDED_OPERATION_S */ }