diff options
author | Andrew Bartlett <abartlet@samba.org> | 2002-09-25 11:34:31 +0000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2002-09-25 11:34:31 +0000 |
commit | 82102d9c99f9b255d6262553187642e9637e4670 (patch) | |
tree | 4fbf42bfe846f73e020b94549a38e2637bb6ee90 | |
parent | 8df2ac63f067e7d11959497a09ff4dd00e8087f7 (diff) | |
download | samba-82102d9c99f9b255d6262553187642e9637e4670.tar.gz |
This patch from "Stefan (metze) Metzmacher" <metze@metzemix.de> cleans up
pdb_ldap and adds a 'ldap passwd sync' option.
The idea with this option is to do allow an ldap backend to do all the fancy
password hashing etc - and to tell smbd no to try and double-up. Using 'ldap
passwd sync = only' will do this, but is not recommended unless such a backend
is in place...
Running 'ldap passwd sync = yes' just gets you the same as doing 'pam passwd
sync = yes' and having both PAM and pam_ldap correctly configured for 'magic
root' behaviour, but only using ldap connection, and one set of credentials.
This also gets us closer to allowing ldap to say 'password too short' etc,
which might assist in maintaining a consistant password policy.
Andrew Bartlett
(This used to be commit f13e243f1a13d34ae057b40b01f561e8b95d4570)
-rw-r--r-- | source3/include/smb.h | 5 | ||||
-rw-r--r-- | source3/param/loadparm.c | 27 | ||||
-rw-r--r-- | source3/passdb/passdb.c | 11 | ||||
-rw-r--r-- | source3/passdb/pdb_get_set.c | 25 | ||||
-rw-r--r-- | source3/passdb/pdb_ldap.c | 291 |
5 files changed, 231 insertions, 128 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h index 59bfb6b4495..c39ebed950f 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -616,7 +616,7 @@ typedef struct sam_passwd DATA_BLOB lm_pw; /* .data is Null if no password */ DATA_BLOB nt_pw; /* .data is Null if no password */ - DATA_BLOB plaintext_pw; /* .data is Null if not available */ + char* plaintext_pw; /* is Null if not available */ uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */ uint32 unknown_3; /* 0x00ff ffff */ @@ -1346,6 +1346,9 @@ enum schema_types {SCHEMA_COMPAT, SCHEMA_AD, SCHEMA_SAMBA}; /* LDAP SSL options */ enum ldap_ssl_types {LDAP_SSL_ON, LDAP_SSL_OFF, LDAP_SSL_START_TLS}; +/* LDAP PASSWD SYNC methods */ +enum ldap_passwd_sync_types {LDAP_PASSWD_SYNC_ON, LDAP_PASSWD_SYNC_OFF, LDAP_PASSWD_SYNC_ONLY}; + /* Remote architectures we know about. */ enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_WIN2K, RA_SAMBA}; diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 7b8efbd5bc7..4aaf6f20eb7 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -207,11 +207,11 @@ typedef struct int iLockSpinTime; char *szLdapMachineSuffix; char *szLdapUserSuffix; - int ldap_port; int ldap_ssl; char *szLdapSuffix; char *szLdapFilter; char *szLdapAdminDn; + int ldap_passwd_sync; BOOL bMsAddPrinterWizard; BOOL bDNSproxy; BOOL bWINSsupport; @@ -600,6 +600,22 @@ static struct enum_list enum_ldap_ssl[] = { {-1, NULL} }; +static struct enum_list enum_ldap_passwd_sync[] = { + {LDAP_PASSWD_SYNC_ON, "Yes"}, + {LDAP_PASSWD_SYNC_ON, "yes"}, + {LDAP_PASSWD_SYNC_ON, "on"}, + {LDAP_PASSWD_SYNC_ON, "On"}, + {LDAP_PASSWD_SYNC_OFF, "no"}, + {LDAP_PASSWD_SYNC_OFF, "No"}, + {LDAP_PASSWD_SYNC_OFF, "off"}, + {LDAP_PASSWD_SYNC_OFF, "Off"}, +#ifdef LDAP_EXOP_X_MODIFY_PASSWD + {LDAP_PASSWD_SYNC_ONLY, "Only"}, + {LDAP_PASSWD_SYNC_ONLY, "only"}, +#endif /* LDAP_EXOP_X_MODIFY_PASSWD */ + {-1, NULL} +}; + /* Types of machine we can announce as. */ #define ANNOUNCE_AS_NT_SERVER 1 #define ANNOUNCE_AS_WIN95 2 @@ -987,12 +1003,13 @@ static struct parm_struct parm_table[] = { {"Ldap Options", P_SEP, P_SEPARATOR}, - {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_machine_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, - {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_machine_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED | FLAG_DEVELOPER}, + {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED | FLAG_DEVELOPER}, {"Miscellaneous Options", P_SEP, P_SEPARATOR}, {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, @@ -1357,6 +1374,7 @@ static void init_globals(void) string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))"); string_set(&Globals.szLdapAdminDn, ""); Globals.ldap_ssl = LDAP_SSL_ON; + Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF; /* these parameters are set to defaults that are more appropriate for the increasing samba install base: @@ -1570,6 +1588,7 @@ FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix) FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter) FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn) FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl) +FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync) FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand) FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand) FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand) diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 05450c9f2f2..e0f0cce67fb 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -75,11 +75,19 @@ static void pdb_fill_default_sam(SAM_ACCOUNT *user) user->private.workstations = ""; user->private.unknown_str = ""; user->private.munged_dial = ""; + + user->private.plaintext_pw = NULL; + } static void destroy_pdb_talloc(SAM_ACCOUNT **user) { if (*user) { + data_blob_clear_free(&((*user)->private.lm_pw)); + data_blob_clear_free(&((*user)->private.nt_pw)); + + if((*user)->private.plaintext_pw!=NULL) + memset((*user)->private.plaintext_pw,'\0',strlen((*user)->private.plaintext_pw)); talloc_destroy((*user)->mem_ctx); *user = NULL; } @@ -310,7 +318,8 @@ static void pdb_free_sam_contents(SAM_ACCOUNT *user) data_blob_clear_free(&(user->private.lm_pw)); data_blob_clear_free(&(user->private.nt_pw)); - data_blob_clear_free(&(user->private.plaintext_pw)); + if (user->private.plaintext_pw!=NULL) + memset(user->private.plaintext_pw,'\0',strlen(user->private.plaintext_pw)); } diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index 2da6de72701..0c338f317ec 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -151,7 +151,7 @@ const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass) const char* pdb_get_plaintext_passwd (const SAM_ACCOUNT *sampass) { if (sampass) { - return ((char*)sampass->private.plaintext_pw.data); + return (sampass->private.plaintext_pw); } else return (NULL); @@ -956,14 +956,24 @@ BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[16]) below) ********************************************************************/ -BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const uint8 *password, size_t len) +BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password) { if (!sampass) return False; - data_blob_clear_free(&sampass->private.plaintext_pw); - - sampass->private.plaintext_pw = data_blob(password, len); + if (password) { + if (sampass->private.plaintext_pw!=NULL) + memset(sampass->private.plaintext_pw,'\0',strlen(sampass->private.plaintext_pw)+1); + sampass->private.plaintext_pw = talloc_strdup(sampass->mem_ctx, password); + + if (!sampass->private.plaintext_pw) { + DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n")); + return False; + } + + } else { + sampass->private.plaintext_pw = NULL; + } return True; } @@ -1062,7 +1072,10 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext) if (!pdb_set_lanman_passwd (sampass, new_lanman_p16)) return False; - + + if (!pdb_set_plaintext_pw_only (sampass, plaintext)) + return False; + if (!pdb_set_pass_changed_now (sampass)) return False; diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 6d38a2600d0..71a8c256a3a 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1,11 +1,11 @@ /* Unix SMB/CIFS implementation. LDAP protocol helper functions for SAMBA - Copyright (C) Jean François Micouleau 1998 - Copyright (C) Gerald Carter 2001 - Copyright (C) Shahms King 2001 - Copyright (C) Andrew Bartlett 2002 - Copyright (C) Stefan (metze) Metzmacher 2002 + Copyright (C) Jean François Micouleau 1998 + Copyright (C) Gerald Carter 2001 + Copyright (C) Shahms King 2001 + Copyright (C) Andrew Bartlett 2002 + Copyright (C) Stefan (metze) Metzmacher 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -273,7 +273,8 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP * a rebind function for authenticated referrals This version takes a void* that we can shove useful stuff in :-) ******************************************************************/ - +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) +#else static int rebindproc_with_state (LDAP * ld, char **whop, char **credp, int *methodp, int freeit, void *arg) { @@ -304,13 +305,14 @@ static int rebindproc_with_state (LDAP * ld, char **whop, char **credp, } return 0; } +#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ /******************************************************************* a rebind function for authenticated referrals This version takes a void* that we can shove useful stuff in :-) and actually does the connection. ******************************************************************/ - +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) static int rebindproc_connect_with_state (LDAP *ldap_struct, LDAP_CONST char *url, ber_tag_t request, @@ -329,11 +331,14 @@ static int rebindproc_connect_with_state (LDAP *ldap_struct, return rc; } +#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ /******************************************************************* Add a rebind function for authenticated referrals ******************************************************************/ - +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) +#else +# if LDAP_SET_REBIND_PROC_ARGS == 2 static int rebindproc (LDAP *ldap_struct, char **whop, char **credp, int *method, int freeit ) { @@ -341,19 +346,23 @@ static int rebindproc (LDAP *ldap_struct, char **whop, char **credp, method, freeit, static_ldap_state); } +# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/ +#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ /******************************************************************* a rebind function for authenticated referrals this also does the connection, but no void*. ******************************************************************/ - +#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000) +# if LDAP_SET_REBIND_PROC_ARGS == 2 static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request, ber_int_t msgid) { return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid, static_ldap_state); } - +# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/ +#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ /******************************************************************* connect to the ldap server under system privilege. @@ -391,18 +400,18 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l # if LDAP_SET_REBIND_PROC_ARGS == 3 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state); # endif -#else +#else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ # if LDAP_SET_REBIND_PROC_ARGS == 2 ldap_set_rebind_proc(ldap_struct, &rebindproc); # endif # if LDAP_SET_REBIND_PROC_ARGS == 3 ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state); # endif -#endif +#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ + rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret); - if (rc != LDAP_SUCCESS) - { + if (rc != LDAP_SUCCESS) { DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc))); return False; } @@ -421,7 +430,7 @@ static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, LDAP * DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter)); - rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, attr, 0, result); + rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, (char **)attr, 0, result); if (rc != LDAP_SUCCESS) { DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n", @@ -944,9 +953,6 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, slprintf(temp, sizeof(temp) - 1, "%i", rid); make_a_mod(mods, ldap_op, "primaryGroupID", temp); - slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass)); - make_a_mod(mods, ldap_op, "pwdLastSet", temp); - /* displayName, cn, and gecos should all be the same * most easily accomplished by giving them the same OID * gecos isn't set here b/c it should be handled by the @@ -989,6 +995,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, make_a_mod(mods, ldap_op, "kickoffTime", temp); } + if (IS_SAM_SET(sampass, FLAG_SAM_CANCHANGETIME)) { slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass)); make_a_mod(mods, ldap_op, "pwdCanChange", temp); @@ -999,13 +1006,22 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state, make_a_mod(mods, ldap_op, "pwdMustChange", temp); } - /* FIXME: Hours stuff goes in LDAP */ - pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass)); - make_a_mod (mods, ldap_op, "lmPassword", temp); + if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))|| + (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) { + + pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass)); + make_a_mod (mods, ldap_op, "lmPassword", temp); - pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass)); - make_a_mod (mods, ldap_op, "ntPassword", temp); + pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass)); + make_a_mod (mods, ldap_op, "ntPassword", temp); + slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass)); + make_a_mod(mods, ldap_op, "pwdLastSet", temp); + + } + + /* FIXME: Hours stuff goes in LDAP */ + make_a_mod (mods, ldap_op, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN)); @@ -1030,18 +1046,18 @@ static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 if (ldapsam_search_one_user_by_rid(ldap_state, ldap_struct, final_rid, &result) != LDAP_SUCCESS) { DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid)); - final_rid = 0; ldap_msgfree(result); + return 0; } - if (ldap_count_entries(ldap_struct, result) != 0) - { + if (ldap_count_entries(ldap_struct, result) != 0) { DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid)); - final_rid = 0; ldap_msgfree(result); + return 0; } DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid, final_rid)); + ldap_msgfree(result); return final_rid; } @@ -1093,12 +1109,10 @@ static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter)); rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, final_filter, attr, 0, + LDAP_SCOPE_SUBTREE, final_filter, (char **)attr, 0, &result); - if (rc != LDAP_SUCCESS) - { - + if (rc != LDAP_SUCCESS) { DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc))); DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter)); @@ -1149,12 +1163,10 @@ static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_s uint32 next_nua_rid; uint32 top_nua_rid; - if (!ldapsam_open_connection(ldap_state, &ldap_struct)) - { + if (!ldapsam_open_connection(ldap_state, &ldap_struct)) { return 0; } - if (!ldapsam_connect_system(ldap_state, ldap_struct)) - { + if (!ldapsam_connect_system(ldap_state, ldap_struct)) { ldap_unbind(ldap_struct); return 0; } @@ -1177,12 +1189,10 @@ static BOOL ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update) int rc; pstring filter; - if (!ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct)) - { + if (!ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct)) { return False; } - if (!ldapsam_connect_system(ldap_state, ldap_state->ldap_struct)) - { + if (!ldapsam_connect_system(ldap_state, ldap_state->ldap_struct)) { ldap_unbind(ldap_state->ldap_struct); return False; } @@ -1191,11 +1201,10 @@ static BOOL ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update) all_string_sub(filter, "%u", "*", sizeof(pstring)); rc = ldap_search_s(ldap_state->ldap_struct, lp_ldap_suffix(), - LDAP_SCOPE_SUBTREE, filter, attr, 0, + LDAP_SCOPE_SUBTREE, filter, (char **)attr, 0, &ldap_state->result); - if (rc != LDAP_SUCCESS) - { + if (rc != LDAP_SUCCESS) { DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc))); DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter)); ldap_msgfree(ldap_state->result); @@ -1222,8 +1231,7 @@ End enumeration of the LDAP password list static void ldapsam_endsampwent(struct pdb_methods *my_methods) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; - if (ldap_state->ldap_struct && ldap_state->result) - { + if (ldap_state->ldap_struct && ldap_state->result) { ldap_msgfree(ldap_state->result); ldap_unbind(ldap_state->ldap_struct); ldap_state->ldap_struct = NULL; @@ -1234,7 +1242,7 @@ static void ldapsam_endsampwent(struct pdb_methods *my_methods) /********************************************************************** Get the next entry in the LDAP password database *********************************************************************/ -static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * user) +static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; BOOL ret = False; @@ -1252,8 +1260,7 @@ static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * us ldap_state->entry); ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct, - ldap_state->entry); - + ldap_state->entry); } return True; @@ -1262,7 +1269,7 @@ static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * us /********************************************************************** Get SAM_ACCOUNT entry from LDAP by username *********************************************************************/ -static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const char *sname) +static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; LDAP *ldap_struct; @@ -1271,18 +1278,15 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us if (!ldapsam_open_connection(ldap_state, &ldap_struct)) return False; - if (!ldapsam_connect_system(ldap_state, ldap_struct)) - { + if (!ldapsam_connect_system(ldap_state, ldap_struct)) { ldap_unbind(ldap_struct); return False; } - if (ldapsam_search_one_user_by_name(ldap_state, ldap_struct, sname, &result) != LDAP_SUCCESS) - { + if (ldapsam_search_one_user_by_name(ldap_state, ldap_struct, sname, &result) != LDAP_SUCCESS) { ldap_unbind(ldap_struct); return False; } - if (ldap_count_entries(ldap_struct, result) < 1) - { + if (ldap_count_entries(ldap_struct, result) < 1) { DEBUG(4, ("We don't find this user [%s] count=%d\n", sname, ldap_count_entries(ldap_struct, result))); @@ -1290,8 +1294,7 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us return False; } entry = ldap_first_entry(ldap_struct, result); - if (entry) - { + if (entry) { if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) { DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname)); ldap_msgfree(result); @@ -1301,9 +1304,7 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us ldap_msgfree(result); ldap_unbind(ldap_struct); return True; - } - else - { + } else { ldap_msgfree(result); ldap_unbind(ldap_struct); return False; @@ -1313,7 +1314,7 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us /********************************************************************** Get SAM_ACCOUNT entry from LDAP by rid *********************************************************************/ -static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, uint32 rid) +static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; LDAP *ldap_struct; @@ -1323,20 +1324,17 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us if (!ldapsam_open_connection(ldap_state, &ldap_struct)) return False; - if (!ldapsam_connect_system(ldap_state, ldap_struct)) - { + if (!ldapsam_connect_system(ldap_state, ldap_struct)) { ldap_unbind(ldap_struct); return False; } if (ldapsam_search_one_user_by_rid(ldap_state, ldap_struct, rid, &result) != - LDAP_SUCCESS) - { + LDAP_SUCCESS) { ldap_unbind(ldap_struct); return False; } - if (ldap_count_entries(ldap_struct, result) < 1) - { + if (ldap_count_entries(ldap_struct, result) < 1) { DEBUG(4, ("We don't find this rid [%i] count=%d\n", rid, ldap_count_entries(ldap_struct, result))); @@ -1345,8 +1343,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us } entry = ldap_first_entry(ldap_struct, result); - if (entry) - { + if (entry) { if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) { DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n")); ldap_msgfree(result); @@ -1356,9 +1353,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us ldap_msgfree(result); ldap_unbind(ldap_struct); return True; - } - else - { + } else { ldap_msgfree(result); ldap_unbind(ldap_struct); return False; @@ -1373,6 +1368,95 @@ static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * us return ldapsam_getsampwrid(my_methods, user, rid); } +static BOOL ldapsam_modify_entry(LDAP *ldap_struct,SAM_ACCOUNT *newpwd,char *dn,LDAPMod **mods,int ldap_op) +{ + int version; + int rc; + + switch(ldap_op) + { + case LDAP_MOD_ADD: + make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account"); + if((rc = ldap_add_s(ldap_struct,dn,mods))!=LDAP_SUCCESS) { + char *ld_error; + ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING, + &ld_error); + DEBUG(0, + ("failed to add user with uid = %s with: %s\n\t%s\n", + pdb_get_username(newpwd), ldap_err2string(rc), + ld_error)); + free(ld_error); + return False; + } + break; + case LDAP_MOD_REPLACE: + if((rc = ldap_modify_s(ldap_struct,dn,mods))!=LDAP_SUCCESS) { + char *ld_error; + ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING, + &ld_error); + DEBUG(0, + ("failed to modify user with uid = %s with: %s\n\t%s\n", + pdb_get_username(newpwd), ldap_err2string(rc), + ld_error)); + free(ld_error); + return False; + } + break; + default: + DEBUG(0,("Wrong LDAP operation type: %d!\n",ldap_op)); + return False; + } + +#ifdef LDAP_EXOP_X_MODIFY_PASSWD + if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))&& + (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_OFF)&& + (pdb_get_plaintext_passwd(newpwd)!=NULL)) { + BerElement *ber; + struct berval *bv; + char *retoid; + struct berval *retdata; + + if (ldap_get_option(ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) { + if (version != LDAP_VERSION3) { + version = LDAP_VERSION3; + ldap_set_option (ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version); + } + } + + if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) { + DEBUG(0,("ber_alloc_t returns NULL\n")); + return False; + } + ber_printf (ber, "{"); + ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID,dn); + ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, pdb_get_plaintext_passwd(newpwd)); + ber_printf (ber, "N}"); + + if ((rc = ber_flatten (ber, &bv))<0) { + DEBUG(0,("ber_flatten returns a value <0\n")); + return False; + } + + ber_free(ber,1); + + if ((rc = ldap_extended_operation_s(ldap_struct, LDAP_EXOP_X_MODIFY_PASSWD, + bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) { + DEBUG(0,("LDAP Password could not be changed for user %s: %s\n", + pdb_get_username(newpwd),ldap_err2string(rc))); + } else { + DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd))); + + ber_bvfree(retdata); + ber_memfree(retoid); + } + ber_bvfree(bv); + } +#else + DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n")); +#endif /* LDAP_EXOP_X_MODIFY_PASSWD */ + return True; +} + /********************************************************************** Delete entry from LDAP for username *********************************************************************/ @@ -1414,7 +1498,8 @@ static BOOL ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOU entry = ldap_first_entry (ldap_struct, result); dn = ldap_get_dn (ldap_struct, entry); - + ldap_msgfree(result); + rc = ldap_delete_s (ldap_struct, dn); ldap_memfree (dn); @@ -1449,8 +1534,7 @@ static BOOL ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOU if (!ldapsam_open_connection(ldap_state, &ldap_struct)) /* open a connection to the server */ return False; - if (!ldapsam_connect_system(ldap_state, ldap_struct)) /* connect as system account */ - { + if (!ldapsam_connect_system(ldap_state, ldap_struct)) { /* connect as system account */ ldap_unbind(ldap_struct); return False; } @@ -1458,8 +1542,7 @@ static BOOL ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOU rc = ldapsam_search_one_user_by_name(ldap_state, ldap_struct, pdb_get_username(newpwd), &result); - if (ldap_count_entries(ldap_struct, result) == 0) - { + if (ldap_count_entries(ldap_struct, result) == 0) { DEBUG(0, ("No user to modify!\n")); ldap_msgfree(result); ldap_unbind(ldap_struct); @@ -1475,23 +1558,17 @@ static BOOL ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOU entry = ldap_first_entry(ldap_struct, result); dn = ldap_get_dn(ldap_struct, entry); - - rc = ldap_modify_s(ldap_struct, dn, mods); - - if (rc != LDAP_SUCCESS) - { - char *ld_error; - ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING, - &ld_error); - DEBUG(0, - ("failed to modify user with uid = %s with: %s\n\t%s\n", - pdb_get_username(newpwd), ldap_err2string(rc), - ld_error)); - free(ld_error); + ldap_msgfree(result); + + if (!ldapsam_modify_entry(ldap_struct,newpwd,dn,mods,LDAP_MOD_REPLACE)) { + DEBUG(0,("failed to modify user with uid = %s\n", + pdb_get_username(newpwd))); + ldap_mods_free(mods,1); ldap_unbind(ldap_struct); return False; } + DEBUG(2, ("successfully modified uid = %s in the LDAP database\n", pdb_get_username(newpwd))); @@ -1514,7 +1591,7 @@ static BOOL ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT LDAPMod **mods = NULL; int ldap_op; uint32 num_result; - + const char *username = pdb_get_username(newpwd); if (!username || !*username) { DEBUG(0, ("Cannot add user without a username!\n")); @@ -1522,20 +1599,16 @@ static BOOL ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT } if (!ldapsam_open_connection(ldap_state, &ldap_struct)) /* open a connection to the server */ - { return False; - } - if (!ldapsam_connect_system(ldap_state, ldap_struct)) /* connect as system account */ - { + if (!ldapsam_connect_system(ldap_state, ldap_struct)) { /* connect as system account */ ldap_unbind(ldap_struct); return False; } rc = ldapsam_search_one_user_by_name (ldap_state, ldap_struct, username, &result); - if (ldap_count_entries(ldap_struct, result) != 0) - { + if (ldap_count_entries(ldap_struct, result) != 0) { DEBUG(0,("User already in the base, with samba properties\n")); ldap_msgfree(result); ldap_unbind(ldap_struct); @@ -1564,8 +1637,7 @@ static BOOL ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT tmp = ldap_get_dn (ldap_struct, entry); slprintf (dn, sizeof (dn) - 1, "%s", tmp); ldap_memfree (tmp); - } - else { + } else { /* Check if we need to add an entry */ DEBUG(3,("Adding new user\n")); ldap_op = LDAP_MOD_ADD; @@ -1586,27 +1658,14 @@ static BOOL ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT } make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount"); - if (ldap_op == LDAP_MOD_REPLACE) { - rc = ldap_modify_s(ldap_struct, dn, mods); - } - else { - make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account"); - rc = ldap_add_s(ldap_struct, dn, mods); - } - - if (rc != LDAP_SUCCESS) - { - char *ld_error; - - ldap_get_option (ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error); - DEBUG(0,("failed to modify/add user with uid = %s (dn = %s) with: %s\n\t%s\n", - pdb_get_username(newpwd), dn, ldap_err2string (rc), ld_error)); - free(ld_error); - ldap_mods_free(mods, 1); + if (!ldapsam_modify_entry(ldap_struct,newpwd,dn,mods,ldap_op)) { + DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n", + pdb_get_username(newpwd),dn)); + ldap_mods_free(mods,1); ldap_unbind(ldap_struct); return False; } - + DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd))); ldap_mods_free(mods, 1); ldap_unbind(ldap_struct); |