More code to store ACEs and SIDs. I have almost enough to start testing
[Samba/gebeck_regimport.git] / source3 / passdb / pdb_ldap.c
blob6d747ef91156ac3052d7965ef0760e27cf20ced8
1 /*
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
6 Copyright (C) Shahms King 2001
7 Copyright (C) Andrew Bartlett 2002
8 Copyright (C) Stefan (metze) Metzmacher 2002
9 Copyright (C) Jim McDonough 2003
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "includes.h"
29 #undef DBGC_CLASS
30 #define DBGC_CLASS DBGC_PASSDB
32 /* TODO:
33 * persistent connections: if using NSS LDAP, many connections are made
34 * however, using only one within Samba would be nice
36 * Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
38 * Other LDAP based login attributes: accountExpires, etc.
39 * (should be the domain of Samba proper, but the sam_password/SAM_ACCOUNT
40 * structures don't have fields for some of these attributes)
42 * SSL is done, but can't get the certificate based authentication to work
43 * against on my test platform (Linux 2.4, OpenLDAP 2.x)
46 /* NOTE: this will NOT work against an Active Directory server
47 * due to the fact that the two password fields cannot be retrieved
48 * from a server; recommend using security = domain in this situation
49 * and/or winbind
52 #include <lber.h>
53 #include <ldap.h>
55 #include "smb_ldap.h"
57 #ifndef SAM_ACCOUNT
58 #define SAM_ACCOUNT struct sam_passwd
59 #endif
61 static uint32 ldapsam_get_next_available_nua_rid(struct smb_ldap_privates *ldap_state);
63 static const char *attr[] = {"uid", "pwdLastSet", "logonTime",
64 "logoffTime", "kickoffTime", "cn",
65 "pwdCanChange", "pwdMustChange",
66 "displayName", "homeDrive",
67 "smbHome", "scriptPath",
68 "profilePath", "description",
69 "userWorkstations", "rid",
70 "primaryGroupID", "lmPassword",
71 "ntPassword", "acctFlags",
72 "domain", "objectClass",
73 "uidNumber", "gidNumber",
74 "homeDirectory", NULL };
76 /*******************************************************************
77 run the search by name.
78 ******************************************************************/
79 static int ldapsam_search_one_user (struct smb_ldap_privates *ldap_state, const char *filter, LDAPMessage ** result)
81 int scope = LDAP_SCOPE_SUBTREE;
82 int rc;
84 DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter));
86 rc = smb_ldap_search(ldap_state, lp_ldap_suffix (), scope, filter, attr, 0, result);
88 if (rc != LDAP_SUCCESS) {
89 char *ld_error = NULL;
90 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
91 &ld_error);
92 DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s (%s)\n",
93 ld_error?ld_error:"(unknown)", ldap_err2string (rc)));
94 DEBUG(3,("ldapsam_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(),
95 filter));
96 SAFE_FREE(ld_error);
99 return rc;
102 /*******************************************************************
103 run the search by name.
104 ******************************************************************/
105 static int ldapsam_search_one_user_by_name (struct smb_ldap_privates *ldap_state, const char *user,
106 LDAPMessage ** result)
108 pstring filter;
109 char *escape_user = escape_ldap_string_alloc(user);
111 if (!escape_user) {
112 return LDAP_NO_MEMORY;
116 * in the filter expression, replace %u with the real name
117 * so in ldap filter, %u MUST exist :-)
119 pstrcpy(filter, lp_ldap_filter());
122 * have to use this here because $ is filtered out
123 * in pstring_sub
127 all_string_sub(filter, "%u", escape_user, sizeof(pstring));
128 SAFE_FREE(escape_user);
130 return ldapsam_search_one_user(ldap_state, filter, result);
133 /*******************************************************************
134 run the search by uid.
135 ******************************************************************/
136 static int ldapsam_search_one_user_by_uid(struct smb_ldap_privates *ldap_state,
137 int uid,
138 LDAPMessage ** result)
140 struct passwd *user;
141 pstring filter;
142 char *escape_user;
144 /* Get the username from the system and look that up in the LDAP */
146 if ((user = getpwuid_alloc(uid)) == NULL) {
147 DEBUG(3,("ldapsam_search_one_user_by_uid: Failed to locate uid [%d]\n", uid));
148 return LDAP_NO_SUCH_OBJECT;
151 pstrcpy(filter, lp_ldap_filter());
153 escape_user = escape_ldap_string_alloc(user->pw_name);
154 if (!escape_user) {
155 passwd_free(&user);
156 return LDAP_NO_MEMORY;
159 all_string_sub(filter, "%u", escape_user, sizeof(pstring));
161 passwd_free(&user);
162 SAFE_FREE(escape_user);
164 return ldapsam_search_one_user(ldap_state, filter, result);
167 /*******************************************************************
168 run the search by rid.
169 ******************************************************************/
170 static int ldapsam_search_one_user_by_rid (struct smb_ldap_privates *ldap_state,
171 uint32 rid,
172 LDAPMessage ** result)
174 pstring filter;
175 int rc;
177 /* check if the user rid exsists, if not, try searching on the uid */
179 snprintf(filter, sizeof(filter) - 1, "rid=%i", rid);
180 rc = ldapsam_search_one_user(ldap_state, filter, result);
182 if (rc != LDAP_SUCCESS)
183 rc = ldapsam_search_one_user_by_uid(ldap_state,
184 fallback_pdb_user_rid_to_uid(rid),
185 result);
187 return rc;
190 /*******************************************************************
191 Delete complete object or objectclass and attrs from
192 object found in search_result depending on lp_ldap_delete_dn
193 ******************************************************************/
194 static NTSTATUS ldapsam_delete_entry(struct smb_ldap_privates *ldap_state,
195 LDAPMessage *result,
196 const char *objectclass,
197 const char **attrs)
199 int rc;
200 LDAPMessage *entry;
201 LDAPMod **mods = NULL;
202 char *name, *dn;
203 BerElement *ptr = NULL;
205 rc = ldap_count_entries(ldap_state->ldap_struct, result);
207 if (rc != 1) {
208 DEBUG(0, ("Entry must exist exactly once!\n"));
209 return NT_STATUS_UNSUCCESSFUL;
212 entry = ldap_first_entry(ldap_state->ldap_struct, result);
213 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
215 if (lp_ldap_delete_dn()) {
216 NTSTATUS ret = NT_STATUS_OK;
217 rc = smb_ldap_delete(ldap_state, dn);
219 if (rc != LDAP_SUCCESS) {
220 DEBUG(0, ("Could not delete object %s\n", dn));
221 ret = NT_STATUS_UNSUCCESSFUL;
223 ldap_memfree(dn);
224 return ret;
227 /* Ok, delete only the SAM attributes */
229 for (name = ldap_first_attribute(ldap_state->ldap_struct, entry, &ptr);
230 name != NULL;
231 name = ldap_next_attribute(ldap_state->ldap_struct, entry, ptr)) {
233 const char **attrib;
235 /* We are only allowed to delete the attributes that
236 really exist. */
238 for (attrib = attrs; *attrib != NULL; attrib++) {
239 if (StrCaseCmp(*attrib, name) == 0) {
240 DEBUG(10, ("deleting attribute %s\n", name));
241 smb_ldap_make_a_mod(&mods, LDAP_MOD_DELETE, name, NULL);
245 ldap_memfree(name);
248 if (ptr != NULL) {
249 ber_free(ptr, 0);
252 smb_ldap_make_a_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
254 rc = smb_ldap_modify(ldap_state, dn, mods);
255 ldap_mods_free(mods, 1);
257 if (rc != LDAP_SUCCESS) {
258 char *ld_error = NULL;
259 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
260 &ld_error);
262 DEBUG(0, ("could not delete attributes for %s, error: %s (%s)\n",
263 dn, ldap_err2string(rc), ld_error?ld_error:"unknown"));
264 SAFE_FREE(ld_error);
265 ldap_memfree(dn);
266 return NT_STATUS_UNSUCCESSFUL;
269 ldap_memfree(dn);
270 return NT_STATUS_OK;
273 /* New Interface is being implemented here */
275 /**********************************************************************
276 Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
277 *********************************************************************/
278 static BOOL get_unix_attributes (struct smb_ldap_privates *ldap_state,
279 SAM_ACCOUNT * sampass,
280 LDAPMessage * entry)
282 pstring homedir;
283 pstring temp;
284 uid_t uid;
285 gid_t gid;
286 char **ldap_values;
287 char **values;
289 if ((ldap_values = ldap_get_values (ldap_state->ldap_struct, entry, "objectClass")) == NULL) {
290 DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
291 return False;
294 for (values=ldap_values;*values;values++) {
295 if (strcasecmp(*values, "posixAccount") == 0) {
296 break;
300 if (!*values) { /*end of array, no posixAccount */
301 DEBUG(10, ("user does not have posixAcccount attributes\n"));
302 ldap_value_free(ldap_values);
303 return False;
305 ldap_value_free(ldap_values);
307 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "homeDirectory", homedir))
308 return False;
310 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "uidNumber", temp))
311 return False;
313 uid = (uid_t)atol(temp);
315 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "gidNumber", temp))
316 return False;
318 gid = (gid_t)atol(temp);
320 pdb_set_unix_homedir(sampass, homedir, PDB_SET);
321 pdb_set_uid(sampass, uid, PDB_SET);
322 pdb_set_gid(sampass, gid, PDB_SET);
324 DEBUG(10, ("user has posixAcccount attributes\n"));
325 return True;
329 /**********************************************************************
330 Initialize SAM_ACCOUNT from an LDAP query
331 (Based on init_sam_from_buffer in pdb_tdb.c)
332 *********************************************************************/
333 static BOOL init_sam_from_ldap (struct smb_ldap_privates *ldap_state,
334 SAM_ACCOUNT * sampass,
335 LDAPMessage * entry)
337 time_t logon_time,
338 logoff_time,
339 kickoff_time,
340 pass_last_set_time,
341 pass_can_change_time,
342 pass_must_change_time;
343 pstring username,
344 domain,
345 nt_username,
346 fullname,
347 homedir,
348 dir_drive,
349 logon_script,
350 profile_path,
351 acct_desc,
352 munged_dial,
353 workstations;
354 struct passwd *pw;
355 uint32 user_rid,
356 group_rid;
357 uint8 smblmpwd[LM_HASH_LEN],
358 smbntpwd[NT_HASH_LEN];
359 uint16 acct_ctrl = 0,
360 logon_divs;
361 uint32 hours_len;
362 uint8 hours[MAX_HOURS_LEN];
363 pstring temp;
364 uid_t uid = -1;
365 gid_t gid = getegid();
369 * do a little initialization
371 username[0] = '\0';
372 domain[0] = '\0';
373 nt_username[0] = '\0';
374 fullname[0] = '\0';
375 homedir[0] = '\0';
376 dir_drive[0] = '\0';
377 logon_script[0] = '\0';
378 profile_path[0] = '\0';
379 acct_desc[0] = '\0';
380 munged_dial[0] = '\0';
381 workstations[0] = '\0';
384 if (sampass == NULL || ldap_state == NULL || entry == NULL) {
385 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
386 return False;
389 if (ldap_state->ldap_struct == NULL) {
390 DEBUG(0, ("init_sam_from_ldap: ldap_state->ldap_struct is NULL!\n"));
391 return False;
394 smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "uid", username);
395 DEBUG(2, ("Entry found for user: %s\n", username));
397 pstrcpy(nt_username, username);
399 pstrcpy(domain, lp_workgroup());
401 pdb_set_username(sampass, username, PDB_SET);
403 pdb_set_domain(sampass, domain, PDB_DEFAULT);
404 pdb_set_nt_username(sampass, nt_username, PDB_SET);
406 smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "rid", temp);
407 user_rid = (uint32)atol(temp);
409 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
411 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "primaryGroupID", temp)) {
412 group_rid = 0;
413 } else {
414 group_rid = (uint32)atol(temp);
415 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
420 * If so configured, try and get the values from LDAP
423 if (!lp_ldap_trust_ids() || (!get_unix_attributes(ldap_state, sampass, entry))) {
426 * Otherwise just ask the system getpw() calls.
429 pw = getpwnam_alloc(username);
430 if (pw == NULL) {
431 if (! ldap_state->permit_non_unix_accounts) {
432 DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\n", username));
433 return False;
435 } else {
436 uid = pw->pw_uid;
437 pdb_set_uid(sampass, uid, PDB_SET);
438 gid = pw->pw_gid;
439 pdb_set_gid(sampass, gid, PDB_SET);
441 pdb_set_unix_homedir(sampass, pw->pw_dir, PDB_SET);
443 passwd_free(&pw);
447 if (group_rid == 0 && pdb_get_init_flags(sampass,PDB_GID) != PDB_DEFAULT) {
448 GROUP_MAP map;
449 gid = pdb_get_gid(sampass);
450 /* call the mapping code here */
451 if(pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) {
452 pdb_set_group_sid(sampass, &map.sid, PDB_SET);
454 else {
455 pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid), PDB_SET);
459 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "pwdLastSet", temp)) {
460 /* leave as default */
461 } else {
462 pass_last_set_time = (time_t) atol(temp);
463 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
466 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "logonTime", temp)) {
467 /* leave as default */
468 } else {
469 logon_time = (time_t) atol(temp);
470 pdb_set_logon_time(sampass, logon_time, PDB_SET);
473 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "logoffTime", temp)) {
474 /* leave as default */
475 } else {
476 logoff_time = (time_t) atol(temp);
477 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
480 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "kickoffTime", temp)) {
481 /* leave as default */
482 } else {
483 kickoff_time = (time_t) atol(temp);
484 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
487 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "pwdCanChange", temp)) {
488 /* leave as default */
489 } else {
490 pass_can_change_time = (time_t) atol(temp);
491 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
494 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "pwdMustChange", temp)) {
495 /* leave as default */
496 } else {
497 pass_must_change_time = (time_t) atol(temp);
498 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
501 /* recommend that 'gecos' and 'displayName' should refer to the same
502 * attribute OID. userFullName depreciated, only used by Samba
503 * primary rules of LDAP: don't make a new attribute when one is already defined
504 * that fits your needs; using cn then displayName rather than 'userFullName'
507 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry,
508 "displayName", fullname)) {
509 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry,
510 "cn", fullname)) {
511 /* leave as default */
512 } else {
513 pdb_set_fullname(sampass, fullname, PDB_SET);
515 } else {
516 pdb_set_fullname(sampass, fullname, PDB_SET);
519 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "homeDrive", dir_drive)) {
520 pdb_set_dir_drive(sampass, talloc_sub_specified(sampass->mem_ctx,
521 lp_logon_drive(),
522 username, domain,
523 uid, gid),
524 PDB_DEFAULT);
525 } else {
526 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
529 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "smbHome", homedir)) {
530 pdb_set_homedir(sampass, talloc_sub_specified(sampass->mem_ctx,
531 lp_logon_home(),
532 username, domain,
533 uid, gid),
534 PDB_DEFAULT);
535 } else {
536 pdb_set_homedir(sampass, homedir, PDB_SET);
539 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "scriptPath", logon_script)) {
540 pdb_set_logon_script(sampass, talloc_sub_specified(sampass->mem_ctx,
541 lp_logon_script(),
542 username, domain,
543 uid, gid),
544 PDB_DEFAULT);
545 } else {
546 pdb_set_logon_script(sampass, logon_script, PDB_SET);
549 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "profilePath", profile_path)) {
550 pdb_set_profile_path(sampass, talloc_sub_specified(sampass->mem_ctx,
551 lp_logon_path(),
552 username, domain,
553 uid, gid),
554 PDB_DEFAULT);
555 } else {
556 pdb_set_profile_path(sampass, profile_path, PDB_SET);
559 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "description", acct_desc)) {
560 /* leave as default */
561 } else {
562 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
565 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "userWorkstations", workstations)) {
566 /* leave as default */;
567 } else {
568 pdb_set_workstations(sampass, workstations, PDB_SET);
571 /* FIXME: hours stuff should be cleaner */
573 logon_divs = 168;
574 hours_len = 21;
575 memset(hours, 0xff, hours_len);
577 if (!smb_ldap_get_single_attribute (ldap_state->ldap_struct, entry, "lmPassword", temp)) {
578 /* leave as default */
579 } else {
580 pdb_gethexpwd(temp, smblmpwd);
581 memset((char *)temp, '\0', strlen(temp)+1);
582 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
583 return False;
584 ZERO_STRUCT(smblmpwd);
587 if (!smb_ldap_get_single_attribute (ldap_state->ldap_struct, entry, "ntPassword", temp)) {
588 /* leave as default */
589 } else {
590 pdb_gethexpwd(temp, smbntpwd);
591 memset((char *)temp, '\0', strlen(temp)+1);
592 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
593 return False;
594 ZERO_STRUCT(smbntpwd);
597 if (!smb_ldap_get_single_attribute (ldap_state->ldap_struct, entry, "acctFlags", temp)) {
598 acct_ctrl |= ACB_NORMAL;
599 } else {
600 acct_ctrl = pdb_decode_acct_ctrl(temp);
602 if (acct_ctrl == 0)
603 acct_ctrl |= ACB_NORMAL;
605 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
608 pdb_set_hours_len(sampass, hours_len, PDB_SET);
609 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
611 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
613 /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
614 /* pdb_set_unknown_5(sampass, unknown5, PDB_SET); */
615 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
617 pdb_set_hours(sampass, hours, PDB_SET);
619 return True;
622 /**********************************************************************
623 An LDAP modification is needed in two cases:
624 * If we are updating the record AND the attribute is CHANGED.
625 * If we are adding the record AND it is SET or CHANGED (ie not default)
626 *********************************************************************/
627 static BOOL need_ldap_mod(BOOL pdb_add, const SAM_ACCOUNT * sampass, enum pdb_elements element) {
628 if (pdb_add) {
629 return (!IS_SAM_DEFAULT(sampass, element));
630 } else {
631 return IS_SAM_CHANGED(sampass, element);
635 /**********************************************************************
636 Set attribute to newval in LDAP, regardless of what value the
637 attribute had in LDAP before.
638 *********************************************************************/
639 static void make_ldap_mod(LDAP *ldap_struct, LDAPMessage *existing,
640 LDAPMod ***mods,
641 const char *attribute, const char *newval)
643 char **values = NULL;
645 if (existing != NULL) {
646 values = ldap_get_values(ldap_struct, existing, attribute);
649 if ((values != NULL) && (values[0] != NULL) &&
650 strcmp(values[0], newval) == 0) {
652 /* Believe it or not, but LDAP will deny a delete and
653 an add at the same time if the values are the
654 same... */
656 ldap_value_free(values);
657 return;
660 /* Regardless of the real operation (add or modify)
661 we add the new value here. We rely on deleting
662 the old value, should it exist. */
664 if ((newval != NULL) && (strlen(newval) > 0)) {
665 smb_ldap_make_a_mod(mods, LDAP_MOD_ADD, attribute, newval);
668 if (values == NULL) {
669 /* There has been no value before, so don't delete it.
670 Here's a possible race: We might end up with
671 duplicate attributes */
672 return;
675 /* By deleting exactly the value we found in the entry this
676 should be race-free in the sense that the LDAP-Server will
677 deny the complete operation if somebody changed the
678 attribute behind our back. */
680 smb_ldap_make_a_mod(mods, LDAP_MOD_DELETE, attribute, values[0]);
681 ldap_value_free(values);
684 /**********************************************************************
685 Initialize SAM_ACCOUNT from an LDAP query
686 (Based on init_buffer_from_sam in pdb_tdb.c)
687 *********************************************************************/
688 static BOOL init_ldap_from_sam (struct smb_ldap_privates *ldap_state,
689 LDAPMessage *existing,
690 LDAPMod *** mods, const SAM_ACCOUNT * sampass,
691 BOOL (*need_update)(const SAM_ACCOUNT *,
692 enum pdb_elements))
694 pstring temp;
695 uint32 rid;
697 if (mods == NULL || sampass == NULL) {
698 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
699 return False;
702 *mods = NULL;
705 * took out adding "objectclass: sambaAccount"
706 * do this on a per-mod basis
708 if (need_update(sampass, PDB_USERNAME))
709 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
710 "uid", pdb_get_username(sampass));
712 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
714 rid = pdb_get_user_rid(sampass);
716 if (rid == 0) {
717 if (!IS_SAM_DEFAULT(sampass, PDB_UID)) {
718 rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass));
719 } else if (ldap_state->permit_non_unix_accounts) {
720 rid = ldapsam_get_next_available_nua_rid(ldap_state);
721 if (rid == 0) {
722 DEBUG(0, ("NO user RID specified on account %s, and "
723 "finding next available NUA RID failed, "
724 "cannot store!\n",
725 pdb_get_username(sampass)));
726 ldap_mods_free(*mods, 1);
727 return False;
729 } else {
730 DEBUG(0, ("NO user RID specified on account %s, "
731 "cannot store!\n", pdb_get_username(sampass)));
732 ldap_mods_free(*mods, 1);
733 return False;
737 slprintf(temp, sizeof(temp) - 1, "%i", rid);
739 if (need_update(sampass, PDB_USERSID))
740 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
741 "rid", temp);
744 rid = pdb_get_group_rid(sampass);
746 if (rid == 0) {
747 if (!IS_SAM_DEFAULT(sampass, PDB_GID)) {
748 rid = pdb_gid_to_group_rid(pdb_get_gid(sampass));
749 } else if (ldap_state->permit_non_unix_accounts) {
750 rid = DOMAIN_GROUP_RID_USERS;
751 } else {
752 DEBUG(0, ("NO group RID specified on account %s, "
753 "cannot store!\n", pdb_get_username(sampass)));
754 ldap_mods_free(*mods, 1);
755 return False;
759 slprintf(temp, sizeof(temp) - 1, "%i", rid);
761 if (need_update(sampass, PDB_GROUPSID))
762 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
763 "primaryGroupID", temp);
765 /* displayName, cn, and gecos should all be the same
766 * most easily accomplished by giving them the same OID
767 * gecos isn't set here b/c it should be handled by the
768 * add-user script
769 * We change displayName only and fall back to cn if
770 * it does not exist.
773 if (need_update(sampass, PDB_FULLNAME))
774 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
775 "displayName", pdb_get_fullname(sampass));
777 if (need_update(sampass, PDB_ACCTDESC))
778 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
779 "description", pdb_get_acct_desc(sampass));
781 if (need_update(sampass, PDB_WORKSTATIONS))
782 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
783 "userWorkstations", pdb_get_workstations(sampass));
785 if (need_update(sampass, PDB_SMBHOME))
786 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
787 "smbHome", pdb_get_homedir(sampass));
789 if (need_update(sampass, PDB_DRIVE))
790 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
791 "homeDrive", pdb_get_dir_drive(sampass));
793 if (need_update(sampass, PDB_LOGONSCRIPT))
794 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
795 "scriptPath", pdb_get_logon_script(sampass));
797 if (need_update(sampass, PDB_PROFILE))
798 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
799 "profilePath", pdb_get_profile_path(sampass));
801 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
803 if (need_update(sampass, PDB_LOGONTIME))
804 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
805 "logonTime", temp);
807 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
809 if (need_update(sampass, PDB_LOGOFFTIME))
810 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
811 "logoffTime", temp);
813 slprintf (temp, sizeof (temp) - 1, "%li",
814 pdb_get_kickoff_time(sampass));
816 if (need_update(sampass, PDB_KICKOFFTIME))
817 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
818 "kickoffTime", temp);
820 slprintf (temp, sizeof (temp) - 1, "%li",
821 pdb_get_pass_can_change_time(sampass));
823 if (need_update(sampass, PDB_CANCHANGETIME))
824 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
825 "pwdCanChange", temp);
827 slprintf (temp, sizeof (temp) - 1, "%li",
828 pdb_get_pass_must_change_time(sampass));
830 if (need_update(sampass, PDB_MUSTCHANGETIME))
831 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
832 "pwdMustChange", temp);
834 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))||
835 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
837 pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass),
838 pdb_get_acct_ctrl(sampass));
840 if (need_update(sampass, PDB_LMPASSWD))
841 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
842 "lmPassword", temp);
844 pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass),
845 pdb_get_acct_ctrl(sampass));
847 if (need_update(sampass, PDB_NTPASSWD))
848 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
849 "ntPassword", temp);
851 slprintf (temp, sizeof (temp) - 1, "%li",
852 pdb_get_pass_last_set_time(sampass));
854 if (need_update(sampass, PDB_PASSLASTSET))
855 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
856 "pwdLastSet", temp);
859 /* FIXME: Hours stuff goes in LDAP */
861 if (need_update(sampass, PDB_ACCTCTRL))
862 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
863 "acctFlags",
864 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
865 NEW_PW_FORMAT_SPACE_PADDED_LEN));
867 return True;
871 /**********************************************************************
872 Connect to LDAP server and find the next available RID.
873 *********************************************************************/
874 static uint32 check_nua_rid_is_avail(struct smb_ldap_privates *ldap_state, uint32 top_rid)
876 LDAPMessage *result;
877 uint32 final_rid = (top_rid & (~USER_RID_TYPE)) + RID_MULTIPLIER;
878 if (top_rid == 0) {
879 return 0;
882 if (final_rid < ldap_state->low_nua_rid || final_rid > ldap_state->high_nua_rid) {
883 return 0;
886 if (ldapsam_search_one_user_by_rid(ldap_state, final_rid, &result) != LDAP_SUCCESS) {
887 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid));
888 return 0;
891 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
892 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid));
893 ldap_msgfree(result);
894 return 0;
897 DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid, final_rid));
898 ldap_msgfree(result);
899 return final_rid;
902 /**********************************************************************
903 Extract the RID from an LDAP entry
904 *********************************************************************/
905 static uint32 entry_to_user_rid(struct smb_ldap_privates *ldap_state, LDAPMessage *entry) {
906 uint32 rid;
907 SAM_ACCOUNT *user = NULL;
908 if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
909 return 0;
912 if (init_sam_from_ldap(ldap_state, user, entry)) {
913 rid = pdb_get_user_rid(user);
914 } else {
915 rid =0;
917 pdb_free_sam(&user);
918 if (rid >= ldap_state->low_nua_rid && rid <= ldap_state->high_nua_rid) {
919 return rid;
921 return 0;
925 /**********************************************************************
926 Connect to LDAP server and find the next available RID.
927 *********************************************************************/
928 static uint32 search_top_nua_rid(struct smb_ldap_privates *ldap_state)
930 int rc;
931 pstring filter;
932 LDAPMessage *result;
933 LDAPMessage *entry;
934 char *final_filter = NULL;
935 uint32 top_rid = 0;
936 uint32 count;
937 uint32 rid;
939 pstrcpy(filter, lp_ldap_filter());
940 all_string_sub(filter, "%u", "*", sizeof(pstring));
942 #if 0
943 asprintf(&final_filter, "(&(%s)(&(rid>=%d)(rid<=%d)))", filter, ldap_state->low_nua_rid, ldap_state->high_nua_rid);
944 #else
945 final_filter = strdup(filter);
946 #endif
947 DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter));
949 rc = smb_ldap_search(ldap_state, lp_ldap_suffix(),
950 LDAP_SCOPE_SUBTREE, final_filter, attr, 0,
951 &result);
953 if (rc != LDAP_SUCCESS) {
954 DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc)));
955 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
957 free(final_filter);
958 result = NULL;
959 return 0;
962 count = ldap_count_entries(ldap_state->ldap_struct, result);
963 DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count));
965 if (count == 0) {
966 DEBUG(3, ("LDAP search returned no records, assuming no non-unix-accounts present!: %s\n", ldap_err2string(rc)));
967 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
968 free(final_filter);
969 ldap_msgfree(result);
970 result = NULL;
971 return ldap_state->low_nua_rid;
974 free(final_filter);
975 entry = ldap_first_entry(ldap_state->ldap_struct,result);
977 top_rid = entry_to_user_rid(ldap_state, entry);
979 while ((entry = ldap_next_entry(ldap_state->ldap_struct, entry))) {
981 rid = entry_to_user_rid(ldap_state, entry);
982 if (rid > top_rid) {
983 top_rid = rid;
987 ldap_msgfree(result);
989 if (top_rid < ldap_state->low_nua_rid)
990 top_rid = ldap_state->low_nua_rid;
992 return top_rid;
995 /**********************************************************************
996 Connect to LDAP server and find the next available RID.
997 *********************************************************************/
998 static uint32 ldapsam_get_next_available_nua_rid(struct smb_ldap_privates *ldap_state) {
999 uint32 next_nua_rid;
1000 uint32 top_nua_rid;
1002 top_nua_rid = search_top_nua_rid(ldap_state);
1004 next_nua_rid = check_nua_rid_is_avail(ldap_state,
1005 top_nua_rid);
1007 return next_nua_rid;
1010 /**********************************************************************
1011 Connect to LDAP server for password enumeration
1012 *********************************************************************/
1013 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
1015 struct smb_ldap_privates *ldap_state = (struct smb_ldap_privates *)my_methods->private_data;
1016 int rc;
1017 pstring filter;
1019 pstrcpy(filter, lp_ldap_filter());
1020 all_string_sub(filter, "%u", "*", sizeof(pstring));
1022 rc = smb_ldap_search(ldap_state, lp_ldap_suffix(),
1023 LDAP_SCOPE_SUBTREE, filter, attr, 0,
1024 &ldap_state->result);
1026 if (rc != LDAP_SUCCESS) {
1027 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
1028 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1029 ldap_msgfree(ldap_state->result);
1030 ldap_state->result = NULL;
1031 return NT_STATUS_UNSUCCESSFUL;
1034 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
1035 ldap_count_entries(ldap_state->ldap_struct,
1036 ldap_state->result)));
1038 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
1039 ldap_state->result);
1040 ldap_state->index = 0;
1042 return NT_STATUS_OK;
1045 /**********************************************************************
1046 End enumeration of the LDAP password list
1047 *********************************************************************/
1048 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1050 struct smb_ldap_privates *ldap_state = (struct smb_ldap_privates *)my_methods->private_data;
1051 if (ldap_state->result) {
1052 ldap_msgfree(ldap_state->result);
1053 ldap_state->result = NULL;
1057 /**********************************************************************
1058 Get the next entry in the LDAP password database
1059 *********************************************************************/
1060 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
1062 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1063 struct smb_ldap_privates *ldap_state = (struct smb_ldap_privates *)my_methods->private_data;
1064 BOOL bret = False;
1066 while (!bret) {
1067 if (!ldap_state->entry)
1068 return ret;
1070 ldap_state->index++;
1071 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
1073 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
1074 ldap_state->entry);
1077 return NT_STATUS_OK;
1080 /**********************************************************************
1081 Get SAM_ACCOUNT entry from LDAP by username
1082 *********************************************************************/
1083 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
1085 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1086 struct smb_ldap_privates *ldap_state = (struct smb_ldap_privates *)my_methods->private_data;
1087 LDAPMessage *result;
1088 LDAPMessage *entry;
1089 int count;
1091 if (ldapsam_search_one_user_by_name(ldap_state, sname, &result) != LDAP_SUCCESS) {
1092 return NT_STATUS_NO_SUCH_USER;
1095 count = ldap_count_entries(ldap_state->ldap_struct, result);
1097 if (count < 1) {
1098 DEBUG(4,
1099 ("We don't find this user [%s] count=%d\n", sname,
1100 count));
1101 return NT_STATUS_NO_SUCH_USER;
1102 } else if (count > 1) {
1103 DEBUG(1,
1104 ("Duplicate entries for this user [%s] Failing. count=%d\n", sname,
1105 count));
1106 return NT_STATUS_NO_SUCH_USER;
1109 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1110 if (entry) {
1111 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1112 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1113 ldap_msgfree(result);
1114 return NT_STATUS_NO_SUCH_USER;
1116 ldap_msgfree(result);
1117 ret = NT_STATUS_OK;
1118 } else {
1119 ldap_msgfree(result);
1121 return ret;
1124 /**********************************************************************
1125 Get SAM_ACCOUNT entry from LDAP by rid
1126 *********************************************************************/
1127 static NTSTATUS ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
1129 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1130 struct smb_ldap_privates *ldap_state =
1131 (struct smb_ldap_privates *)my_methods->private_data;
1132 LDAPMessage *result;
1133 LDAPMessage *entry;
1134 int count;
1136 if (ldapsam_search_one_user_by_rid(ldap_state, rid, &result) != LDAP_SUCCESS) {
1137 return NT_STATUS_NO_SUCH_USER;
1140 count = ldap_count_entries(ldap_state->ldap_struct, result);
1142 if (count < 1) {
1143 DEBUG(4,
1144 ("We don't find this rid [%i] count=%d\n", rid,
1145 count));
1146 return NT_STATUS_NO_SUCH_USER;
1147 } else if (count > 1) {
1148 DEBUG(1,
1149 ("More than one user with rid [%i]. Failing. count=%d\n", rid,
1150 count));
1151 return NT_STATUS_NO_SUCH_USER;
1154 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1155 if (entry) {
1156 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1157 DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
1158 ldap_msgfree(result);
1159 return NT_STATUS_NO_SUCH_USER;
1161 ldap_msgfree(result);
1162 ret = NT_STATUS_OK;
1163 } else {
1164 ldap_msgfree(result);
1166 return ret;
1169 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
1171 uint32 rid;
1172 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
1173 return NT_STATUS_NO_SUCH_USER;
1174 return ldapsam_getsampwrid(my_methods, user, rid);
1177 /********************************************************************
1178 Do the actual modification - also change a plaittext passord if
1179 it it set.
1180 **********************************************************************/
1182 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1183 SAM_ACCOUNT *newpwd, char *dn,
1184 LDAPMod **mods, int ldap_op, BOOL pdb_add)
1186 struct smb_ldap_privates *ldap_state = (struct smb_ldap_privates *)my_methods->private_data;
1187 int rc;
1189 if (!my_methods || !newpwd || !dn) {
1190 return NT_STATUS_INVALID_PARAMETER;
1193 if (!mods) {
1194 DEBUG(5,("mods is empty: nothing to modify\n"));
1195 /* may be password change below however */
1196 } else {
1197 switch(ldap_op)
1199 case LDAP_MOD_ADD:
1200 smb_ldap_make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account");
1201 rc = smb_ldap_add(ldap_state, dn, mods);
1202 break;
1203 case LDAP_MOD_REPLACE:
1204 rc = smb_ldap_modify(ldap_state, dn ,mods);
1205 break;
1206 default:
1207 DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
1208 return NT_STATUS_UNSUCCESSFUL;
1211 if (rc!=LDAP_SUCCESS) {
1212 char *ld_error = NULL;
1213 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1214 &ld_error);
1215 DEBUG(1,
1216 ("failed to %s user dn= %s with: %s\n\t%s\n",
1217 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
1218 dn, ldap_err2string(rc),
1219 ld_error?ld_error:"unknown"));
1220 SAFE_FREE(ld_error);
1221 return NT_STATUS_UNSUCCESSFUL;
1225 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
1226 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))&&
1227 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_OFF)&&
1228 need_ldap_mod(pdb_add, newpwd, PDB_PLAINTEXT_PW)&&
1229 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1230 BerElement *ber;
1231 struct berval *bv;
1232 char *retoid;
1233 struct berval *retdata;
1235 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1236 DEBUG(0,("ber_alloc_t returns NULL\n"));
1237 return NT_STATUS_UNSUCCESSFUL;
1239 ber_printf (ber, "{");
1240 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID,dn);
1241 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, pdb_get_plaintext_passwd(newpwd));
1242 ber_printf (ber, "N}");
1244 if ((rc = ber_flatten (ber, &bv))<0) {
1245 DEBUG(0,("ber_flatten returns a value <0\n"));
1246 return NT_STATUS_UNSUCCESSFUL;
1249 ber_free(ber,1);
1251 if ((rc = smb_ldap_extended_operation(ldap_state, LDAP_EXOP_X_MODIFY_PASSWD,
1252 bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) {
1253 DEBUG(0,("LDAP Password could not be changed for user %s: %s\n",
1254 pdb_get_username(newpwd),ldap_err2string(rc)));
1255 } else {
1256 DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1258 ber_bvfree(retdata);
1259 ber_memfree(retoid);
1261 ber_bvfree(bv);
1263 #else
1264 DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n"));
1265 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */
1266 return NT_STATUS_OK;
1269 /**********************************************************************
1270 Delete entry from LDAP for username
1271 *********************************************************************/
1272 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
1274 struct smb_ldap_privates *ldap_state = (struct smb_ldap_privates *)my_methods->private_data;
1275 const char *sname;
1276 int rc;
1277 LDAPMessage *result;
1278 NTSTATUS ret;
1279 const char *sam_user_attrs[] =
1280 { "lmPassword", "ntPassword", "pwdLastSet", "logonTime", "logoffTime",
1281 "kickoffTime", "pwdCanChange", "pwdMustChange", "acctFlags",
1282 "displayName", "smbHome", "homeDrive", "scriptPath", "profilePath",
1283 "userWorkstations", "primaryGroupID", "domain", "rid", NULL };
1285 if (!sam_acct) {
1286 DEBUG(0, ("sam_acct was NULL!\n"));
1287 return NT_STATUS_INVALID_PARAMETER;
1290 sname = pdb_get_username(sam_acct);
1292 DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
1294 rc = ldapsam_search_one_user_by_name(ldap_state, sname, &result);
1295 if (rc != LDAP_SUCCESS) {
1296 return NT_STATUS_NO_SUCH_USER;
1299 ret = ldapsam_delete_entry(ldap_state, result, "sambaAccount",
1300 sam_user_attrs);
1301 ldap_msgfree(result);
1302 return ret;
1305 /**********************************************************************
1306 Helper function to determine for update_sam_account whether
1307 we need LDAP modification.
1308 *********************************************************************/
1309 static BOOL element_is_changed(const SAM_ACCOUNT *sampass,
1310 enum pdb_elements element)
1312 return IS_SAM_CHANGED(sampass, element);
1315 /**********************************************************************
1316 Update SAM_ACCOUNT
1317 *********************************************************************/
1318 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1320 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1321 struct smb_ldap_privates *ldap_state = (struct smb_ldap_privates *)my_methods->private_data;
1322 int rc;
1323 char *dn;
1324 LDAPMessage *result;
1325 LDAPMessage *entry;
1326 LDAPMod **mods;
1328 rc = ldapsam_search_one_user_by_name(ldap_state, pdb_get_username(newpwd), &result);
1329 if (rc != LDAP_SUCCESS) {
1330 return NT_STATUS_UNSUCCESSFUL;
1333 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
1334 DEBUG(0, ("No user to modify!\n"));
1335 ldap_msgfree(result);
1336 return NT_STATUS_UNSUCCESSFUL;
1339 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1340 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
1342 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
1343 element_is_changed)) {
1344 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1345 ldap_msgfree(result);
1346 return NT_STATUS_UNSUCCESSFUL;
1349 ldap_msgfree(result);
1351 if (mods == NULL) {
1352 DEBUG(4,("mods is empty: nothing to update for user: %s\n",
1353 pdb_get_username(newpwd)));
1354 ldap_mods_free(mods, 1);
1355 return NT_STATUS_OK;
1358 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, False);
1359 ldap_mods_free(mods,1);
1361 if (!NT_STATUS_IS_OK(ret)) {
1362 char *ld_error = NULL;
1363 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1364 &ld_error);
1365 DEBUG(0,("failed to modify user with uid = %s, error: %s (%s)\n",
1366 pdb_get_username(newpwd), ld_error?ld_error:"(unknwon)", ldap_err2string(rc)));
1367 SAFE_FREE(ld_error);
1368 return ret;
1371 DEBUG(2, ("successfully modified uid = %s in the LDAP database\n",
1372 pdb_get_username(newpwd)));
1373 return NT_STATUS_OK;
1376 /**********************************************************************
1377 Helper function to determine for update_sam_account whether
1378 we need LDAP modification.
1379 *********************************************************************/
1380 static BOOL element_is_set_or_changed(const SAM_ACCOUNT *sampass,
1381 enum pdb_elements element)
1383 return (IS_SAM_SET(sampass, element) ||
1384 IS_SAM_CHANGED(sampass, element));
1387 /**********************************************************************
1388 Add SAM_ACCOUNT to LDAP
1389 *********************************************************************/
1390 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1392 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1393 struct smb_ldap_privates *ldap_state = (struct smb_ldap_privates *)my_methods->private_data;
1394 int rc;
1395 pstring filter;
1396 LDAPMessage *result = NULL;
1397 LDAPMessage *entry = NULL;
1398 pstring dn;
1399 LDAPMod **mods = NULL;
1400 int ldap_op;
1401 uint32 num_result;
1403 const char *username = pdb_get_username(newpwd);
1404 if (!username || !*username) {
1405 DEBUG(0, ("Cannot add user without a username!\n"));
1406 return NT_STATUS_INVALID_PARAMETER;
1409 rc = ldapsam_search_one_user_by_name (ldap_state, username, &result);
1410 if (rc != LDAP_SUCCESS) {
1411 return NT_STATUS_UNSUCCESSFUL;
1414 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
1415 DEBUG(0,("User '%s' already in the base, with samba properties\n",
1416 username));
1417 ldap_msgfree(result);
1418 return NT_STATUS_UNSUCCESSFUL;
1420 ldap_msgfree(result);
1422 slprintf (filter, sizeof (filter) - 1, "uid=%s", username);
1423 rc = ldapsam_search_one_user(ldap_state, filter, &result);
1424 if (rc != LDAP_SUCCESS) {
1425 return NT_STATUS_UNSUCCESSFUL;
1428 num_result = ldap_count_entries(ldap_state->ldap_struct, result);
1430 if (num_result > 1) {
1431 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
1432 ldap_msgfree(result);
1433 return NT_STATUS_UNSUCCESSFUL;
1436 /* Check if we need to update an existing entry */
1437 if (num_result == 1) {
1438 char *tmp;
1440 DEBUG(3,("User exists without samba properties: adding them\n"));
1441 ldap_op = LDAP_MOD_REPLACE;
1442 entry = ldap_first_entry (ldap_state->ldap_struct, result);
1443 tmp = ldap_get_dn (ldap_state->ldap_struct, entry);
1444 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
1445 ldap_memfree (tmp);
1446 } else {
1447 /* Check if we need to add an entry */
1448 DEBUG(3,("Adding new user\n"));
1449 ldap_op = LDAP_MOD_ADD;
1450 if (username[strlen(username)-1] == '$') {
1451 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
1452 } else {
1453 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
1457 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
1458 element_is_set_or_changed)) {
1459 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
1460 ldap_msgfree(result);
1461 return NT_STATUS_UNSUCCESSFUL;
1464 ldap_msgfree(result);
1466 if (mods == NULL) {
1467 DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
1468 return NT_STATUS_UNSUCCESSFUL;
1471 smb_ldap_make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
1473 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, True);
1474 if (NT_STATUS_IS_ERR(ret)) {
1475 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
1476 pdb_get_username(newpwd),dn));
1477 ldap_mods_free(mods,1);
1478 return ret;
1481 DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd)));
1482 ldap_mods_free(mods, 1);
1483 return NT_STATUS_OK;
1486 static void free_private_data(void **vp)
1488 struct smb_ldap_privates **ldap_state = (struct smb_ldap_privates **)vp;
1490 smb_ldap_close(*ldap_state);
1492 if ((*ldap_state)->bind_secret) {
1493 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
1496 smb_ldap_close(*ldap_state);
1498 SAFE_FREE((*ldap_state)->bind_dn);
1499 SAFE_FREE((*ldap_state)->bind_secret);
1501 *ldap_state = NULL;
1503 /* No need to free any further, as it is talloc()ed */
1506 static const char *group_attr[] = {"cn", "ntSid", "ntGroupType",
1507 "gidNumber",
1508 "displayName", "description",
1509 NULL };
1511 static int ldapsam_search_one_group (struct smb_ldap_privates *ldap_state,
1512 const char *filter,
1513 LDAPMessage ** result)
1515 int scope = LDAP_SCOPE_SUBTREE;
1516 int rc;
1518 DEBUG(2, ("ldapsam_search_one_group: searching for:[%s]\n", filter));
1520 rc = smb_ldap_search(ldap_state, lp_ldap_suffix (), scope,
1521 filter, group_attr, 0, result);
1523 if (rc != LDAP_SUCCESS) {
1524 char *ld_error = NULL;
1525 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1526 &ld_error);
1527 DEBUG(0, ("ldapsam_search_one_group: "
1528 "Problem during the LDAP search: LDAP error: %s (%s)",
1529 ld_error?ld_error:"(unknown)", ldap_err2string(rc)));
1530 DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
1531 lp_ldap_suffix(), filter));
1532 SAFE_FREE(ld_error);
1535 return rc;
1538 static BOOL init_group_from_ldap(struct smb_ldap_privates *ldap_state,
1539 GROUP_MAP *map, LDAPMessage *entry)
1541 pstring temp;
1543 if (ldap_state == NULL || map == NULL || entry == NULL ||
1544 ldap_state->ldap_struct == NULL) {
1545 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
1546 return False;
1549 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "gidNumber",
1550 temp)) {
1551 DEBUG(0, ("Mandatory attribute gidNumber not found\n"));
1552 return False;
1554 DEBUG(2, ("Entry found for group: %s\n", temp));
1556 map->gid = (gid_t)atol(temp);
1558 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "ntSid",
1559 temp)) {
1560 DEBUG(0, ("Mandatory attribute ntSid not found\n"));
1561 return False;
1563 string_to_sid(&map->sid, temp);
1565 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "ntGroupType",
1566 temp)) {
1567 DEBUG(0, ("Mandatory attribute ntGroupType not found\n"));
1568 return False;
1570 map->sid_name_use = (uint32)atol(temp);
1572 if ((map->sid_name_use < SID_NAME_USER) ||
1573 (map->sid_name_use > SID_NAME_UNKNOWN)) {
1574 DEBUG(0, ("Unknown Group type: %d\n", map->sid_name_use));
1575 return False;
1578 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "displayName",
1579 temp)) {
1580 DEBUG(3, ("Attribute displayName not found\n"));
1581 temp[0] = '\0';
1582 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "cn",
1583 temp)) {
1584 DEBUG(0, ("Attributes cn not found either "
1585 "for gidNumber(%i)\n",map->gid));
1586 return False;
1589 fstrcpy(map->nt_name, temp);
1591 if (!smb_ldap_get_single_attribute(ldap_state->ldap_struct, entry, "description",
1592 temp)) {
1593 DEBUG(3, ("Attribute description not found\n"));
1594 temp[0] = '\0';
1596 fstrcpy(map->comment, temp);
1598 map->systemaccount = 0;
1599 init_privilege(&map->priv_set);
1601 return True;
1604 static BOOL init_ldap_from_group(LDAP *ldap_struct,
1605 LDAPMessage *existing,
1606 LDAPMod ***mods,
1607 const GROUP_MAP *map)
1609 pstring tmp;
1611 if (mods == NULL || map == NULL) {
1612 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
1613 return False;
1616 *mods = NULL;
1618 sid_to_string(tmp, &map->sid);
1619 make_ldap_mod(ldap_struct, existing, mods, "ntSid", tmp);
1620 snprintf(tmp, sizeof(tmp)-1, "%i", map->sid_name_use);
1621 make_ldap_mod(ldap_struct, existing, mods, "ntGroupType", tmp);
1623 make_ldap_mod(ldap_struct, existing, mods, "displayName", map->nt_name);
1624 make_ldap_mod(ldap_struct, existing, mods, "description", map->comment);
1626 return True;
1629 static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
1630 const char *filter,
1631 GROUP_MAP *map)
1633 struct smb_ldap_privates *ldap_state =
1634 (struct smb_ldap_privates *)methods->private_data;
1635 LDAPMessage *result;
1636 LDAPMessage *entry;
1637 int count;
1639 if (ldapsam_search_one_group(ldap_state, filter, &result)
1640 != LDAP_SUCCESS) {
1641 return NT_STATUS_NO_SUCH_GROUP;
1644 count = ldap_count_entries(ldap_state->ldap_struct, result);
1646 if (count < 1) {
1647 DEBUG(4, ("Did not find group for filter %s\n", filter));
1648 return NT_STATUS_NO_SUCH_GROUP;
1651 if (count > 1) {
1652 DEBUG(1, ("Duplicate entries for filter %s: count=%d\n",
1653 filter, count));
1654 return NT_STATUS_NO_SUCH_GROUP;
1657 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1659 if (!entry) {
1660 ldap_msgfree(result);
1661 return NT_STATUS_UNSUCCESSFUL;
1664 if (!init_group_from_ldap(ldap_state, map, entry)) {
1665 DEBUG(1, ("init_group_from_ldap failed for group filter %s\n",
1666 filter));
1667 ldap_msgfree(result);
1668 return NT_STATUS_NO_SUCH_GROUP;
1671 ldap_msgfree(result);
1672 return NT_STATUS_OK;
1675 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
1676 DOM_SID sid, BOOL with_priv)
1678 pstring filter;
1680 snprintf(filter, sizeof(filter)-1,
1681 "(&(objectClass=sambaGroupMapping)(ntSid=%s))",
1682 sid_string_static(&sid));
1684 return ldapsam_getgroup(methods, filter, map);
1687 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
1688 gid_t gid, BOOL with_priv)
1690 pstring filter;
1692 snprintf(filter, sizeof(filter)-1,
1693 "(&(objectClass=sambaGroupMapping)(gidNumber=%d))",
1694 gid);
1696 return ldapsam_getgroup(methods, filter, map);
1699 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
1700 char *name, BOOL with_priv)
1702 pstring filter;
1704 /* TODO: Escaping of name? */
1706 snprintf(filter, sizeof(filter)-1,
1707 "(&(objectClass=sambaGroupMapping)(|(displayName=%s)(cn=%s)))",
1708 name, name);
1710 return ldapsam_getgroup(methods, filter, map);
1713 static int ldapsam_search_one_group_by_gid(struct smb_ldap_privates *ldap_state,
1714 gid_t gid,
1715 LDAPMessage **result)
1717 pstring filter;
1719 snprintf(filter, sizeof(filter)-1,
1720 "(&(objectClass=posixGroup)(gidNumber=%i))", gid);
1722 return ldapsam_search_one_group(ldap_state, filter, result);
1725 static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
1726 GROUP_MAP *map)
1728 struct smb_ldap_privates *ldap_state =
1729 (struct smb_ldap_privates *)methods->private_data;
1730 LDAPMessage *result = NULL;
1731 LDAPMod **mods = NULL;
1733 char *tmp;
1734 pstring dn;
1735 LDAPMessage *entry;
1737 GROUP_MAP dummy;
1739 int rc;
1741 if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
1742 map->gid, False))) {
1743 DEBUG(0, ("Group %i already exists in LDAP\n", map->gid));
1744 return NT_STATUS_UNSUCCESSFUL;
1747 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
1748 if (rc != LDAP_SUCCESS) {
1749 return NT_STATUS_UNSUCCESSFUL;
1752 if (ldap_count_entries(ldap_state->ldap_struct, result) != 1) {
1753 DEBUG(2, ("Group %i must exist exactly once in LDAP\n",
1754 map->gid));
1755 ldap_msgfree(result);
1756 return NT_STATUS_UNSUCCESSFUL;
1759 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1760 tmp = ldap_get_dn(ldap_state->ldap_struct, entry);
1761 pstrcpy(dn, tmp);
1762 ldap_memfree(tmp);
1764 if (!init_ldap_from_group(ldap_state->ldap_struct,
1765 result, &mods, map)) {
1766 DEBUG(0, ("init_ldap_from_group failed!\n"));
1767 ldap_mods_free(mods, 1);
1768 ldap_msgfree(result);
1769 return NT_STATUS_UNSUCCESSFUL;
1772 ldap_msgfree(result);
1774 if (mods == NULL) {
1775 DEBUG(0, ("mods is empty\n"));
1776 return NT_STATUS_UNSUCCESSFUL;
1779 smb_ldap_make_a_mod(&mods, LDAP_MOD_ADD, "objectClass",
1780 "sambaGroupMapping");
1782 rc = smb_ldap_modify(ldap_state, dn, mods);
1783 ldap_mods_free(mods, 1);
1785 if (rc != LDAP_SUCCESS) {
1786 char *ld_error = NULL;
1787 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1788 &ld_error);
1789 DEBUG(0, ("failed to add group %i error: %s (%s)\n", map->gid,
1790 ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
1791 SAFE_FREE(ld_error);
1792 return NT_STATUS_UNSUCCESSFUL;
1795 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
1796 return NT_STATUS_OK;
1799 static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
1800 GROUP_MAP *map)
1802 struct smb_ldap_privates *ldap_state =
1803 (struct smb_ldap_privates *)methods->private_data;
1804 int rc;
1805 char *dn;
1806 LDAPMessage *result;
1807 LDAPMessage *entry;
1808 LDAPMod **mods;
1810 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
1812 if (rc != LDAP_SUCCESS) {
1813 return NT_STATUS_UNSUCCESSFUL;
1816 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
1817 DEBUG(0, ("No group to modify!\n"));
1818 ldap_msgfree(result);
1819 return NT_STATUS_UNSUCCESSFUL;
1822 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1823 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
1825 if (!init_ldap_from_group(ldap_state->ldap_struct,
1826 result, &mods, map)) {
1827 DEBUG(0, ("init_ldap_from_group failed\n"));
1828 ldap_msgfree(result);
1829 return NT_STATUS_UNSUCCESSFUL;
1832 ldap_msgfree(result);
1834 if (mods == NULL) {
1835 DEBUG(4, ("mods is empty: nothing to do\n"));
1836 return NT_STATUS_UNSUCCESSFUL;
1839 rc = smb_ldap_modify(ldap_state, dn, mods);
1841 ldap_mods_free(mods, 1);
1843 if (rc != LDAP_SUCCESS) {
1844 char *ld_error = NULL;
1845 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1846 &ld_error);
1847 DEBUG(0, ("failed to modify group %i error: %s (%s)\n", map->gid,
1848 ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
1849 SAFE_FREE(ld_error);
1852 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
1853 return NT_STATUS_OK;
1856 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
1857 DOM_SID sid)
1859 struct smb_ldap_privates *ldap_state =
1860 (struct smb_ldap_privates *)methods->private_data;
1861 pstring sidstring, filter;
1862 LDAPMessage *result;
1863 int rc;
1864 NTSTATUS ret;
1866 const char *sam_group_attrs[] = { "ntSid", "ntGroupType",
1867 "description", "displayName",
1868 NULL };
1869 sid_to_string(sidstring, &sid);
1870 snprintf(filter, sizeof(filter)-1,
1871 "(&(objectClass=sambaGroupMapping)(ntSid=%s))", sidstring);
1873 rc = ldapsam_search_one_group(ldap_state, filter, &result);
1875 if (rc != LDAP_SUCCESS) {
1876 return NT_STATUS_NO_SUCH_GROUP;
1879 ret = ldapsam_delete_entry(ldap_state, result, "sambaGroupMapping",
1880 sam_group_attrs);
1881 ldap_msgfree(result);
1882 return ret;
1885 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
1886 BOOL update)
1888 struct smb_ldap_privates *ldap_state =
1889 (struct smb_ldap_privates *)my_methods->private_data;
1890 const char *filter = "(objectClass=sambaGroupMapping)";
1891 int rc;
1893 rc = smb_ldap_search(ldap_state, lp_ldap_suffix(),
1894 LDAP_SCOPE_SUBTREE, filter,
1895 group_attr, 0, &ldap_state->result);
1897 if (rc != LDAP_SUCCESS) {
1898 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
1899 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1900 ldap_msgfree(ldap_state->result);
1901 ldap_state->result = NULL;
1902 return NT_STATUS_UNSUCCESSFUL;
1905 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
1906 ldap_count_entries(ldap_state->ldap_struct,
1907 ldap_state->result)));
1909 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
1910 ldap_state->result);
1911 ldap_state->index = 0;
1913 return NT_STATUS_OK;
1916 static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
1918 ldapsam_endsampwent(my_methods);
1921 static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
1922 GROUP_MAP *map)
1924 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1925 struct smb_ldap_privates *ldap_state = (struct smb_ldap_privates *)my_methods->private_data;
1926 BOOL bret = False;
1928 while (!bret) {
1929 if (!ldap_state->entry)
1930 return ret;
1932 ldap_state->index++;
1933 bret = init_group_from_ldap(ldap_state, map, ldap_state->entry);
1935 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
1936 ldap_state->entry);
1939 return NT_STATUS_OK;
1942 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
1943 enum SID_NAME_USE sid_name_use,
1944 GROUP_MAP **rmap, int *num_entries,
1945 BOOL unix_only, BOOL with_priv)
1947 GROUP_MAP map;
1948 GROUP_MAP *mapt;
1949 int entries = 0;
1950 NTSTATUS nt_status;
1952 *num_entries = 0;
1953 *rmap = NULL;
1955 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
1956 DEBUG(0, ("Unable to open passdb\n"));
1957 return NT_STATUS_ACCESS_DENIED;
1960 while (NT_STATUS_IS_OK(nt_status = ldapsam_getsamgrent(methods, &map))) {
1961 if (sid_name_use != SID_NAME_UNKNOWN &&
1962 sid_name_use != map.sid_name_use) {
1963 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
1964 continue;
1966 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
1967 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name));
1968 continue;
1971 mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP));
1972 if (!mapt) {
1973 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
1974 SAFE_FREE(*rmap);
1975 return NT_STATUS_UNSUCCESSFUL;
1977 else
1978 (*rmap) = mapt;
1980 mapt[entries] = map;
1982 entries += 1;
1985 ldapsam_endsamgrent(methods);
1987 *num_entries = entries;
1989 return NT_STATUS_OK;
1992 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
1994 NTSTATUS nt_status;
1995 struct smb_ldap_privates *ldap_state;
1997 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
1998 return nt_status;
2001 (*pdb_method)->name = "ldapsam";
2003 (*pdb_method)->setsampwent = ldapsam_setsampwent;
2004 (*pdb_method)->endsampwent = ldapsam_endsampwent;
2005 (*pdb_method)->getsampwent = ldapsam_getsampwent;
2006 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
2007 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
2008 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
2009 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
2010 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
2012 (*pdb_method)->getgrsid = ldapsam_getgrsid;
2013 (*pdb_method)->getgrgid = ldapsam_getgrgid;
2014 (*pdb_method)->getgrnam = ldapsam_getgrnam;
2015 (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
2016 (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
2017 (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
2018 (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
2020 /* TODO: Setup private data and free */
2022 ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct smb_ldap_privates));
2024 if (!ldap_state) {
2025 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
2026 return NT_STATUS_NO_MEMORY;
2029 if (location) {
2030 ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
2031 #ifdef WITH_LDAP_SAMCONFIG
2032 } else {
2033 int ldap_port = lp_ldap_port();
2035 /* remap default port if not using SSL (ie clear or TLS) */
2036 if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
2037 ldap_port = 389;
2040 ldap_state->uri = talloc_asprintf(pdb_context->mem_ctx, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON ? "ldaps" : "ldap", lp_ldap_server(), ldap_port);
2041 if (!ldap_state->uri) {
2042 return NT_STATUS_NO_MEMORY;
2044 #else
2045 } else {
2046 ldap_state->uri = "ldap://localhost";
2047 #endif
2050 (*pdb_method)->private_data = ldap_state;
2052 (*pdb_method)->free_private_data = free_private_data;
2054 return NT_STATUS_OK;
2057 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2059 NTSTATUS nt_status;
2060 struct smb_ldap_privates *ldap_state;
2061 uint32 low_nua_uid, high_nua_uid;
2063 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) {
2064 return nt_status;
2067 (*pdb_method)->name = "ldapsam_nua";
2069 ldap_state = (*pdb_method)->private_data;
2071 ldap_state->permit_non_unix_accounts = True;
2073 if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) {
2074 DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n"));
2075 return NT_STATUS_UNSUCCESSFUL;
2078 ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid);
2080 ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid);
2082 return NT_STATUS_OK;
2085 int pdb_ldap_init(void)
2087 smb_register_passdb("ldapsam", pdb_init_ldapsam, PASSDB_INTERFACE_VERSION);
2088 smb_register_passdb("ldapsam_nua", pdb_init_ldapsam_nua, PASSDB_INTERFACE_VERSION);
2089 return True;