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
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #define DBGC_CLASS DBGC_PASSDB
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
56 #define SAM_ACCOUNT struct sam_passwd
59 struct ldapsam_privates {
68 /* retrive-once info */
71 BOOL permit_non_unix_accounts;
80 #define LDAPSAM_DONT_PING_TIME 10 /* ping only all 10 seconds */
82 static struct ldapsam_privates *static_ldap_state;
84 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state);
86 /*******************************************************************
87 find the ldap password
88 ******************************************************************/
89 static BOOL fetch_ldapsam_pw(char **dn, char** pw)
94 *dn = smb_xstrdup(lp_ldap_admin_dn());
96 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
98 DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
101 *pw=secrets_fetch(key, &size);
103 /* Upgrade 2.2 style entry */
105 char* old_style_key = strdup(*dn);
107 fstring old_style_pw;
109 if (!old_style_key) {
110 DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n"));
114 for (p=old_style_key; *p; p++)
115 if (*p == ',') *p = '/';
117 data=secrets_fetch(old_style_key, &size);
118 if (!size && size < sizeof(old_style_pw)) {
119 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
120 SAFE_FREE(old_style_key);
125 strncpy(old_style_pw, data, size);
126 old_style_pw[size] = 0;
130 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
131 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
132 SAFE_FREE(old_style_key);
136 if (!secrets_delete(old_style_key)) {
137 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
140 SAFE_FREE(old_style_key);
142 *pw = smb_xstrdup(old_style_pw);
148 static const char *attr[] = {"uid", "pwdLastSet", "logonTime",
149 "logoffTime", "kickoffTime", "cn",
150 "pwdCanChange", "pwdMustChange",
151 "displayName", "homeDrive",
152 "smbHome", "scriptPath",
153 "profilePath", "description",
154 "userWorkstations", "rid",
155 "primaryGroupID", "lmPassword",
156 "ntPassword", "acctFlags",
159 /*******************************************************************
160 open a connection to the ldap server.
161 ******************************************************************/
162 static int ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct)
164 int rc = LDAP_SUCCESS;
166 BOOL ldap_v3 = False;
168 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
169 DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri));
171 if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) {
172 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
178 /* Parse the string manually */
184 const char *p = ldap_state->uri;
185 SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
187 /* skip leading "URL:" (if any) */
188 if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
192 sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port);
195 if (strequal(protocol, "ldap")) {
197 } else if (strequal(protocol, "ldaps")) {
200 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
204 if ((*ldap_struct = ldap_init(host, port)) == NULL) {
205 DEBUG(0, ("ldap_init failed !\n"));
206 return LDAP_OPERATIONS_ERROR;
209 if (strequal(protocol, "ldaps")) {
210 #ifdef LDAP_OPT_X_TLS
211 int tls = LDAP_OPT_X_TLS_HARD;
212 if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
214 DEBUG(0, ("Failed to setup a TLS session\n"));
217 DEBUG(3,("LDAPS option set...!\n"));
219 DEBUG(0,("ldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
220 return LDAP_OPERATIONS_ERROR;
226 if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
228 if (version != LDAP_VERSION3)
230 version = LDAP_VERSION3;
231 if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
239 if (lp_ldap_ssl() == LDAP_SSL_START_TLS) {
240 #ifdef LDAP_OPT_X_TLS
242 if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
244 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
245 ldap_err2string(rc)));
248 DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
251 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
252 return LDAP_OPERATIONS_ERROR;
255 DEBUG(0,("ldap_open_connection: StartTLS not supported by LDAP client libraries!\n"));
256 return LDAP_OPERATIONS_ERROR;
260 DEBUG(2, ("ldap_open_connection: connection opened\n"));
265 /*******************************************************************
266 a rebind function for authenticated referrals
267 This version takes a void* that we can shove useful stuff in :-)
268 ******************************************************************/
269 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
271 static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
272 int *methodp, int freeit, void *arg)
274 struct ldapsam_privates *ldap_state = arg;
276 /** @TODO Should we be doing something to check what servers we rebind to?
277 Could we get a referral to a machine that we don't want to give our
278 username and password to? */
282 memset(*credp, '\0', strlen(*credp));
285 DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
286 ldap_state->bind_dn));
288 *whop = strdup(ldap_state->bind_dn);
290 return LDAP_NO_MEMORY;
292 *credp = strdup(ldap_state->bind_secret);
295 return LDAP_NO_MEMORY;
297 *methodp = LDAP_AUTH_SIMPLE;
301 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
303 /*******************************************************************
304 a rebind function for authenticated referrals
305 This version takes a void* that we can shove useful stuff in :-)
306 and actually does the connection.
307 ******************************************************************/
308 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
309 static int rebindproc_connect_with_state (LDAP *ldap_struct,
310 LDAP_CONST char *url,
312 ber_int_t msgid, void *arg)
314 struct ldapsam_privates *ldap_state = arg;
316 DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
317 ldap_state->bind_dn));
319 /** @TODO Should we be doing something to check what servers we rebind to?
320 Could we get a referral to a machine that we don't want to give our
321 username and password to? */
323 rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
327 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
329 /*******************************************************************
330 Add a rebind function for authenticated referrals
331 ******************************************************************/
332 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
334 # if LDAP_SET_REBIND_PROC_ARGS == 2
335 static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
336 int *method, int freeit )
338 return rebindproc_with_state(ldap_struct, whop, credp,
339 method, freeit, static_ldap_state);
342 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
343 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
345 /*******************************************************************
346 a rebind function for authenticated referrals
347 this also does the connection, but no void*.
348 ******************************************************************/
349 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
350 # if LDAP_SET_REBIND_PROC_ARGS == 2
351 static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
354 return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid,
357 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
358 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
360 /*******************************************************************
361 connect to the ldap server under system privilege.
362 ******************************************************************/
363 static int ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct)
369 /* The rebind proc needs this *HACK*. We are not multithreaded, so
370 this will work, but it's not nice. */
371 static_ldap_state = ldap_state;
373 /* get the password */
374 if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
376 DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
377 return LDAP_INVALID_CREDENTIALS;
380 ldap_state->bind_dn = ldap_dn;
381 ldap_state->bind_secret = ldap_secret;
383 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
384 (OpenLDAP) doesnt' seem to support it */
386 DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n",
389 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
390 # if LDAP_SET_REBIND_PROC_ARGS == 2
391 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);
393 # if LDAP_SET_REBIND_PROC_ARGS == 3
394 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);
396 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
397 # if LDAP_SET_REBIND_PROC_ARGS == 2
398 ldap_set_rebind_proc(ldap_struct, &rebindproc);
400 # if LDAP_SET_REBIND_PROC_ARGS == 3
401 ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);
403 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
405 rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
407 if (rc != LDAP_SUCCESS) {
408 DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
412 DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n"));
416 /**********************************************************************
417 Connect to LDAP server
418 *********************************************************************/
419 static int ldapsam_open(struct ldapsam_privates *ldap_state)
422 SMB_ASSERT(ldap_state);
424 #ifndef NO_LDAP_SECURITY
425 if (geteuid() != 0) {
426 DEBUG(0, ("ldapsam_open: cannot access LDAP when not root..\n"));
427 return LDAP_INSUFFICIENT_ACCESS;
431 if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + LDAPSAM_DONT_PING_TIME) < time(NULL))) {
432 struct sockaddr_un addr;
435 if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
436 getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
437 /* the other end has died. reopen. */
438 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
439 ldap_state->ldap_struct = NULL;
440 ldap_state->last_ping = (time_t)0;
442 ldap_state->last_ping = time(NULL);
446 if (ldap_state->ldap_struct != NULL) {
447 DEBUG(5,("ldapsam_open: allready connected to the LDAP server\n"));
451 if ((rc = ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct))) {
455 if ((rc = ldapsam_connect_system(ldap_state, ldap_state->ldap_struct))) {
456 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
457 ldap_state->ldap_struct = NULL;
462 ldap_state->last_ping = time(NULL);
463 DEBUG(4,("The LDAP server is succesful connected\n"));
468 /**********************************************************************
469 Disconnect from LDAP server
470 *********************************************************************/
471 static NTSTATUS ldapsam_close(struct ldapsam_privates *ldap_state)
474 return NT_STATUS_INVALID_PARAMETER;
476 if (ldap_state->ldap_struct != NULL) {
477 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
478 ldap_state->ldap_struct = NULL;
481 DEBUG(5,("The connection to the LDAP server was closed\n"));
482 /* maybe free the results here --metze */
487 static int ldapsam_retry_open(struct ldapsam_privates *ldap_state, int *attempts)
491 SMB_ASSERT(ldap_state && attempts);
493 if (*attempts != 0) {
494 /* we retry after 0.5, 2, 4.5, 8, 12.5, 18, 24.5 seconds */
495 msleep((((*attempts)*(*attempts))/2)*1000);
499 if ((rc = ldapsam_open(ldap_state))) {
500 DEBUG(0,("Connection to LDAP Server failed for the %d try!\n",*attempts));
508 static int ldapsam_search(struct ldapsam_privates *ldap_state, char *base, int scope, char *filter, char *attrs[], int attrsonly, LDAPMessage **res)
510 int rc = LDAP_SERVER_DOWN;
513 SMB_ASSERT(ldap_state);
515 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
517 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
520 rc = ldap_search_s(ldap_state->ldap_struct, base, scope, filter, attrs, attrsonly, res);
523 if (rc == LDAP_SERVER_DOWN) {
524 DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__));
525 ldapsam_close(ldap_state);
531 static int ldapsam_modify(struct ldapsam_privates *ldap_state, char *dn, LDAPMod *attrs[])
533 int rc = LDAP_SERVER_DOWN;
539 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
541 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
544 rc = ldap_modify_s(ldap_state->ldap_struct, dn, attrs);
547 if (rc == LDAP_SERVER_DOWN) {
548 DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__));
549 ldapsam_close(ldap_state);
555 static int ldapsam_add(struct ldapsam_privates *ldap_state, const char *dn, LDAPMod *attrs[])
557 int rc = LDAP_SERVER_DOWN;
563 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
565 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
568 rc = ldap_add_s(ldap_state->ldap_struct, dn, attrs);
571 if (rc == LDAP_SERVER_DOWN) {
572 DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__));
573 ldapsam_close(ldap_state);
579 static int ldapsam_delete(struct ldapsam_privates *ldap_state, char *dn)
581 int rc = LDAP_SERVER_DOWN;
587 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
589 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
592 rc = ldap_delete_s(ldap_state->ldap_struct, dn);
595 if (rc == LDAP_SERVER_DOWN) {
596 DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__));
597 ldapsam_close(ldap_state);
603 static int ldapsam_extended_operation(struct ldapsam_privates *ldap_state, LDAP_CONST char *reqoid, struct berval *reqdata, LDAPControl **serverctrls, LDAPControl **clientctrls, char **retoidp, struct berval **retdatap)
605 int rc = LDAP_SERVER_DOWN;
611 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
613 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
616 rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata, serverctrls, clientctrls, retoidp, retdatap);
619 if (rc == LDAP_SERVER_DOWN) {
620 DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__));
621 ldapsam_close(ldap_state);
627 /*******************************************************************
628 run the search by name.
629 ******************************************************************/
630 static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, const char *filter, LDAPMessage ** result)
632 int scope = LDAP_SCOPE_SUBTREE;
635 DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter));
637 rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope, (char *)filter, (char **)attr, 0, result);
639 if (rc != LDAP_SUCCESS) {
640 DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n",
641 ldap_err2string (rc)));
642 DEBUG(3,("ldapsam_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(),
649 /*******************************************************************
650 run the search by name.
651 ******************************************************************/
652 static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, const char *user,
653 LDAPMessage ** result)
658 * in the filter expression, replace %u with the real name
659 * so in ldap filter, %u MUST exist :-)
661 pstrcpy(filter, lp_ldap_filter());
664 * have to use this here because $ is filtered out
667 all_string_sub(filter, "%u", user, sizeof(pstring));
669 return ldapsam_search_one_user(ldap_state, filter, result);
672 /*******************************************************************
673 run the search by uid.
674 ******************************************************************/
675 static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state,
677 LDAPMessage ** result)
682 /* Get the username from the system and look that up in the LDAP */
684 if ((user = getpwuid_alloc(uid)) == NULL) {
685 DEBUG(3,("ldapsam_search_one_user_by_uid: Failed to locate uid [%d]\n", uid));
686 return LDAP_NO_SUCH_OBJECT;
689 pstrcpy(filter, lp_ldap_filter());
691 all_string_sub(filter, "%u", user->pw_name, sizeof(pstring));
695 return ldapsam_search_one_user(ldap_state, filter, result);
698 /*******************************************************************
699 run the search by rid.
700 ******************************************************************/
701 static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state,
703 LDAPMessage ** result)
708 /* check if the user rid exsists, if not, try searching on the uid */
710 snprintf(filter, sizeof(filter) - 1, "rid=%i", rid);
711 rc = ldapsam_search_one_user(ldap_state, filter, result);
713 if (rc != LDAP_SUCCESS)
714 rc = ldapsam_search_one_user_by_uid(ldap_state,
715 fallback_pdb_user_rid_to_uid(rid),
721 /*******************************************************************
722 search an attribute and return the first value found.
723 ******************************************************************/
724 static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
725 char *attribute, pstring value)
729 if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
731 DEBUG (10, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute));
736 pstrcpy(value, values[0]);
737 ldap_value_free(values);
738 #ifdef DEBUG_PASSWORDS
739 DEBUG (100, ("get_single_attribute: [%s] = [%s]\n", attribute, value));
744 /************************************************************************
745 Routine to manage the LDAPMod structure array
746 manage memory used by the array, by each struct, and values
748 ************************************************************************/
749 static void make_a_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
757 if (attribute == NULL || *attribute == '\0')
760 if (value == NULL || *value == '\0')
765 mods = (LDAPMod **) malloc(sizeof(LDAPMod *));
768 DEBUG(0, ("make_a_mod: out of memory!\n"));
774 for (i = 0; mods[i] != NULL; ++i) {
775 if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute))
781 mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *));
784 DEBUG(0, ("make_a_mod: out of memory!\n"));
787 mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
790 DEBUG(0, ("make_a_mod: out of memory!\n"));
793 mods[i]->mod_op = modop;
794 mods[i]->mod_values = NULL;
795 mods[i]->mod_type = strdup(attribute);
802 if (mods[i]->mod_values != NULL) {
803 for (; mods[i]->mod_values[j] != NULL; j++);
805 mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values,
806 (j + 2) * sizeof (char *));
808 if (mods[i]->mod_values == NULL) {
809 DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
812 mods[i]->mod_values[j] = strdup(value);
813 mods[i]->mod_values[j + 1] = NULL;
818 /* New Interface is being implemented here */
820 /**********************************************************************
821 Initialize SAM_ACCOUNT from an LDAP query
822 (Based on init_sam_from_buffer in pdb_tdb.c)
823 *********************************************************************/
824 static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
825 SAM_ACCOUNT * sampass,
832 pass_can_change_time,
833 pass_must_change_time;
848 uint8 smblmpwd[LM_HASH_LEN],
849 smbntpwd[NT_HASH_LEN];
853 uint8 hours[MAX_HOURS_LEN];
856 gid_t gid = getegid();
860 * do a little initialization
864 nt_username[0] = '\0';
868 logon_script[0] = '\0';
869 profile_path[0] = '\0';
871 munged_dial[0] = '\0';
872 workstations[0] = '\0';
875 if (sampass == NULL || ldap_state == NULL || entry == NULL) {
876 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
880 if (ldap_state->ldap_struct == NULL) {
881 DEBUG(0, ("init_sam_from_ldap: ldap_state->ldap_struct is NULL!\n"));
885 get_single_attribute(ldap_state->ldap_struct, entry, "uid", username);
886 DEBUG(2, ("Entry found for user: %s\n", username));
888 pstrcpy(nt_username, username);
890 pstrcpy(domain, lp_workgroup());
892 pdb_set_username(sampass, username, PDB_SET);
894 pdb_set_domain(sampass, domain, PDB_DEFAULT);
895 pdb_set_nt_username(sampass, nt_username, PDB_SET);
897 get_single_attribute(ldap_state->ldap_struct, entry, "rid", temp);
898 user_rid = (uint32)atol(temp);
900 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
902 if (!get_single_attribute(ldap_state->ldap_struct, entry, "primaryGroupID", temp)) {
905 group_rid = (uint32)atol(temp);
906 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
909 if ((ldap_state->permit_non_unix_accounts)
910 && (user_rid >= ldap_state->low_nua_rid)
911 && (user_rid <= ldap_state->high_nua_rid)) {
915 /* These values MAY be in LDAP, but they can also be retrieved through
916 * sys_getpw*() which is how we're doing it
919 pw = getpwnam_alloc(username);
921 DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\n", username));
927 pdb_set_unix_homedir(sampass, pw->pw_dir, PDB_SET);
931 pdb_set_uid(sampass, uid, PDB_SET);
932 pdb_set_gid(sampass, gid, PDB_SET);
934 if (group_rid == 0) {
936 /* call the mapping code here */
937 if(pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) {
938 pdb_set_group_sid(sampass, &map.sid, PDB_SET);
941 pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid), PDB_SET);
946 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdLastSet", temp)) {
947 /* leave as default */
949 pass_last_set_time = (time_t) atol(temp);
950 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
953 if (!get_single_attribute(ldap_state->ldap_struct, entry, "logonTime", temp)) {
954 /* leave as default */
956 logon_time = (time_t) atol(temp);
957 pdb_set_logon_time(sampass, logon_time, PDB_SET);
960 if (!get_single_attribute(ldap_state->ldap_struct, entry, "logoffTime", temp)) {
961 /* leave as default */
963 logoff_time = (time_t) atol(temp);
964 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
967 if (!get_single_attribute(ldap_state->ldap_struct, entry, "kickoffTime", temp)) {
968 /* leave as default */
970 kickoff_time = (time_t) atol(temp);
971 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
974 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdCanChange", temp)) {
975 /* leave as default */
977 pass_can_change_time = (time_t) atol(temp);
978 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
981 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdMustChange", temp)) {
982 /* leave as default */
984 pass_must_change_time = (time_t) atol(temp);
985 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
988 /* recommend that 'gecos' and 'displayName' should refer to the same
989 * attribute OID. userFullName depreciated, only used by Samba
990 * primary rules of LDAP: don't make a new attribute when one is already defined
991 * that fits your needs; using cn then displayName rather than 'userFullName'
994 if (!get_single_attribute(ldap_state->ldap_struct, entry, "cn", fullname)) {
995 if (!get_single_attribute(ldap_state->ldap_struct, entry, "displayName", fullname)) {
996 /* leave as default */
998 pdb_set_fullname(sampass, fullname, PDB_SET);
1001 pdb_set_fullname(sampass, fullname, PDB_SET);
1004 if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDrive", dir_drive)) {
1005 pdb_set_dir_drive(sampass, talloc_sub_specified(sampass->mem_ctx,
1011 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1014 if (!get_single_attribute(ldap_state->ldap_struct, entry, "smbHome", homedir)) {
1015 pdb_set_homedir(sampass, talloc_sub_specified(sampass->mem_ctx,
1021 pdb_set_homedir(sampass, homedir, PDB_SET);
1024 if (!get_single_attribute(ldap_state->ldap_struct, entry, "scriptPath", logon_script)) {
1025 pdb_set_logon_script(sampass, talloc_sub_specified(sampass->mem_ctx,
1031 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1034 if (!get_single_attribute(ldap_state->ldap_struct, entry, "profilePath", profile_path)) {
1035 pdb_set_profile_path(sampass, talloc_sub_specified(sampass->mem_ctx,
1041 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1044 if (!get_single_attribute(ldap_state->ldap_struct, entry, "description", acct_desc)) {
1045 /* leave as default */
1047 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1050 if (!get_single_attribute(ldap_state->ldap_struct, entry, "userWorkstations", workstations)) {
1051 /* leave as default */;
1053 pdb_set_workstations(sampass, workstations, PDB_SET);
1056 /* FIXME: hours stuff should be cleaner */
1060 memset(hours, 0xff, hours_len);
1062 if (!get_single_attribute (ldap_state->ldap_struct, entry, "lmPassword", temp)) {
1063 /* leave as default */
1065 pdb_gethexpwd(temp, smblmpwd);
1066 memset((char *)temp, '\0', strlen(temp)+1);
1067 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
1069 ZERO_STRUCT(smblmpwd);
1072 if (!get_single_attribute (ldap_state->ldap_struct, entry, "ntPassword", temp)) {
1073 /* leave as default */
1075 pdb_gethexpwd(temp, smbntpwd);
1076 memset((char *)temp, '\0', strlen(temp)+1);
1077 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
1079 ZERO_STRUCT(smbntpwd);
1082 if (!get_single_attribute (ldap_state->ldap_struct, entry, "acctFlags", temp)) {
1083 acct_ctrl |= ACB_NORMAL;
1085 acct_ctrl = pdb_decode_acct_ctrl(temp);
1088 acct_ctrl |= ACB_NORMAL;
1090 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1093 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1094 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1096 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1098 /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
1099 /* pdb_set_unknown_5(sampass, unknown5, PDB_SET); */
1100 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
1102 pdb_set_hours(sampass, hours, PDB_SET);
1107 static BOOL need_ldap_mod(BOOL pdb_add, const SAM_ACCOUNT * sampass, enum pdb_elements element) {
1109 return (!IS_SAM_DEFAULT(sampass, element));
1111 return IS_SAM_CHANGED(sampass, element);
1115 /**********************************************************************
1116 Initialize SAM_ACCOUNT from an LDAP query
1117 (Based on init_buffer_from_sam in pdb_tdb.c)
1118 *********************************************************************/
1119 static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
1120 LDAPMod *** mods, int ldap_op,
1122 const SAM_ACCOUNT * sampass)
1127 if (mods == NULL || sampass == NULL) {
1128 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
1135 * took out adding "objectclass: sambaAccount"
1136 * do this on a per-mod basis
1138 if (need_ldap_mod(pdb_add, sampass, PDB_USERNAME)) {
1139 make_a_mod(mods, ldap_op, "uid", pdb_get_username(sampass));
1140 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
1143 if ((rid = pdb_get_user_rid(sampass))!=0 ) {
1144 if (need_ldap_mod(pdb_add, sampass, PDB_USERSID)) {
1145 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1146 make_a_mod(mods, ldap_op, "rid", temp);
1148 } else if (!IS_SAM_DEFAULT(sampass, PDB_UID)) {
1149 rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass));
1150 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1151 make_a_mod(mods, ldap_op, "rid", temp);
1152 } else if (ldap_state->permit_non_unix_accounts) {
1153 rid = ldapsam_get_next_available_nua_rid(ldap_state);
1155 DEBUG(0, ("NO user RID specified on account %s, and findining next available NUA RID failed, cannot store!\n", pdb_get_username(sampass)));
1158 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1159 make_a_mod(mods, ldap_op, "rid", temp);
1161 DEBUG(0, ("NO user RID specified on account %s, cannot store!\n", pdb_get_username(sampass)));
1167 if ((rid = pdb_get_group_rid(sampass))!=0 ) {
1168 if (need_ldap_mod(pdb_add, sampass, PDB_GROUPSID)) {
1169 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1170 make_a_mod(mods, ldap_op, "primaryGroupID", temp);
1172 } else if (!IS_SAM_DEFAULT(sampass, PDB_GID)) {
1173 rid = pdb_gid_to_group_rid(pdb_get_gid(sampass));
1174 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1175 make_a_mod(mods, ldap_op, "primaryGroupID", temp);
1176 } else if (ldap_state->permit_non_unix_accounts) {
1177 rid = DOMAIN_GROUP_RID_USERS;
1178 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1179 make_a_mod(mods, ldap_op, "primaryGroupID", temp);
1181 DEBUG(0, ("NO group RID specified on account %s, cannot store!\n", pdb_get_username(sampass)));
1186 /* displayName, cn, and gecos should all be the same
1187 * most easily accomplished by giving them the same OID
1188 * gecos isn't set here b/c it should be handled by the
1191 if (need_ldap_mod(pdb_add, sampass, PDB_FULLNAME)) {
1192 make_a_mod(mods, ldap_op, "displayName", pdb_get_fullname(sampass));
1193 make_a_mod(mods, ldap_op, "cn", pdb_get_fullname(sampass));
1195 if (need_ldap_mod(pdb_add, sampass, PDB_ACCTDESC)) {
1196 make_a_mod(mods, ldap_op, "description", pdb_get_acct_desc(sampass));
1198 if (need_ldap_mod(pdb_add, sampass, PDB_WORKSTATIONS)) {
1199 make_a_mod(mods, ldap_op, "userWorkstations", pdb_get_workstations(sampass));
1202 * Only updates fields which have been set (not defaults from smb.conf)
1205 if (need_ldap_mod(pdb_add, sampass, PDB_SMBHOME)) {
1206 make_a_mod(mods, ldap_op, "smbHome", pdb_get_homedir(sampass));
1209 if (need_ldap_mod(pdb_add, sampass, PDB_DRIVE)) {
1210 make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dir_drive(sampass));
1213 if (need_ldap_mod(pdb_add, sampass, PDB_LOGONSCRIPT)) {
1214 make_a_mod(mods, ldap_op, "scriptPath", pdb_get_logon_script(sampass));
1217 if (need_ldap_mod(pdb_add, sampass, PDB_PROFILE))
1218 make_a_mod(mods, ldap_op, "profilePath", pdb_get_profile_path(sampass));
1220 if (need_ldap_mod(pdb_add, sampass, PDB_LOGONTIME)) {
1221 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
1222 make_a_mod(mods, ldap_op, "logonTime", temp);
1225 if (need_ldap_mod(pdb_add, sampass, PDB_LOGOFFTIME)) {
1226 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
1227 make_a_mod(mods, ldap_op, "logoffTime", temp);
1230 if (need_ldap_mod(pdb_add, sampass, PDB_KICKOFFTIME)) {
1231 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
1232 make_a_mod(mods, ldap_op, "kickoffTime", temp);
1236 if (need_ldap_mod(pdb_add, sampass, PDB_CANCHANGETIME)) {
1237 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
1238 make_a_mod(mods, ldap_op, "pwdCanChange", temp);
1241 if (need_ldap_mod(pdb_add, sampass, PDB_MUSTCHANGETIME)) {
1242 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
1243 make_a_mod(mods, ldap_op, "pwdMustChange", temp);
1246 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))||
1247 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
1249 if (need_ldap_mod(pdb_add, sampass, PDB_LMPASSWD)) {
1250 pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass));
1251 make_a_mod (mods, ldap_op, "lmPassword", temp);
1254 if (need_ldap_mod(pdb_add, sampass, PDB_NTPASSWD)) {
1255 pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass));
1256 make_a_mod (mods, ldap_op, "ntPassword", temp);
1259 if (need_ldap_mod(pdb_add, sampass, PDB_PASSLASTSET)) {
1260 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
1261 make_a_mod(mods, ldap_op, "pwdLastSet", temp);
1265 /* FIXME: Hours stuff goes in LDAP */
1266 if (need_ldap_mod(pdb_add, sampass, PDB_ACCTCTRL)) {
1267 make_a_mod (mods, ldap_op, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
1268 NEW_PW_FORMAT_SPACE_PADDED_LEN));
1275 /**********************************************************************
1276 Connect to LDAP server and find the next available RID.
1277 *********************************************************************/
1278 static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 top_rid)
1280 LDAPMessage *result;
1281 uint32 final_rid = (top_rid & (~USER_RID_TYPE)) + RID_MULTIPLIER;
1286 if (final_rid < ldap_state->low_nua_rid || final_rid > ldap_state->high_nua_rid) {
1290 if (ldapsam_search_one_user_by_rid(ldap_state, final_rid, &result) != LDAP_SUCCESS) {
1291 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid));
1292 ldap_msgfree(result);
1296 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
1297 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid));
1298 ldap_msgfree(result);
1302 DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid, final_rid));
1303 ldap_msgfree(result);
1307 /**********************************************************************
1308 Extract the RID from an LDAP entry
1309 *********************************************************************/
1310 static uint32 entry_to_user_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry) {
1312 SAM_ACCOUNT *user = NULL;
1313 if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
1317 if (init_sam_from_ldap(ldap_state, user, entry)) {
1318 rid = pdb_get_user_rid(user);
1322 pdb_free_sam(&user);
1323 if (rid >= ldap_state->low_nua_rid && rid <= ldap_state->high_nua_rid) {
1330 /**********************************************************************
1331 Connect to LDAP server and find the next available RID.
1332 *********************************************************************/
1333 static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state)
1337 LDAPMessage *result;
1339 char *final_filter = NULL;
1344 pstrcpy(filter, lp_ldap_filter());
1345 all_string_sub(filter, "%u", "*", sizeof(pstring));
1348 asprintf(&final_filter, "(&(%s)(&(rid>=%d)(rid<=%d)))", filter, ldap_state->low_nua_rid, ldap_state->high_nua_rid);
1350 final_filter = strdup(filter);
1352 DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter));
1354 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1355 LDAP_SCOPE_SUBTREE, final_filter, (char **)attr, 0,
1358 if (rc != LDAP_SUCCESS) {
1359 DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc)));
1360 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1363 ldap_msgfree(result);
1368 count = ldap_count_entries(ldap_state->ldap_struct, result);
1369 DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count));
1372 DEBUG(3, ("LDAP search returned no records, assuming no non-unix-accounts present!: %s\n", ldap_err2string(rc)));
1373 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1375 ldap_msgfree(result);
1377 return ldap_state->low_nua_rid;
1381 entry = ldap_first_entry(ldap_state->ldap_struct,result);
1383 top_rid = entry_to_user_rid(ldap_state, entry);
1385 while ((entry = ldap_next_entry(ldap_state->ldap_struct, entry))) {
1387 rid = entry_to_user_rid(ldap_state, entry);
1388 if (rid > top_rid) {
1393 ldap_msgfree(result);
1395 if (top_rid < ldap_state->low_nua_rid)
1396 top_rid = ldap_state->low_nua_rid;
1401 /**********************************************************************
1402 Connect to LDAP server and find the next available RID.
1403 *********************************************************************/
1404 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state) {
1405 uint32 next_nua_rid;
1408 top_nua_rid = search_top_nua_rid(ldap_state);
1410 next_nua_rid = check_nua_rid_is_avail(ldap_state,
1413 return next_nua_rid;
1416 /**********************************************************************
1417 Connect to LDAP server for password enumeration
1418 *********************************************************************/
1419 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
1421 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1425 pstrcpy(filter, lp_ldap_filter());
1426 all_string_sub(filter, "%u", "*", sizeof(pstring));
1428 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1429 LDAP_SCOPE_SUBTREE, filter, (char **)attr, 0,
1430 &ldap_state->result);
1432 if (rc != LDAP_SUCCESS) {
1433 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
1434 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1435 ldap_msgfree(ldap_state->result);
1436 ldap_state->result = NULL;
1437 return NT_STATUS_UNSUCCESSFUL;
1440 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
1441 ldap_count_entries(ldap_state->ldap_struct,
1442 ldap_state->result)));
1444 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
1445 ldap_state->result);
1446 ldap_state->index = 0;
1448 return NT_STATUS_OK;
1451 /**********************************************************************
1452 End enumeration of the LDAP password list
1453 *********************************************************************/
1454 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1456 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1457 if (ldap_state->result) {
1458 ldap_msgfree(ldap_state->result);
1459 ldap_state->result = NULL;
1463 /**********************************************************************
1464 Get the next entry in the LDAP password database
1465 *********************************************************************/
1466 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
1468 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1469 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1472 /* The rebind proc needs this *HACK*. We are not multithreaded, so
1473 this will work, but it's not nice. */
1474 static_ldap_state = ldap_state;
1477 if (!ldap_state->entry)
1480 ldap_state->index++;
1481 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
1483 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
1487 return NT_STATUS_OK;
1490 /**********************************************************************
1491 Get SAM_ACCOUNT entry from LDAP by username
1492 *********************************************************************/
1493 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
1495 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1496 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1497 LDAPMessage *result;
1500 if (ldapsam_search_one_user_by_name(ldap_state, sname, &result) != LDAP_SUCCESS) {
1501 return NT_STATUS_UNSUCCESSFUL;
1503 if (ldap_count_entries(ldap_state->ldap_struct, result) < 1) {
1505 ("We don't find this user [%s] count=%d\n", sname,
1506 ldap_count_entries(ldap_state->ldap_struct, result)));
1507 return NT_STATUS_UNSUCCESSFUL;
1509 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1511 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1512 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1513 ldap_msgfree(result);
1514 return NT_STATUS_UNSUCCESSFUL;
1516 ldap_msgfree(result);
1519 ldap_msgfree(result);
1524 /**********************************************************************
1525 Get SAM_ACCOUNT entry from LDAP by rid
1526 *********************************************************************/
1527 static NTSTATUS ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
1529 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1530 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1531 LDAPMessage *result;
1534 if (ldapsam_search_one_user_by_rid(ldap_state, rid, &result) != LDAP_SUCCESS) {
1535 return NT_STATUS_UNSUCCESSFUL;
1538 if (ldap_count_entries(ldap_state->ldap_struct, result) < 1) {
1540 ("We don't find this rid [%i] count=%d\n", rid,
1541 ldap_count_entries(ldap_state->ldap_struct, result)));
1542 return NT_STATUS_UNSUCCESSFUL;
1545 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1547 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1548 DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
1549 ldap_msgfree(result);
1550 return NT_STATUS_UNSUCCESSFUL;
1552 ldap_msgfree(result);
1555 ldap_msgfree(result);
1560 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
1563 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
1564 return NT_STATUS_UNSUCCESSFUL;
1565 return ldapsam_getsampwrid(my_methods, user, rid);
1568 /********************************************************************
1569 Do the actual modification - also change a plaittext passord if
1571 **********************************************************************/
1573 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1574 SAM_ACCOUNT *newpwd, char *dn,
1575 LDAPMod **mods, int ldap_op, BOOL pdb_add)
1577 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1580 if (!my_methods || !newpwd || !dn) {
1581 return NT_STATUS_INVALID_PARAMETER;
1585 DEBUG(5,("mods is empty: nothing to modify\n"));
1586 /* may be password change below however */
1591 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account");
1592 rc = ldapsam_add(ldap_state, dn, mods);
1594 case LDAP_MOD_REPLACE:
1595 rc = ldapsam_modify(ldap_state, dn ,mods);
1598 DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
1599 return NT_STATUS_UNSUCCESSFUL;
1602 if (rc!=LDAP_SUCCESS) {
1604 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1607 ("failed to %s user dn= %s with: %s\n\t%s\n",
1608 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
1609 dn, ldap_err2string(rc),
1612 return NT_STATUS_UNSUCCESSFUL;
1616 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
1617 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))&&
1618 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_OFF)&&
1619 need_ldap_mod(pdb_add, newpwd, PDB_PLAINTEXT_PW)&&
1620 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1624 struct berval *retdata;
1626 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1627 DEBUG(0,("ber_alloc_t returns NULL\n"));
1628 return NT_STATUS_UNSUCCESSFUL;
1630 ber_printf (ber, "{");
1631 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID,dn);
1632 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, pdb_get_plaintext_passwd(newpwd));
1633 ber_printf (ber, "N}");
1635 if ((rc = ber_flatten (ber, &bv))<0) {
1636 DEBUG(0,("ber_flatten returns a value <0\n"));
1637 return NT_STATUS_UNSUCCESSFUL;
1642 if ((rc = ldapsam_extended_operation(ldap_state, LDAP_EXOP_X_MODIFY_PASSWD,
1643 bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) {
1644 DEBUG(0,("LDAP Password could not be changed for user %s: %s\n",
1645 pdb_get_username(newpwd),ldap_err2string(rc)));
1647 DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1649 ber_bvfree(retdata);
1650 ber_memfree(retoid);
1655 DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n"));
1656 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */
1657 return NT_STATUS_OK;
1660 /**********************************************************************
1661 Delete entry from LDAP for username
1662 *********************************************************************/
1663 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
1665 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1670 LDAPMessage *result;
1673 DEBUG(0, ("sam_acct was NULL!\n"));
1674 return NT_STATUS_UNSUCCESSFUL;
1677 sname = pdb_get_username(sam_acct);
1679 DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
1681 rc = ldapsam_search_one_user_by_name(ldap_state, sname, &result);
1682 if (ldap_count_entries (ldap_state->ldap_struct, result) == 0) {
1683 DEBUG (0, ("User doesn't exit!\n"));
1684 ldap_msgfree (result);
1685 return NT_STATUS_UNSUCCESSFUL;
1688 entry = ldap_first_entry (ldap_state->ldap_struct, result);
1689 dn = ldap_get_dn (ldap_state->ldap_struct, entry);
1690 ldap_msgfree(result);
1692 rc = ldapsam_delete(ldap_state, dn);
1695 if (rc != LDAP_SUCCESS) {
1697 ldap_get_option (ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
1698 DEBUG (0,("failed to delete user with uid = %s with: %s\n\t%s\n",
1699 sname, ldap_err2string (rc), ld_error));
1701 return NT_STATUS_UNSUCCESSFUL;
1704 DEBUG (2,("successfully deleted uid = %s from the LDAP database\n", sname));
1705 return NT_STATUS_OK;
1708 /**********************************************************************
1710 *********************************************************************/
1711 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1713 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1714 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1717 LDAPMessage *result;
1721 if (!init_ldap_from_sam(ldap_state, &mods, LDAP_MOD_REPLACE, False, newpwd)) {
1722 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1723 ldap_msgfree(result);
1724 return NT_STATUS_UNSUCCESSFUL;
1728 DEBUG(4,("mods is empty: nothing to update for user: %s\n",pdb_get_username(newpwd)));
1729 return NT_STATUS_OK;
1732 rc = ldapsam_search_one_user_by_name(ldap_state, pdb_get_username(newpwd), &result);
1734 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
1735 DEBUG(0, ("No user to modify!\n"));
1736 ldap_msgfree(result);
1737 return NT_STATUS_UNSUCCESSFUL;
1740 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1741 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
1742 ldap_msgfree(result);
1744 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, False);
1745 if (NT_STATUS_IS_ERR(ret)) {
1746 DEBUG(0,("failed to modify user with uid = %s\n",
1747 pdb_get_username(newpwd)));
1748 ldap_mods_free(mods,1);
1754 ("successfully modified uid = %s in the LDAP database\n",
1755 pdb_get_username(newpwd)));
1756 ldap_mods_free(mods, 1);
1757 return NT_STATUS_OK;
1760 /**********************************************************************
1761 Add SAM_ACCOUNT to LDAP
1762 *********************************************************************/
1763 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1765 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1766 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1769 LDAPMessage *result = NULL;
1771 LDAPMod **mods = NULL;
1775 const char *username = pdb_get_username(newpwd);
1776 if (!username || !*username) {
1777 DEBUG(0, ("Cannot add user without a username!\n"));
1778 return NT_STATUS_UNSUCCESSFUL;
1781 rc = ldapsam_search_one_user_by_name (ldap_state, username, &result);
1783 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
1784 DEBUG(0,("User already in the base, with samba properties\n"));
1785 ldap_msgfree(result);
1786 return NT_STATUS_UNSUCCESSFUL;
1788 ldap_msgfree(result);
1790 slprintf (filter, sizeof (filter) - 1, "uid=%s", username);
1791 rc = ldapsam_search_one_user(ldap_state, filter, &result);
1792 num_result = ldap_count_entries(ldap_state->ldap_struct, result);
1794 if (num_result > 1) {
1795 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
1796 ldap_msgfree(result);
1797 return NT_STATUS_UNSUCCESSFUL;
1800 /* Check if we need to update an existing entry */
1801 if (num_result == 1) {
1805 DEBUG(3,("User exists without samba properties: adding them\n"));
1806 ldap_op = LDAP_MOD_REPLACE;
1807 entry = ldap_first_entry (ldap_state->ldap_struct, result);
1808 tmp = ldap_get_dn (ldap_state->ldap_struct, entry);
1809 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
1812 /* Check if we need to add an entry */
1813 DEBUG(3,("Adding new user\n"));
1814 ldap_op = LDAP_MOD_ADD;
1815 if (username[strlen(username)-1] == '$') {
1816 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
1818 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
1822 ldap_msgfree(result);
1824 if (!init_ldap_from_sam(ldap_state, &mods, ldap_op, True, newpwd)) {
1825 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
1826 ldap_mods_free(mods, 1);
1827 return NT_STATUS_UNSUCCESSFUL;
1831 DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
1832 return NT_STATUS_UNSUCCESSFUL;
1835 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
1837 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, True);
1838 if (NT_STATUS_IS_ERR(ret)) {
1839 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
1840 pdb_get_username(newpwd),dn));
1841 ldap_mods_free(mods,1);
1845 DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd)));
1846 ldap_mods_free(mods, 1);
1847 return NT_STATUS_OK;
1850 static NTSTATUS lsapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
1851 DOM_SID sid, BOOL with_priv)
1853 return get_group_map_from_sid(sid, map, with_priv) ?
1854 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1857 static NTSTATUS lsapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
1858 gid_t gid, BOOL with_priv)
1860 return get_group_map_from_gid(gid, map, with_priv) ?
1861 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1864 static NTSTATUS lsapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
1865 char *name, BOOL with_priv)
1867 return get_group_map_from_ntname(name, map, with_priv) ?
1868 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1871 static NTSTATUS lsapsam_add_group_mapping_entry(struct pdb_methods *methods,
1874 return add_mapping_entry(map, TDB_INSERT) ?
1875 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1878 static NTSTATUS lsapsam_update_group_mapping_entry(struct pdb_methods *methods,
1881 return add_mapping_entry(map, TDB_REPLACE) ?
1882 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1885 static NTSTATUS lsapsam_delete_group_mapping_entry(struct pdb_methods *methods,
1888 return group_map_remove(sid) ?
1889 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1892 static NTSTATUS lsapsam_enum_group_mapping(struct pdb_methods *methods,
1893 enum SID_NAME_USE sid_name_use,
1894 GROUP_MAP **rmap, int *num_entries,
1895 BOOL unix_only, BOOL with_priv)
1897 return enum_group_mapping(sid_name_use, rmap, num_entries, unix_only,
1899 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1902 static void free_private_data(void **vp)
1904 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
1906 ldapsam_close(*ldap_state);
1908 if ((*ldap_state)->bind_secret) {
1909 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
1912 ldapsam_close(*ldap_state);
1914 SAFE_FREE((*ldap_state)->bind_dn);
1915 SAFE_FREE((*ldap_state)->bind_secret);
1919 /* No need to free any further, as it is talloc()ed */
1922 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
1925 struct ldapsam_privates *ldap_state;
1927 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
1931 (*pdb_method)->name = "ldapsam";
1933 (*pdb_method)->setsampwent = ldapsam_setsampwent;
1934 (*pdb_method)->endsampwent = ldapsam_endsampwent;
1935 (*pdb_method)->getsampwent = ldapsam_getsampwent;
1936 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
1937 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
1938 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
1939 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
1940 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
1941 (*pdb_method)->getgrsid = lsapsam_getgrsid;
1942 (*pdb_method)->getgrgid = lsapsam_getgrgid;
1943 (*pdb_method)->getgrnam = lsapsam_getgrnam;
1944 (*pdb_method)->add_group_mapping_entry = lsapsam_add_group_mapping_entry;
1945 (*pdb_method)->update_group_mapping_entry = lsapsam_update_group_mapping_entry;
1946 (*pdb_method)->delete_group_mapping_entry = lsapsam_delete_group_mapping_entry;
1947 (*pdb_method)->enum_group_mapping = lsapsam_enum_group_mapping;
1949 /* TODO: Setup private data and free */
1951 ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct ldapsam_privates));
1954 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
1955 return NT_STATUS_NO_MEMORY;
1959 ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
1960 #ifdef WITH_LDAP_SAMCONFIG
1962 int ldap_port = lp_ldap_port();
1964 /* remap default port if not using SSL (ie clear or TLS) */
1965 if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
1969 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);
1970 if (!ldap_state->uri) {
1971 return NT_STATUS_NO_MEMORY;
1975 ldap_state->uri = "ldap://localhost";
1979 (*pdb_method)->private_data = ldap_state;
1981 (*pdb_method)->free_private_data = free_private_data;
1983 return NT_STATUS_OK;
1986 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
1989 struct ldapsam_privates *ldap_state;
1990 uint32 low_nua_uid, high_nua_uid;
1992 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) {
1996 (*pdb_method)->name = "ldapsam_nua";
1998 ldap_state = (*pdb_method)->private_data;
2000 ldap_state->permit_non_unix_accounts = True;
2002 if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) {
2003 DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n"));
2004 return NT_STATUS_UNSUCCESSFUL;
2007 ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid);
2009 ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid);
2011 return NT_STATUS_OK;
2017 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2019 DEBUG(0, ("ldap not detected at configure time, ldapsam not availalble!\n"));
2020 return NT_STATUS_UNSUCCESSFUL;
2023 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2025 DEBUG(0, ("ldap not dectected at configure time, ldapsam_nua not available!\n"));
2026 return NT_STATUS_UNSUCCESSFUL;