2 Unix SMB/CIFS implementation.
3 LDAP protocol helper functions for SAMBA
4 Copyright (C) Gerald Carter 2001
5 Copyright (C) Shahms King 2001
6 Copyright (C) Jean François Micouleau 1998
7 Copyright (C) Andrew Bartlett 2002
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #define DBGC_CLASS DBGC_PASSDB
32 * persistent connections: if using NSS LDAP, many connections are made
33 * however, using only one within Samba would be nice
35 * Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
37 * Other LDAP based login attributes: accountExpires, etc.
38 * (should be the domain of Samba proper, but the sam_password/SAM_ACCOUNT
39 * structures don't have fields for some of these attributes)
41 * SSL is done, but can't get the certificate based authentication to work
42 * against on my test platform (Linux 2.4, OpenLDAP 2.x)
45 /* NOTE: this will NOT work against an Active Directory server
46 * due to the fact that the two password fields cannot be retrieved
47 * from a server; recommend using security = domain in this situation
55 #define SAM_ACCOUNT struct sam_passwd
58 struct ldapsam_privates {
66 /* retrive-once info */
69 BOOL permit_non_unix_accounts;
75 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state);
77 /*******************************************************************
78 find the ldap password
79 ******************************************************************/
80 static BOOL fetch_ldapsam_pw(char **dn, char** pw)
85 *dn = smb_xstrdup(lp_ldap_admin_dn());
87 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
89 DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
92 *pw=secrets_fetch(key, &size);
94 /* Upgrade 2.2 style entry */
96 char* old_style_key = strdup(*dn);
100 if (!old_style_key) {
101 DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n"));
105 for (p=old_style_key; *p; p++)
106 if (*p == ',') *p = '/';
108 data=secrets_fetch(old_style_key, &size);
109 if (!size && size < sizeof(old_style_pw)) {
110 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
111 SAFE_FREE(old_style_key);
116 strncpy(old_style_pw, data, size);
117 old_style_pw[size] = 0;
121 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
122 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
123 SAFE_FREE(old_style_key);
127 if (!secrets_delete(old_style_key)) {
128 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
131 SAFE_FREE(old_style_key);
133 *pw = smb_xstrdup(old_style_pw);
139 char *attr[] = {"uid", "pwdLastSet", "logonTime",
140 "logoffTime", "kickoffTime", "cn",
141 "pwdCanChange", "pwdMustChange",
142 "dislplayName", "homeDrive",
143 "smbHome", "scriptPath",
144 "profilePath", "description",
145 "userWorkstation", "rid",
146 "primaryGroupID", "lmPassword",
147 "ntPassword", "acctFlags",
148 "domain", "description", NULL };
150 /*******************************************************************
151 open a connection to the ldap server.
152 ******************************************************************/
153 static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct)
156 if (geteuid() != 0) {
157 DEBUG(0, ("ldap_open_connection: cannot access LDAP when not root..\n"));
161 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
162 DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri));
164 if (ldap_initialize(ldap_struct, ldap_state->uri) != LDAP_SUCCESS) {
165 DEBUG(0, ("ldap_initialize: %s\n", strerror(errno)));
170 /* Parse the string manually */
174 int tls = LDAP_OPT_X_TLS_HARD;
179 const char *p = ldap_state->uri;
180 SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
182 /* skip leading "URL:" (if any) */
183 if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
187 sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port);
190 if (strequal(protocol, "ldap")) {
192 } else if (strequal(protocol, "ldaps")) {
195 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
199 if ((*ldap_struct = ldap_init(host, port)) == NULL) {
200 DEBUG(0, ("ldap_init failed !\n"));
204 /* Connect to older servers using SSL and V2 rather than Start TLS */
205 if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
207 if (version != LDAP_VERSION2)
209 version = LDAP_VERSION2;
210 ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
214 if (strequal(protocol, "ldaps")) {
215 if (lp_ldap_ssl() == LDAP_SSL_START_TLS) {
216 if (ldap_get_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION,
217 &version) == LDAP_OPT_SUCCESS)
219 if (version < LDAP_VERSION3)
221 version = LDAP_VERSION3;
222 ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION,
226 if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
228 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
229 ldap_err2string(rc)));
232 DEBUG (2, ("StartTLS issued: using a TLS connection\n"));
235 if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
237 DEBUG(0, ("Failed to setup a TLS session\n"));
242 * No special needs to setup options prior to the LDAP
243 * bind (which should be called next via ldap_connect_system()
249 DEBUG(2, ("ldap_open_connection: connection opened\n"));
254 /*******************************************************************
255 Add a rebind function for authenticated referrals
256 ******************************************************************/
258 static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
259 int *method, int freeit )
265 /** @TODO Should we be doing something to check what servers we rebind to?
266 Could we get a referral to a machine that we don't want to give our
267 username and password to? */
272 if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
274 DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
275 return LDAP_OPERATIONS_ERROR; /* No idea what to return */
278 DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
281 rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
284 SAFE_FREE(ldap_secret);
291 /*******************************************************************
292 connect to the ldap server under system privilege.
293 ******************************************************************/
294 static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct)
300 /* get the password */
301 if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
303 DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
307 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
308 (OpenLDAP) doesnt' seem to support it */
310 DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n",
313 ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc));
315 rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
318 SAFE_FREE(ldap_secret);
320 if (rc != LDAP_SUCCESS)
322 DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
326 DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n"));
330 /*******************************************************************
331 run the search by name.
332 ******************************************************************/
333 static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, LDAP * ldap_struct, const char *filter, LDAPMessage ** result)
335 int scope = LDAP_SCOPE_SUBTREE;
338 DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter));
340 rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, attr, 0, result);
342 if (rc != LDAP_SUCCESS) {
343 DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n",
344 ldap_err2string (rc)));
345 DEBUG(3,("ldapsam_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(),
352 /*******************************************************************
353 run the search by name.
354 ******************************************************************/
355 static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, LDAP * ldap_struct, const char *user,
356 LDAPMessage ** result)
361 * in the filter expression, replace %u with the real name
362 * so in ldap filter, %u MUST exist :-)
364 pstrcpy(filter, lp_ldap_filter());
367 * have to use this here because $ is filtered out
370 all_string_sub(filter, "%u", user, sizeof(pstring));
372 return ldapsam_search_one_user(ldap_state, ldap_struct, filter, result);
375 /*******************************************************************
376 run the search by uid.
377 ******************************************************************/
378 static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state,
379 LDAP * ldap_struct, int uid,
380 LDAPMessage ** result)
385 /* Get the username from the system and look that up in the LDAP */
387 if ((user = getpwuid_alloc(uid)) == NULL) {
388 DEBUG(3,("ldapsam_search_one_user_by_uid: Failed to locate uid [%d]\n", uid));
389 return LDAP_NO_SUCH_OBJECT;
392 pstrcpy(filter, lp_ldap_filter());
394 all_string_sub(filter, "%u", user->pw_name, sizeof(pstring));
398 return ldapsam_search_one_user(ldap_state, ldap_struct, filter, result);
401 /*******************************************************************
402 run the search by rid.
403 ******************************************************************/
404 static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state,
405 LDAP * ldap_struct, uint32 rid,
406 LDAPMessage ** result)
411 /* check if the user rid exsists, if not, try searching on the uid */
413 snprintf(filter, sizeof(filter) - 1, "rid=%i", rid);
414 rc = ldapsam_search_one_user(ldap_state, ldap_struct, filter, result);
416 if (rc != LDAP_SUCCESS)
417 rc = ldapsam_search_one_user_by_uid(ldap_state, ldap_struct,
418 fallback_pdb_user_rid_to_uid(rid),
424 /*******************************************************************
425 search an attribute and return the first value found.
426 ******************************************************************/
427 static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
428 char *attribute, pstring value)
432 if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
434 DEBUG (10, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute));
439 pstrcpy(value, values[0]);
440 ldap_value_free(values);
441 #ifdef DEBUG_PASSWORDS
442 DEBUG (100, ("get_single_attribute: [%s] = [%s]\n", attribute, value));
447 /************************************************************************
448 Routine to manage the LDAPMod structure array
449 manage memory used by the array, by each struct, and values
451 ************************************************************************/
452 static void make_a_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
460 if (attribute == NULL || *attribute == '\0')
463 if (value == NULL || *value == '\0')
468 mods = (LDAPMod **) malloc(sizeof(LDAPMod *));
471 DEBUG(0, ("make_a_mod: out of memory!\n"));
477 for (i = 0; mods[i] != NULL; ++i) {
478 if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute))
484 mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *));
487 DEBUG(0, ("make_a_mod: out of memory!\n"));
490 mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
493 DEBUG(0, ("make_a_mod: out of memory!\n"));
496 mods[i]->mod_op = modop;
497 mods[i]->mod_values = NULL;
498 mods[i]->mod_type = strdup(attribute);
505 if (mods[i]->mod_values != NULL) {
506 for (; mods[i]->mod_values[j] != NULL; j++);
508 mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values,
509 (j + 2) * sizeof (char *));
511 if (mods[i]->mod_values == NULL) {
512 DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
515 mods[i]->mod_values[j] = strdup(value);
516 mods[i]->mod_values[j + 1] = NULL;
521 /* New Interface is being implemented here */
523 /**********************************************************************
524 Initialize SAM_ACCOUNT from an LDAP query
525 (Based on init_sam_from_buffer in pdb_tdb.c)
526 *********************************************************************/
527 static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
528 SAM_ACCOUNT * sampass,
529 LDAP * ldap_struct, LDAPMessage * entry)
535 pass_can_change_time,
536 pass_must_change_time;
556 uint8 hours[MAX_HOURS_LEN];
559 gid_t gid = getegid();
563 * do a little initialization
567 nt_username[0] = '\0';
571 logon_script[0] = '\0';
572 profile_path[0] = '\0';
574 munged_dial[0] = '\0';
575 workstations[0] = '\0';
578 if (sampass == NULL || ldap_struct == NULL || entry == NULL) {
579 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
583 get_single_attribute(ldap_struct, entry, "uid", username);
584 DEBUG(2, ("Entry found for user: %s\n", username));
586 pstrcpy(nt_username, username);
588 pstrcpy(domain, lp_workgroup());
590 get_single_attribute(ldap_struct, entry, "rid", temp);
591 user_rid = (uint32)atol(temp);
592 if (!get_single_attribute(ldap_struct, entry, "primaryGroupID", temp)) {
595 group_rid = (uint32)atol(temp);
598 if ((ldap_state->permit_non_unix_accounts)
599 && (user_rid >= ldap_state->low_nua_rid)
600 && (user_rid <= ldap_state->high_nua_rid)) {
604 /* These values MAY be in LDAP, but they can also be retrieved through
605 * sys_getpw*() which is how we're doing it
608 pw = getpwnam_alloc(username);
610 DEBUG (2,("init_sam_from_ldap: User [%s] does not ave a uid!\n", username));
616 pdb_set_unix_homedir(sampass, pw->pw_dir);
620 pdb_set_uid(sampass, uid);
621 pdb_set_gid(sampass, gid);
623 if (group_rid == 0) {
625 /* call the mapping code here */
626 if(get_group_map_from_gid(gid, &map, MAPPING_WITHOUT_PRIV)) {
627 if (!sid_peek_check_rid(get_global_sam_sid(), &map.sid, &group_rid))
631 group_rid=pdb_gid_to_group_rid(gid);
636 if (!get_single_attribute(ldap_struct, entry, "pwdLastSet", temp)) {
637 /* leave as default */
639 pass_last_set_time = (time_t) atol(temp);
640 pdb_set_pass_last_set_time(sampass, pass_last_set_time);
643 if (!get_single_attribute(ldap_struct, entry, "logonTime", temp)) {
644 /* leave as default */
646 logon_time = (time_t) atol(temp);
647 pdb_set_logon_time(sampass, logon_time, True);
650 if (!get_single_attribute(ldap_struct, entry, "logoffTime", temp)) {
651 /* leave as default */
653 logoff_time = (time_t) atol(temp);
654 pdb_set_logoff_time(sampass, logoff_time, True);
657 if (!get_single_attribute(ldap_struct, entry, "kickoffTime", temp)) {
658 /* leave as default */
660 kickoff_time = (time_t) atol(temp);
661 pdb_set_kickoff_time(sampass, kickoff_time, True);
664 if (!get_single_attribute(ldap_struct, entry, "pwdCanChange", temp)) {
665 /* leave as default */
667 pass_can_change_time = (time_t) atol(temp);
668 pdb_set_pass_can_change_time(sampass, pass_can_change_time, True);
671 if (!get_single_attribute(ldap_struct, entry, "pwdMustChange", temp)) {
672 /* leave as default */
674 pass_must_change_time = (time_t) atol(temp);
675 pdb_set_pass_must_change_time(sampass, pass_must_change_time, True);
678 /* recommend that 'gecos' and 'displayName' should refer to the same
679 * attribute OID. userFullName depreciated, only used by Samba
680 * primary rules of LDAP: don't make a new attribute when one is already defined
681 * that fits your needs; using cn then displayName rather than 'userFullName'
684 if (!get_single_attribute(ldap_struct, entry, "cn", fullname)) {
685 if (!get_single_attribute(ldap_struct, entry, "displayName", fullname)) {
686 /* leave as default */
688 pdb_set_fullname(sampass, fullname);
691 pdb_set_fullname(sampass, fullname);
694 if (!get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive)) {
695 pdb_set_dir_drive(sampass, standard_sub_specified(sampass->mem_ctx,
701 pdb_set_dir_drive(sampass, dir_drive, True);
704 if (!get_single_attribute(ldap_struct, entry, "smbHome", homedir)) {
705 pdb_set_homedir(sampass, standard_sub_specified(sampass->mem_ctx,
711 pdb_set_homedir(sampass, homedir, True);
714 if (!get_single_attribute(ldap_struct, entry, "scriptPath", logon_script)) {
715 pdb_set_logon_script(sampass, standard_sub_specified(sampass->mem_ctx,
721 pdb_set_logon_script(sampass, logon_script, True);
724 if (!get_single_attribute(ldap_struct, entry, "profilePath", profile_path)) {
725 pdb_set_profile_path(sampass, standard_sub_specified(sampass->mem_ctx,
731 pdb_set_profile_path(sampass, profile_path, True);
734 if (!get_single_attribute(ldap_struct, entry, "description", acct_desc)) {
735 /* leave as default */
737 pdb_set_acct_desc(sampass, acct_desc);
740 if (!get_single_attribute(ldap_struct, entry, "userWorkstations", workstations)) {
741 /* leave as default */;
743 pdb_set_workstations(sampass, workstations);
746 /* FIXME: hours stuff should be cleaner */
750 memset(hours, 0xff, hours_len);
752 if (!get_single_attribute (ldap_struct, entry, "lmPassword", temp)) {
753 /* leave as default */
755 pdb_gethexpwd(temp, smblmpwd);
756 memset((char *)temp, '\0', sizeof(temp));
757 if (!pdb_set_lanman_passwd(sampass, smblmpwd))
761 if (!get_single_attribute (ldap_struct, entry, "ntPassword", temp)) {
762 /* leave as default */
764 pdb_gethexpwd(temp, smbntpwd);
765 memset((char *)temp, '\0', sizeof(temp));
766 if (!pdb_set_nt_passwd(sampass, smbntpwd))
770 if (!get_single_attribute (ldap_struct, entry, "acctFlags", temp)) {
771 acct_ctrl |= ACB_NORMAL;
773 acct_ctrl = pdb_decode_acct_ctrl(temp);
776 acct_ctrl |= ACB_NORMAL;
778 pdb_set_acct_ctrl(sampass, acct_ctrl);
781 pdb_set_hours_len(sampass, hours_len);
782 pdb_set_logon_divs(sampass, logon_divs);
784 pdb_set_user_sid_from_rid(sampass, user_rid);
785 pdb_set_group_sid_from_rid(sampass, group_rid);
787 pdb_set_username(sampass, username);
789 pdb_set_domain(sampass, domain);
790 pdb_set_nt_username(sampass, nt_username);
792 pdb_set_munged_dial(sampass, munged_dial);
794 /* pdb_set_unknown_3(sampass, unknown3); */
795 /* pdb_set_unknown_5(sampass, unknown5); */
796 /* pdb_set_unknown_6(sampass, unknown6); */
798 pdb_set_hours(sampass, hours);
803 /**********************************************************************
804 Initialize SAM_ACCOUNT from an LDAP query
805 (Based on init_buffer_from_sam in pdb_tdb.c)
806 *********************************************************************/
807 static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
808 LDAPMod *** mods, int ldap_op,
809 const SAM_ACCOUNT * sampass)
814 if (mods == NULL || sampass == NULL) {
815 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
822 * took out adding "objectclass: sambaAccount"
823 * do this on a per-mod basis
826 make_a_mod(mods, ldap_op, "uid", pdb_get_username(sampass));
827 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
829 if ( pdb_get_user_rid(sampass) ) {
830 rid = pdb_get_user_rid(sampass);
831 } else if (IS_SAM_SET(sampass, FLAG_SAM_UID)) {
832 rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass));
833 } else if (ldap_state->permit_non_unix_accounts) {
834 rid = ldapsam_get_next_available_nua_rid(ldap_state);
836 DEBUG(0, ("NO user RID specified on account %s, and findining next available NUA RID failed, cannot store!\n", pdb_get_username(sampass)));
840 DEBUG(0, ("NO user RID specified on account %s, cannot store!\n", pdb_get_username(sampass)));
844 slprintf(temp, sizeof(temp) - 1, "%i", rid);
845 make_a_mod(mods, ldap_op, "rid", temp);
847 if ( pdb_get_group_rid(sampass) ) {
848 rid = pdb_get_group_rid(sampass);
849 } else if (IS_SAM_SET(sampass, FLAG_SAM_GID)) {
850 rid = pdb_gid_to_group_rid(pdb_get_gid(sampass));
851 } else if (ldap_state->permit_non_unix_accounts) {
852 rid = DOMAIN_GROUP_RID_USERS;
854 DEBUG(0, ("NO group RID specified on account %s, cannot store!\n", pdb_get_username(sampass)));
858 slprintf(temp, sizeof(temp) - 1, "%i", rid);
859 make_a_mod(mods, ldap_op, "primaryGroupID", temp);
861 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
862 make_a_mod(mods, ldap_op, "pwdLastSet", temp);
864 /* displayName, cn, and gecos should all be the same
865 * most easily accomplished by giving them the same OID
866 * gecos isn't set here b/c it should be handled by the
870 make_a_mod(mods, ldap_op, "displayName", pdb_get_fullname(sampass));
871 make_a_mod(mods, ldap_op, "cn", pdb_get_fullname(sampass));
872 make_a_mod(mods, ldap_op, "description", pdb_get_acct_desc(sampass));
873 make_a_mod(mods, ldap_op, "userWorkstations", pdb_get_workstations(sampass));
876 * Only updates fields which have been set (not defaults from smb.conf)
879 if (IS_SAM_SET(sampass, FLAG_SAM_SMBHOME))
880 make_a_mod(mods, ldap_op, "smbHome", pdb_get_homedir(sampass));
882 if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE))
883 make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dirdrive(sampass));
885 if (IS_SAM_SET(sampass, FLAG_SAM_LOGONSCRIPT))
886 make_a_mod(mods, ldap_op, "scriptPath", pdb_get_logon_script(sampass));
888 if (IS_SAM_SET(sampass, FLAG_SAM_PROFILE))
889 make_a_mod(mods, ldap_op, "profilePath", pdb_get_profile_path(sampass));
891 if (IS_SAM_SET(sampass, FLAG_SAM_LOGONTIME)) {
892 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
893 make_a_mod(mods, ldap_op, "logonTime", temp);
896 if (IS_SAM_SET(sampass, FLAG_SAM_LOGOFFTIME)) {
897 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
898 make_a_mod(mods, ldap_op, "logoffTime", temp);
901 if (IS_SAM_SET(sampass, FLAG_SAM_KICKOFFTIME)) {
902 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
903 make_a_mod(mods, ldap_op, "kickoffTime", temp);
906 if (IS_SAM_SET(sampass, FLAG_SAM_CANCHANGETIME)) {
907 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
908 make_a_mod(mods, ldap_op, "pwdCanChange", temp);
911 if (IS_SAM_SET(sampass, FLAG_SAM_MUSTCHANGETIME)) {
912 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
913 make_a_mod(mods, ldap_op, "pwdMustChange", temp);
916 /* FIXME: Hours stuff goes in LDAP */
917 pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass));
918 make_a_mod (mods, ldap_op, "lmPassword", temp);
920 pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass));
921 make_a_mod (mods, ldap_op, "ntPassword", temp);
923 make_a_mod (mods, ldap_op, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
924 NEW_PW_FORMAT_SPACE_PADDED_LEN));
930 /**********************************************************************
931 Connect to LDAP server and find the next available RID.
932 *********************************************************************/
933 static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 top_rid, LDAP *ldap_struct)
936 uint32 final_rid = (top_rid & (~USER_RID_TYPE)) + RID_MULTIPLIER;
941 if (final_rid < ldap_state->low_nua_rid || final_rid > ldap_state->high_nua_rid) {
945 if (ldapsam_search_one_user_by_rid(ldap_state, ldap_struct, final_rid, &result) != LDAP_SUCCESS) {
946 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid));
948 ldap_msgfree(result);
951 if (ldap_count_entries(ldap_struct, result) != 0)
953 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid));
955 ldap_msgfree(result);
958 DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid, final_rid));
962 /**********************************************************************
963 Extract the RID from an LDAP entry
964 *********************************************************************/
965 static uint32 entry_to_user_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry, LDAP *ldap_struct) {
967 SAM_ACCOUNT *user = NULL;
968 if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
972 if (init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) {
973 rid = pdb_get_user_rid(user);
978 if (rid >= ldap_state->low_nua_rid && rid <= ldap_state->high_nua_rid) {
985 /**********************************************************************
986 Connect to LDAP server and find the next available RID.
987 *********************************************************************/
988 static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap_struct)
994 char *final_filter = NULL;
999 pstrcpy(filter, lp_ldap_filter());
1000 all_string_sub(filter, "%u", "*", sizeof(pstring));
1003 asprintf(&final_filter, "(&(%s)(&(rid>=%d)(rid<=%d)))", filter, ldap_state->low_nua_rid, ldap_state->high_nua_rid);
1005 final_filter = strdup(filter);
1007 DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter));
1009 rc = ldap_search_s(ldap_struct, lp_ldap_suffix(),
1010 LDAP_SCOPE_SUBTREE, final_filter, attr, 0,
1013 if (rc != LDAP_SUCCESS)
1016 DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc)));
1017 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1020 ldap_msgfree(result);
1025 count = ldap_count_entries(ldap_struct, result);
1026 DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count));
1029 DEBUG(3, ("LDAP search returned no records, assuming no non-unix-accounts present!: %s\n", ldap_err2string(rc)));
1030 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1032 ldap_msgfree(result);
1034 return ldap_state->low_nua_rid;
1038 entry = ldap_first_entry(ldap_struct,result);
1040 top_rid = entry_to_user_rid(ldap_state, entry, ldap_struct);
1042 while ((entry = ldap_next_entry(ldap_struct, entry))) {
1044 rid = entry_to_user_rid(ldap_state, entry, ldap_struct);
1045 if (rid > top_rid) {
1050 ldap_msgfree(result);
1052 if (top_rid < ldap_state->low_nua_rid)
1053 top_rid = ldap_state->low_nua_rid;
1058 /**********************************************************************
1059 Connect to LDAP server and find the next available RID.
1060 *********************************************************************/
1061 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state) {
1063 uint32 next_nua_rid;
1066 if (!ldapsam_open_connection(ldap_state, &ldap_struct))
1070 if (!ldapsam_connect_system(ldap_state, ldap_struct))
1072 ldap_unbind(ldap_struct);
1076 top_nua_rid = search_top_nua_rid(ldap_state, ldap_struct);
1078 next_nua_rid = check_nua_rid_is_avail(ldap_state,
1079 top_nua_rid, ldap_struct);
1081 ldap_unbind(ldap_struct);
1082 return next_nua_rid;
1085 /**********************************************************************
1086 Connect to LDAP server for password enumeration
1087 *********************************************************************/
1088 static BOOL ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
1090 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1094 if (!ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct))
1098 if (!ldapsam_connect_system(ldap_state, ldap_state->ldap_struct))
1100 ldap_unbind(ldap_state->ldap_struct);
1104 pstrcpy(filter, lp_ldap_filter());
1105 all_string_sub(filter, "%u", "*", sizeof(pstring));
1107 rc = ldap_search_s(ldap_state->ldap_struct, lp_ldap_suffix(),
1108 LDAP_SCOPE_SUBTREE, filter, attr, 0,
1109 &ldap_state->result);
1111 if (rc != LDAP_SUCCESS)
1113 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
1114 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1115 ldap_msgfree(ldap_state->result);
1116 ldap_unbind(ldap_state->ldap_struct);
1117 ldap_state->ldap_struct = NULL;
1118 ldap_state->result = NULL;
1122 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
1123 ldap_count_entries(ldap_state->ldap_struct,
1124 ldap_state->result)));
1126 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
1127 ldap_state->result);
1128 ldap_state->index = 0;
1133 /**********************************************************************
1134 End enumeration of the LDAP password list
1135 *********************************************************************/
1136 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1138 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1139 if (ldap_state->ldap_struct && ldap_state->result)
1141 ldap_msgfree(ldap_state->result);
1142 ldap_unbind(ldap_state->ldap_struct);
1143 ldap_state->ldap_struct = NULL;
1144 ldap_state->result = NULL;
1148 /**********************************************************************
1149 Get the next entry in the LDAP password database
1150 *********************************************************************/
1151 static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * user)
1153 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1157 if (!ldap_state->entry)
1160 ldap_state->index++;
1161 ret = init_sam_from_ldap(ldap_state, user, ldap_state->ldap_struct,
1164 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
1172 /**********************************************************************
1173 Get SAM_ACCOUNT entry from LDAP by username
1174 *********************************************************************/
1175 static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const char *sname)
1177 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1179 LDAPMessage *result;
1182 if (!ldapsam_open_connection(ldap_state, &ldap_struct))
1184 if (!ldapsam_connect_system(ldap_state, ldap_struct))
1186 ldap_unbind(ldap_struct);
1189 if (ldapsam_search_one_user_by_name(ldap_state, ldap_struct, sname, &result) != LDAP_SUCCESS)
1191 ldap_unbind(ldap_struct);
1194 if (ldap_count_entries(ldap_struct, result) < 1)
1197 ("We don't find this user [%s] count=%d\n", sname,
1198 ldap_count_entries(ldap_struct, result)));
1199 ldap_unbind(ldap_struct);
1202 entry = ldap_first_entry(ldap_struct, result);
1205 if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) {
1206 DEBUG(0,("ldapsam_getsampwnam: init_sam_from_ldap failed!\n"));
1207 ldap_msgfree(result);
1208 ldap_unbind(ldap_struct);
1211 ldap_msgfree(result);
1212 ldap_unbind(ldap_struct);
1217 ldap_msgfree(result);
1218 ldap_unbind(ldap_struct);
1223 /**********************************************************************
1224 Get SAM_ACCOUNT entry from LDAP by rid
1225 *********************************************************************/
1226 static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, uint32 rid)
1228 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1230 LDAPMessage *result;
1233 if (!ldapsam_open_connection(ldap_state, &ldap_struct))
1236 if (!ldapsam_connect_system(ldap_state, ldap_struct))
1238 ldap_unbind(ldap_struct);
1241 if (ldapsam_search_one_user_by_rid(ldap_state, ldap_struct, rid, &result) !=
1244 ldap_unbind(ldap_struct);
1248 if (ldap_count_entries(ldap_struct, result) < 1)
1251 ("We don't find this rid [%i] count=%d\n", rid,
1252 ldap_count_entries(ldap_struct, result)));
1253 ldap_unbind(ldap_struct);
1257 entry = ldap_first_entry(ldap_struct, result);
1260 if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) {
1261 DEBUG(0,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
1262 ldap_msgfree(result);
1263 ldap_unbind(ldap_struct);
1266 ldap_msgfree(result);
1267 ldap_unbind(ldap_struct);
1272 ldap_msgfree(result);
1273 ldap_unbind(ldap_struct);
1278 static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
1281 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
1283 return ldapsam_getsampwrid(my_methods, user, rid);
1286 /**********************************************************************
1287 Delete entry from LDAP for username
1288 *********************************************************************/
1289 static BOOL ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
1291 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1297 LDAPMessage *result;
1300 DEBUG(0, ("sam_acct was NULL!\n"));
1304 sname = pdb_get_username(sam_acct);
1306 if (!ldapsam_open_connection(ldap_state, &ldap_struct))
1309 DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
1311 if (!ldapsam_connect_system(ldap_state, ldap_struct)) {
1312 ldap_unbind (ldap_struct);
1313 DEBUG(0, ("Failed to delete user %s from LDAP.\n", sname));
1317 rc = ldapsam_search_one_user_by_name(ldap_state, ldap_struct, sname, &result);
1318 if (ldap_count_entries (ldap_struct, result) == 0) {
1319 DEBUG (0, ("User doesn't exit!\n"));
1320 ldap_msgfree (result);
1321 ldap_unbind (ldap_struct);
1325 entry = ldap_first_entry (ldap_struct, result);
1326 dn = ldap_get_dn (ldap_struct, entry);
1328 rc = ldap_delete_s (ldap_struct, dn);
1331 if (rc != LDAP_SUCCESS) {
1333 ldap_get_option (ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
1334 DEBUG (0,("failed to delete user with uid = %s with: %s\n\t%s\n",
1335 sname, ldap_err2string (rc), ld_error));
1337 ldap_unbind (ldap_struct);
1341 DEBUG (2,("successfully deleted uid = %s from the LDAP database\n", sname));
1342 ldap_unbind (ldap_struct);
1346 /**********************************************************************
1348 *********************************************************************/
1349 static BOOL ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1351 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1355 LDAPMessage *result;
1359 if (!ldapsam_open_connection(ldap_state, &ldap_struct)) /* open a connection to the server */
1362 if (!ldapsam_connect_system(ldap_state, ldap_struct)) /* connect as system account */
1364 ldap_unbind(ldap_struct);
1368 rc = ldapsam_search_one_user_by_name(ldap_state, ldap_struct,
1369 pdb_get_username(newpwd), &result);
1371 if (ldap_count_entries(ldap_struct, result) == 0)
1373 DEBUG(0, ("No user to modify!\n"));
1374 ldap_msgfree(result);
1375 ldap_unbind(ldap_struct);
1379 if (!init_ldap_from_sam(ldap_state, &mods, LDAP_MOD_REPLACE, newpwd)) {
1380 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1381 ldap_msgfree(result);
1382 ldap_unbind(ldap_struct);
1386 entry = ldap_first_entry(ldap_struct, result);
1387 dn = ldap_get_dn(ldap_struct, entry);
1389 rc = ldap_modify_s(ldap_struct, dn, mods);
1391 if (rc != LDAP_SUCCESS)
1394 ldap_get_option(ldap_struct, LDAP_OPT_ERROR_STRING,
1397 ("failed to modify user with uid = %s with: %s\n\t%s\n",
1398 pdb_get_username(newpwd), ldap_err2string(rc),
1401 ldap_unbind(ldap_struct);
1406 ("successfully modified uid = %s in the LDAP database\n",
1407 pdb_get_username(newpwd)));
1408 ldap_mods_free(mods, 1);
1409 ldap_unbind(ldap_struct);
1413 /**********************************************************************
1414 Add SAM_ACCOUNT to LDAP
1415 *********************************************************************/
1416 static BOOL ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1418 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1421 LDAP *ldap_struct = NULL;
1422 LDAPMessage *result = NULL;
1424 LDAPMod **mods = NULL;
1428 const char *username = pdb_get_username(newpwd);
1429 if (!username || !*username) {
1430 DEBUG(0, ("Cannot add user without a username!\n"));
1434 if (!ldapsam_open_connection(ldap_state, &ldap_struct)) /* open a connection to the server */
1439 if (!ldapsam_connect_system(ldap_state, ldap_struct)) /* connect as system account */
1441 ldap_unbind(ldap_struct);
1445 rc = ldapsam_search_one_user_by_name (ldap_state, ldap_struct, username, &result);
1447 if (ldap_count_entries(ldap_struct, result) != 0)
1449 DEBUG(0,("User already in the base, with samba properties\n"));
1450 ldap_msgfree(result);
1451 ldap_unbind(ldap_struct);
1454 ldap_msgfree(result);
1456 slprintf (filter, sizeof (filter) - 1, "uid=%s", username);
1457 rc = ldapsam_search_one_user(ldap_state, ldap_struct, filter, &result);
1458 num_result = ldap_count_entries(ldap_struct, result);
1460 if (num_result > 1) {
1461 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
1462 ldap_msgfree(result);
1466 /* Check if we need to update an existing entry */
1467 if (num_result == 1) {
1471 DEBUG(3,("User exists without samba properties: adding them\n"));
1472 ldap_op = LDAP_MOD_REPLACE;
1473 entry = ldap_first_entry (ldap_struct, result);
1474 tmp = ldap_get_dn (ldap_struct, entry);
1475 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
1479 /* Check if we need to add an entry */
1480 DEBUG(3,("Adding new user\n"));
1481 ldap_op = LDAP_MOD_ADD;
1482 if (username[strlen(username)-1] == '$') {
1483 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
1485 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
1489 ldap_msgfree(result);
1491 if (!init_ldap_from_sam(ldap_state, &mods, ldap_op, newpwd)) {
1492 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
1493 ldap_mods_free(mods, 1);
1494 ldap_unbind(ldap_struct);
1497 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
1499 if (ldap_op == LDAP_MOD_REPLACE) {
1500 rc = ldap_modify_s(ldap_struct, dn, mods);
1503 rc = ldap_add_s(ldap_struct, dn, mods);
1506 if (rc != LDAP_SUCCESS)
1510 ldap_get_option (ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
1511 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s) with: %s\n\t%s\n",
1512 pdb_get_username(newpwd), dn, ldap_err2string (rc), ld_error));
1514 ldap_mods_free(mods, 1);
1515 ldap_unbind(ldap_struct);
1519 DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd)));
1520 ldap_mods_free(mods, 1);
1521 ldap_unbind(ldap_struct);
1525 static void free_private_data(void **vp)
1527 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
1529 if ((*ldap_state)->ldap_struct) {
1530 ldap_unbind((*ldap_state)->ldap_struct);
1535 /* No need to free any further, as it is talloc()ed */
1538 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
1541 struct ldapsam_privates *ldap_state;
1543 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
1547 (*pdb_method)->name = "ldapsam";
1549 (*pdb_method)->setsampwent = ldapsam_setsampwent;
1550 (*pdb_method)->endsampwent = ldapsam_endsampwent;
1551 (*pdb_method)->getsampwent = ldapsam_getsampwent;
1552 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
1553 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
1554 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
1555 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
1556 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
1558 /* TODO: Setup private data and free */
1560 ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct ldapsam_privates));
1563 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
1564 return NT_STATUS_NO_MEMORY;
1568 ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
1570 ldap_state->uri = "ldap://localhost";
1573 (*pdb_method)->private_data = ldap_state;
1575 (*pdb_method)->free_private_data = free_private_data;
1577 return NT_STATUS_OK;
1580 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
1583 struct ldapsam_privates *ldap_state;
1584 uint32 low_nua_uid, high_nua_uid;
1586 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) {
1590 (*pdb_method)->name = "ldapsam_nua";
1592 ldap_state = (*pdb_method)->private_data;
1594 ldap_state->permit_non_unix_accounts = True;
1596 if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) {
1597 DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n"));
1598 return NT_STATUS_UNSUCCESSFUL;
1601 ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid);
1603 ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid);
1605 return NT_STATUS_OK;
1611 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
1613 DEBUG(0, ("ldap not detected at configure time, ldapsam not availalble!\n"));
1614 return NT_STATUS_UNSUCCESSFUL;
1617 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
1619 DEBUG(0, ("ldap not dectected at configure time, ldapsam_nua not available!\n"));
1620 return NT_STATUS_UNSUCCESSFUL;