2 Unix SMB/CIFS implementation.
3 LDAP protocol helper functions for SAMBA
4 Copyright (C) Jean François Micouleau 1998
5 Copyright (C) Gerald Carter 2001-2003
6 Copyright (C) Shahms King 2001
7 Copyright (C) Andrew Bartlett 2002-2003
8 Copyright (C) Stefan (metze) Metzmacher 2002-2003
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * persistent connections: if using NSS LDAP, many connections are made
28 * however, using only one within Samba would be nice
30 * Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
32 * Other LDAP based login attributes: accountExpires, etc.
33 * (should be the domain of Samba proper, but the sam_password/SAM_ACCOUNT
34 * structures don't have fields for some of these attributes)
36 * SSL is done, but can't get the certificate based authentication to work
37 * against on my test platform (Linux 2.4, OpenLDAP 2.x)
40 /* NOTE: this will NOT work against an Active Directory server
41 * due to the fact that the two password fields cannot be retrieved
42 * from a server; recommend using security = domain in this situation
49 #define DBGC_CLASS DBGC_PASSDB
55 * Work around versions of the LDAP client libs that don't have the OIDs
56 * defined, or have them defined under the old name.
57 * This functionality is really a factor of the server, not the client
61 #if defined(LDAP_EXOP_X_MODIFY_PASSWD) && !defined(LDAP_EXOP_MODIFY_PASSWD)
62 #define LDAP_EXOP_MODIFY_PASSWD LDAP_EXOP_X_MODIFY_PASSWD
63 #elif !defined(LDAP_EXOP_MODIFY_PASSWD)
64 #define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1"
67 #if defined(LDAP_EXOP_X_MODIFY_PASSWD_ID) && !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
68 #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID LDAP_EXOP_X_MODIFY_PASSWD_ID
69 #elif !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
70 #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U)
73 #if defined(LDAP_EXOP_X_MODIFY_PASSWD_NEW) && !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
74 #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW LDAP_EXOP_X_MODIFY_PASSWD_NEW
75 #elif !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
76 #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U)
81 #define SAM_ACCOUNT struct sam_passwd
86 /**********************************************************************
87 Free a LDAPMessage (one is stored on the SAM_ACCOUNT).
88 **********************************************************************/
90 void private_data_free_fn(void **result)
92 ldap_msgfree(*result);
96 /**********************************************************************
97 Get the attribute name given a user schame version.
98 **********************************************************************/
100 static const char* get_userattr_key2string( int schema_ver, int key )
102 switch ( schema_ver ) {
103 case SCHEMAVER_SAMBAACCOUNT:
104 return get_attr_key2string( attrib_map_v22, key );
106 case SCHEMAVER_SAMBASAMACCOUNT:
107 return get_attr_key2string( attrib_map_v30, key );
110 DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
116 /**********************************************************************
117 Return the list of attribute names given a user schema version.
118 **********************************************************************/
120 const char** get_userattr_list( int schema_ver )
122 switch ( schema_ver ) {
123 case SCHEMAVER_SAMBAACCOUNT:
124 return get_attr_list( attrib_map_v22 );
126 case SCHEMAVER_SAMBASAMACCOUNT:
127 return get_attr_list( attrib_map_v30 );
129 DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
136 /**************************************************************************
137 Return the list of attribute names to delete given a user schema version.
138 **************************************************************************/
140 static const char** get_userattr_delete_list( int schema_ver )
142 switch ( schema_ver ) {
143 case SCHEMAVER_SAMBAACCOUNT:
144 return get_attr_list( attrib_map_to_delete_v22 );
146 case SCHEMAVER_SAMBASAMACCOUNT:
147 return get_attr_list( attrib_map_to_delete_v30 );
149 DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n"));
157 /*******************************************************************
158 Generate the LDAP search filter for the objectclass based on the
159 version of the schema we are using.
160 ******************************************************************/
162 static const char* get_objclass_filter( int schema_ver )
164 static fstring objclass_filter;
166 switch( schema_ver ) {
167 case SCHEMAVER_SAMBAACCOUNT:
168 fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT );
170 case SCHEMAVER_SAMBASAMACCOUNT:
171 fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
174 DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));
178 return objclass_filter;
181 /*****************************************************************
182 Scan a sequence number off OpenLDAP's syncrepl contextCSN
183 ******************************************************************/
185 static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_num)
187 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
188 NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
189 LDAPMessage *msg = NULL;
190 LDAPMessage *entry = NULL;
192 char **values = NULL;
193 int rc, num_result, num_values, rid;
199 /* Unfortunatly there is no proper way to detect syncrepl-support in
200 * smbldap_connect_system(). The syncrepl OIDs are submitted for publication
201 * but do not show up in the root-DSE yet. Neither we can query the
202 * subschema-context for the syncProviderSubentry or syncConsumerSubentry
203 * objectclass. Currently we require lp_ldap_suffix() to show up as
204 * namingContext. - Guenther
207 if (!lp_parm_bool(-1, "ldapsam", "syncrepl_seqnum", False)) {
212 DEBUG(3,("ldapsam_get_seq_num: no sequence_number\n"));
216 if (!smbldap_has_naming_context(ldap_state->smbldap_state, lp_ldap_suffix())) {
217 DEBUG(3,("ldapsam_get_seq_num: DIT not configured to hold %s "
218 "as top-level namingContext\n", lp_ldap_suffix()));
222 mem_ctx = talloc_init("ldapsam_get_seq_num");
225 return NT_STATUS_NO_MEMORY;
227 attrs = TALLOC_ARRAY(mem_ctx, const char *, 2);
229 /* if we got a syncrepl-rid (up to three digits long) we speak with a consumer */
230 rid = lp_parm_int(-1, "ldapsam", "syncrepl_rid", -1);
233 /* consumer syncreplCookie: */
234 /* csn=20050126161620Z#0000001#00#00000 */
235 attrs[0] = talloc_strdup(mem_ctx, "syncreplCookie");
237 pstr_sprintf( suffix, "cn=syncrepl%d,%s", rid, lp_ldap_suffix());
241 /* provider contextCSN */
242 /* 20050126161620Z#000009#00#000000 */
243 attrs[0] = talloc_strdup(mem_ctx, "contextCSN");
245 pstr_sprintf( suffix, "cn=ldapsync,%s", lp_ldap_suffix());
249 rc = smbldap_search(ldap_state->smbldap_state, suffix,
250 LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &msg);
252 if (rc != LDAP_SUCCESS) {
254 char *ld_error = NULL;
255 ldap_get_option(ldap_state->smbldap_state->ldap_struct,
256 LDAP_OPT_ERROR_STRING, &ld_error);
257 DEBUG(0,("ldapsam_get_seq_num: Failed search for suffix: %s, error: %s (%s)\n",
258 suffix,ldap_err2string(rc), ld_error?ld_error:"unknown"));
263 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg);
264 if (num_result != 1) {
265 DEBUG(3,("ldapsam_get_seq_num: Expected one entry, got %d\n", num_result));
269 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, msg);
271 DEBUG(3,("ldapsam_get_seq_num: Could not retrieve entry\n"));
275 values = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, attrs[0]);
276 if (values == NULL) {
277 DEBUG(3,("ldapsam_get_seq_num: no values\n"));
281 num_values = ldap_count_values(values);
282 if (num_values == 0) {
283 DEBUG(3,("ldapsam_get_seq_num: not a single value\n"));
288 if (!next_token(&p, tok, "#", sizeof(tok))) {
289 DEBUG(0,("ldapsam_get_seq_num: failed to parse sequence number\n"));
294 if (!strncmp(p, "csn=", strlen("csn=")))
297 DEBUG(10,("ldapsam_get_seq_num: got %s: %s\n", attrs[0], p));
299 *seq_num = generalized_to_unix_time(p);
301 /* very basic sanity check */
303 DEBUG(3,("ldapsam_get_seq_num: invalid sequence number: %d\n",
308 ntstatus = NT_STATUS_OK;
312 ldap_value_free(values);
316 talloc_destroy(mem_ctx);
321 /*******************************************************************
322 Run the search by name.
323 ******************************************************************/
325 int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
327 LDAPMessage ** result,
331 char *escape_user = escape_ldap_string_alloc(user);
334 return LDAP_NO_MEMORY;
338 * in the filter expression, replace %u with the real name
339 * so in ldap filter, %u MUST exist :-)
341 pstr_sprintf(filter, "(&%s%s)", "(uid=%u)",
342 get_objclass_filter(ldap_state->schema_ver));
345 * have to use this here because $ is filtered out
350 all_string_sub(filter, "%u", escape_user, sizeof(pstring));
351 SAFE_FREE(escape_user);
353 return smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
356 /*******************************************************************
357 Run the search by rid.
358 ******************************************************************/
360 static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
361 uint32 rid, LDAPMessage ** result,
367 pstr_sprintf(filter, "(&(rid=%i)%s)", rid,
368 get_objclass_filter(ldap_state->schema_ver));
370 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
375 /*******************************************************************
376 Run the search by SID.
377 ******************************************************************/
379 static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
380 const DOM_SID *sid, LDAPMessage ** result,
387 pstr_sprintf(filter, "(&(%s=%s)%s)",
388 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
389 sid_to_string(sid_string, sid),
390 get_objclass_filter(ldap_state->schema_ver));
392 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
397 /*******************************************************************
398 Delete complete object or objectclass and attrs from
399 object found in search_result depending on lp_ldap_delete_dn
400 ******************************************************************/
402 static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
404 const char *objectclass,
408 LDAPMessage *entry = NULL;
409 LDAPMod **mods = NULL;
411 BerElement *ptr = NULL;
413 rc = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
416 DEBUG(0, ("ldapsam_delete_entry: Entry must exist exactly once!\n"));
417 return NT_STATUS_UNSUCCESSFUL;
420 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
421 dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
423 return NT_STATUS_UNSUCCESSFUL;
426 if (lp_ldap_delete_dn()) {
427 NTSTATUS ret = NT_STATUS_OK;
428 rc = smbldap_delete(ldap_state->smbldap_state, dn);
430 if (rc != LDAP_SUCCESS) {
431 DEBUG(0, ("ldapsam_delete_entry: Could not delete object %s\n", dn));
432 ret = NT_STATUS_UNSUCCESSFUL;
438 /* Ok, delete only the SAM attributes */
440 for (name = ldap_first_attribute(ldap_state->smbldap_state->ldap_struct, entry, &ptr);
442 name = ldap_next_attribute(ldap_state->smbldap_state->ldap_struct, entry, ptr)) {
445 /* We are only allowed to delete the attributes that
448 for (attrib = attrs; *attrib != NULL; attrib++) {
449 /* Don't delete LDAP_ATTR_MOD_TIMESTAMP attribute. */
450 if (strequal(*attrib, get_userattr_key2string(ldap_state->schema_ver,
451 LDAP_ATTR_MOD_TIMESTAMP))) {
454 if (strequal(*attrib, name)) {
455 DEBUG(10, ("ldapsam_delete_entry: deleting "
456 "attribute %s\n", name));
457 smbldap_set_mod(&mods, LDAP_MOD_DELETE, name,
469 smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
471 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
472 ldap_mods_free(mods, True);
474 if (rc != LDAP_SUCCESS) {
475 char *ld_error = NULL;
476 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
479 DEBUG(0, ("ldapsam_delete_entry: Could not delete attributes for %s, error: %s (%s)\n",
480 dn, ldap_err2string(rc), ld_error?ld_error:"unknown"));
483 return NT_STATUS_UNSUCCESSFUL;
490 /* New Interface is being implemented here */
492 #if 0 /* JERRY - not uesed anymore */
494 /**********************************************************************
495 Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
496 *********************************************************************/
497 static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
498 SAM_ACCOUNT * sampass,
507 if ((ldap_values = ldap_get_values (ldap_state->smbldap_state->ldap_struct, entry, "objectClass")) == NULL) {
508 DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
512 for (values=ldap_values;*values;values++) {
513 if (strequal(*values, LDAP_OBJ_POSIXACCOUNT )) {
518 if (!*values) { /*end of array, no posixAccount */
519 DEBUG(10, ("user does not have %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
520 ldap_value_free(ldap_values);
523 ldap_value_free(ldap_values);
525 if ( !smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
526 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_UNIX_HOME), homedir) )
531 if ( !smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
532 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_GIDNUMBER), temp) )
537 *gid = (gid_t)atol(temp);
539 pdb_set_unix_homedir(sampass, homedir, PDB_SET);
541 DEBUG(10, ("user has %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
548 static time_t ldapsam_get_entry_timestamp(
549 struct ldapsam_privates *ldap_state,
555 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
556 get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP),
560 strptime(temp, "%Y%m%d%H%M%SZ", &tm);
565 /**********************************************************************
566 Initialize SAM_ACCOUNT from an LDAP query.
567 (Based on init_sam_from_buffer in pdb_tdb.c)
568 *********************************************************************/
570 static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
571 SAM_ACCOUNT * sampass,
578 pass_can_change_time,
579 pass_must_change_time,
592 char munged_dial[2048];
594 uint8 smblmpwd[LM_HASH_LEN],
595 smbntpwd[NT_HASH_LEN];
596 BOOL use_samba_attrs = True;
597 uint16 acct_ctrl = 0,
599 uint16 bad_password_count = 0,
602 uint8 hours[MAX_HOURS_LEN];
604 LOGIN_CACHE *cache_entry = NULL;
607 BOOL expand_explicit = lp_parm_bool(-1, "passdb", "expand_explicit",
611 * do a little initialization
615 nt_username[0] = '\0';
619 logon_script[0] = '\0';
620 profile_path[0] = '\0';
622 munged_dial[0] = '\0';
623 workstations[0] = '\0';
626 if (sampass == NULL || ldap_state == NULL || entry == NULL) {
627 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
631 if (ldap_state->smbldap_state->ldap_struct == NULL) {
632 DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->ldap_struct is NULL!\n"));
636 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry, "uid", username)) {
637 DEBUG(1, ("init_sam_from_ldap: No uid attribute found for this user!\n"));
641 DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username));
643 pstrcpy(nt_username, username);
645 pstrcpy(domain, ldap_state->domain_name);
647 pdb_set_username(sampass, username, PDB_SET);
649 pdb_set_domain(sampass, domain, PDB_DEFAULT);
650 pdb_set_nt_username(sampass, nt_username, PDB_SET);
652 /* deal with different attributes between the schema first */
654 if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ) {
655 if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
656 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), temp)) {
657 pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
660 if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
661 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_SID), temp)) {
662 pdb_set_group_sid_from_string(sampass, temp, PDB_SET);
664 pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
667 if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
668 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), temp)) {
669 user_rid = (uint32)atol(temp);
670 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
673 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
674 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_RID), temp)) {
675 pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
679 group_rid = (uint32)atol(temp);
681 /* for some reason, we often have 0 as a primary group RID.
682 Make sure that we treat this just as a 'default' value */
685 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
687 pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
691 if (pdb_get_init_flags(sampass,PDB_USERSID) == PDB_DEFAULT) {
692 DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n",
693 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
694 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
699 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
700 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), temp)) {
701 /* leave as default */
703 pass_last_set_time = (time_t) atol(temp);
704 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
707 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
708 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp)) {
709 /* leave as default */
711 logon_time = (time_t) atol(temp);
712 pdb_set_logon_time(sampass, logon_time, PDB_SET);
715 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
716 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp)) {
717 /* leave as default */
719 logoff_time = (time_t) atol(temp);
720 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
723 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
724 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp)) {
725 /* leave as default */
727 kickoff_time = (time_t) atol(temp);
728 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
731 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
732 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp)) {
733 /* leave as default */
735 pass_can_change_time = (time_t) atol(temp);
736 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
739 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
740 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp)) {
741 /* leave as default */
743 pass_must_change_time = (time_t) atol(temp);
744 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
747 /* recommend that 'gecos' and 'displayName' should refer to the same
748 * attribute OID. userFullName depreciated, only used by Samba
749 * primary rules of LDAP: don't make a new attribute when one is already defined
750 * that fits your needs; using cn then displayName rather than 'userFullName'
753 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
754 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME), fullname)) {
755 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
756 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_CN), fullname)) {
757 /* leave as default */
759 pdb_set_fullname(sampass, fullname, PDB_SET);
762 pdb_set_fullname(sampass, fullname, PDB_SET);
765 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
766 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), dir_drive))
768 pdb_set_dir_drive( sampass, lp_logon_drive(), PDB_DEFAULT );
770 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
773 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
774 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), homedir))
776 pdb_set_homedir( sampass,
777 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
780 pstrcpy( tmpstring, homedir );
781 if (expand_explicit) {
782 standard_sub_basic( username, tmpstring,
785 pdb_set_homedir(sampass, tmpstring, PDB_SET);
788 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
789 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), logon_script))
791 pdb_set_logon_script( sampass,
792 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
795 pstrcpy( tmpstring, logon_script );
796 if (expand_explicit) {
797 standard_sub_basic( username, tmpstring,
800 pdb_set_logon_script(sampass, tmpstring, PDB_SET);
803 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
804 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), profile_path))
806 pdb_set_profile_path( sampass,
807 talloc_sub_basic( sampass->mem_ctx, username, lp_logon_path()),
810 pstrcpy( tmpstring, profile_path );
811 if (expand_explicit) {
812 standard_sub_basic( username, tmpstring,
815 pdb_set_profile_path(sampass, tmpstring, PDB_SET);
818 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
819 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC), acct_desc))
821 /* leave as default */
823 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
826 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
827 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), workstations)) {
828 /* leave as default */;
830 pdb_set_workstations(sampass, workstations, PDB_SET);
833 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
834 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), munged_dial, sizeof(munged_dial))) {
835 /* leave as default */;
837 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
840 /* FIXME: hours stuff should be cleaner */
844 memset(hours, 0xff, hours_len);
846 if (ldap_state->is_nds_ldap) {
849 char clear_text_pw[512];
851 /* Make call to Novell eDirectory ldap extension to get clear text password.
852 NOTE: This will only work if we have an SSL connection to eDirectory. */
853 user_dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
854 if (user_dn != NULL) {
855 DEBUG(3, ("init_sam_from_ldap: smbldap_get_dn(%s) returned '%s'\n", username, user_dn));
857 pwd_len = sizeof(clear_text_pw);
858 if (pdb_nds_get_password(ldap_state->smbldap_state, user_dn, &pwd_len, clear_text_pw) == LDAP_SUCCESS) {
859 nt_lm_owf_gen(clear_text_pw, smbntpwd, smblmpwd);
860 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
862 ZERO_STRUCT(smblmpwd);
863 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
865 ZERO_STRUCT(smbntpwd);
866 use_samba_attrs = False;
869 DEBUG(0, ("init_sam_from_ldap: failed to get user_dn for '%s'\n", username));
873 if (use_samba_attrs) {
874 if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
875 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), temp)) {
876 /* leave as default */
878 pdb_gethexpwd(temp, smblmpwd);
879 memset((char *)temp, '\0', strlen(temp)+1);
880 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
882 ZERO_STRUCT(smblmpwd);
885 if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
886 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), temp)) {
887 /* leave as default */
889 pdb_gethexpwd(temp, smbntpwd);
890 memset((char *)temp, '\0', strlen(temp)+1);
891 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
893 ZERO_STRUCT(smbntpwd);
899 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
901 uint8 *pwhist = NULL;
904 /* We can only store (sizeof(pstring)-1)/64 password history entries. */
905 pwHistLen = MIN(pwHistLen, ((sizeof(temp)-1)/64));
907 if ((pwhist = SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN)) == NULL){
908 DEBUG(0, ("init_sam_from_ldap: malloc failed!\n"));
911 memset(pwhist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
913 if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
914 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY), temp)) {
915 /* leave as default - zeros */
917 BOOL hex_failed = False;
918 for (i = 0; i < pwHistLen; i++){
919 /* Get the 16 byte salt. */
920 if (!pdb_gethexpwd(&temp[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN])) {
924 /* Get the 16 byte MD5 hash of salt+passwd. */
925 if (!pdb_gethexpwd(&temp[(i*64)+32],
926 &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN])) {
932 DEBUG(0,("init_sam_from_ldap: Failed to get password history for user %s\n",
934 memset(pwhist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
937 if (!pdb_set_pw_history(sampass, pwhist, pwHistLen, PDB_SET)){
944 if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
945 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), temp)) {
946 acct_ctrl |= ACB_NORMAL;
948 acct_ctrl = pdb_decode_acct_ctrl(temp);
951 acct_ctrl |= ACB_NORMAL;
953 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
956 pdb_set_hours_len(sampass, hours_len, PDB_SET);
957 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
959 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
960 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_COUNT), temp)) {
961 /* leave as default */
963 bad_password_count = (uint32) atol(temp);
964 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
967 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
968 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_TIME), temp)) {
969 /* leave as default */
971 bad_password_time = (time_t) atol(temp);
972 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
976 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
977 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_COUNT), temp)) {
978 /* leave as default */
980 logon_count = (uint32) atol(temp);
981 pdb_set_logon_count(sampass, logon_count, PDB_SET);
984 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
986 if(!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
987 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_HOURS), temp)) {
988 /* leave as default */
990 pdb_gethexhours(temp, hours);
991 memset((char *)temp, '\0', strlen(temp) +1);
992 pdb_set_hours(sampass, hours, PDB_SET);
996 /* check the timestamp of the cache vs ldap entry */
997 if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state,
1001 /* see if we have newer updates */
1002 if (!(cache_entry = login_cache_read(sampass))) {
1003 DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n",
1004 (unsigned int)pdb_get_bad_password_count(sampass),
1005 (unsigned int)pdb_get_bad_password_time(sampass)));
1009 DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n",
1010 (unsigned int)ldap_entry_time, (unsigned int)cache_entry->entry_timestamp,
1011 (unsigned int)cache_entry->bad_password_time));
1013 if (ldap_entry_time > cache_entry->entry_timestamp) {
1014 /* cache is older than directory , so
1015 we need to delete the entry but allow the
1016 fields to be written out */
1017 login_cache_delentry(sampass);
1020 pdb_set_acct_ctrl(sampass,
1021 pdb_get_acct_ctrl(sampass) |
1022 (cache_entry->acct_ctrl & ACB_AUTOLOCK),
1024 pdb_set_bad_password_count(sampass,
1025 cache_entry->bad_password_count,
1027 pdb_set_bad_password_time(sampass,
1028 cache_entry->bad_password_time,
1032 SAFE_FREE(cache_entry);
1036 /**********************************************************************
1037 Initialize the ldap db from a SAM_ACCOUNT. Called on update.
1038 (Based on init_buffer_from_sam in pdb_tdb.c)
1039 *********************************************************************/
1041 static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
1042 LDAPMessage *existing,
1043 LDAPMod *** mods, SAM_ACCOUNT * sampass,
1044 BOOL (*need_update)(const SAM_ACCOUNT *,
1050 if (mods == NULL || sampass == NULL) {
1051 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
1058 * took out adding "objectclass: sambaAccount"
1059 * do this on a per-mod basis
1061 if (need_update(sampass, PDB_USERNAME))
1062 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1063 "uid", pdb_get_username(sampass));
1065 DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass)));
1067 /* only update the RID if we actually need to */
1068 if (need_update(sampass, PDB_USERSID)) {
1070 fstring dom_sid_string;
1071 const DOM_SID *user_sid = pdb_get_user_sid(sampass);
1073 switch ( ldap_state->schema_ver ) {
1074 case SCHEMAVER_SAMBAACCOUNT:
1075 if (!sid_peek_check_rid(&ldap_state->domain_sid, user_sid, &rid)) {
1076 DEBUG(1, ("init_ldap_from_sam: User's SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
1077 sid_to_string(sid_string, user_sid),
1078 sid_to_string(dom_sid_string, &ldap_state->domain_sid)));
1081 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1082 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1083 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
1087 case SCHEMAVER_SAMBASAMACCOUNT:
1088 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1089 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
1090 sid_to_string(sid_string, user_sid));
1094 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
1099 /* we don't need to store the primary group RID - so leaving it
1100 'free' to hang off the unix primary group makes life easier */
1102 if (need_update(sampass, PDB_GROUPSID)) {
1104 fstring dom_sid_string;
1105 const DOM_SID *group_sid = pdb_get_group_sid(sampass);
1107 switch ( ldap_state->schema_ver ) {
1108 case SCHEMAVER_SAMBAACCOUNT:
1109 if (!sid_peek_check_rid(&ldap_state->domain_sid, group_sid, &rid)) {
1110 DEBUG(1, ("init_ldap_from_sam: User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
1111 sid_to_string(sid_string, group_sid),
1112 sid_to_string(dom_sid_string, &ldap_state->domain_sid)));
1116 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1117 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1118 get_userattr_key2string(ldap_state->schema_ver,
1119 LDAP_ATTR_PRIMARY_GROUP_RID), temp);
1122 case SCHEMAVER_SAMBASAMACCOUNT:
1123 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1124 get_userattr_key2string(ldap_state->schema_ver,
1125 LDAP_ATTR_PRIMARY_GROUP_SID), sid_to_string(sid_string, group_sid));
1129 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
1135 /* displayName, cn, and gecos should all be the same
1136 * most easily accomplished by giving them the same OID
1137 * gecos isn't set here b/c it should be handled by the
1139 * We change displayName only and fall back to cn if
1140 * it does not exist.
1143 if (need_update(sampass, PDB_FULLNAME))
1144 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1145 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME),
1146 pdb_get_fullname(sampass));
1148 if (need_update(sampass, PDB_ACCTDESC))
1149 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1150 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC),
1151 pdb_get_acct_desc(sampass));
1153 if (need_update(sampass, PDB_WORKSTATIONS))
1154 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1155 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS),
1156 pdb_get_workstations(sampass));
1158 if (need_update(sampass, PDB_MUNGEDDIAL))
1159 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1160 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL),
1161 pdb_get_munged_dial(sampass));
1163 if (need_update(sampass, PDB_SMBHOME))
1164 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1165 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH),
1166 pdb_get_homedir(sampass));
1168 if (need_update(sampass, PDB_DRIVE))
1169 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1170 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE),
1171 pdb_get_dir_drive(sampass));
1173 if (need_update(sampass, PDB_LOGONSCRIPT))
1174 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1175 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT),
1176 pdb_get_logon_script(sampass));
1178 if (need_update(sampass, PDB_PROFILE))
1179 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1180 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH),
1181 pdb_get_profile_path(sampass));
1183 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
1184 if (need_update(sampass, PDB_LOGONTIME))
1185 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1186 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
1188 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
1189 if (need_update(sampass, PDB_LOGOFFTIME))
1190 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1191 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
1193 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
1194 if (need_update(sampass, PDB_KICKOFFTIME))
1195 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1196 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
1198 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
1199 if (need_update(sampass, PDB_CANCHANGETIME))
1200 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1201 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
1203 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
1204 if (need_update(sampass, PDB_MUSTCHANGETIME))
1205 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1206 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp);
1209 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
1210 || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
1212 if (need_update(sampass, PDB_LMPASSWD)) {
1213 const uchar *lm_pw = pdb_get_lanman_passwd(sampass);
1215 pdb_sethexpwd(temp, lm_pw,
1216 pdb_get_acct_ctrl(sampass));
1217 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1218 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
1221 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1222 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
1226 if (need_update(sampass, PDB_NTPASSWD)) {
1227 const uchar *nt_pw = pdb_get_nt_passwd(sampass);
1229 pdb_sethexpwd(temp, nt_pw,
1230 pdb_get_acct_ctrl(sampass));
1231 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1232 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
1235 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1236 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
1241 if (need_update(sampass, PDB_PWHISTORY)) {
1242 uint32 pwHistLen = 0;
1243 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1244 if (pwHistLen == 0) {
1245 /* Remove any password history from the LDAP store. */
1246 memset(temp, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
1250 uint32 currHistLen = 0;
1251 const uint8 *pwhist = pdb_get_pw_history(sampass, &currHistLen);
1252 if (pwhist != NULL) {
1253 /* We can only store (sizeof(pstring)-1)/64 password history entries. */
1254 pwHistLen = MIN(pwHistLen, ((sizeof(temp)-1)/64));
1255 for (i=0; i< pwHistLen && i < currHistLen; i++) {
1256 /* Store the salt. */
1257 pdb_sethexpwd(&temp[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN], 0);
1258 /* Followed by the md5 hash of salt + md4 hash */
1259 pdb_sethexpwd(&temp[(i*64)+32],
1260 &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN], 0);
1261 DEBUG(100, ("temp=%s\n", temp));
1265 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1266 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY),
1270 if (need_update(sampass, PDB_PASSLASTSET)) {
1271 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
1272 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1273 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET),
1278 if (need_update(sampass, PDB_HOURS)) {
1279 const uint8 *hours = pdb_get_hours(sampass);
1281 pdb_sethexhours(temp, hours);
1282 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct,
1285 get_userattr_key2string(ldap_state->schema_ver,
1286 LDAP_ATTR_LOGON_HOURS),
1291 if (need_update(sampass, PDB_ACCTCTRL))
1292 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1293 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO),
1294 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
1296 /* password lockout cache:
1297 - If we are now autolocking or clearing, we write to ldap
1298 - If we are clearing, we delete the cache entry
1299 - If the count is > 0, we update the cache
1301 This even means when autolocking, we cache, just in case the
1302 update doesn't work, and we have to cache the autolock flag */
1304 if (need_update(sampass, PDB_BAD_PASSWORD_COUNT)) /* &&
1305 need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ {
1306 uint16 badcount = pdb_get_bad_password_count(sampass);
1307 time_t badtime = pdb_get_bad_password_time(sampass);
1309 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &pol);
1311 DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
1312 (unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime));
1314 if ((badcount >= pol) || (badcount == 0)) {
1315 DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n",
1316 (unsigned int)badcount, (unsigned int)badtime));
1317 slprintf (temp, sizeof (temp) - 1, "%li", (long)badcount);
1319 ldap_state->smbldap_state->ldap_struct,
1321 get_userattr_key2string(
1322 ldap_state->schema_ver,
1323 LDAP_ATTR_BAD_PASSWORD_COUNT),
1326 slprintf (temp, sizeof (temp) - 1, "%li", badtime);
1328 ldap_state->smbldap_state->ldap_struct,
1330 get_userattr_key2string(
1331 ldap_state->schema_ver,
1332 LDAP_ATTR_BAD_PASSWORD_TIME),
1335 if (badcount == 0) {
1336 DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass)));
1337 login_cache_delentry(sampass);
1339 LOGIN_CACHE cache_entry;
1341 cache_entry.entry_timestamp = time(NULL);
1342 cache_entry.acct_ctrl = pdb_get_acct_ctrl(sampass);
1343 cache_entry.bad_password_count = badcount;
1344 cache_entry.bad_password_time = badtime;
1346 DEBUG(7, ("Updating bad password count and time in login cache\n"));
1347 login_cache_write(sampass, cache_entry);
1354 /**********************************************************************
1355 Connect to LDAP server for password enumeration.
1356 *********************************************************************/
1358 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint16 acb_mask)
1360 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1362 pstring filter, suffix;
1363 const char **attr_list;
1364 BOOL machine_mask = False, user_mask = False;
1366 pstr_sprintf( filter, "(&%s%s)", "(uid=%u)",
1367 get_objclass_filter(ldap_state->schema_ver));
1368 all_string_sub(filter, "%u", "*", sizeof(pstring));
1370 machine_mask = ((acb_mask != 0) && (acb_mask & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)));
1371 user_mask = ((acb_mask != 0) && (acb_mask & ACB_NORMAL));
1374 pstrcpy(suffix, lp_ldap_machine_suffix());
1375 } else if (user_mask) {
1376 pstrcpy(suffix, lp_ldap_user_suffix());
1378 pstrcpy(suffix, lp_ldap_suffix());
1381 DEBUG(10,("ldapsam_setsampwent: LDAP Query for acb_mask 0x%x will use suffix %s\n",
1384 attr_list = get_userattr_list(ldap_state->schema_ver);
1385 rc = smbldap_search(ldap_state->smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter,
1386 attr_list, 0, &ldap_state->result);
1387 free_attr_list( attr_list );
1389 if (rc != LDAP_SUCCESS) {
1390 DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc)));
1391 DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", suffix, filter));
1392 ldap_msgfree(ldap_state->result);
1393 ldap_state->result = NULL;
1394 return NT_STATUS_UNSUCCESSFUL;
1397 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base %s\n",
1398 ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
1399 ldap_state->result), suffix));
1401 ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
1402 ldap_state->result);
1403 ldap_state->index = 0;
1405 return NT_STATUS_OK;
1408 /**********************************************************************
1409 End enumeration of the LDAP password list.
1410 *********************************************************************/
1412 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1414 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1415 if (ldap_state->result) {
1416 ldap_msgfree(ldap_state->result);
1417 ldap_state->result = NULL;
1421 /**********************************************************************
1422 Get the next entry in the LDAP password database.
1423 *********************************************************************/
1425 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
1427 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1428 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1432 if (!ldap_state->entry)
1435 ldap_state->index++;
1436 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
1438 ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
1442 return NT_STATUS_OK;
1445 static void append_attr(const char ***attr_list, const char *new_attr)
1449 if (new_attr == NULL) {
1453 for (i=0; (*attr_list)[i] != NULL; i++) {
1457 (*attr_list) = SMB_REALLOC_ARRAY((*attr_list), const char *, i+2);
1458 SMB_ASSERT((*attr_list) != NULL);
1459 (*attr_list)[i] = SMB_STRDUP(new_attr);
1460 (*attr_list)[i+1] = NULL;
1463 /**********************************************************************
1464 Get SAM_ACCOUNT entry from LDAP by username.
1465 *********************************************************************/
1467 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
1469 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1470 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1471 LDAPMessage *result = NULL;
1472 LDAPMessage *entry = NULL;
1474 const char ** attr_list;
1477 attr_list = get_userattr_list( ldap_state->schema_ver );
1478 append_attr(&attr_list, get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP));
1479 rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
1480 free_attr_list( attr_list );
1482 if ( rc != LDAP_SUCCESS )
1483 return NT_STATUS_NO_SUCH_USER;
1485 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1488 DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname, count));
1489 ldap_msgfree(result);
1490 return NT_STATUS_NO_SUCH_USER;
1491 } else if (count > 1) {
1492 DEBUG(1, ("ldapsam_getsampwnam: Duplicate entries for this user [%s] Failing. count=%d\n", sname, count));
1493 ldap_msgfree(result);
1494 return NT_STATUS_NO_SUCH_USER;
1497 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1499 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1500 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1501 ldap_msgfree(result);
1502 return NT_STATUS_NO_SUCH_USER;
1504 pdb_set_backend_private_data(user, result,
1505 private_data_free_fn,
1506 my_methods, PDB_CHANGED);
1509 ldap_msgfree(result);
1514 static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
1515 const DOM_SID *sid, LDAPMessage **result)
1518 const char ** attr_list;
1521 switch ( ldap_state->schema_ver ) {
1522 case SCHEMAVER_SAMBASAMACCOUNT:
1523 attr_list = get_userattr_list(ldap_state->schema_ver);
1524 append_attr(&attr_list, get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP));
1525 rc = ldapsam_search_suffix_by_sid(ldap_state, sid, result, attr_list);
1526 free_attr_list( attr_list );
1528 if ( rc != LDAP_SUCCESS )
1532 case SCHEMAVER_SAMBAACCOUNT:
1533 if (!sid_peek_check_rid(&ldap_state->domain_sid, sid, &rid)) {
1537 attr_list = get_userattr_list(ldap_state->schema_ver);
1538 rc = ldapsam_search_suffix_by_rid(ldap_state, rid, result, attr_list );
1539 free_attr_list( attr_list );
1541 if ( rc != LDAP_SUCCESS )
1548 /**********************************************************************
1549 Get SAM_ACCOUNT entry from LDAP by SID.
1550 *********************************************************************/
1552 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
1554 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1555 LDAPMessage *result = NULL;
1556 LDAPMessage *entry = NULL;
1561 rc = ldapsam_get_ldap_user_by_sid(ldap_state,
1563 if (rc != LDAP_SUCCESS)
1564 return NT_STATUS_NO_SUCH_USER;
1566 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1569 DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] count=%d\n", sid_to_string(sid_string, sid),
1571 ldap_msgfree(result);
1572 return NT_STATUS_NO_SUCH_USER;
1573 } else if (count > 1) {
1574 DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID [%s]. Failing. count=%d\n", sid_to_string(sid_string, sid),
1576 ldap_msgfree(result);
1577 return NT_STATUS_NO_SUCH_USER;
1580 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1582 ldap_msgfree(result);
1583 return NT_STATUS_NO_SUCH_USER;
1586 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1587 DEBUG(1,("ldapsam_getsampwsid: init_sam_from_ldap failed!\n"));
1588 ldap_msgfree(result);
1589 return NT_STATUS_NO_SUCH_USER;
1592 pdb_set_backend_private_data(user, result,
1593 private_data_free_fn,
1594 my_methods, PDB_CHANGED);
1595 return NT_STATUS_OK;
1598 static BOOL ldapsam_can_pwchange_exop(struct smbldap_state *ldap_state)
1600 return smbldap_has_extension(ldap_state, LDAP_EXOP_MODIFY_PASSWD);
1603 /********************************************************************
1604 Do the actual modification - also change a plaintext passord if
1606 **********************************************************************/
1608 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1609 SAM_ACCOUNT *newpwd, char *dn,
1610 LDAPMod **mods, int ldap_op,
1611 BOOL (*need_update)(const SAM_ACCOUNT *, enum pdb_elements))
1613 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1616 if (!my_methods || !newpwd || !dn) {
1617 return NT_STATUS_INVALID_PARAMETER;
1621 DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
1622 /* may be password change below however */
1626 smbldap_set_mod(&mods, LDAP_MOD_ADD,
1629 rc = smbldap_add(ldap_state->smbldap_state,
1632 case LDAP_MOD_REPLACE:
1633 rc = smbldap_modify(ldap_state->smbldap_state,
1637 DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n",
1639 return NT_STATUS_INVALID_PARAMETER;
1642 if (rc!=LDAP_SUCCESS) {
1643 char *ld_error = NULL;
1644 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1646 DEBUG(1, ("ldapsam_modify_entry: Failed to %s user dn= %s with: %s\n\t%s\n",
1647 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
1648 dn, ldap_err2string(rc),
1649 ld_error?ld_error:"unknown"));
1650 SAFE_FREE(ld_error);
1651 return NT_STATUS_UNSUCCESSFUL;
1655 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) &&
1656 (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) &&
1657 need_update(newpwd, PDB_PLAINTEXT_PW) &&
1658 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1661 char *retoid = NULL;
1662 struct berval *retdata = NULL;
1663 char *utf8_password;
1666 if (!ldap_state->is_nds_ldap) {
1667 if (!ldapsam_can_pwchange_exop(ldap_state->smbldap_state)) {
1668 DEBUG(2, ("ldap password change requested, but LDAP "
1669 "server does not support it -- ignoring\n"));
1670 return NT_STATUS_OK;
1674 if (push_utf8_allocate(&utf8_password, pdb_get_plaintext_passwd(newpwd)) == (size_t)-1) {
1675 return NT_STATUS_NO_MEMORY;
1678 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
1679 return NT_STATUS_NO_MEMORY;
1682 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1683 DEBUG(0,("ber_alloc_t returns NULL\n"));
1684 SAFE_FREE(utf8_password);
1685 return NT_STATUS_UNSUCCESSFUL;
1688 ber_printf (ber, "{");
1689 ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn);
1690 ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password);
1691 ber_printf (ber, "N}");
1693 if ((rc = ber_flatten (ber, &bv))<0) {
1694 DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
1697 SAFE_FREE(utf8_password);
1698 return NT_STATUS_UNSUCCESSFUL;
1702 SAFE_FREE(utf8_password);
1705 if (!ldap_state->is_nds_ldap) {
1706 rc = smbldap_extended_operation(ldap_state->smbldap_state,
1707 LDAP_EXOP_MODIFY_PASSWD,
1708 bv, NULL, NULL, &retoid,
1711 rc = pdb_nds_set_password(ldap_state->smbldap_state, dn,
1712 pdb_get_plaintext_passwd(newpwd));
1714 if (rc != LDAP_SUCCESS) {
1715 char *ld_error = NULL;
1717 if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
1718 DEBUG(3, ("Could not set userPassword "
1719 "attribute due to an objectClass "
1720 "violation -- ignoring\n"));
1722 return NT_STATUS_OK;
1725 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1727 DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n",
1728 pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
1729 SAFE_FREE(ld_error);
1731 return NT_STATUS_UNSUCCESSFUL;
1733 DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1734 #ifdef DEBUG_PASSWORD
1735 DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd)));
1738 ber_bvfree(retdata);
1740 ber_memfree(retoid);
1744 return NT_STATUS_OK;
1747 /**********************************************************************
1748 Delete entry from LDAP for username.
1749 *********************************************************************/
1751 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
1753 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1756 LDAPMessage *result = NULL;
1758 const char **attr_list;
1762 DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n"));
1763 return NT_STATUS_INVALID_PARAMETER;
1766 sname = pdb_get_username(sam_acct);
1768 DEBUG (3, ("ldapsam_delete_sam_account: Deleting user %s from LDAP.\n", sname));
1770 attr_list= get_userattr_delete_list( ldap_state->schema_ver );
1771 rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
1773 if (rc != LDAP_SUCCESS) {
1774 free_attr_list( attr_list );
1775 return NT_STATUS_NO_SUCH_USER;
1778 switch ( ldap_state->schema_ver ) {
1779 case SCHEMAVER_SAMBASAMACCOUNT:
1780 fstrcpy( objclass, LDAP_OBJ_SAMBASAMACCOUNT );
1783 case SCHEMAVER_SAMBAACCOUNT:
1784 fstrcpy( objclass, LDAP_OBJ_SAMBAACCOUNT );
1787 fstrcpy( objclass, "UNKNOWN" );
1788 DEBUG(0,("ldapsam_delete_sam_account: Unknown schema version specified!\n"));
1792 ret = ldapsam_delete_entry(ldap_state, result, objclass, attr_list );
1793 ldap_msgfree(result);
1794 free_attr_list( attr_list );
1799 /**********************************************************************
1800 Helper function to determine for update_sam_account whether
1801 we need LDAP modification.
1802 *********************************************************************/
1804 static BOOL element_is_changed(const SAM_ACCOUNT *sampass,
1805 enum pdb_elements element)
1807 return IS_SAM_CHANGED(sampass, element);
1810 /**********************************************************************
1812 *********************************************************************/
1814 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1816 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1817 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1820 LDAPMessage *result = NULL;
1821 LDAPMessage *entry = NULL;
1822 LDAPMod **mods = NULL;
1823 const char **attr_list;
1825 result = pdb_get_backend_private_data(newpwd, my_methods);
1827 attr_list = get_userattr_list(ldap_state->schema_ver);
1828 rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
1829 free_attr_list( attr_list );
1830 if (rc != LDAP_SUCCESS) {
1831 return NT_STATUS_UNSUCCESSFUL;
1833 pdb_set_backend_private_data(newpwd, result, private_data_free_fn, my_methods, PDB_CHANGED);
1836 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
1837 DEBUG(0, ("ldapsam_update_sam_account: No user to modify!\n"));
1838 return NT_STATUS_UNSUCCESSFUL;
1841 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1842 dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
1844 return NT_STATUS_UNSUCCESSFUL;
1847 DEBUG(4, ("ldapsam_update_sam_account: user %s to be modified has dn: %s\n", pdb_get_username(newpwd), dn));
1849 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
1850 element_is_changed)) {
1851 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1854 ldap_mods_free(mods,True);
1855 return NT_STATUS_UNSUCCESSFUL;
1859 DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
1860 pdb_get_username(newpwd)));
1862 return NT_STATUS_OK;
1865 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed);
1866 ldap_mods_free(mods,True);
1869 if (!NT_STATUS_IS_OK(ret)) {
1870 char *ld_error = NULL;
1871 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1873 DEBUG(0,("ldapsam_update_sam_account: failed to modify user with uid = %s, error: %s (%s)\n",
1874 pdb_get_username(newpwd), ld_error?ld_error:"(unknwon)", ldap_err2string(rc)));
1875 SAFE_FREE(ld_error);
1879 DEBUG(2, ("ldapsam_update_sam_account: successfully modified uid = %s in the LDAP database\n",
1880 pdb_get_username(newpwd)));
1881 return NT_STATUS_OK;
1884 /***************************************************************************
1885 Renames a SAM_ACCOUNT
1886 - The "rename user script" has full responsibility for changing everything
1887 ***************************************************************************/
1889 static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
1890 SAM_ACCOUNT *old_acct,
1891 const char *newname)
1893 const char *oldname;
1895 pstring rename_script;
1898 DEBUG(0, ("ldapsam_rename_sam_account: old_acct was NULL!\n"));
1899 return NT_STATUS_INVALID_PARAMETER;
1902 DEBUG(0, ("ldapsam_rename_sam_account: newname was NULL!\n"));
1903 return NT_STATUS_INVALID_PARAMETER;
1906 oldname = pdb_get_username(old_acct);
1908 /* rename the posix user */
1909 pstrcpy(rename_script, lp_renameuser_script());
1911 if (!(*rename_script))
1912 return NT_STATUS_ACCESS_DENIED;
1914 DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n",
1917 pstring_sub(rename_script, "%unew", newname);
1918 pstring_sub(rename_script, "%uold", oldname);
1919 rc = smbrun(rename_script, NULL);
1921 DEBUG(rc ? 0 : 3,("Running the command `%s' gave %d\n",
1922 rename_script, rc));
1925 return NT_STATUS_UNSUCCESSFUL;
1927 return NT_STATUS_OK;
1930 /**********************************************************************
1931 Helper function to determine for update_sam_account whether
1932 we need LDAP modification.
1933 *********************************************************************/
1935 static BOOL element_is_set_or_changed(const SAM_ACCOUNT *sampass,
1936 enum pdb_elements element)
1938 return (IS_SAM_SET(sampass, element) ||
1939 IS_SAM_CHANGED(sampass, element));
1942 /**********************************************************************
1943 Add SAM_ACCOUNT to LDAP.
1944 *********************************************************************/
1946 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1948 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1949 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1951 LDAPMessage *result = NULL;
1952 LDAPMessage *entry = NULL;
1954 LDAPMod **mods = NULL;
1955 int ldap_op = LDAP_MOD_REPLACE;
1957 const char **attr_list;
1959 const char *username = pdb_get_username(newpwd);
1960 const DOM_SID *sid = pdb_get_user_sid(newpwd);
1964 if (!username || !*username) {
1965 DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
1966 return NT_STATUS_INVALID_PARAMETER;
1969 /* free this list after the second search or in case we exit on failure */
1970 attr_list = get_userattr_list(ldap_state->schema_ver);
1972 rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
1974 if (rc != LDAP_SUCCESS) {
1975 free_attr_list( attr_list );
1976 return NT_STATUS_UNSUCCESSFUL;
1979 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
1980 DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n",
1982 ldap_msgfree(result);
1983 free_attr_list( attr_list );
1984 return NT_STATUS_UNSUCCESSFUL;
1986 ldap_msgfree(result);
1989 if (element_is_set_or_changed(newpwd, PDB_USERSID)) {
1990 rc = ldapsam_get_ldap_user_by_sid(ldap_state,
1992 if (rc == LDAP_SUCCESS) {
1993 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
1994 DEBUG(0,("ldapsam_add_sam_account: SID '%s' already in the base, with samba attributes\n",
1995 sid_to_string(sid_string, sid)));
1996 free_attr_list( attr_list );
1997 ldap_msgfree(result);
1998 return NT_STATUS_UNSUCCESSFUL;
2000 ldap_msgfree(result);
2004 /* does the entry already exist but without a samba attributes?
2005 we need to return the samba attributes here */
2007 escape_user = escape_ldap_string_alloc( username );
2008 pstrcpy( filter, "(uid=%u)" );
2009 all_string_sub( filter, "%u", escape_user, sizeof(filter) );
2010 SAFE_FREE( escape_user );
2012 rc = smbldap_search_suffix(ldap_state->smbldap_state,
2013 filter, attr_list, &result);
2014 if ( rc != LDAP_SUCCESS ) {
2015 free_attr_list( attr_list );
2016 return NT_STATUS_UNSUCCESSFUL;
2019 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2021 if (num_result > 1) {
2022 DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
2023 free_attr_list( attr_list );
2024 ldap_msgfree(result);
2025 return NT_STATUS_UNSUCCESSFUL;
2028 /* Check if we need to update an existing entry */
2029 if (num_result == 1) {
2032 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
2033 ldap_op = LDAP_MOD_REPLACE;
2034 entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
2035 tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
2037 free_attr_list( attr_list );
2038 ldap_msgfree(result);
2039 return NT_STATUS_UNSUCCESSFUL;
2041 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
2044 } else if (ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT) {
2046 /* There might be a SID for this account already - say an idmap entry */
2048 pstr_sprintf(filter, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
2049 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
2050 sid_to_string(sid_string, sid),
2051 LDAP_OBJ_IDMAP_ENTRY,
2052 LDAP_OBJ_SID_ENTRY);
2054 /* free old result before doing a new search */
2055 if (result != NULL) {
2056 ldap_msgfree(result);
2059 rc = smbldap_search_suffix(ldap_state->smbldap_state,
2060 filter, attr_list, &result);
2062 if ( rc != LDAP_SUCCESS ) {
2063 free_attr_list( attr_list );
2064 return NT_STATUS_UNSUCCESSFUL;
2067 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2069 if (num_result > 1) {
2070 DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
2071 free_attr_list( attr_list );
2072 ldap_msgfree(result);
2073 return NT_STATUS_UNSUCCESSFUL;
2076 /* Check if we need to update an existing entry */
2077 if (num_result == 1) {
2080 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
2081 ldap_op = LDAP_MOD_REPLACE;
2082 entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
2083 tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
2085 free_attr_list( attr_list );
2086 ldap_msgfree(result);
2087 return NT_STATUS_UNSUCCESSFUL;
2089 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
2094 free_attr_list( attr_list );
2096 if (num_result == 0) {
2097 /* Check if we need to add an entry */
2098 DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
2099 ldap_op = LDAP_MOD_ADD;
2100 if (username[strlen(username)-1] == '$') {
2101 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
2103 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
2107 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
2108 element_is_set_or_changed)) {
2109 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
2110 ldap_msgfree(result);
2112 ldap_mods_free(mods,True);
2113 return NT_STATUS_UNSUCCESSFUL;
2116 ldap_msgfree(result);
2119 DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
2120 return NT_STATUS_UNSUCCESSFUL;
2122 switch ( ldap_state->schema_ver ) {
2123 case SCHEMAVER_SAMBAACCOUNT:
2124 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT);
2126 case SCHEMAVER_SAMBASAMACCOUNT:
2127 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
2130 DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
2134 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, element_is_set_or_changed);
2135 if (!NT_STATUS_IS_OK(ret)) {
2136 DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
2137 pdb_get_username(newpwd),dn));
2138 ldap_mods_free(mods, True);
2142 DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
2143 ldap_mods_free(mods, True);
2145 return NT_STATUS_OK;
2148 /**********************************************************************
2149 *********************************************************************/
2151 static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
2153 LDAPMessage ** result)
2155 int scope = LDAP_SCOPE_SUBTREE;
2157 const char **attr_list;
2159 attr_list = get_attr_list(groupmap_attr_list);
2160 rc = smbldap_search(ldap_state->smbldap_state,
2161 lp_ldap_group_suffix (), scope,
2162 filter, attr_list, 0, result);
2163 free_attr_list( attr_list );
2165 if (rc != LDAP_SUCCESS) {
2166 char *ld_error = NULL;
2167 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
2169 DEBUG(0, ("ldapsam_search_one_group: "
2170 "Problem during the LDAP search: LDAP error: %s (%s)\n",
2171 ld_error?ld_error:"(unknown)", ldap_err2string(rc)));
2172 DEBUGADD(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
2173 lp_ldap_group_suffix(), filter));
2174 SAFE_FREE(ld_error);
2180 /**********************************************************************
2181 *********************************************************************/
2183 static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
2184 GROUP_MAP *map, LDAPMessage *entry)
2188 if (ldap_state == NULL || map == NULL || entry == NULL ||
2189 ldap_state->smbldap_state->ldap_struct == NULL) {
2190 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
2194 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
2195 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER), temp)) {
2196 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2197 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER)));
2200 DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp));
2202 map->gid = (gid_t)atol(temp);
2204 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
2205 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID), temp)) {
2206 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2207 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID)));
2211 if (!string_to_sid(&map->sid, temp)) {
2212 DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp));
2216 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
2217 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), temp)) {
2218 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2219 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
2222 map->sid_name_use = (enum SID_NAME_USE)atol(temp);
2224 if ((map->sid_name_use < SID_NAME_USER) ||
2225 (map->sid_name_use > SID_NAME_UNKNOWN)) {
2226 DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map->sid_name_use));
2230 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
2231 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), temp)) {
2233 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
2234 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_CN), temp))
2236 DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
2237 for gidNumber(%lu)\n",(unsigned long)map->gid));
2241 fstrcpy(map->nt_name, temp);
2243 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
2244 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), temp)) {
2247 fstrcpy(map->comment, temp);
2252 /**********************************************************************
2253 *********************************************************************/
2255 static BOOL init_ldap_from_group(LDAP *ldap_struct,
2256 LDAPMessage *existing,
2258 const GROUP_MAP *map)
2262 if (mods == NULL || map == NULL) {
2263 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
2269 sid_to_string(tmp, &map->sid);
2271 smbldap_make_mod(ldap_struct, existing, mods,
2272 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID), tmp);
2273 pstr_sprintf(tmp, "%i", map->sid_name_use);
2274 smbldap_make_mod(ldap_struct, existing, mods,
2275 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), tmp);
2277 smbldap_make_mod(ldap_struct, existing, mods,
2278 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), map->nt_name);
2279 smbldap_make_mod(ldap_struct, existing, mods,
2280 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), map->comment);
2285 /**********************************************************************
2286 *********************************************************************/
2288 static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
2292 struct ldapsam_privates *ldap_state =
2293 (struct ldapsam_privates *)methods->private_data;
2294 LDAPMessage *result = NULL;
2295 LDAPMessage *entry = NULL;
2298 if (ldapsam_search_one_group(ldap_state, filter, &result)
2300 return NT_STATUS_NO_SUCH_GROUP;
2303 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2306 DEBUG(4, ("ldapsam_getgroup: Did not find group\n"));
2307 ldap_msgfree(result);
2308 return NT_STATUS_NO_SUCH_GROUP;
2312 DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: count=%d\n",
2314 ldap_msgfree(result);
2315 return NT_STATUS_NO_SUCH_GROUP;
2318 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
2321 ldap_msgfree(result);
2322 return NT_STATUS_UNSUCCESSFUL;
2325 if (!init_group_from_ldap(ldap_state, map, entry)) {
2326 DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for group filter %s\n",
2328 ldap_msgfree(result);
2329 return NT_STATUS_NO_SUCH_GROUP;
2332 ldap_msgfree(result);
2333 return NT_STATUS_OK;
2336 /**********************************************************************
2337 *********************************************************************/
2339 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
2344 pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
2346 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
2347 sid_string_static(&sid));
2349 return ldapsam_getgroup(methods, filter, map);
2352 /**********************************************************************
2353 *********************************************************************/
2355 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
2360 pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
2362 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
2363 (unsigned long)gid);
2365 return ldapsam_getgroup(methods, filter, map);
2368 /**********************************************************************
2369 *********************************************************************/
2371 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
2375 char *escape_name = escape_ldap_string_alloc(name);
2378 return NT_STATUS_NO_MEMORY;
2381 pstr_sprintf(filter, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
2383 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
2384 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN), escape_name);
2386 SAFE_FREE(escape_name);
2388 return ldapsam_getgroup(methods, filter, map);
2391 static void add_rid_to_array_unique(TALLOC_CTX *mem_ctx,
2392 uint32 rid, uint32 **pp_rids, size_t *p_num)
2396 for (i=0; i<*p_num; i++) {
2397 if ((*pp_rids)[i] == rid)
2401 *pp_rids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_rids, uint32, *p_num+1);
2403 if (*pp_rids == NULL)
2406 (*pp_rids)[*p_num] = rid;
2410 static BOOL ldapsam_extract_rid_from_entry(LDAP *ldap_struct,
2412 const DOM_SID *domain_sid,
2418 if (!smbldap_get_single_attribute(ldap_struct, entry, "sambaSID",
2419 str, sizeof(str)-1)) {
2420 DEBUG(10, ("Could not find sambaSID attribute\n"));
2424 if (!string_to_sid(&sid, str)) {
2425 DEBUG(10, ("Could not convert string %s to sid\n", str));
2429 if (sid_compare_domain(&sid, domain_sid) != 0) {
2430 DEBUG(10, ("SID %s is not in expected domain %s\n",
2431 str, sid_string_static(domain_sid)));
2435 if (!sid_peek_rid(&sid, rid)) {
2436 DEBUG(10, ("Could not peek into RID\n"));
2443 static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
2444 TALLOC_CTX *mem_ctx,
2445 const DOM_SID *group,
2446 uint32 **pp_member_rids,
2447 size_t *p_num_members)
2449 struct ldapsam_privates *ldap_state =
2450 (struct ldapsam_privates *)methods->private_data;
2451 struct smbldap_state *conn = ldap_state->smbldap_state;
2454 LDAPMessage *msg = NULL;
2456 char **values = NULL;
2458 char *sid_filter = NULL;
2460 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2462 if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
2463 return pdb_default_enum_group_members(methods, mem_ctx, group,
2467 *pp_member_rids = NULL;
2470 pstr_sprintf(filter,
2471 "(&(objectClass=sambaSamAccount)"
2472 "(sambaPrimaryGroupSid=%s))",
2473 sid_string_static(group));
2476 const char *attrs[] = { "sambaSID", NULL };
2477 rc = smbldap_search(conn, lp_ldap_user_suffix(),
2478 LDAP_SCOPE_SUBTREE, filter, attrs, 0,
2482 if (rc != LDAP_SUCCESS)
2485 for (entry = ldap_first_entry(conn->ldap_struct, msg);
2487 entry = ldap_next_entry(conn->ldap_struct, entry))
2491 if (!ldapsam_extract_rid_from_entry(conn->ldap_struct,
2493 get_global_sam_sid(),
2495 DEBUG(2, ("Could not find sid from ldap entry\n"));
2499 add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
2506 pstr_sprintf(filter,
2507 "(&(objectClass=sambaGroupMapping)"
2508 "(objectClass=posixGroup)"
2510 sid_string_static(group));
2513 const char *attrs[] = { "memberUid", NULL };
2514 rc = smbldap_search(conn, lp_ldap_user_suffix(),
2515 LDAP_SCOPE_SUBTREE, filter, attrs, 0,
2519 if (rc != LDAP_SUCCESS)
2522 count = ldap_count_entries(conn->ldap_struct, msg);
2525 DEBUG(1, ("Found more than one groupmap entry for %s\n",
2526 sid_string_static(group)));
2531 result = NT_STATUS_OK;
2535 entry = ldap_first_entry(conn->ldap_struct, msg);
2539 values = ldap_get_values(conn->ldap_struct, msg, "memberUid");
2540 if (values == NULL) {
2541 result = NT_STATUS_OK;
2545 sid_filter = SMB_STRDUP("(&(objectClass=sambaSamAccount)(|");
2546 if (sid_filter == NULL) {
2547 result = NT_STATUS_NO_MEMORY;
2551 for (memberuid = values; *memberuid != NULL; memberuid += 1) {
2553 asprintf(&sid_filter, "%s(uid=%s)", tmp, *memberuid);
2555 if (sid_filter == NULL) {
2556 result = NT_STATUS_NO_MEMORY;
2562 asprintf(&sid_filter, "%s))", sid_filter);
2564 if (sid_filter == NULL) {
2565 result = NT_STATUS_NO_MEMORY;
2570 const char *attrs[] = { "sambaSID", NULL };
2571 rc = smbldap_search(conn, lp_ldap_user_suffix(),
2572 LDAP_SCOPE_SUBTREE, sid_filter, attrs, 0,
2576 if (rc != LDAP_SUCCESS)
2579 for (entry = ldap_first_entry(conn->ldap_struct, msg);
2581 entry = ldap_next_entry(conn->ldap_struct, entry))
2587 if (!smbldap_get_single_attribute(conn->ldap_struct,
2589 str, sizeof(str)-1))
2592 if (!string_to_sid(&sid, str))
2595 if (!sid_check_is_in_our_domain(&sid)) {
2596 DEBUG(1, ("Inconsistent SAM -- group member uid not "
2597 "in our domain\n"));
2601 sid_peek_rid(&sid, &rid);
2603 add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
2607 result = NT_STATUS_OK;
2610 SAFE_FREE(sid_filter);
2613 ldap_value_free(values);
2621 static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
2622 const char *username,
2624 DOM_SID **pp_sids, gid_t **pp_gids,
2625 size_t *p_num_groups)
2627 struct ldapsam_privates *ldap_state =
2628 (struct ldapsam_privates *)methods->private_data;
2629 struct smbldap_state *conn = ldap_state->smbldap_state;
2631 const char *attrs[] = { "gidNumber", "sambaSID", NULL };
2634 LDAPMessage *msg = NULL;
2636 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2637 size_t num_sids, num_gids;
2639 if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
2640 return pdb_default_enum_group_memberships(methods, username,
2641 primary_gid, pp_sids,
2642 pp_gids, p_num_groups);
2647 escape_name = escape_ldap_string_alloc(username);
2649 if (escape_name == NULL)
2650 return NT_STATUS_NO_MEMORY;
2652 pstr_sprintf(filter, "(&(objectClass=posixGroup)"
2653 "(|(memberUid=%s)(gidNumber=%d)))",
2654 username, primary_gid);
2656 rc = smbldap_search(conn, lp_ldap_group_suffix(),
2657 LDAP_SCOPE_SUBTREE, filter, attrs, 0, &msg);
2659 if (rc != LDAP_SUCCESS)
2668 /* We need to add the primary group as the first gid/sid */
2670 add_gid_to_array_unique(NULL, primary_gid, pp_gids, &num_gids);
2672 /* This sid will be replaced later */
2674 add_sid_to_array_unique(NULL, &global_sid_NULL, pp_sids, &num_sids);
2676 for (entry = ldap_first_entry(conn->ldap_struct, msg);
2678 entry = ldap_next_entry(conn->ldap_struct, entry))
2685 if (!smbldap_get_single_attribute(conn->ldap_struct,
2687 str, sizeof(str)-1))
2690 if (!string_to_sid(&sid, str))
2693 if (!smbldap_get_single_attribute(conn->ldap_struct,
2695 str, sizeof(str)-1))
2698 gid = strtoul(str, &end, 10);
2700 if (PTR_DIFF(end, str) != strlen(str))
2703 if (gid == primary_gid) {
2704 sid_copy(&(*pp_sids)[0], &sid);
2706 add_gid_to_array_unique(NULL, gid, pp_gids, &num_gids);
2707 add_sid_to_array_unique(NULL, &sid, pp_sids, &num_sids);
2711 if (sid_compare(&global_sid_NULL, &(*pp_sids)[0]) == 0) {
2712 DEBUG(3, ("primary group of [%s] not found\n", username));
2716 *p_num_groups = num_sids;
2718 result = NT_STATUS_OK;
2722 SAFE_FREE(escape_name);
2729 /**********************************************************************
2730 *********************************************************************/
2732 static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
2734 LDAPMessage **result)
2738 pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%lu))",
2739 LDAP_OBJ_POSIXGROUP, LDAP_OBJ_IDMAP_ENTRY,
2740 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
2741 (unsigned long)gid);
2743 return ldapsam_search_one_group(ldap_state, filter, result);
2746 /**********************************************************************
2747 *********************************************************************/
2749 static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
2752 struct ldapsam_privates *ldap_state =
2753 (struct ldapsam_privates *)methods->private_data;
2754 LDAPMessage *result = NULL;
2755 LDAPMod **mods = NULL;
2766 if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
2768 DEBUG(0, ("ldapsam_add_group_mapping_entry: Group %ld already exists in LDAP\n", (unsigned long)map->gid));
2769 return NT_STATUS_UNSUCCESSFUL;
2772 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
2773 if (rc != LDAP_SUCCESS) {
2774 ldap_msgfree(result);
2775 return NT_STATUS_UNSUCCESSFUL;
2778 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2781 /* There's no posixGroup account, let's try to find an
2782 * appropriate idmap entry for aliases */
2786 const char **attr_list;
2788 ldap_msgfree(result);
2790 pstrcpy( suffix, lp_ldap_idmap_suffix() );
2791 pstr_sprintf(filter, "(&(objectClass=%s)(%s=%u))",
2792 LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_GIDNUMBER,
2795 attr_list = get_attr_list( sidmap_attr_list );
2796 rc = smbldap_search(ldap_state->smbldap_state, suffix,
2797 LDAP_SCOPE_SUBTREE, filter, attr_list,
2800 free_attr_list(attr_list);
2802 if (rc != LDAP_SUCCESS) {
2803 DEBUG(3,("Failure looking up entry (%s)\n",
2804 ldap_err2string(rc) ));
2805 ldap_msgfree(result);
2806 return NT_STATUS_UNSUCCESSFUL;
2810 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2812 ldap_msgfree(result);
2813 return NT_STATUS_UNSUCCESSFUL;
2817 DEBUG(2, ("ldapsam_add_group_mapping_entry: Group %lu must exist exactly once in LDAP\n",
2818 (unsigned long)map->gid));
2819 ldap_msgfree(result);
2820 return NT_STATUS_UNSUCCESSFUL;
2823 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
2824 tmp = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
2826 ldap_msgfree(result);
2827 return NT_STATUS_UNSUCCESSFUL;
2832 if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
2833 result, &mods, map)) {
2834 DEBUG(0, ("ldapsam_add_group_mapping_entry: init_ldap_from_group failed!\n"));
2835 ldap_mods_free(mods, True);
2836 ldap_msgfree(result);
2837 return NT_STATUS_UNSUCCESSFUL;
2840 ldap_msgfree(result);
2843 DEBUG(0, ("ldapsam_add_group_mapping_entry: mods is empty\n"));
2844 return NT_STATUS_UNSUCCESSFUL;
2847 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP );
2849 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
2850 ldap_mods_free(mods, True);
2852 if (rc != LDAP_SUCCESS) {
2853 char *ld_error = NULL;
2854 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
2856 DEBUG(0, ("ldapsam_add_group_mapping_entry: failed to add group %lu error: %s (%s)\n", (unsigned long)map->gid,
2857 ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
2858 SAFE_FREE(ld_error);
2859 return NT_STATUS_UNSUCCESSFUL;
2862 DEBUG(2, ("ldapsam_add_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map->gid));
2863 return NT_STATUS_OK;
2866 /**********************************************************************
2867 *********************************************************************/
2869 static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
2872 struct ldapsam_privates *ldap_state =
2873 (struct ldapsam_privates *)methods->private_data;
2876 LDAPMessage *result = NULL;
2877 LDAPMessage *entry = NULL;
2878 LDAPMod **mods = NULL;
2880 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
2882 if (rc != LDAP_SUCCESS) {
2883 return NT_STATUS_UNSUCCESSFUL;
2886 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
2887 DEBUG(0, ("ldapsam_update_group_mapping_entry: No group to modify!\n"));
2888 ldap_msgfree(result);
2889 return NT_STATUS_UNSUCCESSFUL;
2892 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
2894 if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
2895 result, &mods, map)) {
2896 DEBUG(0, ("ldapsam_update_group_mapping_entry: init_ldap_from_group failed\n"));
2897 ldap_msgfree(result);
2899 ldap_mods_free(mods,True);
2900 return NT_STATUS_UNSUCCESSFUL;
2904 DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: nothing to do\n"));
2905 ldap_msgfree(result);
2906 return NT_STATUS_OK;
2909 dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
2911 ldap_msgfree(result);
2912 return NT_STATUS_UNSUCCESSFUL;
2914 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
2917 ldap_mods_free(mods, True);
2918 ldap_msgfree(result);
2920 if (rc != LDAP_SUCCESS) {
2921 char *ld_error = NULL;
2922 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
2924 DEBUG(0, ("ldapsam_update_group_mapping_entry: failed to modify group %lu error: %s (%s)\n", (unsigned long)map->gid,
2925 ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
2926 SAFE_FREE(ld_error);
2927 return NT_STATUS_UNSUCCESSFUL;
2930 DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map->gid));
2931 return NT_STATUS_OK;
2934 /**********************************************************************
2935 *********************************************************************/
2937 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
2940 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data;
2941 pstring sidstring, filter;
2942 LDAPMessage *result = NULL;
2945 const char **attr_list;
2947 sid_to_string(sidstring, &sid);
2949 pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
2950 LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID, sidstring);
2952 rc = ldapsam_search_one_group(ldap_state, filter, &result);
2954 if (rc != LDAP_SUCCESS) {
2955 return NT_STATUS_NO_SUCH_GROUP;
2958 attr_list = get_attr_list( groupmap_attr_list_to_delete );
2959 ret = ldapsam_delete_entry(ldap_state, result, LDAP_OBJ_GROUPMAP, attr_list);
2960 free_attr_list ( attr_list );
2962 ldap_msgfree(result);
2967 /**********************************************************************
2968 *********************************************************************/
2970 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update)
2972 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2975 const char **attr_list;
2977 pstr_sprintf( filter, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
2978 attr_list = get_attr_list( groupmap_attr_list );
2979 rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
2980 LDAP_SCOPE_SUBTREE, filter,
2981 attr_list, 0, &ldap_state->result);
2982 free_attr_list( attr_list );
2984 if (rc != LDAP_SUCCESS) {
2985 DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n", ldap_err2string(rc)));
2986 DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n", lp_ldap_group_suffix(), filter));
2987 ldap_msgfree(ldap_state->result);
2988 ldap_state->result = NULL;
2989 return NT_STATUS_UNSUCCESSFUL;
2992 DEBUG(2, ("ldapsam_setsamgrent: %d entries in the base!\n",
2993 ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
2994 ldap_state->result)));
2996 ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result);
2997 ldap_state->index = 0;
2999 return NT_STATUS_OK;
3002 /**********************************************************************
3003 *********************************************************************/
3005 static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
3007 ldapsam_endsampwent(my_methods);
3010 /**********************************************************************
3011 *********************************************************************/
3013 static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
3016 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
3017 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
3021 if (!ldap_state->entry)
3024 ldap_state->index++;
3025 bret = init_group_from_ldap(ldap_state, map, ldap_state->entry);
3027 ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
3031 return NT_STATUS_OK;
3034 /**********************************************************************
3035 *********************************************************************/
3037 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
3038 enum SID_NAME_USE sid_name_use,
3039 GROUP_MAP **pp_rmap, size_t *p_num_entries,
3049 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
3050 DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open passdb\n"));
3051 return NT_STATUS_ACCESS_DENIED;
3054 while (NT_STATUS_IS_OK(ldapsam_getsamgrent(methods, &map))) {
3055 if (sid_name_use != SID_NAME_UNKNOWN &&
3056 sid_name_use != map.sid_name_use) {
3057 DEBUG(11,("ldapsam_enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
3060 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
3061 DEBUG(11,("ldapsam_enum_group_mapping: group %s is non mapped\n", map.nt_name));
3065 mapt=SMB_REALLOC_ARRAY((*pp_rmap), GROUP_MAP, entries+1);
3067 DEBUG(0,("ldapsam_enum_group_mapping: Unable to enlarge group map!\n"));
3068 SAFE_FREE(*pp_rmap);
3069 return NT_STATUS_UNSUCCESSFUL;
3074 mapt[entries] = map;
3079 ldapsam_endsamgrent(methods);
3081 *p_num_entries = entries;
3083 return NT_STATUS_OK;
3086 static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
3087 const DOM_SID *alias,
3088 const DOM_SID *member,
3091 struct ldapsam_privates *ldap_state =
3092 (struct ldapsam_privates *)methods->private_data;
3094 LDAPMessage *result = NULL;
3095 LDAPMessage *entry = NULL;
3097 LDAPMod **mods = NULL;
3102 pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%s))",
3103 LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
3104 get_attr_key2string(groupmap_attr_list,
3105 LDAP_ATTR_GROUP_SID),
3106 sid_string_static(alias));
3108 if (ldapsam_search_one_group(ldap_state, filter,
3109 &result) != LDAP_SUCCESS)
3110 return NT_STATUS_NO_SUCH_ALIAS;
3112 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
3116 DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
3117 ldap_msgfree(result);
3118 return NT_STATUS_NO_SUCH_ALIAS;
3122 DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for filter %s: "
3123 "count=%d\n", filter, count));
3124 ldap_msgfree(result);
3125 return NT_STATUS_NO_SUCH_ALIAS;
3128 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
3132 ldap_msgfree(result);
3133 return NT_STATUS_UNSUCCESSFUL;
3136 dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
3138 ldap_msgfree(result);
3139 return NT_STATUS_UNSUCCESSFUL;
3142 smbldap_set_mod(&mods, modop,
3143 get_attr_key2string(groupmap_attr_list,
3144 LDAP_ATTR_SID_LIST),
3145 sid_string_static(member));
3147 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3149 ldap_mods_free(mods, True);
3150 ldap_msgfree(result);
3152 if (rc != LDAP_SUCCESS) {
3153 char *ld_error = NULL;
3154 ldap_get_option(ldap_state->smbldap_state->ldap_struct,
3155 LDAP_OPT_ERROR_STRING,&ld_error);
3157 DEBUG(0, ("ldapsam_modify_aliasmem: Could not modify alias "
3158 "for %s, error: %s (%s)\n", dn, ldap_err2string(rc),
3159 ld_error?ld_error:"unknown"));
3160 SAFE_FREE(ld_error);
3162 return NT_STATUS_UNSUCCESSFUL;
3167 return NT_STATUS_OK;
3170 static NTSTATUS ldapsam_add_aliasmem(struct pdb_methods *methods,
3171 const DOM_SID *alias,
3172 const DOM_SID *member)
3174 return ldapsam_modify_aliasmem(methods, alias, member, LDAP_MOD_ADD);
3177 static NTSTATUS ldapsam_del_aliasmem(struct pdb_methods *methods,
3178 const DOM_SID *alias,
3179 const DOM_SID *member)
3181 return ldapsam_modify_aliasmem(methods, alias, member,
3185 static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
3186 const DOM_SID *alias, DOM_SID **pp_members,
3187 size_t *p_num_members)
3189 struct ldapsam_privates *ldap_state =
3190 (struct ldapsam_privates *)methods->private_data;
3191 LDAPMessage *result = NULL;
3192 LDAPMessage *entry = NULL;
3202 pstr_sprintf(filter, "(&(|(objectClass=%s)(objectclass=%s))(%s=%s))",
3203 LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
3204 get_attr_key2string(groupmap_attr_list,
3205 LDAP_ATTR_GROUP_SID),
3206 sid_string_static(alias));
3208 if (ldapsam_search_one_group(ldap_state, filter,
3209 &result) != LDAP_SUCCESS)
3210 return NT_STATUS_NO_SUCH_ALIAS;
3212 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
3216 DEBUG(4, ("ldapsam_enum_aliasmem: Did not find alias\n"));
3217 ldap_msgfree(result);
3218 return NT_STATUS_NO_SUCH_ALIAS;
3222 DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for filter %s: "
3223 "count=%d\n", filter, count));
3224 ldap_msgfree(result);
3225 return NT_STATUS_NO_SUCH_ALIAS;
3228 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
3232 ldap_msgfree(result);
3233 return NT_STATUS_UNSUCCESSFUL;
3236 values = ldap_get_values(ldap_state->smbldap_state->ldap_struct,
3238 get_attr_key2string(groupmap_attr_list,
3239 LDAP_ATTR_SID_LIST));
3241 if (values == NULL) {
3242 ldap_msgfree(result);
3243 return NT_STATUS_OK;
3246 count = ldap_count_values(values);
3248 for (i=0; i<count; i++) {
3251 if (!string_to_sid(&member, values[i]))
3254 add_sid_to_array(NULL, &member, pp_members, &num_members);
3257 *p_num_members = num_members;
3258 ldap_value_free(values);
3259 ldap_msgfree(result);
3261 return NT_STATUS_OK;
3264 static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
3265 TALLOC_CTX *mem_ctx,
3266 const DOM_SID *domain_sid,
3267 const DOM_SID *members,
3269 uint32 **pp_alias_rids,
3270 size_t *p_num_alias_rids)
3272 struct ldapsam_privates *ldap_state =
3273 (struct ldapsam_privates *)methods->private_data;
3276 const char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL };
3278 LDAPMessage *result = NULL;
3279 LDAPMessage *entry = NULL;
3284 /* This query could be further optimized by adding a
3285 (&(sambaSID=<domain-sid>*)) so that only those aliases that are
3286 asked for in the getuseraliases are returned. */
3288 filter = talloc_asprintf(mem_ctx,
3289 "(&(|(objectclass=%s)(objectclass=%s))(|",
3290 LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY);
3292 for (i=0; i<num_members; i++)
3293 filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)",
3295 sid_string_static(&members[i]));
3297 filter = talloc_asprintf(mem_ctx, "%s))", filter);
3299 rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
3300 LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
3302 if (rc != LDAP_SUCCESS)
3303 return NT_STATUS_UNSUCCESSFUL;
3305 ldap_struct = ldap_state->smbldap_state->ldap_struct;
3307 for (entry = ldap_first_entry(ldap_struct, result);
3309 entry = ldap_next_entry(ldap_struct, entry))
3315 if (!smbldap_get_single_attribute(ldap_struct, entry,
3321 if (!string_to_sid(&sid, sid_str))
3324 if (!sid_peek_check_rid(domain_sid, &sid, &rid))
3327 add_rid_to_array_unique(mem_ctx, rid, pp_alias_rids,
3331 ldap_msgfree(result);
3332 return NT_STATUS_OK;
3335 static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
3337 NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
3339 LDAPMod **mods = NULL;
3340 fstring value_string;
3341 const char *policy_attr = NULL;
3343 struct ldapsam_privates *ldap_state =
3344 (struct ldapsam_privates *)methods->private_data;
3346 const char *attrs[2];
3348 DEBUG(10,("ldapsam_set_account_policy\n"));
3350 if (!ldap_state->domain_dn) {
3351 return NT_STATUS_INVALID_PARAMETER;
3354 policy_attr = get_account_policy_attr(policy_index);
3355 if (policy_attr == NULL) {
3356 DEBUG(0,("ldapsam_set_account_policy: invalid policy\n"));
3360 attrs[0] = policy_attr;
3363 slprintf(value_string, sizeof(value_string) - 1, "%i", value);
3365 smbldap_set_mod(&mods, LDAP_MOD_REPLACE, policy_attr, value_string);
3367 rc = smbldap_modify(ldap_state->smbldap_state, ldap_state->domain_dn, mods);
3369 ldap_mods_free(mods, True);
3371 if (rc != LDAP_SUCCESS) {
3372 char *ld_error = NULL;
3373 ldap_get_option(ldap_state->smbldap_state->ldap_struct,
3374 LDAP_OPT_ERROR_STRING,&ld_error);
3376 DEBUG(0, ("ldapsam_set_account_policy: Could not set account policy "
3377 "for %s, error: %s (%s)\n", ldap_state->domain_dn, ldap_err2string(rc),
3378 ld_error?ld_error:"unknown"));
3379 SAFE_FREE(ld_error);
3383 if (!cache_account_policy_set(policy_index, value)) {
3384 DEBUG(0,("ldapsam_set_account_policy: failed to update local tdb cache\n"));
3388 return NT_STATUS_OK;
3391 static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods, int policy_index, uint32 *value)
3393 NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
3394 LDAPMessage *result = NULL;
3395 LDAPMessage *entry = NULL;
3399 const char *policy_attr = NULL;
3401 struct ldapsam_privates *ldap_state =
3402 (struct ldapsam_privates *)methods->private_data;
3404 const char *attrs[2];
3406 DEBUG(10,("ldapsam_get_account_policy_from_ldap\n"));
3408 if (!ldap_state->domain_dn) {
3409 return NT_STATUS_INVALID_PARAMETER;
3412 policy_attr = get_account_policy_attr(policy_index);
3414 DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid policy index: %d\n", policy_index));
3418 attrs[0] = policy_attr;
3421 rc = smbldap_search(ldap_state->smbldap_state, ldap_state->domain_dn,
3422 LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &result);
3424 if (rc != LDAP_SUCCESS) {
3425 char *ld_error = NULL;
3426 ldap_get_option(ldap_state->smbldap_state->ldap_struct,
3427 LDAP_OPT_ERROR_STRING,&ld_error);
3429 DEBUG(0, ("ldapsam_get_account_policy_from_ldap: Could not get account policy "
3430 "for %s, error: %s (%s)\n", ldap_state->domain_dn, ldap_err2string(rc),
3431 ld_error?ld_error:"unknown"));
3432 SAFE_FREE(ld_error);
3436 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
3441 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
3442 if (entry == NULL) {
3446 vals = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, policy_attr);
3451 *value = (uint32)atol(vals[0]);
3453 ntstatus = NT_STATUS_OK;
3457 ldap_value_free(vals);
3458 ldap_msgfree(result);
3463 /* wrapper around ldapsam_get_account_policy_from_ldap(), handles tdb as cache
3465 - if there is a valid cache entry, return that
3466 - if there is an LDAP entry, update cache and return
3467 - otherwise set to default, update cache and return
3471 static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
3473 NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
3475 if (cache_account_policy_get(policy_index, value)) {
3476 DEBUG(11,("ldapsam_get_account_policy: got valid value from cache\n"));
3477 return NT_STATUS_OK;
3480 ntstatus = ldapsam_get_account_policy_from_ldap(methods, policy_index, value);
3481 if (NT_STATUS_IS_OK(ntstatus)) {
3485 DEBUG(10,("ldapsam_get_account_policy: failed to retrieve from ldap, returning default.\n"));
3488 /* should we automagically migrate old tdb value here ? */
3489 if (account_policy_get(policy_index, value))
3492 DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying default\n", policy_index));
3495 if (!account_policy_get_default(policy_index, value)) {
3501 ntstatus = ldapsam_set_account_policy(methods, policy_index, *value);
3502 if (!NT_STATUS_IS_OK(ntstatus)) {
3508 if (!cache_account_policy_set(policy_index, *value)) {
3509 DEBUG(0,("ldapsam_get_account_policy: failed to update local tdb as a cache\n"));
3510 return NT_STATUS_UNSUCCESSFUL;
3513 return NT_STATUS_OK;
3516 static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
3517 const DOM_SID *domain_sid,
3523 struct ldapsam_privates *ldap_state =
3524 (struct ldapsam_privates *)methods->private_data;
3525 LDAP *ldap_struct = ldap_state->smbldap_state->ldap_struct;
3526 LDAPMessage *msg = NULL;
3528 char *allsids = NULL;
3530 int i, rc, num_mapped;
3531 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
3533 if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
3534 return pdb_default_lookup_rids(methods, domain_sid,
3535 num_rids, rids, names, attrs);
3537 if (!sid_equal(domain_sid, get_global_sam_sid())) {
3538 /* TODO: Sooner or later we need to look up BUILTIN rids as
3543 for (i=0; i<num_rids; i++)
3544 attrs[i] = SID_NAME_UNKNOWN;
3546 allsids = SMB_STRDUP("");
3547 if (allsids == NULL) return NT_STATUS_NO_MEMORY;
3549 for (i=0; i<num_rids; i++) {
3551 sid_copy(&sid, domain_sid);
3552 sid_append_rid(&sid, rids[i]);
3554 asprintf(&allsids, "%s(sambaSid=%s)", allsids,
3555 sid_string_static(&sid));
3556 if (allsids == NULL) return NT_STATUS_NO_MEMORY;
3560 /* First look for users */
3564 const char *ldap_attrs[] = { "uid", "sambaSid", NULL };
3566 asprintf(&filter, ("(&(objectClass=sambaSamAccount)(|%s))"),
3568 if (filter == NULL) return NT_STATUS_NO_MEMORY;
3570 rc = smbldap_search(ldap_state->smbldap_state,
3571 lp_ldap_user_suffix(),
3572 LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
3578 if (rc != LDAP_SUCCESS)
3583 for (entry = ldap_first_entry(ldap_struct, msg);
3585 entry = ldap_next_entry(ldap_struct, entry))
3591 if (!ldapsam_extract_rid_from_entry(ldap_struct, entry,
3592 get_global_sam_sid(),
3594 DEBUG(2, ("Could not find sid from ldap entry\n"));
3598 if (!smbldap_get_single_attribute(ldap_struct, entry,
3599 "uid", str, sizeof(str)-1)) {
3600 DEBUG(2, ("Could not retrieve uid attribute\n"));
3604 for (rid_index = 0; rid_index < num_rids; rid_index++) {
3605 if (rid == rids[rid_index])
3609 if (rid_index == num_rids) {
3610 DEBUG(2, ("Got a RID not asked for: %d\n", rid));
3614 attrs[rid_index] = SID_NAME_USER;
3615 names[rid_index] = talloc_strdup(names, str);
3616 if (names[rid_index] == NULL) return NT_STATUS_NO_MEMORY;
3621 if (num_mapped == num_rids) {
3622 /* No need to look for groups anymore -- we're done */
3623 result = NT_STATUS_OK;
3627 /* Same game for groups */
3631 const char *ldap_attrs[] = { "cn", "sambaSid", NULL };
3633 asprintf(&filter, ("(&(objectClass=sambaGroupMapping)(|%s))"),
3635 if (filter == NULL) return NT_STATUS_NO_MEMORY;
3637 rc = smbldap_search(ldap_state->smbldap_state,
3638 lp_ldap_group_suffix(),
3639 LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
3645 if (rc != LDAP_SUCCESS)
3648 for (entry = ldap_first_entry(ldap_struct, msg);
3650 entry = ldap_next_entry(ldap_struct, entry))
3656 if (!ldapsam_extract_rid_from_entry(ldap_struct, entry,
3657 get_global_sam_sid(),
3659 DEBUG(2, ("Could not find sid from ldap entry\n"));
3663 if (!smbldap_get_single_attribute(ldap_struct, entry,
3664 "cn", str, sizeof(str)-1)) {
3665 DEBUG(2, ("Could not retrieve cn attribute\n"));
3669 for (rid_index = 0; rid_index < num_rids; rid_index++) {
3670 if (rid == rids[rid_index])
3674 if (rid_index == num_rids) {
3675 DEBUG(2, ("Got a RID not asked for: %d\n", rid));
3679 attrs[rid_index] = SID_NAME_DOM_GRP;
3680 names[rid_index] = talloc_strdup(names, str);
3681 if (names[rid_index] == NULL) return NT_STATUS_NO_MEMORY;
3685 result = NT_STATUS_NONE_MAPPED;
3688 result = (num_mapped == num_rids) ?
3689 NT_STATUS_OK : STATUS_SOME_UNMAPPED;
3699 char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
3701 char *filter = NULL;
3702 char *escaped = NULL;
3703 char *result = NULL;
3705 asprintf(&filter, "(&%s(objectclass=sambaSamAccount))",
3707 if (filter == NULL) goto done;
3709 escaped = escape_ldap_string_alloc(username);
3710 if (escaped == NULL) goto done;
3712 filter = realloc_string_sub(filter, "%u", username);
3713 result = talloc_strdup(mem_ctx, filter);
3722 const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
3726 const char **result;
3728 va_start(ap, mem_ctx);
3729 while (va_arg(ap, const char *) != NULL)
3733 result = TALLOC_ARRAY(mem_ctx, const char *, num+1);
3735 va_start(ap, mem_ctx);
3736 for (i=0; i<num; i++)
3737 result[i] = talloc_strdup(mem_ctx, va_arg(ap, const char*));
3744 struct ldap_search_state {
3745 struct smbldap_state *connection;
3755 void *pagedresults_cookie;
3757 LDAPMessage *entries, *current_entry;
3758 BOOL (*ldap2displayentry)(struct ldap_search_state *state,
3759 TALLOC_CTX *mem_ctx,
3760 LDAP *ld, LDAPMessage *entry,
3761 struct samr_displayentry *result);
3764 static BOOL ldapsam_search_firstpage(struct pdb_search *search)
3766 struct ldap_search_state *state = search->private_data;
3768 int rc = LDAP_OPERATIONS_ERROR;
3770 state->entries = NULL;
3772 if (state->connection->paged_results) {
3773 rc = smbldap_search_paged(state->connection, state->base,
3774 state->scope, state->filter,
3775 state->attrs, state->attrsonly,
3776 lp_ldap_page_size(), &state->entries,
3777 &state->pagedresults_cookie);
3780 if ((rc != LDAP_SUCCESS) || (state->entries == NULL)) {
3782 if (state->entries != NULL) {
3783 /* Left over from unsuccessful paged attempt */
3784 ldap_msgfree(state->entries);
3785 state->entries = NULL;
3788 rc = smbldap_search(state->connection, state->base,
3789 state->scope, state->filter, state->attrs,
3790 state->attrsonly, &state->entries);
3792 if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
3795 /* Ok, the server was lying. It told us it could do paged
3796 * searches when it could not. */
3797 state->connection->paged_results = False;
3800 ld = state->connection->ldap_struct;
3802 DEBUG(5, ("Don't have an LDAP connection right after a "
3806 state->current_entry = ldap_first_entry(ld, state->entries);
3808 if (state->current_entry == NULL) {
3809 ldap_msgfree(state->entries);
3810 state->entries = NULL;
3816 static BOOL ldapsam_search_nextpage(struct pdb_search *search)
3818 struct ldap_search_state *state = search->private_data;
3819 LDAP *ld = state->connection->ldap_struct;
3822 if (!state->connection->paged_results) {
3823 /* There is no next page when there are no paged results */
3827 rc = smbldap_search_paged(state->connection, state->base,
3828 state->scope, state->filter, state->attrs,
3829 state->attrsonly, lp_ldap_page_size(),
3831 &state->pagedresults_cookie);
3833 if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
3836 state->current_entry = ldap_first_entry(ld, state->entries);
3838 if (state->current_entry == NULL) {
3839 ldap_msgfree(state->entries);
3840 state->entries = NULL;
3846 static BOOL ldapsam_search_next_entry(struct pdb_search *search,
3847 struct samr_displayentry *entry)
3849 struct ldap_search_state *state = search->private_data;
3850 LDAP *ld = state->connection->ldap_struct;
3854 if ((state->entries == NULL) && (state->pagedresults_cookie == NULL))
3857 if ((state->entries == NULL) &&
3858 !ldapsam_search_nextpage(search))
3861 result = state->ldap2displayentry(state, search->mem_ctx, ld,
3862 state->current_entry, entry);
3866 dn = ldap_get_dn(ld, state->current_entry);
3867 DEBUG(5, ("Skipping entry %s\n", dn != NULL ? dn : "<NULL>"));
3868 if (dn != NULL) ldap_memfree(dn);
3871 state->current_entry = ldap_next_entry(ld, state->current_entry);
3873 if (state->current_entry == NULL) {
3874 ldap_msgfree(state->entries);
3875 state->entries = NULL;
3878 if (!result) goto retry;
3883 static void ldapsam_search_end(struct pdb_search *search)
3885 struct ldap_search_state *state = search->private_data;
3888 if (state->pagedresults_cookie == NULL)
3891 if (state->entries != NULL)
3892 ldap_msgfree(state->entries);
3894 state->entries = NULL;
3895 state->current_entry = NULL;
3897 if (!state->connection->paged_results)
3900 /* Tell the LDAP server we're not interested in the rest anymore. */
3902 rc = smbldap_search_paged(state->connection, state->base, state->scope,
3903 state->filter, state->attrs,
3904 state->attrsonly, 0, &state->entries,
3905 &state->pagedresults_cookie);
3907 if (rc != LDAP_SUCCESS)
3908 DEBUG(5, ("Could not end search properly\n"));
3913 static BOOL ldapuser2displayentry(struct ldap_search_state *state,
3914 TALLOC_CTX *mem_ctx,
3915 LDAP *ld, LDAPMessage *entry,
3916 struct samr_displayentry *result)
3922 vals = ldap_get_values(ld, entry, "sambaAcctFlags");
3923 if ((vals == NULL) || (vals[0] == NULL)) {
3924 DEBUG(5, ("\"sambaAcctFlags\" not found\n"));
3927 acct_flags = pdb_decode_acct_ctrl(vals[0]);
3928 ldap_value_free(vals);
3930 if ((state->acct_flags != 0) &&
3931 ((state->acct_flags & acct_flags) == 0))
3934 result->acct_flags = acct_flags;
3935 result->account_name = "";
3936 result->fullname = "";
3937 result->description = "";
3939 vals = ldap_get_values(ld, entry, "uid");
3940 if ((vals == NULL) || (vals[0] == NULL)) {
3941 DEBUG(5, ("\"uid\" not found\n"));
3944 pull_utf8_talloc(mem_ctx,
3945 CONST_DISCARD(char **, &result->account_name),
3947 ldap_value_free(vals);
3949 vals = ldap_get_values(ld, entry, "displayName");
3950 if ((vals == NULL) || (vals[0] == NULL))
3951 DEBUG(8, ("\"displayName\" not found\n"));
3953 pull_utf8_talloc(mem_ctx,
3954 CONST_DISCARD(char **, &result->fullname),
3956 ldap_value_free(vals);
3958 vals = ldap_get_values(ld, entry, "description");
3959 if ((vals == NULL) || (vals[0] == NULL))
3960 DEBUG(8, ("\"description\" not found\n"));
3962 pull_utf8_talloc(mem_ctx,
3963 CONST_DISCARD(char **, &result->description),
3965 ldap_value_free(vals);
3967 if ((result->account_name == NULL) ||
3968 (result->fullname == NULL) ||
3969 (result->description == NULL)) {
3970 DEBUG(0, ("talloc failed\n"));
3974 vals = ldap_get_values(ld, entry, "sambaSid");
3975 if ((vals == NULL) || (vals[0] == NULL)) {
3976 DEBUG(0, ("\"objectSid\" not found\n"));
3980 if (!string_to_sid(&sid, vals[0])) {
3981 DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
3982 ldap_value_free(vals);
3985 ldap_value_free(vals);
3987 if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
3988 DEBUG(0, ("sid %s does not belong to our domain\n", sid_string_static(&sid)));
3996 static BOOL ldapsam_search_users(struct pdb_methods *methods,
3997 struct pdb_search *search,
4000 struct ldapsam_privates *ldap_state = methods->private_data;
4001 struct ldap_search_state *state;
4003 state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
4004 if (state == NULL) {
4005 DEBUG(0, ("talloc failed\n"));
4009 state->connection = ldap_state->smbldap_state;
4011 if ((acct_flags != 0) && ((acct_flags & ACB_NORMAL) != 0))
4012 state->base = lp_ldap_user_suffix();
4013 else if ((acct_flags != 0) &&
4014 ((acct_flags & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) != 0))
4015 state->base = lp_ldap_machine_suffix();
4017 state->base = lp_ldap_suffix();
4019 state->acct_flags = acct_flags;
4020 state->base = talloc_strdup(search->mem_ctx, state->base);
4021 state->scope = LDAP_SCOPE_SUBTREE;
4022 state->filter = get_ldap_filter(search->mem_ctx, "*");
4023 state->attrs = talloc_attrs(search->mem_ctx, "uid", "sambaSid",
4024 "displayName", "description",
4025 "sambaAcctFlags", NULL);
4026 state->attrsonly = 0;
4027 state->pagedresults_cookie = NULL;
4028 state->entries = NULL;
4029 state->ldap2displayentry = ldapuser2displayentry;
4031 if ((state->filter == NULL) || (state->attrs == NULL)) {
4032 DEBUG(0, ("talloc failed\n"));
4036 search->private_data = state;
4037 search->next_entry = ldapsam_search_next_entry;
4038 search->search_end = ldapsam_search_end;
4040 return ldapsam_search_firstpage(search);
4043 static BOOL ldapgroup2displayentry(struct ldap_search_state *state,
4044 TALLOC_CTX *mem_ctx,
4045 LDAP *ld, LDAPMessage *entry,
4046 struct samr_displayentry *result)
4052 result->account_name = "";
4053 result->fullname = "";
4054 result->description = "";
4057 vals = ldap_get_values(ld, entry, "sambaGroupType");
4058 if ((vals == NULL) || (vals[0] == NULL)) {
4059 DEBUG(5, ("\"sambaGroupType\" not found\n"));
4063 group_type = atoi(vals[0]);
4065 if ((state->group_type != 0) &&
4066 ((state->group_type != group_type))) {
4070 /* display name is the NT group name */
4072 vals = ldap_get_values(ld, entry, "displayName");
4073 if ((vals == NULL) || (vals[0] == NULL)) {
4074 DEBUG(8, ("\"displayName\" not found\n"));
4076 /* fallback to the 'cn' attribute */
4077 vals = ldap_get_values(ld, entry, "cn");
4078 if ((vals == NULL) || (vals[0] == NULL)) {
4079 DEBUG(5, ("\"cn\" not found\n"));
4082 pull_utf8_talloc(mem_ctx, CONST_DISCARD(char **, &result->account_name), vals[0]);
4085 pull_utf8_talloc(mem_ctx, CONST_DISCARD(char **, &result->account_name), vals[0]);
4088 ldap_value_free(vals);
4090 vals = ldap_get_values(ld, entry, "description");
4091 if ((vals == NULL) || (vals[0] == NULL))
4092 DEBUG(8, ("\"description\" not found\n"));
4094 pull_utf8_talloc(mem_ctx,
4095 CONST_DISCARD(char **, &result->description),
4097 ldap_value_free(vals);
4099 if ((result->account_name == NULL) ||
4100 (result->fullname == NULL) ||
4101 (result->description == NULL)) {
4102 DEBUG(0, ("talloc failed\n"));
4106 vals = ldap_get_values(ld, entry, "sambaSid");
4107 if ((vals == NULL) || (vals[0] == NULL)) {
4108 DEBUG(0, ("\"objectSid\" not found\n"));
4112 if (!string_to_sid(&sid, vals[0])) {
4113 DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
4117 ldap_value_free(vals);
4119 switch (group_type) {
4120 case SID_NAME_DOM_GRP:
4121 case SID_NAME_ALIAS:
4123 if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
4124 DEBUG(0, ("%s is not in our domain\n", sid_string_static(&sid)));
4129 case SID_NAME_WKN_GRP:
4131 if (!sid_peek_check_rid(&global_sid_Builtin, &sid, &result->rid)) {
4133 DEBUG(0, ("%s is not in builtin sid\n", sid_string_static(&sid)));
4139 DEBUG(0,("unkown group type: %d\n", group_type));
4146 static BOOL ldapsam_search_grouptype(struct pdb_methods *methods,
4147 struct pdb_search *search,
4148 enum SID_NAME_USE type)
4150 struct ldapsam_privates *ldap_state = methods->private_data;
4151 struct ldap_search_state *state;
4153 state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
4154 if (state == NULL) {
4155 DEBUG(0, ("talloc failed\n"));
4159 state->connection = ldap_state->smbldap_state;
4161 state->base = talloc_strdup(search->mem_ctx, lp_ldap_group_suffix());
4162 state->connection = ldap_state->smbldap_state;
4163 state->scope = LDAP_SCOPE_SUBTREE;
4164 state->filter = talloc_asprintf(search->mem_ctx,
4165 "(&(objectclass=sambaGroupMapping)"
4166 "(sambaGroupType=%d))", type);
4167 state->attrs = talloc_attrs(search->mem_ctx, "cn", "sambaSid",
4168 "displayName", "description", "sambaGroupType", NULL);
4169 state->attrsonly = 0;
4170 state->pagedresults_cookie = NULL;
4171 state->entries = NULL;
4172 state->group_type = type;
4173 state->ldap2displayentry = ldapgroup2displayentry;
4175 if ((state->filter == NULL) || (state->attrs == NULL)) {
4176 DEBUG(0, ("talloc failed\n"));
4180 search->private_data = state;
4181 search->next_entry = ldapsam_search_next_entry;
4182 search->search_end = ldapsam_search_end;
4184 return ldapsam_search_firstpage(search);
4187 static BOOL ldapsam_search_groups(struct pdb_methods *methods,
4188 struct pdb_search *search)
4190 return ldapsam_search_grouptype(methods, search, SID_NAME_DOM_GRP);
4193 static BOOL ldapsam_search_aliases(struct pdb_methods *methods,
4194 struct pdb_search *search,
4197 if (sid_check_is_domain(sid))
4198 return ldapsam_search_grouptype(methods, search,
4201 if (sid_check_is_builtin(sid))
4202 return ldapsam_search_grouptype(methods, search,
4205 DEBUG(5, ("Don't know SID %s\n", sid_string_static(sid)));
4209 /**********************************************************************
4211 *********************************************************************/
4213 static void free_private_data(void **vp)
4215 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
4217 smbldap_free_struct(&(*ldap_state)->smbldap_state);
4219 if ((*ldap_state)->result != NULL) {
4220 ldap_msgfree((*ldap_state)->result);
4221 (*ldap_state)->result = NULL;
4223 if ((*ldap_state)->domain_dn != NULL) {
4224 SAFE_FREE((*ldap_state)->domain_dn);
4229 /* No need to free any further, as it is talloc()ed */
4232 /**********************************************************************
4233 Intitalise the parts of the pdb_context that are common to all pdb_ldap modes
4234 *********************************************************************/
4236 static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method,
4237 const char *location)
4240 struct ldapsam_privates *ldap_state;
4242 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
4246 (*pdb_method)->name = "ldapsam";
4248 (*pdb_method)->setsampwent = ldapsam_setsampwent;
4249 (*pdb_method)->endsampwent = ldapsam_endsampwent;
4250 (*pdb_method)->getsampwent = ldapsam_getsampwent;
4251 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
4252 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
4253 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
4254 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
4255 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
4256 (*pdb_method)->rename_sam_account = ldapsam_rename_sam_account;
4258 (*pdb_method)->getgrsid = ldapsam_getgrsid;
4259 (*pdb_method)->getgrgid = ldapsam_getgrgid;
4260 (*pdb_method)->getgrnam = ldapsam_getgrnam;
4261 (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
4262 (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
4263 (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
4264 (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
4265 (*pdb_method)->enum_group_members = ldapsam_enum_group_members;
4266 (*pdb_method)->enum_group_memberships = ldapsam_enum_group_memberships;
4267 (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
4269 (*pdb_method)->get_account_policy = ldapsam_get_account_policy;
4270 (*pdb_method)->set_account_policy = ldapsam_set_account_policy;
4272 (*pdb_method)->get_seq_num = ldapsam_get_seq_num;
4274 /* TODO: Setup private data and free */
4276 ldap_state = TALLOC_ZERO_P(pdb_context->mem_ctx, struct ldapsam_privates);
4278 DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
4279 return NT_STATUS_NO_MEMORY;
4282 if (!NT_STATUS_IS_OK(nt_status =
4283 smbldap_init(pdb_context->mem_ctx, location,
4284 &ldap_state->smbldap_state)));
4286 ldap_state->domain_name = talloc_strdup(pdb_context->mem_ctx, get_global_sam_name());
4287 if (!ldap_state->domain_name) {
4288 return NT_STATUS_NO_MEMORY;
4291 (*pdb_method)->private_data = ldap_state;
4293 (*pdb_method)->free_private_data = free_private_data;
4295 return NT_STATUS_OK;
4298 /**********************************************************************
4299 Initialise the 'compat' mode for pdb_ldap
4300 *********************************************************************/
4302 NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
4305 struct ldapsam_privates *ldap_state;
4307 #ifdef WITH_LDAP_SAMCONFIG
4309 int ldap_port = lp_ldap_port();
4311 /* remap default port if not using SSL (ie clear or TLS) */
4312 if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
4316 location = talloc_asprintf(pdb_context->mem_ctx, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON ? "ldaps" : "ldap", lp_ldap_server(), ldap_port);
4318 return NT_STATUS_NO_MEMORY;
4323 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
4327 (*pdb_method)->name = "ldapsam_compat";
4329 ldap_state = (*pdb_method)->private_data;
4330 ldap_state->schema_ver = SCHEMAVER_SAMBAACCOUNT;
4332 sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
4334 return NT_STATUS_OK;
4337 /**********************************************************************
4338 Initialise the normal mode for pdb_ldap
4339 *********************************************************************/
4341 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
4344 struct ldapsam_privates *ldap_state;
4345 uint32 alg_rid_base;
4346 pstring alg_rid_base_string;
4347 LDAPMessage *result = NULL;
4348 LDAPMessage *entry = NULL;
4349 DOM_SID ldap_domain_sid;
4350 DOM_SID secrets_domain_sid;
4351 pstring domain_sid_string;
4354 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
4358 (*pdb_method)->name = "ldapsam";
4360 (*pdb_method)->add_aliasmem = ldapsam_add_aliasmem;
4361 (*pdb_method)->del_aliasmem = ldapsam_del_aliasmem;
4362 (*pdb_method)->enum_aliasmem = ldapsam_enum_aliasmem;
4363 (*pdb_method)->enum_alias_memberships = ldapsam_alias_memberships;
4364 (*pdb_method)->search_users = ldapsam_search_users;
4365 (*pdb_method)->search_groups = ldapsam_search_groups;
4366 (*pdb_method)->search_aliases = ldapsam_search_aliases;
4368 ldap_state = (*pdb_method)->private_data;
4369 ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
4371 /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
4373 nt_status = smbldap_search_domain_info(ldap_state->smbldap_state, &result,
4374 ldap_state->domain_name, True);
4376 if ( !NT_STATUS_IS_OK(nt_status) ) {
4377 DEBUG(2, ("pdb_init_ldapsam: WARNING: Could not get domain info, nor add one to the domain\n"));
4378 DEBUGADD(2, ("pdb_init_ldapsam: Continuing on regardless, will be unable to allocate new users/groups, \
4379 and will risk BDCs having inconsistant SIDs\n"));
4380 sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
4381 return NT_STATUS_OK;
4384 /* Given that the above might fail, everything below this must be optional */
4386 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
4388 DEBUG(0, ("pdb_init_ldapsam: Could not get domain info entry\n"));
4389 ldap_msgfree(result);
4390 return NT_STATUS_UNSUCCESSFUL;
4393 dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
4395 return NT_STATUS_UNSUCCESSFUL;
4398 ldap_state->domain_dn = smb_xstrdup(dn);
4401 if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
4402 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
4403 domain_sid_string)) {
4405 if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) {
4406 DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be read as a valid SID\n", domain_sid_string));
4407 return NT_STATUS_INVALID_PARAMETER;
4409 found_sid = secrets_fetch_domain_sid(ldap_state->domain_name, &secrets_domain_sid);
4410 if (!found_sid || !sid_equal(&secrets_domain_sid, &ldap_domain_sid)) {
4411 fstring new_sid_str, old_sid_str;
4412 DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain %s based on pdb_ldap results %s -> %s\n",
4413 ldap_state->domain_name,
4414 sid_to_string(old_sid_str, &secrets_domain_sid),
4415 sid_to_string(new_sid_str, &ldap_domain_sid)));
4417 /* reset secrets.tdb sid */
4418 secrets_store_domain_sid(ldap_state->domain_name, &ldap_domain_sid);
4419 DEBUG(1, ("New global sam SID: %s\n", sid_to_string(new_sid_str, get_global_sam_sid())));
4421 sid_copy(&ldap_state->domain_sid, &ldap_domain_sid);
4424 if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
4425 get_attr_key2string( dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE ),
4426 alg_rid_base_string)) {
4427 alg_rid_base = (uint32)atol(alg_rid_base_string);
4428 if (alg_rid_base != algorithmic_rid_base()) {
4429 DEBUG(0, ("The value of 'algorithmic RID base' has changed since the LDAP\n"
4430 "database was initialised. Aborting. \n"));
4431 ldap_msgfree(result);
4432 return NT_STATUS_UNSUCCESSFUL;
4435 ldap_msgfree(result);
4437 return NT_STATUS_OK;
4440 NTSTATUS pdb_ldap_init(void)
4443 if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam", pdb_init_ldapsam)))
4446 if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_compat", pdb_init_ldapsam_compat)))
4449 /* Let pdb_nds register backends */
4452 return NT_STATUS_OK;