Use ldap c api to modify a user's password in MS Active Directory

Source: Internet
Author: User
Tags ldap openssl x509 openldap

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

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.