1. First, you need to understand the notes for modifying the user password in the Windows Active Directory:
1. In the Active Directory, the user's password is Unicode encoding, so the password must be converted from ASCII to unicode encoding, the following shell command Conversion
[Root @ local ~] Echo-n "/" ppaa1234/"" | iconv-F utf8-T utf16le | base64-w 0
Igbwahaaqqbbadeamgazadqaiga =
2. SSL connections must be used to ensure normal communication with the Active Directory Server.
Ii. Example
# Include <stdio. h>
# Include <stdlib. h>
# Include <LDAP. h>
# Include <unistd. h>
Using namespace STD;
# Ifndef pass_log
# Define pass_log (FMT, Arg...) printf (FMT, # Arg)
# Endif
# Define buf_max_len1024
# Define passwd_max_len 512
# Define ad_ldap_port 636
# Define ad_ldap_url "LDAPS: // ad02.example.com: 636"
Char g_admin_dn [buf_max_len] = "cn = admin, ou = finance, Dc = example, Dc = com ";
Char g_admin_pass [buf_max_len] = "123456 ";
// Char g_user_dn [buf_max_len] = "cn = user_test, ou = finance, Dc = example, Dc = com ";
Char g_base_dn [buf_max_len] = "ou = finance, Dc = example, Dc = com ";
Int modifyaccountattributeinactivitydirectory (char * admin_dn, char * admin_pass, char * username, char * user_pass)
{
Char filter [buf_max_len];
Char * user_dn = NULL;
LDAP * LD = NULL;
Ldapmessage * result = NULL, * element = NULL;
Ldapmod, mod2;
Ldapmod * mod [3];
Struct berval bvalold;
Struct berval bvalnew;
Struct berval * bvalsold [2];
Struct berval * bvalsnew [2];
Char old_password_with_quotes [passwd_max_len], new_password_with_quotes [passwd_max_len];
Char old_unicode_password [passwd_max_len * 2], new_unicode_password [passwd_max_len * 2];
Const char * new_password = NULL;
Const char x old_password = "1234 PPMM ";
Int ldap_version = ldap_version3;
Int rc =-1, err_code =-1;
Int I = 0;
If (null = admin_dn | null = admin_pass | null = username | null = user_pass)
{
Pass_log ("modifyaccountattributeinactivitydirectory: parameters is null/N ");
Err_code =-1;
Goto clean;
}
Rc = ldap_initialize (& lD, ad_ldap_url );
If (RC! = Ldap_success)
{
Ldap_perror (LD, "ldap_initialize ");
Pass_log ("ldap_initialize: % s/n", ldap_err2string (RC ));
Err_code = RC;
Goto clean;
}
Rc = ldap_set_option (LD, ldap_opt_protocol_version, & ldap_version );
If (RC! = Ldap_success)
{
Ldap_perror (LD, "ldap_set_option ");
Pass_log ("ldap_set_option: % s/n", ldap_err2string (RC ));
Err_code = RC;
Goto unbind_ld;
}
Rc = ldap_simple_bind_s (LD, admin_dn, admin_pass );
If (RC! = Ldap_success)
{
Ldap_perror (LD, "ldap_simple_bind_s ");
Pass_log ("ldap_simple_bind_s: % s/n", ldap_err2string (RC ));
Err_code = RC;
Goto unbind_ld;
}
Memset (filter, 0, sizeof (filter ));
Sprintf (filter, "cn = % s", username );
Rc = ldap_search_s (LD,
G_base_dn,
Ldap_scope_subtree,
Filter,
Null,
0,
& Result );
If (RC! = Ldap_success)
{
Ldap_perror (LD, "ldap_search_s ");
Pass_log ("ldap_search_s: % s/n", ldap_err2string (RC ));
Err_code = RC;
Goto unbind_ld;
}
For (element = ldap_first_entry (LD, result); element! = NULL; element = ldap_next_entry (LD, element ))
{
User_dn = ldap_get_dn (LD, element );
Pass_log ("DN: % s/n", user_dn );
}
If (user_dn = NULL)
{
Pass_log ("DN is null/N ");
Err_code =-1;
Goto free_msg;
}
New_password = user_pass;
Memset (new_password_with_quotes, 0, sizeof (new_password_with_quotes ));
Snprintf (new_password_with_quotes, sizeof (new_password_with_quotes), "/" % S/"", new_password );
Memset (new_unicode_password, 0, sizeof (new_unicode_password ));
For (I = 0; I <strlen (new_password_with_quotes); I ++)
{
New_unicode_password [I * 2] = new_password_with_quotes [I];
}
Bvalnew. bv_val = new_unicode_password;
Bvalnew. bv_len = strlen (new_password_with_quotes) * 2;
Bvalsnew [0] = & bvalnew;
Bvalsnew [1] = NULL;
Mod. mod_vals.modv_bvals = bvalsnew;
Mod. mod_type = (char *) "unicodepwd ";
# If 0
/* User must supply old password */
Memset (old_password_with_quotes, 0, sizeof (old_password_with_quotes ));
Snprintf (old_password_with_quotes,
Sizeof (old_password_with_quotes), "/" % S /"",
Old_password );
Memset (old_unicode_password, 0, sizeof (old_unicode_password ));
For (I = 0; I <strlen (old_password_with_quotes); I ++)
{
Old_unicode_password [I * 2] = old_password_with_quotes [I];
}
Bvalold. bv_val = old_unicode_password;
Bvalold. bv_len = strlen (old_password_with_quotes) * 2;
Bvalsold [0] = & bvalold;
Bvalsold [1] = NULL;
Mod2.mod _ Vals. modv_bvals = bvalsold;
Mod2.mod _ type = (char *) "unicodepwd ";
Mod2.mod _ OP = ldap_mod_delete | ldap_mod_bvalues;
Mod. mod_op = ldap_mod_add | ldap_mod_bvalues;
MoD [0] = & mod2;
MoD [1] = & MOD;
MoD [2] = NULL;
# Else
Mod. mod_op = ldap_mod_replace | ldap_mod_bvalues;
MoD [0] = & MOD;
MoD [1] = NULL;
# Endif
Rc = ldap_modify_s (LD, user_dn, MoD );
If (RC! = Ldap_success)
{
Ldap_perror (LD, "ldap_modify_s ");
Pass_log ("ldap_modify_s: % s/n", ldap_err2string (RC ));
}
Err_code = RC;
Pass_log ("Modify account's attribute in activity directory OK/N ");
If (null! = LD)
{
Free (user_dn );
}
Free_msg:
If (null! = Result)
{
Ldap_msgfree (result );
}
Unbind_ld:
If (null! = LD)
{
Ldap_unbind (LD );
}
Clean:
Return err_code;
}
Int main (INT argc, char * argv [])
{
Char * new_password = "ooxx1234 ";
If (modifyaccountattributeinactivitydirectory (g_admin_dn, g_admin_pass, "user_test", new_password) <0)
{
Pass_log ("failed to modify account's attribute in activity directory ");
Return-1;
}
Return 0;
}
[Root @ local ~] G ++ change_passwd.cpp-lldap-g-dldap_deprecated = 1-O change_passwd
Iii. CA certificate
[Root @ local ~] #./Change_passwd
Ldap_simple_bind_s: Can't contact LDAP Server (-1)
Additional Info: Error: 14090086: SSL routines: ssl3_get_server_certificate: Certificate verify failed
Solution:
1. Export the. Cer file from the domain control
2. Change the format of the CER file to PEM.
[Root @ local ~] # OpenSSL X509-inform der-in/root/ad02.cer-out/root/ad02.pem-outform PEM
3. Configure/etc/OpenLDAP/ldap. conf
[Root @ local ~] # Vim/etc/OpenLDAP/ldap. conf
Use_sasl on
SSL on
SASL start_tls
Sasl_mech gssapi
Tls_checkpeer No
Tls_ciphers tlsv1
Tls_reqcert never
Chasereferrals Yes
Deref always
Uri LDAPS: // ad02.example.com: 636
Binddn Cn = admin, ou = finance, Dc = example, Dc = com
# Tell gssapi not to negotiate a security or privacy layer since
# Ad doesn' t support nested security or privacy Layers
Sasl_secprops minssf = 0, maxssf = 0
Tls_cacertfile/root/ad02.pem
[Root @ local ~] #./Change_passwd
Modify account's attribute in activity directory OK
Creating Active Directory accounts
Iv. References
Openldap server with server-side SSL/TLS and client authentication (the most valuable reference is ldap_initialize)
_ Get_authtok in pam_ldap.c (the most valuable reference is Unicode conversion)
LDAP authentication and password management
How to change the password of a Windows 2000 user through LDAP
Instructions on enabling communication between an LDAP client and an LDAP server through SSL
Ldap c Programming Development-SDK man pages
Mozilla ldap c sdk programmer's Guide
LDAP 636 Java Python C # Cold Fusion Perl PHP Ruby