Fix const warning
[Samba.git] / source / passdb / pdb_ldap.c
blob0cdbdf0f2601ced728654a9a5a1dc795c35d89b2
1 /*
2 Unix SMB/CIFS mplementation.
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.
26 /* TODO:
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
43 * and/or winbind
46 #include "includes.h"
48 #undef DBGC_CLASS
49 #define DBGC_CLASS DBGC_PASSDB
51 #include <lber.h>
52 #include <ldap.h>
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"
65 #endif
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)
71 #endif
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)
77 #endif
80 #ifndef SAM_ACCOUNT
81 #define SAM_ACCOUNT struct sam_passwd
82 #endif
84 #include "smbldap.h"
86 struct ldapsam_privates {
87 struct smbldap_state *smbldap_state;
89 /* Former statics */
90 LDAPMessage *result;
91 LDAPMessage *entry;
92 int index;
94 const char *domain_name;
95 DOM_SID domain_sid;
97 /* configuration items */
98 int schema_ver;
101 /**********************************************************************
102 Free a LDAPMessage (one is stored on the SAM_ACCOUNT).
103 **********************************************************************/
105 static void private_data_free_fn(void **result)
107 ldap_msgfree(*result);
108 *result = NULL;
111 /**********************************************************************
112 Get the attribute name given a user schame version.
113 **********************************************************************/
115 static const char* get_userattr_key2string( int schema_ver, int key )
117 switch ( schema_ver ) {
118 case SCHEMAVER_SAMBAACCOUNT:
119 return get_attr_key2string( attrib_map_v22, key );
121 case SCHEMAVER_SAMBASAMACCOUNT:
122 return get_attr_key2string( attrib_map_v30, key );
124 default:
125 DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
126 break;
128 return NULL;
131 /**********************************************************************
132 Return the list of attribute names given a user schema version.
133 **********************************************************************/
135 static char** get_userattr_list( int schema_ver )
137 switch ( schema_ver ) {
138 case SCHEMAVER_SAMBAACCOUNT:
139 return get_attr_list( attrib_map_v22 );
141 case SCHEMAVER_SAMBASAMACCOUNT:
142 return get_attr_list( attrib_map_v30 );
143 default:
144 DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
145 break;
148 return NULL;
151 /*******************************************************************
152 Generate the LDAP search filter for the objectclass based on the
153 version of the schema we are using.
154 ******************************************************************/
156 static const char* get_objclass_filter( int schema_ver )
158 static fstring objclass_filter;
160 switch( schema_ver ) {
161 case SCHEMAVER_SAMBAACCOUNT:
162 fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT );
163 break;
164 case SCHEMAVER_SAMBASAMACCOUNT:
165 fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
166 break;
167 default:
168 DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));
169 break;
172 return objclass_filter;
175 /*******************************************************************
176 Run the search by name.
177 ******************************************************************/
179 static int ldapsam_search_suffix_by_name (struct ldapsam_privates *ldap_state,
180 const char *user,
181 LDAPMessage ** result, char **attr)
183 pstring filter;
184 char *escape_user = escape_ldap_string_alloc(user);
186 if (!escape_user) {
187 return LDAP_NO_MEMORY;
191 * in the filter expression, replace %u with the real name
192 * so in ldap filter, %u MUST exist :-)
194 pstr_sprintf(filter, "(&%s%s)", lp_ldap_filter(),
195 get_objclass_filter(ldap_state->schema_ver));
198 * have to use this here because $ is filtered out
199 * in pstring_sub
203 all_string_sub(filter, "%u", escape_user, sizeof(pstring));
204 SAFE_FREE(escape_user);
206 return smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
209 /*******************************************************************
210 Run the search by rid.
211 ******************************************************************/
213 static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
214 uint32 rid, LDAPMessage ** result,
215 char **attr)
217 pstring filter;
218 int rc;
220 pstr_sprintf(filter, "(&(rid=%i)%s)", rid,
221 get_objclass_filter(ldap_state->schema_ver));
223 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
225 return rc;
228 /*******************************************************************
229 Run the search by SID.
230 ******************************************************************/
232 static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
233 const DOM_SID *sid, LDAPMessage ** result,
234 char **attr)
236 pstring filter;
237 int rc;
238 fstring sid_string;
240 pstr_sprintf(filter, "(&(%s=%s)%s)",
241 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
242 sid_to_string(sid_string, sid),
243 get_objclass_filter(ldap_state->schema_ver));
245 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
247 return rc;
250 /*******************************************************************
251 Delete complete object or objectclass and attrs from
252 object found in search_result depending on lp_ldap_delete_dn
253 ******************************************************************/
255 static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
256 LDAPMessage *result,
257 const char *objectclass,
258 char **attrs)
260 int rc;
261 LDAPMessage *entry = NULL;
262 LDAPMod **mods = NULL;
263 char *name, *dn;
264 BerElement *ptr = NULL;
266 rc = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
268 if (rc != 1) {
269 DEBUG(0, ("ldapsam_delete_entry: Entry must exist exactly once!\n"));
270 return NT_STATUS_UNSUCCESSFUL;
273 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
274 dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
275 if (!dn) {
276 return NT_STATUS_UNSUCCESSFUL;
279 if (lp_ldap_delete_dn()) {
280 NTSTATUS ret = NT_STATUS_OK;
281 rc = smbldap_delete(ldap_state->smbldap_state, dn);
283 if (rc != LDAP_SUCCESS) {
284 DEBUG(0, ("ldapsam_delete_entry: Could not delete object %s\n", dn));
285 ret = NT_STATUS_UNSUCCESSFUL;
287 SAFE_FREE(dn);
288 return ret;
291 /* Ok, delete only the SAM attributes */
293 for (name = ldap_first_attribute(ldap_state->smbldap_state->ldap_struct, entry, &ptr);
294 name != NULL;
295 name = ldap_next_attribute(ldap_state->smbldap_state->ldap_struct, entry, ptr)) {
296 char **attrib;
298 /* We are only allowed to delete the attributes that
299 really exist. */
301 for (attrib = attrs; *attrib != NULL; attrib++) {
302 if (StrCaseCmp(*attrib, name) == 0) {
303 DEBUG(10, ("ldapsam_delete_entry: deleting attribute %s\n", name));
304 smbldap_set_mod(&mods, LDAP_MOD_DELETE, name, NULL);
308 ldap_memfree(name);
311 if (ptr != NULL) {
312 ber_free(ptr, 0);
315 smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
317 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
318 ldap_mods_free(mods, True);
320 if (rc != LDAP_SUCCESS) {
321 char *ld_error = NULL;
322 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
323 &ld_error);
325 DEBUG(0, ("ldapsam_delete_entry: Could not delete attributes for %s, error: %s (%s)\n",
326 dn, ldap_err2string(rc), ld_error?ld_error:"unknown"));
327 SAFE_FREE(ld_error);
328 SAFE_FREE(dn);
329 return NT_STATUS_UNSUCCESSFUL;
332 SAFE_FREE(dn);
333 return NT_STATUS_OK;
336 /* New Interface is being implemented here */
338 #if 0 /* JERRY - not uesed anymore */
340 /**********************************************************************
341 Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
342 *********************************************************************/
343 static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
344 SAM_ACCOUNT * sampass,
345 LDAPMessage * entry,
346 gid_t *gid)
348 pstring homedir;
349 pstring temp;
350 char **ldap_values;
351 char **values;
353 if ((ldap_values = ldap_get_values (ldap_state->smbldap_state->ldap_struct, entry, "objectClass")) == NULL) {
354 DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
355 return False;
358 for (values=ldap_values;*values;values++) {
359 if (strequal(*values, LDAP_OBJ_POSIXACCOUNT )) {
360 break;
364 if (!*values) { /*end of array, no posixAccount */
365 DEBUG(10, ("user does not have %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
366 ldap_value_free(ldap_values);
367 return False;
369 ldap_value_free(ldap_values);
371 if ( !smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
372 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_UNIX_HOME), homedir) )
374 return False;
377 if ( !smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
378 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_GIDNUMBER), temp) )
380 return False;
383 *gid = (gid_t)atol(temp);
385 pdb_set_unix_homedir(sampass, homedir, PDB_SET);
387 DEBUG(10, ("user has %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
389 return True;
392 #endif
394 /**********************************************************************
395 Initialize SAM_ACCOUNT from an LDAP query.
396 (Based on init_sam_from_buffer in pdb_tdb.c)
397 *********************************************************************/
399 static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
400 SAM_ACCOUNT * sampass,
401 LDAPMessage * entry)
403 time_t logon_time,
404 logoff_time,
405 kickoff_time,
406 pass_last_set_time,
407 pass_can_change_time,
408 pass_must_change_time;
409 pstring username,
410 domain,
411 nt_username,
412 fullname,
413 homedir,
414 dir_drive,
415 logon_script,
416 profile_path,
417 acct_desc,
418 workstations;
419 char munged_dial[2048];
420 uint32 user_rid;
421 uint8 smblmpwd[LM_HASH_LEN],
422 smbntpwd[NT_HASH_LEN];
423 uint16 acct_ctrl = 0,
424 logon_divs;
425 uint16 bad_password_count = 0,
426 logon_count = 0;
427 uint32 hours_len;
428 uint8 hours[MAX_HOURS_LEN];
429 pstring temp;
432 * do a little initialization
434 username[0] = '\0';
435 domain[0] = '\0';
436 nt_username[0] = '\0';
437 fullname[0] = '\0';
438 homedir[0] = '\0';
439 dir_drive[0] = '\0';
440 logon_script[0] = '\0';
441 profile_path[0] = '\0';
442 acct_desc[0] = '\0';
443 munged_dial[0] = '\0';
444 workstations[0] = '\0';
447 if (sampass == NULL || ldap_state == NULL || entry == NULL) {
448 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
449 return False;
452 if (ldap_state->smbldap_state->ldap_struct == NULL) {
453 DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->ldap_struct is NULL!\n"));
454 return False;
457 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, "uid", username)) {
458 DEBUG(1, ("init_sam_from_ldap: No uid attribute found for this user!\n"));
459 return False;
462 DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username));
464 pstrcpy(nt_username, username);
466 pstrcpy(domain, ldap_state->domain_name);
468 pdb_set_username(sampass, username, PDB_SET);
470 pdb_set_domain(sampass, domain, PDB_DEFAULT);
471 pdb_set_nt_username(sampass, nt_username, PDB_SET);
473 /* deal with different attributes between the schema first */
475 if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ) {
476 if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
477 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), temp)) {
478 pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
481 if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
482 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_SID), temp)) {
483 pdb_set_group_sid_from_string(sampass, temp, PDB_SET);
484 } else {
485 pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
487 } else {
488 if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
489 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), temp)) {
490 user_rid = (uint32)atol(temp);
491 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
494 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
495 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_RID), temp)) {
496 pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
497 } else {
498 uint32 group_rid;
500 group_rid = (uint32)atol(temp);
502 /* for some reason, we often have 0 as a primary group RID.
503 Make sure that we treat this just as a 'default' value */
505 if ( group_rid > 0 )
506 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
507 else
508 pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
512 if (pdb_get_init_flags(sampass,PDB_USERSID) == PDB_DEFAULT) {
513 DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n",
514 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
515 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
516 username));
517 return False;
521 #if 0 /* JERRY -- not used anymore */
523 * If so configured, try and get the values from LDAP
526 if (lp_ldap_trust_ids() && (get_unix_attributes(ldap_state, sampass, entry, &gid)))
528 if (pdb_get_init_flags(sampass,PDB_GROUPSID) == PDB_DEFAULT)
530 GROUP_MAP map;
531 /* call the mapping code here */
532 if(pdb_getgrgid(&map, gid)) {
533 pdb_set_group_sid(sampass, &map.sid, PDB_SET);
535 else {
536 pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid), PDB_SET);
540 #endif
542 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
543 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), temp)) {
544 /* leave as default */
545 } else {
546 pass_last_set_time = (time_t) atol(temp);
547 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
550 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
551 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp)) {
552 /* leave as default */
553 } else {
554 logon_time = (time_t) atol(temp);
555 pdb_set_logon_time(sampass, logon_time, PDB_SET);
558 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
559 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp)) {
560 /* leave as default */
561 } else {
562 logoff_time = (time_t) atol(temp);
563 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
566 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
567 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp)) {
568 /* leave as default */
569 } else {
570 kickoff_time = (time_t) atol(temp);
571 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
574 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
575 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp)) {
576 /* leave as default */
577 } else {
578 pass_can_change_time = (time_t) atol(temp);
579 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
582 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
583 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp)) {
584 /* leave as default */
585 } else {
586 pass_must_change_time = (time_t) atol(temp);
587 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
590 /* recommend that 'gecos' and 'displayName' should refer to the same
591 * attribute OID. userFullName depreciated, only used by Samba
592 * primary rules of LDAP: don't make a new attribute when one is already defined
593 * that fits your needs; using cn then displayName rather than 'userFullName'
596 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
597 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME), fullname)) {
598 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
599 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_CN), fullname)) {
600 /* leave as default */
601 } else {
602 pdb_set_fullname(sampass, fullname, PDB_SET);
604 } else {
605 pdb_set_fullname(sampass, fullname, PDB_SET);
608 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
609 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), dir_drive))
611 pdb_set_dir_drive( sampass,
612 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
613 PDB_DEFAULT );
614 } else {
615 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
618 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
619 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), homedir))
621 pdb_set_homedir( sampass,
622 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
623 PDB_DEFAULT );
624 } else {
625 pdb_set_homedir(sampass, homedir, PDB_SET);
628 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
629 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), logon_script))
631 pdb_set_logon_script( sampass,
632 talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
633 PDB_DEFAULT );
634 } else {
635 pdb_set_logon_script(sampass, logon_script, PDB_SET);
638 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
639 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), profile_path))
641 pdb_set_profile_path( sampass,
642 talloc_sub_basic( sampass->mem_ctx, username, lp_logon_path()),
643 PDB_DEFAULT );
644 } else {
645 pdb_set_profile_path(sampass, profile_path, PDB_SET);
648 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
649 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC), acct_desc))
651 /* leave as default */
652 } else {
653 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
656 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
657 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), workstations)) {
658 /* leave as default */;
659 } else {
660 pdb_set_workstations(sampass, workstations, PDB_SET);
663 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
664 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), munged_dial)) {
665 /* leave as default */;
666 } else {
667 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
670 /* FIXME: hours stuff should be cleaner */
672 logon_divs = 168;
673 hours_len = 21;
674 memset(hours, 0xff, hours_len);
676 if (!smbldap_get_single_attribute (ldap_state->smbldap_state->ldap_struct, entry,
677 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), temp)) {
678 /* leave as default */
679 } else {
680 pdb_gethexpwd(temp, smblmpwd);
681 memset((char *)temp, '\0', strlen(temp)+1);
682 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
683 return False;
684 ZERO_STRUCT(smblmpwd);
687 if (!smbldap_get_single_attribute (ldap_state->smbldap_state->ldap_struct, entry,
688 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), temp)) {
689 /* leave as default */
690 } else {
691 pdb_gethexpwd(temp, smbntpwd);
692 memset((char *)temp, '\0', strlen(temp)+1);
693 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
694 return False;
695 ZERO_STRUCT(smbntpwd);
698 if (!smbldap_get_single_attribute (ldap_state->smbldap_state->ldap_struct, entry,
699 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), temp)) {
700 acct_ctrl |= ACB_NORMAL;
701 } else {
702 acct_ctrl = pdb_decode_acct_ctrl(temp);
704 if (acct_ctrl == 0)
705 acct_ctrl |= ACB_NORMAL;
707 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
710 pdb_set_hours_len(sampass, hours_len, PDB_SET);
711 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
713 /* pdb_set_munged_dial(sampass, munged_dial, PDB_SET); */
715 /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
717 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
718 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_COUNT), temp)) {
719 /* leave as default */
720 } else {
721 bad_password_count = (uint32) atol(temp);
722 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
725 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
726 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_COUNT), temp)) {
727 /* leave as default */
728 } else {
729 logon_count = (uint32) atol(temp);
730 pdb_set_logon_count(sampass, logon_count, PDB_SET);
733 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
735 pdb_set_hours(sampass, hours, PDB_SET);
737 return True;
740 /**********************************************************************
741 Initialize SAM_ACCOUNT from an LDAP query.
742 (Based on init_buffer_from_sam in pdb_tdb.c)
743 *********************************************************************/
745 static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
746 LDAPMessage *existing,
747 LDAPMod *** mods, SAM_ACCOUNT * sampass,
748 BOOL (*need_update)(const SAM_ACCOUNT *,
749 enum pdb_elements))
751 pstring temp;
752 uint32 rid;
754 if (mods == NULL || sampass == NULL) {
755 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
756 return False;
759 *mods = NULL;
762 * took out adding "objectclass: sambaAccount"
763 * do this on a per-mod basis
765 if (need_update(sampass, PDB_USERNAME))
766 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
767 "uid", pdb_get_username(sampass));
769 DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass)));
771 /* only update the RID if we actually need to */
772 if (need_update(sampass, PDB_USERSID)) {
773 fstring sid_string;
774 fstring dom_sid_string;
775 const DOM_SID *user_sid = pdb_get_user_sid(sampass);
777 switch ( ldap_state->schema_ver ) {
778 case SCHEMAVER_SAMBAACCOUNT:
779 if (!sid_peek_check_rid(&ldap_state->domain_sid, user_sid, &rid)) {
780 DEBUG(1, ("init_ldap_from_sam: User's SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
781 sid_to_string(sid_string, user_sid),
782 sid_to_string(dom_sid_string, &ldap_state->domain_sid)));
783 return False;
785 slprintf(temp, sizeof(temp) - 1, "%i", rid);
786 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
787 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
788 temp);
789 break;
791 case SCHEMAVER_SAMBASAMACCOUNT:
792 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
793 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
794 sid_to_string(sid_string, user_sid));
795 break;
797 default:
798 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
799 break;
803 /* we don't need to store the primary group RID - so leaving it
804 'free' to hang off the unix primary group makes life easier */
806 if (need_update(sampass, PDB_GROUPSID)) {
807 fstring sid_string;
808 fstring dom_sid_string;
809 const DOM_SID *group_sid = pdb_get_group_sid(sampass);
811 switch ( ldap_state->schema_ver ) {
812 case SCHEMAVER_SAMBAACCOUNT:
813 if (!sid_peek_check_rid(&ldap_state->domain_sid, group_sid, &rid)) {
814 DEBUG(1, ("init_ldap_from_sam: User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
815 sid_to_string(sid_string, group_sid),
816 sid_to_string(dom_sid_string, &ldap_state->domain_sid)));
817 return False;
820 slprintf(temp, sizeof(temp) - 1, "%i", rid);
821 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
822 get_userattr_key2string(ldap_state->schema_ver,
823 LDAP_ATTR_PRIMARY_GROUP_RID), temp);
824 break;
826 case SCHEMAVER_SAMBASAMACCOUNT:
827 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
828 get_userattr_key2string(ldap_state->schema_ver,
829 LDAP_ATTR_PRIMARY_GROUP_SID), sid_to_string(sid_string, group_sid));
830 break;
832 default:
833 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
834 break;
839 /* displayName, cn, and gecos should all be the same
840 * most easily accomplished by giving them the same OID
841 * gecos isn't set here b/c it should be handled by the
842 * add-user script
843 * We change displayName only and fall back to cn if
844 * it does not exist.
847 if (need_update(sampass, PDB_FULLNAME))
848 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
849 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME),
850 pdb_get_fullname(sampass));
852 if (need_update(sampass, PDB_ACCTDESC))
853 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
854 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC),
855 pdb_get_acct_desc(sampass));
857 if (need_update(sampass, PDB_WORKSTATIONS))
858 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
859 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS),
860 pdb_get_workstations(sampass));
862 if (need_update(sampass, PDB_MUNGEDDIAL))
863 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
864 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL),
865 pdb_get_munged_dial(sampass));
867 if (need_update(sampass, PDB_SMBHOME))
868 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
869 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH),
870 pdb_get_homedir(sampass));
872 if (need_update(sampass, PDB_DRIVE))
873 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
874 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE),
875 pdb_get_dir_drive(sampass));
877 if (need_update(sampass, PDB_LOGONSCRIPT))
878 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
879 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT),
880 pdb_get_logon_script(sampass));
882 if (need_update(sampass, PDB_PROFILE))
883 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
884 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH),
885 pdb_get_profile_path(sampass));
887 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
888 if (need_update(sampass, PDB_LOGONTIME))
889 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
890 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
892 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
893 if (need_update(sampass, PDB_LOGOFFTIME))
894 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
895 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
897 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
898 if (need_update(sampass, PDB_KICKOFFTIME))
899 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
900 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
902 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
903 if (need_update(sampass, PDB_CANCHANGETIME))
904 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
905 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
907 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
908 if (need_update(sampass, PDB_MUSTCHANGETIME))
909 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
910 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp);
912 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
913 || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
915 if (need_update(sampass, PDB_LMPASSWD)) {
916 const uchar *lm_pw = pdb_get_lanman_passwd(sampass);
917 if (lm_pw) {
918 pdb_sethexpwd(temp, lm_pw,
919 pdb_get_acct_ctrl(sampass));
920 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
921 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
922 temp);
923 } else {
924 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
925 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
926 NULL);
929 if (need_update(sampass, PDB_NTPASSWD)) {
930 const uchar *nt_pw = pdb_get_nt_passwd(sampass);
931 if (nt_pw) {
932 pdb_sethexpwd(temp, nt_pw,
933 pdb_get_acct_ctrl(sampass));
934 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
935 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
936 temp);
937 } else {
938 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
939 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
940 NULL);
944 if (need_update(sampass, PDB_PASSLASTSET)) {
945 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
946 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
947 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET),
948 temp);
952 /* FIXME: Hours stuff goes in LDAP */
954 if (need_update(sampass, PDB_ACCTCTRL))
955 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
956 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO),
957 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
959 return True;
962 /**********************************************************************
963 Connect to LDAP server for password enumeration.
964 *********************************************************************/
966 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
968 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
969 int rc;
970 pstring filter;
971 char **attr_list;
973 pstr_sprintf( filter, "(&%s%s)", lp_ldap_filter(),
974 get_objclass_filter(ldap_state->schema_ver));
975 all_string_sub(filter, "%u", "*", sizeof(pstring));
977 attr_list = get_userattr_list(ldap_state->schema_ver);
978 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
979 attr_list, &ldap_state->result);
980 free_attr_list( attr_list );
982 if (rc != LDAP_SUCCESS) {
983 DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc)));
984 DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", lp_ldap_suffix(), filter));
985 ldap_msgfree(ldap_state->result);
986 ldap_state->result = NULL;
987 return NT_STATUS_UNSUCCESSFUL;
990 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
991 ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
992 ldap_state->result)));
994 ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
995 ldap_state->result);
996 ldap_state->index = 0;
998 return NT_STATUS_OK;
1001 /**********************************************************************
1002 End enumeration of the LDAP password list.
1003 *********************************************************************/
1005 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1007 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1008 if (ldap_state->result) {
1009 ldap_msgfree(ldap_state->result);
1010 ldap_state->result = NULL;
1014 /**********************************************************************
1015 Get the next entry in the LDAP password database.
1016 *********************************************************************/
1018 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
1020 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1021 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1022 BOOL bret = False;
1024 while (!bret) {
1025 if (!ldap_state->entry)
1026 return ret;
1028 ldap_state->index++;
1029 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
1031 ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
1032 ldap_state->entry);
1035 return NT_STATUS_OK;
1038 /**********************************************************************
1039 Get SAM_ACCOUNT entry from LDAP by username.
1040 *********************************************************************/
1042 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
1044 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1045 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1046 LDAPMessage *result = NULL;
1047 LDAPMessage *entry = NULL;
1048 int count;
1049 char ** attr_list;
1050 int rc;
1052 attr_list = get_userattr_list( ldap_state->schema_ver );
1053 rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
1054 free_attr_list( attr_list );
1056 if ( rc != LDAP_SUCCESS )
1057 return NT_STATUS_NO_SUCH_USER;
1059 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1061 if (count < 1) {
1062 DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname, count));
1063 ldap_msgfree(result);
1064 return NT_STATUS_NO_SUCH_USER;
1065 } else if (count > 1) {
1066 DEBUG(1, ("ldapsam_getsampwnam: Duplicate entries for this user [%s] Failing. count=%d\n", sname, count));
1067 ldap_msgfree(result);
1068 return NT_STATUS_NO_SUCH_USER;
1071 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1072 if (entry) {
1073 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1074 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1075 ldap_msgfree(result);
1076 return NT_STATUS_NO_SUCH_USER;
1078 pdb_set_backend_private_data(user, result,
1079 private_data_free_fn,
1080 my_methods, PDB_CHANGED);
1081 ret = NT_STATUS_OK;
1082 } else {
1083 ldap_msgfree(result);
1085 return ret;
1088 static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
1089 const DOM_SID *sid, LDAPMessage **result)
1091 int rc = -1;
1092 char ** attr_list;
1093 uint32 rid;
1095 switch ( ldap_state->schema_ver ) {
1096 case SCHEMAVER_SAMBASAMACCOUNT:
1097 attr_list = get_userattr_list(ldap_state->schema_ver);
1098 rc = ldapsam_search_suffix_by_sid(ldap_state, sid, result, attr_list);
1099 free_attr_list( attr_list );
1101 if ( rc != LDAP_SUCCESS )
1102 return rc;
1103 break;
1105 case SCHEMAVER_SAMBAACCOUNT:
1106 if (!sid_peek_check_rid(&ldap_state->domain_sid, sid, &rid)) {
1107 return rc;
1110 attr_list = get_userattr_list(ldap_state->schema_ver);
1111 rc = ldapsam_search_suffix_by_rid(ldap_state, rid, result, attr_list );
1112 free_attr_list( attr_list );
1114 if ( rc != LDAP_SUCCESS )
1115 return rc;
1116 break;
1118 return rc;
1121 /**********************************************************************
1122 Get SAM_ACCOUNT entry from LDAP by SID.
1123 *********************************************************************/
1125 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
1127 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1128 LDAPMessage *result = NULL;
1129 LDAPMessage *entry = NULL;
1130 int count;
1131 int rc;
1132 fstring sid_string;
1134 rc = ldapsam_get_ldap_user_by_sid(ldap_state,
1135 sid, &result);
1136 if (rc != LDAP_SUCCESS)
1137 return NT_STATUS_NO_SUCH_USER;
1139 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1141 if (count < 1) {
1142 DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] count=%d\n", sid_to_string(sid_string, sid),
1143 count));
1144 ldap_msgfree(result);
1145 return NT_STATUS_NO_SUCH_USER;
1146 } else if (count > 1) {
1147 DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID [%s]. Failing. count=%d\n", sid_to_string(sid_string, sid),
1148 count));
1149 ldap_msgfree(result);
1150 return NT_STATUS_NO_SUCH_USER;
1153 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1154 if (!entry) {
1155 ldap_msgfree(result);
1156 return NT_STATUS_NO_SUCH_USER;
1159 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1160 DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
1161 ldap_msgfree(result);
1162 return NT_STATUS_NO_SUCH_USER;
1165 pdb_set_backend_private_data(user, result,
1166 private_data_free_fn,
1167 my_methods, PDB_CHANGED);
1168 return NT_STATUS_OK;
1171 /********************************************************************
1172 Do the actual modification - also change a plaintext passord if
1173 it it set.
1174 **********************************************************************/
1176 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1177 SAM_ACCOUNT *newpwd, char *dn,
1178 LDAPMod **mods, int ldap_op,
1179 BOOL (*need_update)(const SAM_ACCOUNT *, enum pdb_elements))
1181 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1182 int rc;
1184 if (!my_methods || !newpwd || !dn) {
1185 return NT_STATUS_INVALID_PARAMETER;
1188 if (!mods) {
1189 DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
1190 /* may be password change below however */
1191 } else {
1192 switch(ldap_op) {
1193 case LDAP_MOD_ADD:
1194 smbldap_set_mod(&mods, LDAP_MOD_ADD,
1195 "objectclass",
1196 LDAP_OBJ_ACCOUNT);
1197 rc = smbldap_add(ldap_state->smbldap_state,
1198 dn, mods);
1199 break;
1200 case LDAP_MOD_REPLACE:
1201 rc = smbldap_modify(ldap_state->smbldap_state,
1202 dn ,mods);
1203 break;
1204 default:
1205 DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n",
1206 ldap_op));
1207 return NT_STATUS_INVALID_PARAMETER;
1210 if (rc!=LDAP_SUCCESS) {
1211 char *ld_error = NULL;
1212 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1213 &ld_error);
1214 DEBUG(1, ("ldapsam_modify_entry: Failed to %s user dn= %s with: %s\n\t%s\n",
1215 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
1216 dn, ldap_err2string(rc),
1217 ld_error?ld_error:"unknown"));
1218 SAFE_FREE(ld_error);
1219 return NT_STATUS_UNSUCCESSFUL;
1223 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) &&
1224 (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) &&
1225 need_update(newpwd, PDB_PLAINTEXT_PW) &&
1226 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1227 BerElement *ber;
1228 struct berval *bv;
1229 char *retoid;
1230 struct berval *retdata;
1231 char *utf8_password;
1232 char *utf8_dn;
1234 if (push_utf8_allocate(&utf8_password, pdb_get_plaintext_passwd(newpwd)) == (size_t)-1) {
1235 return NT_STATUS_NO_MEMORY;
1238 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
1239 return NT_STATUS_NO_MEMORY;
1242 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1243 DEBUG(0,("ber_alloc_t returns NULL\n"));
1244 SAFE_FREE(utf8_password);
1245 return NT_STATUS_UNSUCCESSFUL;
1248 ber_printf (ber, "{");
1249 ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn);
1250 ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password);
1251 ber_printf (ber, "N}");
1253 if ((rc = ber_flatten (ber, &bv))<0) {
1254 DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
1255 ber_free(ber,1);
1256 SAFE_FREE(utf8_dn);
1257 SAFE_FREE(utf8_password);
1258 return NT_STATUS_UNSUCCESSFUL;
1261 SAFE_FREE(utf8_dn);
1262 SAFE_FREE(utf8_password);
1263 ber_free(ber, 1);
1265 if ((rc = smbldap_extended_operation(ldap_state->smbldap_state,
1266 LDAP_EXOP_MODIFY_PASSWD,
1267 bv, NULL, NULL, &retoid,
1268 &retdata)) != LDAP_SUCCESS) {
1269 char *ld_error = NULL;
1270 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1271 &ld_error);
1272 DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n",
1273 pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
1274 SAFE_FREE(ld_error);
1275 ber_bvfree(bv);
1276 return NT_STATUS_UNSUCCESSFUL;
1277 } else {
1278 DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1279 #ifdef DEBUG_PASSWORD
1280 DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd)));
1281 #endif
1282 ber_bvfree(retdata);
1283 ber_memfree(retoid);
1285 ber_bvfree(bv);
1287 return NT_STATUS_OK;
1290 /**********************************************************************
1291 Delete entry from LDAP for username.
1292 *********************************************************************/
1294 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
1296 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1297 const char *sname;
1298 int rc;
1299 LDAPMessage *result = NULL;
1300 NTSTATUS ret;
1301 char **attr_list;
1302 fstring objclass;
1304 if (!sam_acct) {
1305 DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n"));
1306 return NT_STATUS_INVALID_PARAMETER;
1309 sname = pdb_get_username(sam_acct);
1311 DEBUG (3, ("ldapsam_delete_sam_account: Deleting user %s from LDAP.\n", sname));
1313 attr_list= get_userattr_list( ldap_state->schema_ver );
1314 rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
1316 if (rc != LDAP_SUCCESS) {
1317 free_attr_list( attr_list );
1318 return NT_STATUS_NO_SUCH_USER;
1321 switch ( ldap_state->schema_ver ) {
1322 case SCHEMAVER_SAMBASAMACCOUNT:
1323 fstrcpy( objclass, LDAP_OBJ_SAMBASAMACCOUNT );
1324 break;
1326 case SCHEMAVER_SAMBAACCOUNT:
1327 fstrcpy( objclass, LDAP_OBJ_SAMBAACCOUNT );
1328 break;
1329 default:
1330 fstrcpy( objclass, "UNKNOWN" );
1331 DEBUG(0,("ldapsam_delete_sam_account: Unknown schema version specified!\n"));
1332 break;
1335 ret = ldapsam_delete_entry(ldap_state, result, objclass, attr_list );
1336 ldap_msgfree(result);
1337 free_attr_list( attr_list );
1339 return ret;
1342 /**********************************************************************
1343 Helper function to determine for update_sam_account whether
1344 we need LDAP modification.
1345 *********************************************************************/
1347 static BOOL element_is_changed(const SAM_ACCOUNT *sampass,
1348 enum pdb_elements element)
1350 return IS_SAM_CHANGED(sampass, element);
1353 /**********************************************************************
1354 Update SAM_ACCOUNT.
1355 *********************************************************************/
1357 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1359 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1360 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1361 int rc = 0;
1362 char *dn;
1363 LDAPMessage *result = NULL;
1364 LDAPMessage *entry = NULL;
1365 LDAPMod **mods = NULL;
1366 char **attr_list;
1368 result = pdb_get_backend_private_data(newpwd, my_methods);
1369 if (!result) {
1370 attr_list = get_userattr_list(ldap_state->schema_ver);
1371 rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
1372 free_attr_list( attr_list );
1373 if (rc != LDAP_SUCCESS) {
1374 return NT_STATUS_UNSUCCESSFUL;
1376 pdb_set_backend_private_data(newpwd, result, private_data_free_fn, my_methods, PDB_CHANGED);
1379 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
1380 DEBUG(0, ("ldapsam_update_sam_account: No user to modify!\n"));
1381 return NT_STATUS_UNSUCCESSFUL;
1384 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1385 dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
1386 if (!dn) {
1387 return NT_STATUS_UNSUCCESSFUL;
1390 DEBUG(4, ("ldapsam_update_sam_account: user %s to be modified has dn: %s\n", pdb_get_username(newpwd), dn));
1392 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
1393 element_is_changed)) {
1394 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1395 SAFE_FREE(dn);
1396 if (mods != NULL)
1397 ldap_mods_free(mods,True);
1398 return NT_STATUS_UNSUCCESSFUL;
1401 if (mods == NULL) {
1402 DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
1403 pdb_get_username(newpwd)));
1404 SAFE_FREE(dn);
1405 return NT_STATUS_OK;
1408 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed);
1409 ldap_mods_free(mods,True);
1410 SAFE_FREE(dn);
1412 if (!NT_STATUS_IS_OK(ret)) {
1413 char *ld_error = NULL;
1414 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1415 &ld_error);
1416 DEBUG(0,("ldapsam_update_sam_account: failed to modify user with uid = %s, error: %s (%s)\n",
1417 pdb_get_username(newpwd), ld_error?ld_error:"(unknwon)", ldap_err2string(rc)));
1418 SAFE_FREE(ld_error);
1419 return ret;
1422 DEBUG(2, ("ldapsam_update_sam_account: successfully modified uid = %s in the LDAP database\n",
1423 pdb_get_username(newpwd)));
1424 return NT_STATUS_OK;
1427 /**********************************************************************
1428 Helper function to determine for update_sam_account whether
1429 we need LDAP modification.
1430 *********************************************************************/
1432 static BOOL element_is_set_or_changed(const SAM_ACCOUNT *sampass,
1433 enum pdb_elements element)
1435 return (IS_SAM_SET(sampass, element) ||
1436 IS_SAM_CHANGED(sampass, element));
1439 /**********************************************************************
1440 Add SAM_ACCOUNT to LDAP.
1441 *********************************************************************/
1443 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1445 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1446 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1447 int rc;
1448 LDAPMessage *result = NULL;
1449 LDAPMessage *entry = NULL;
1450 pstring dn;
1451 LDAPMod **mods = NULL;
1452 int ldap_op = LDAP_MOD_REPLACE;
1453 uint32 num_result;
1454 char **attr_list;
1455 char *escape_user;
1456 const char *username = pdb_get_username(newpwd);
1457 const DOM_SID *sid = pdb_get_user_sid(newpwd);
1458 pstring filter;
1459 fstring sid_string;
1461 if (!username || !*username) {
1462 DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
1463 return NT_STATUS_INVALID_PARAMETER;
1466 /* free this list after the second search or in case we exit on failure */
1467 attr_list = get_userattr_list(ldap_state->schema_ver);
1469 rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
1471 if (rc != LDAP_SUCCESS) {
1472 free_attr_list( attr_list );
1473 return NT_STATUS_UNSUCCESSFUL;
1476 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
1477 DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n",
1478 username));
1479 ldap_msgfree(result);
1480 free_attr_list( attr_list );
1481 return NT_STATUS_UNSUCCESSFUL;
1483 ldap_msgfree(result);
1484 result = NULL;
1486 if (element_is_set_or_changed(newpwd, PDB_USERSID)) {
1487 rc = ldapsam_get_ldap_user_by_sid(ldap_state,
1488 sid, &result);
1489 if (rc == LDAP_SUCCESS) {
1490 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
1491 DEBUG(0,("ldapsam_add_sam_account: SID '%s' already in the base, with samba attributes\n",
1492 sid_to_string(sid_string, sid)));
1493 free_attr_list( attr_list );
1494 ldap_msgfree(result);
1495 return NT_STATUS_UNSUCCESSFUL;
1497 ldap_msgfree(result);
1501 /* does the entry already exist but without a samba attributes?
1502 we need to return the samba attributes here */
1504 escape_user = escape_ldap_string_alloc( username );
1505 pstrcpy( filter, lp_ldap_filter() );
1506 all_string_sub( filter, "%u", escape_user, sizeof(filter) );
1507 SAFE_FREE( escape_user );
1509 rc = smbldap_search_suffix(ldap_state->smbldap_state,
1510 filter, attr_list, &result);
1511 if ( rc != LDAP_SUCCESS ) {
1512 free_attr_list( attr_list );
1513 return NT_STATUS_UNSUCCESSFUL;
1516 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1518 if (num_result > 1) {
1519 DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
1520 free_attr_list( attr_list );
1521 ldap_msgfree(result);
1522 return NT_STATUS_UNSUCCESSFUL;
1525 /* Check if we need to update an existing entry */
1526 if (num_result == 1) {
1527 char *tmp;
1529 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
1530 ldap_op = LDAP_MOD_REPLACE;
1531 entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
1532 tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
1533 if (!tmp) {
1534 free_attr_list( attr_list );
1535 ldap_msgfree(result);
1536 return NT_STATUS_UNSUCCESSFUL;
1538 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
1539 SAFE_FREE(tmp);
1541 } else if (ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT) {
1543 /* There might be a SID for this account already - say an idmap entry */
1545 pstr_sprintf(filter, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
1546 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
1547 sid_to_string(sid_string, sid),
1548 LDAP_OBJ_IDMAP_ENTRY,
1549 LDAP_OBJ_SID_ENTRY);
1551 /* free old result before doing a new search */
1552 if (result != NULL) {
1553 ldap_msgfree(result);
1554 result = NULL;
1556 rc = smbldap_search_suffix(ldap_state->smbldap_state,
1557 filter, attr_list, &result);
1559 if ( rc != LDAP_SUCCESS ) {
1560 free_attr_list( attr_list );
1561 return NT_STATUS_UNSUCCESSFUL;
1564 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1566 if (num_result > 1) {
1567 DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
1568 free_attr_list( attr_list );
1569 ldap_msgfree(result);
1570 return NT_STATUS_UNSUCCESSFUL;
1573 /* Check if we need to update an existing entry */
1574 if (num_result == 1) {
1575 char *tmp;
1577 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
1578 ldap_op = LDAP_MOD_REPLACE;
1579 entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
1580 tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
1581 if (!tmp) {
1582 free_attr_list( attr_list );
1583 ldap_msgfree(result);
1584 return NT_STATUS_UNSUCCESSFUL;
1586 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
1587 SAFE_FREE(tmp);
1591 free_attr_list( attr_list );
1593 if (num_result == 0) {
1594 /* Check if we need to add an entry */
1595 DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
1596 ldap_op = LDAP_MOD_ADD;
1597 if (username[strlen(username)-1] == '$') {
1598 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
1599 } else {
1600 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
1604 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
1605 element_is_set_or_changed)) {
1606 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
1607 ldap_msgfree(result);
1608 if (mods != NULL)
1609 ldap_mods_free(mods,True);
1610 return NT_STATUS_UNSUCCESSFUL;
1613 ldap_msgfree(result);
1615 if (mods == NULL) {
1616 DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
1617 return NT_STATUS_UNSUCCESSFUL;
1619 switch ( ldap_state->schema_ver ) {
1620 case SCHEMAVER_SAMBAACCOUNT:
1621 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT);
1622 break;
1623 case SCHEMAVER_SAMBASAMACCOUNT:
1624 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
1625 break;
1626 default:
1627 DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
1628 break;
1631 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, element_is_set_or_changed);
1632 if (!NT_STATUS_IS_OK(ret)) {
1633 DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
1634 pdb_get_username(newpwd),dn));
1635 ldap_mods_free(mods, True);
1636 return ret;
1639 DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
1640 ldap_mods_free(mods, True);
1642 return NT_STATUS_OK;
1645 /**********************************************************************
1646 *********************************************************************/
1648 static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
1649 const char *filter,
1650 LDAPMessage ** result)
1652 int scope = LDAP_SCOPE_SUBTREE;
1653 int rc;
1654 char **attr_list;
1656 attr_list = get_attr_list(groupmap_attr_list);
1657 rc = smbldap_search(ldap_state->smbldap_state,
1658 lp_ldap_group_suffix (), scope,
1659 filter, attr_list, 0, result);
1660 free_attr_list( attr_list );
1662 if (rc != LDAP_SUCCESS) {
1663 char *ld_error = NULL;
1664 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1665 &ld_error);
1666 DEBUG(0, ("ldapsam_search_one_group: "
1667 "Problem during the LDAP search: LDAP error: %s (%s)\n",
1668 ld_error?ld_error:"(unknown)", ldap_err2string(rc)));
1669 DEBUGADD(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
1670 lp_ldap_group_suffix(), filter));
1671 SAFE_FREE(ld_error);
1674 return rc;
1677 /**********************************************************************
1678 *********************************************************************/
1680 static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
1681 GROUP_MAP *map, LDAPMessage *entry)
1683 pstring temp;
1685 if (ldap_state == NULL || map == NULL || entry == NULL ||
1686 ldap_state->smbldap_state->ldap_struct == NULL) {
1687 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
1688 return False;
1691 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1692 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER), temp)) {
1693 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
1694 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER)));
1695 return False;
1697 DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp));
1699 map->gid = (gid_t)atol(temp);
1701 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1702 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID), temp)) {
1703 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
1704 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID)));
1705 return False;
1708 if (!string_to_sid(&map->sid, temp)) {
1709 DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp));
1710 return False;
1713 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1714 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), temp)) {
1715 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
1716 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
1717 return False;
1719 map->sid_name_use = (enum SID_NAME_USE)atol(temp);
1721 if ((map->sid_name_use < SID_NAME_USER) ||
1722 (map->sid_name_use > SID_NAME_UNKNOWN)) {
1723 DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map->sid_name_use));
1724 return False;
1727 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1728 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), temp)) {
1729 temp[0] = '\0';
1730 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1731 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_CN), temp))
1733 DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
1734 for gidNumber(%lu)\n",(unsigned long)map->gid));
1735 return False;
1738 fstrcpy(map->nt_name, temp);
1740 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1741 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), temp)) {
1742 temp[0] = '\0';
1744 fstrcpy(map->comment, temp);
1746 return True;
1749 /**********************************************************************
1750 *********************************************************************/
1752 static BOOL init_ldap_from_group(LDAP *ldap_struct,
1753 LDAPMessage *existing,
1754 LDAPMod ***mods,
1755 const GROUP_MAP *map)
1757 pstring tmp;
1759 if (mods == NULL || map == NULL) {
1760 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
1761 return False;
1764 *mods = NULL;
1766 sid_to_string(tmp, &map->sid);
1768 smbldap_make_mod(ldap_struct, existing, mods,
1769 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID), tmp);
1770 pstr_sprintf(tmp, "%i", map->sid_name_use);
1771 smbldap_make_mod(ldap_struct, existing, mods,
1772 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), tmp);
1774 smbldap_make_mod(ldap_struct, existing, mods,
1775 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), map->nt_name);
1776 smbldap_make_mod(ldap_struct, existing, mods,
1777 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), map->comment);
1779 return True;
1782 /**********************************************************************
1783 *********************************************************************/
1785 static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
1786 const char *filter,
1787 GROUP_MAP *map)
1789 struct ldapsam_privates *ldap_state =
1790 (struct ldapsam_privates *)methods->private_data;
1791 LDAPMessage *result = NULL;
1792 LDAPMessage *entry = NULL;
1793 int count;
1795 if (ldapsam_search_one_group(ldap_state, filter, &result)
1796 != LDAP_SUCCESS) {
1797 return NT_STATUS_NO_SUCH_GROUP;
1800 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1802 if (count < 1) {
1803 DEBUG(4, ("ldapsam_getgroup: Did not find group\n"));
1804 ldap_msgfree(result);
1805 return NT_STATUS_NO_SUCH_GROUP;
1808 if (count > 1) {
1809 DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: count=%d\n",
1810 filter, count));
1811 ldap_msgfree(result);
1812 return NT_STATUS_NO_SUCH_GROUP;
1815 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1817 if (!entry) {
1818 ldap_msgfree(result);
1819 return NT_STATUS_UNSUCCESSFUL;
1822 if (!init_group_from_ldap(ldap_state, map, entry)) {
1823 DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for group filter %s\n",
1824 filter));
1825 ldap_msgfree(result);
1826 return NT_STATUS_NO_SUCH_GROUP;
1829 ldap_msgfree(result);
1830 return NT_STATUS_OK;
1833 /**********************************************************************
1834 *********************************************************************/
1836 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
1837 DOM_SID sid)
1839 pstring filter;
1841 pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
1842 LDAP_OBJ_GROUPMAP,
1843 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
1844 sid_string_static(&sid));
1846 return ldapsam_getgroup(methods, filter, map);
1849 /**********************************************************************
1850 *********************************************************************/
1852 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
1853 gid_t gid)
1855 pstring filter;
1857 pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
1858 LDAP_OBJ_GROUPMAP,
1859 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
1860 (unsigned long)gid);
1862 return ldapsam_getgroup(methods, filter, map);
1865 /**********************************************************************
1866 *********************************************************************/
1868 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
1869 const char *name)
1871 pstring filter;
1872 char *escape_name = escape_ldap_string_alloc(name);
1874 if (!escape_name) {
1875 return NT_STATUS_NO_MEMORY;
1878 pstr_sprintf(filter, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
1879 LDAP_OBJ_GROUPMAP,
1880 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
1881 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN), escape_name);
1883 SAFE_FREE(escape_name);
1885 return ldapsam_getgroup(methods, filter, map);
1888 /**********************************************************************
1889 *********************************************************************/
1891 static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
1892 gid_t gid,
1893 LDAPMessage **result)
1895 pstring filter;
1897 pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
1898 LDAP_OBJ_POSIXGROUP,
1899 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
1900 (unsigned long)gid);
1902 return ldapsam_search_one_group(ldap_state, filter, result);
1905 /**********************************************************************
1906 *********************************************************************/
1908 static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
1909 GROUP_MAP *map)
1911 struct ldapsam_privates *ldap_state =
1912 (struct ldapsam_privates *)methods->private_data;
1913 LDAPMessage *result = NULL;
1914 LDAPMod **mods = NULL;
1915 int count;
1917 char *tmp;
1918 pstring dn;
1919 LDAPMessage *entry;
1921 GROUP_MAP dummy;
1923 int rc;
1925 if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
1926 map->gid))) {
1927 DEBUG(0, ("ldapsam_add_group_mapping_entry: Group %ld already exists in LDAP\n", (unsigned long)map->gid));
1928 return NT_STATUS_UNSUCCESSFUL;
1931 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
1932 if (rc != LDAP_SUCCESS) {
1933 ldap_msgfree(result);
1934 return NT_STATUS_UNSUCCESSFUL;
1937 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1939 if ( count == 0 ) {
1940 ldap_msgfree(result);
1941 return NT_STATUS_UNSUCCESSFUL;
1944 if (count > 1) {
1945 DEBUG(2, ("ldapsam_add_group_mapping_entry: Group %lu must exist exactly once in LDAP\n",
1946 (unsigned long)map->gid));
1947 ldap_msgfree(result);
1948 return NT_STATUS_UNSUCCESSFUL;
1951 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1952 tmp = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
1953 if (!tmp) {
1954 ldap_msgfree(result);
1955 return NT_STATUS_UNSUCCESSFUL;
1957 pstrcpy(dn, tmp);
1958 SAFE_FREE(tmp);
1960 if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
1961 result, &mods, map)) {
1962 DEBUG(0, ("ldapsam_add_group_mapping_entry: init_ldap_from_group failed!\n"));
1963 ldap_mods_free(mods, True);
1964 ldap_msgfree(result);
1965 return NT_STATUS_UNSUCCESSFUL;
1968 ldap_msgfree(result);
1970 if (mods == NULL) {
1971 DEBUG(0, ("ldapsam_add_group_mapping_entry: mods is empty\n"));
1972 return NT_STATUS_UNSUCCESSFUL;
1975 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP );
1977 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
1978 ldap_mods_free(mods, True);
1980 if (rc != LDAP_SUCCESS) {
1981 char *ld_error = NULL;
1982 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1983 &ld_error);
1984 DEBUG(0, ("ldapsam_add_group_mapping_entry: failed to add group %lu error: %s (%s)\n", (unsigned long)map->gid,
1985 ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
1986 SAFE_FREE(ld_error);
1987 return NT_STATUS_UNSUCCESSFUL;
1990 DEBUG(2, ("ldapsam_add_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map->gid));
1991 return NT_STATUS_OK;
1994 /**********************************************************************
1995 *********************************************************************/
1997 static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
1998 GROUP_MAP *map)
2000 struct ldapsam_privates *ldap_state =
2001 (struct ldapsam_privates *)methods->private_data;
2002 int rc;
2003 char *dn = NULL;
2004 LDAPMessage *result = NULL;
2005 LDAPMessage *entry = NULL;
2006 LDAPMod **mods = NULL;
2008 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
2010 if (rc != LDAP_SUCCESS) {
2011 return NT_STATUS_UNSUCCESSFUL;
2014 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
2015 DEBUG(0, ("ldapsam_update_group_mapping_entry: No group to modify!\n"));
2016 ldap_msgfree(result);
2017 return NT_STATUS_UNSUCCESSFUL;
2020 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
2022 if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
2023 result, &mods, map)) {
2024 DEBUG(0, ("ldapsam_update_group_mapping_entry: init_ldap_from_group failed\n"));
2025 ldap_msgfree(result);
2026 if (mods != NULL)
2027 ldap_mods_free(mods,True);
2028 return NT_STATUS_UNSUCCESSFUL;
2031 if (mods == NULL) {
2032 DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: nothing to do\n"));
2033 ldap_msgfree(result);
2034 return NT_STATUS_OK;
2037 dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
2038 if (!dn) {
2039 ldap_msgfree(result);
2040 return NT_STATUS_UNSUCCESSFUL;
2042 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
2043 SAFE_FREE(dn);
2045 ldap_mods_free(mods, True);
2046 ldap_msgfree(result);
2048 if (rc != LDAP_SUCCESS) {
2049 char *ld_error = NULL;
2050 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
2051 &ld_error);
2052 DEBUG(0, ("ldapsam_update_group_mapping_entry: failed to modify group %lu error: %s (%s)\n", (unsigned long)map->gid,
2053 ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
2054 SAFE_FREE(ld_error);
2055 return NT_STATUS_UNSUCCESSFUL;
2058 DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map->gid));
2059 return NT_STATUS_OK;
2062 /**********************************************************************
2063 *********************************************************************/
2065 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
2066 DOM_SID sid)
2068 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data;
2069 pstring sidstring, filter;
2070 LDAPMessage *result = NULL;
2071 int rc;
2072 NTSTATUS ret;
2073 char **attr_list;
2075 sid_to_string(sidstring, &sid);
2077 pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
2078 LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID, sidstring);
2080 rc = ldapsam_search_one_group(ldap_state, filter, &result);
2082 if (rc != LDAP_SUCCESS) {
2083 return NT_STATUS_NO_SUCH_GROUP;
2086 attr_list = get_attr_list( groupmap_attr_list_to_delete );
2087 ret = ldapsam_delete_entry(ldap_state, result, LDAP_OBJ_GROUPMAP, attr_list);
2088 free_attr_list ( attr_list );
2090 ldap_msgfree(result);
2092 return ret;
2095 /**********************************************************************
2096 *********************************************************************/
2098 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update)
2100 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2101 fstring filter;
2102 int rc;
2103 char **attr_list;
2105 pstr_sprintf( filter, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
2106 attr_list = get_attr_list( groupmap_attr_list );
2107 rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
2108 LDAP_SCOPE_SUBTREE, filter,
2109 attr_list, 0, &ldap_state->result);
2110 free_attr_list( attr_list );
2112 if (rc != LDAP_SUCCESS) {
2113 DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n", ldap_err2string(rc)));
2114 DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n", lp_ldap_group_suffix(), filter));
2115 ldap_msgfree(ldap_state->result);
2116 ldap_state->result = NULL;
2117 return NT_STATUS_UNSUCCESSFUL;
2120 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
2121 ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
2122 ldap_state->result)));
2124 ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result);
2125 ldap_state->index = 0;
2127 return NT_STATUS_OK;
2130 /**********************************************************************
2131 *********************************************************************/
2133 static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
2135 ldapsam_endsampwent(my_methods);
2138 /**********************************************************************
2139 *********************************************************************/
2141 static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
2142 GROUP_MAP *map)
2144 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2145 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2146 BOOL bret = False;
2148 while (!bret) {
2149 if (!ldap_state->entry)
2150 return ret;
2152 ldap_state->index++;
2153 bret = init_group_from_ldap(ldap_state, map, ldap_state->entry);
2155 ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
2156 ldap_state->entry);
2159 return NT_STATUS_OK;
2162 /**********************************************************************
2163 *********************************************************************/
2165 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
2166 enum SID_NAME_USE sid_name_use,
2167 GROUP_MAP **rmap, int *num_entries,
2168 BOOL unix_only)
2170 GROUP_MAP map;
2171 GROUP_MAP *mapt;
2172 int entries = 0;
2174 *num_entries = 0;
2175 *rmap = NULL;
2177 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
2178 DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open passdb\n"));
2179 return NT_STATUS_ACCESS_DENIED;
2182 while (NT_STATUS_IS_OK(ldapsam_getsamgrent(methods, &map))) {
2183 if (sid_name_use != SID_NAME_UNKNOWN &&
2184 sid_name_use != map.sid_name_use) {
2185 DEBUG(11,("ldapsam_enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
2186 continue;
2188 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
2189 DEBUG(11,("ldapsam_enum_group_mapping: group %s is non mapped\n", map.nt_name));
2190 continue;
2193 mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP));
2194 if (!mapt) {
2195 DEBUG(0,("ldapsam_enum_group_mapping: Unable to enlarge group map!\n"));
2196 SAFE_FREE(*rmap);
2197 return NT_STATUS_UNSUCCESSFUL;
2199 else
2200 (*rmap) = mapt;
2202 mapt[entries] = map;
2204 entries += 1;
2207 ldapsam_endsamgrent(methods);
2209 *num_entries = entries;
2211 return NT_STATUS_OK;
2214 /**********************************************************************
2215 Housekeeping
2216 *********************************************************************/
2218 static void free_private_data(void **vp)
2220 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
2222 smbldap_free_struct(&(*ldap_state)->smbldap_state);
2224 if ((*ldap_state)->result != NULL) {
2225 ldap_msgfree((*ldap_state)->result);
2226 (*ldap_state)->result = NULL;
2229 *ldap_state = NULL;
2231 /* No need to free any further, as it is talloc()ed */
2234 /**********************************************************************
2235 Intitalise the parts of the pdb_context that are common to all pdb_ldap modes
2236 *********************************************************************/
2238 static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method,
2239 const char *location)
2241 NTSTATUS nt_status;
2242 struct ldapsam_privates *ldap_state;
2244 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
2245 return nt_status;
2248 (*pdb_method)->name = "ldapsam";
2250 (*pdb_method)->setsampwent = ldapsam_setsampwent;
2251 (*pdb_method)->endsampwent = ldapsam_endsampwent;
2252 (*pdb_method)->getsampwent = ldapsam_getsampwent;
2253 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
2254 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
2255 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
2256 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
2257 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
2259 (*pdb_method)->getgrsid = ldapsam_getgrsid;
2260 (*pdb_method)->getgrgid = ldapsam_getgrgid;
2261 (*pdb_method)->getgrnam = ldapsam_getgrnam;
2262 (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
2263 (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
2264 (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
2265 (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
2267 /* TODO: Setup private data and free */
2269 ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(*ldap_state));
2270 if (!ldap_state) {
2271 DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
2272 return NT_STATUS_NO_MEMORY;
2275 if (!NT_STATUS_IS_OK(nt_status =
2276 smbldap_init(pdb_context->mem_ctx, location,
2277 &ldap_state->smbldap_state)));
2279 ldap_state->domain_name = talloc_strdup(pdb_context->mem_ctx, get_global_sam_name());
2280 if (!ldap_state->domain_name) {
2281 return NT_STATUS_NO_MEMORY;
2284 (*pdb_method)->private_data = ldap_state;
2286 (*pdb_method)->free_private_data = free_private_data;
2288 return NT_STATUS_OK;
2291 /**********************************************************************
2292 Initialise the 'compat' mode for pdb_ldap
2293 *********************************************************************/
2295 static NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2297 NTSTATUS nt_status;
2298 struct ldapsam_privates *ldap_state;
2300 #ifdef WITH_LDAP_SAMCONFIG
2301 if (!location) {
2302 int ldap_port = lp_ldap_port();
2304 /* remap default port if not using SSL (ie clear or TLS) */
2305 if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
2306 ldap_port = 389;
2309 location = talloc_asprintf(pdb_context->mem_ctx, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON ? "ldaps" : "ldap", lp_ldap_server(), ldap_port);
2310 if (!location) {
2311 return NT_STATUS_NO_MEMORY;
2314 #endif
2316 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
2317 return nt_status;
2320 (*pdb_method)->name = "ldapsam_compat";
2322 ldap_state = (*pdb_method)->private_data;
2323 ldap_state->schema_ver = SCHEMAVER_SAMBAACCOUNT;
2325 sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
2327 return NT_STATUS_OK;
2330 /**********************************************************************
2331 Initialise the normal mode for pdb_ldap
2332 *********************************************************************/
2334 static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2336 NTSTATUS nt_status;
2337 struct ldapsam_privates *ldap_state;
2338 uint32 alg_rid_base;
2339 pstring alg_rid_base_string;
2340 LDAPMessage *result = NULL;
2341 LDAPMessage *entry = NULL;
2342 DOM_SID ldap_domain_sid;
2343 DOM_SID secrets_domain_sid;
2344 pstring domain_sid_string;
2346 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
2347 return nt_status;
2350 (*pdb_method)->name = "ldapsam";
2352 ldap_state = (*pdb_method)->private_data;
2353 ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
2355 /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
2357 nt_status = smbldap_search_domain_info(ldap_state->smbldap_state, &result,
2358 ldap_state->domain_name, True);
2360 if ( !NT_STATUS_IS_OK(nt_status) ) {
2361 DEBUG(2, ("pdb_init_ldapsam: WARNING: Could not get domain info, nor add one to the domain\n"));
2362 DEBUGADD(2, ("pdb_init_ldapsam: Continuing on regardless, will be unable to allocate new users/groups, \
2363 and will risk BDCs having inconsistant SIDs\n"));
2364 sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
2365 return NT_STATUS_OK;
2368 /* Given that the above might fail, everything below this must be optional */
2370 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
2371 if (!entry) {
2372 DEBUG(0, ("pdb_init_ldapsam: Could not get domain info entry\n"));
2373 ldap_msgfree(result);
2374 return NT_STATUS_UNSUCCESSFUL;
2377 if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
2378 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
2379 domain_sid_string)) {
2380 BOOL found_sid;
2381 if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) {
2382 DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be read as a valid SID\n", domain_sid_string));
2383 return NT_STATUS_INVALID_PARAMETER;
2385 found_sid = secrets_fetch_domain_sid(ldap_state->domain_name, &secrets_domain_sid);
2386 if (!found_sid || !sid_equal(&secrets_domain_sid, &ldap_domain_sid)) {
2387 /* reset secrets.tdb sid */
2388 secrets_store_domain_sid(ldap_state->domain_name, &ldap_domain_sid);
2390 sid_copy(&ldap_state->domain_sid, &ldap_domain_sid);
2393 if (smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
2394 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ALGORITHMIC_RID_BASE),
2395 alg_rid_base_string)) {
2396 alg_rid_base = (uint32)atol(alg_rid_base_string);
2397 if (alg_rid_base != algorithmic_rid_base()) {
2398 DEBUG(0, ("The value of 'algorithmic RID base' has changed since the LDAP\n"
2399 "database was initialised. Aborting. \n"));
2400 ldap_msgfree(result);
2401 return NT_STATUS_UNSUCCESSFUL;
2404 ldap_msgfree(result);
2406 return NT_STATUS_OK;
2409 NTSTATUS pdb_ldap_init(void)
2411 NTSTATUS nt_status;
2412 if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam", pdb_init_ldapsam)))
2413 return nt_status;
2415 if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_compat", pdb_init_ldapsam_compat)))
2416 return nt_status;
2418 return NT_STATUS_OK;