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",
157 "domain", "objectClass",
158 "uidNumber", "gidNumber",
159 "homeDirectory", NULL };
161 /*******************************************************************
162 open a connection to the ldap server.
163 ******************************************************************/
164 static int ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct)
166 int rc = LDAP_SUCCESS;
168 BOOL ldap_v3 = False;
170 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
171 DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri));
173 if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) {
174 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
180 /* Parse the string manually */
186 const char *p = ldap_state->uri;
187 SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
189 /* skip leading "URL:" (if any) */
190 if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
194 sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port);
197 if (strequal(protocol, "ldap")) {
199 } else if (strequal(protocol, "ldaps")) {
202 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
206 if ((*ldap_struct = ldap_init(host, port)) == NULL) {
207 DEBUG(0, ("ldap_init failed !\n"));
208 return LDAP_OPERATIONS_ERROR;
211 if (strequal(protocol, "ldaps")) {
212 #ifdef LDAP_OPT_X_TLS
213 int tls = LDAP_OPT_X_TLS_HARD;
214 if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
216 DEBUG(0, ("Failed to setup a TLS session\n"));
219 DEBUG(3,("LDAPS option set...!\n"));
221 DEBUG(0,("ldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
222 return LDAP_OPERATIONS_ERROR;
228 if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
230 if (version != LDAP_VERSION3)
232 version = LDAP_VERSION3;
233 if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
241 if (lp_ldap_ssl() == LDAP_SSL_START_TLS) {
242 #ifdef LDAP_OPT_X_TLS
244 if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
246 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
247 ldap_err2string(rc)));
250 DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
253 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
254 return LDAP_OPERATIONS_ERROR;
257 DEBUG(0,("ldap_open_connection: StartTLS not supported by LDAP client libraries!\n"));
258 return LDAP_OPERATIONS_ERROR;
262 DEBUG(2, ("ldap_open_connection: connection opened\n"));
267 /*******************************************************************
268 a rebind function for authenticated referrals
269 This version takes a void* that we can shove useful stuff in :-)
270 ******************************************************************/
271 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
273 static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
274 int *methodp, int freeit, void *arg)
276 struct ldapsam_privates *ldap_state = arg;
278 /** @TODO Should we be doing something to check what servers we rebind to?
279 Could we get a referral to a machine that we don't want to give our
280 username and password to? */
284 memset(*credp, '\0', strlen(*credp));
287 DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
288 ldap_state->bind_dn));
290 *whop = strdup(ldap_state->bind_dn);
292 return LDAP_NO_MEMORY;
294 *credp = strdup(ldap_state->bind_secret);
297 return LDAP_NO_MEMORY;
299 *methodp = LDAP_AUTH_SIMPLE;
303 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
305 /*******************************************************************
306 a rebind function for authenticated referrals
307 This version takes a void* that we can shove useful stuff in :-)
308 and actually does the connection.
309 ******************************************************************/
310 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
311 static int rebindproc_connect_with_state (LDAP *ldap_struct,
312 LDAP_CONST char *url,
314 ber_int_t msgid, void *arg)
316 struct ldapsam_privates *ldap_state = arg;
318 DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
319 ldap_state->bind_dn));
321 /** @TODO Should we be doing something to check what servers we rebind to?
322 Could we get a referral to a machine that we don't want to give our
323 username and password to? */
325 rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
329 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
331 /*******************************************************************
332 Add a rebind function for authenticated referrals
333 ******************************************************************/
334 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
336 # if LDAP_SET_REBIND_PROC_ARGS == 2
337 static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
338 int *method, int freeit )
340 return rebindproc_with_state(ldap_struct, whop, credp,
341 method, freeit, static_ldap_state);
344 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
345 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
347 /*******************************************************************
348 a rebind function for authenticated referrals
349 this also does the connection, but no void*.
350 ******************************************************************/
351 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
352 # if LDAP_SET_REBIND_PROC_ARGS == 2
353 static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
356 return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid,
359 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
360 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
362 /*******************************************************************
363 connect to the ldap server under system privilege.
364 ******************************************************************/
365 static int ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct)
371 /* The rebind proc needs this *HACK*. We are not multithreaded, so
372 this will work, but it's not nice. */
373 static_ldap_state = ldap_state;
375 /* get the password */
376 if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
378 DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
379 return LDAP_INVALID_CREDENTIALS;
382 ldap_state->bind_dn = ldap_dn;
383 ldap_state->bind_secret = ldap_secret;
385 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
386 (OpenLDAP) doesnt' seem to support it */
388 DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n",
391 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
392 # if LDAP_SET_REBIND_PROC_ARGS == 2
393 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);
395 # if LDAP_SET_REBIND_PROC_ARGS == 3
396 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);
398 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
399 # if LDAP_SET_REBIND_PROC_ARGS == 2
400 ldap_set_rebind_proc(ldap_struct, &rebindproc);
402 # if LDAP_SET_REBIND_PROC_ARGS == 3
403 ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);
405 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
407 rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
409 if (rc != LDAP_SUCCESS) {
410 DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
414 DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n"));
418 /**********************************************************************
419 Connect to LDAP server
420 *********************************************************************/
421 static int ldapsam_open(struct ldapsam_privates *ldap_state)
424 SMB_ASSERT(ldap_state);
426 #ifndef NO_LDAP_SECURITY
427 if (geteuid() != 0) {
428 DEBUG(0, ("ldapsam_open: cannot access LDAP when not root..\n"));
429 return LDAP_INSUFFICIENT_ACCESS;
433 if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + LDAPSAM_DONT_PING_TIME) < time(NULL))) {
434 struct sockaddr_un addr;
437 if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
438 getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
439 /* the other end has died. reopen. */
440 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
441 ldap_state->ldap_struct = NULL;
442 ldap_state->last_ping = (time_t)0;
444 ldap_state->last_ping = time(NULL);
448 if (ldap_state->ldap_struct != NULL) {
449 DEBUG(5,("ldapsam_open: allready connected to the LDAP server\n"));
453 if ((rc = ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct))) {
457 if ((rc = ldapsam_connect_system(ldap_state, ldap_state->ldap_struct))) {
458 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
459 ldap_state->ldap_struct = NULL;
464 ldap_state->last_ping = time(NULL);
465 DEBUG(4,("The LDAP server is succesful connected\n"));
470 /**********************************************************************
471 Disconnect from LDAP server
472 *********************************************************************/
473 static NTSTATUS ldapsam_close(struct ldapsam_privates *ldap_state)
476 return NT_STATUS_INVALID_PARAMETER;
478 if (ldap_state->ldap_struct != NULL) {
479 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
480 ldap_state->ldap_struct = NULL;
483 DEBUG(5,("The connection to the LDAP server was closed\n"));
484 /* maybe free the results here --metze */
489 static int ldapsam_retry_open(struct ldapsam_privates *ldap_state, int *attempts)
493 SMB_ASSERT(ldap_state && attempts);
495 if (*attempts != 0) {
496 /* we retry after 0.5, 2, 4.5, 8, 12.5, 18, 24.5 seconds */
497 msleep((((*attempts)*(*attempts))/2)*1000);
501 if ((rc = ldapsam_open(ldap_state))) {
502 DEBUG(0,("Connection to LDAP Server failed for the %d try!\n",*attempts));
510 static int ldapsam_search(struct ldapsam_privates *ldap_state, char *base, int scope, char *filter, char *attrs[], int attrsonly, LDAPMessage **res)
512 int rc = LDAP_SERVER_DOWN;
515 SMB_ASSERT(ldap_state);
517 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
519 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
522 rc = ldap_search_s(ldap_state->ldap_struct, base, scope, filter, attrs, attrsonly, res);
525 if (rc == LDAP_SERVER_DOWN) {
526 DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__));
527 ldapsam_close(ldap_state);
533 static int ldapsam_modify(struct ldapsam_privates *ldap_state, char *dn, LDAPMod *attrs[])
535 int rc = LDAP_SERVER_DOWN;
541 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
543 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
546 rc = ldap_modify_s(ldap_state->ldap_struct, dn, attrs);
549 if (rc == LDAP_SERVER_DOWN) {
550 DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__));
551 ldapsam_close(ldap_state);
557 static int ldapsam_add(struct ldapsam_privates *ldap_state, const char *dn, LDAPMod *attrs[])
559 int rc = LDAP_SERVER_DOWN;
565 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
567 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
570 rc = ldap_add_s(ldap_state->ldap_struct, dn, attrs);
573 if (rc == LDAP_SERVER_DOWN) {
574 DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__));
575 ldapsam_close(ldap_state);
581 static int ldapsam_delete(struct ldapsam_privates *ldap_state, char *dn)
583 int rc = LDAP_SERVER_DOWN;
589 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
591 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
594 rc = ldap_delete_s(ldap_state->ldap_struct, dn);
597 if (rc == LDAP_SERVER_DOWN) {
598 DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__));
599 ldapsam_close(ldap_state);
605 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)
607 int rc = LDAP_SERVER_DOWN;
613 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
615 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
618 rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata, serverctrls, clientctrls, retoidp, retdatap);
621 if (rc == LDAP_SERVER_DOWN) {
622 DEBUG(0,("%s: LDAP server is down!\n",__FUNCTION__));
623 ldapsam_close(ldap_state);
629 /*******************************************************************
630 run the search by name.
631 ******************************************************************/
632 static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, const char *filter, LDAPMessage ** result)
634 int scope = LDAP_SCOPE_SUBTREE;
637 DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter));
639 rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope, (char *)filter, (char **)attr, 0, result);
641 if (rc != LDAP_SUCCESS) {
642 DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n",
643 ldap_err2string (rc)));
644 DEBUG(3,("ldapsam_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(),
651 /*******************************************************************
652 run the search by name.
653 ******************************************************************/
654 static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, const char *user,
655 LDAPMessage ** result)
660 * in the filter expression, replace %u with the real name
661 * so in ldap filter, %u MUST exist :-)
663 pstrcpy(filter, lp_ldap_filter());
666 * have to use this here because $ is filtered out
669 all_string_sub(filter, "%u", user, sizeof(pstring));
671 return ldapsam_search_one_user(ldap_state, filter, result);
674 /*******************************************************************
675 run the search by uid.
676 ******************************************************************/
677 static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state,
679 LDAPMessage ** result)
684 /* Get the username from the system and look that up in the LDAP */
686 if ((user = getpwuid_alloc(uid)) == NULL) {
687 DEBUG(3,("ldapsam_search_one_user_by_uid: Failed to locate uid [%d]\n", uid));
688 return LDAP_NO_SUCH_OBJECT;
691 pstrcpy(filter, lp_ldap_filter());
693 all_string_sub(filter, "%u", user->pw_name, sizeof(pstring));
697 return ldapsam_search_one_user(ldap_state, filter, result);
700 /*******************************************************************
701 run the search by rid.
702 ******************************************************************/
703 static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state,
705 LDAPMessage ** result)
710 /* check if the user rid exsists, if not, try searching on the uid */
712 snprintf(filter, sizeof(filter) - 1, "rid=%i", rid);
713 rc = ldapsam_search_one_user(ldap_state, filter, result);
715 if (rc != LDAP_SUCCESS)
716 rc = ldapsam_search_one_user_by_uid(ldap_state,
717 fallback_pdb_user_rid_to_uid(rid),
723 /*******************************************************************
724 search an attribute and return the first value found.
725 ******************************************************************/
726 static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
727 char *attribute, pstring value)
731 if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
733 DEBUG (10, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute));
738 pstrcpy(value, values[0]);
739 ldap_value_free(values);
740 #ifdef DEBUG_PASSWORDS
741 DEBUG (100, ("get_single_attribute: [%s] = [%s]\n", attribute, value));
746 /************************************************************************
747 Routine to manage the LDAPMod structure array
748 manage memory used by the array, by each struct, and values
750 ************************************************************************/
751 static void make_a_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
759 if (attribute == NULL || *attribute == '\0')
762 if (value == NULL || *value == '\0')
767 mods = (LDAPMod **) malloc(sizeof(LDAPMod *));
770 DEBUG(0, ("make_a_mod: out of memory!\n"));
776 for (i = 0; mods[i] != NULL; ++i) {
777 if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute))
783 mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *));
786 DEBUG(0, ("make_a_mod: out of memory!\n"));
789 mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
792 DEBUG(0, ("make_a_mod: out of memory!\n"));
795 mods[i]->mod_op = modop;
796 mods[i]->mod_values = NULL;
797 mods[i]->mod_type = strdup(attribute);
804 if (mods[i]->mod_values != NULL) {
805 for (; mods[i]->mod_values[j] != NULL; j++);
807 mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values,
808 (j + 2) * sizeof (char *));
810 if (mods[i]->mod_values == NULL) {
811 DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
814 mods[i]->mod_values[j] = strdup(value);
815 mods[i]->mod_values[j + 1] = NULL;
820 /* New Interface is being implemented here */
822 /**********************************************************************
823 Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
824 *********************************************************************/
825 static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
826 SAM_ACCOUNT * sampass,
836 if ((ldap_values = ldap_get_values (ldap_state->ldap_struct, entry, "objectClass")) == NULL) {
837 DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
841 for (values=ldap_values;*values;values++) {
842 if (strcasecmp(*values, "posixAccount") == 0) {
847 if (!*values) { /*end of array, no posixAccount */
848 DEBUG(10, ("user does not have posixAcccount attributes\n"));
849 ldap_value_free(ldap_values);
852 ldap_value_free(ldap_values);
854 if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDirectory", homedir))
857 if (!get_single_attribute(ldap_state->ldap_struct, entry, "uidNumber", temp))
860 uid = (uid_t)atol(temp);
862 if (!get_single_attribute(ldap_state->ldap_struct, entry, "gidNumber", temp))
865 gid = (gid_t)atol(temp);
867 pdb_set_unix_homedir(sampass, homedir, PDB_SET);
868 pdb_set_uid(sampass, uid, PDB_SET);
869 pdb_set_gid(sampass, gid, PDB_SET);
871 DEBUG(10, ("user has posixAcccount attributes\n"));
876 /**********************************************************************
877 Initialize SAM_ACCOUNT from an LDAP query
878 (Based on init_sam_from_buffer in pdb_tdb.c)
879 *********************************************************************/
880 static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
881 SAM_ACCOUNT * sampass,
888 pass_can_change_time,
889 pass_must_change_time;
904 uint8 smblmpwd[LM_HASH_LEN],
905 smbntpwd[NT_HASH_LEN];
909 uint8 hours[MAX_HOURS_LEN];
912 gid_t gid = getegid();
916 * do a little initialization
920 nt_username[0] = '\0';
924 logon_script[0] = '\0';
925 profile_path[0] = '\0';
927 munged_dial[0] = '\0';
928 workstations[0] = '\0';
931 if (sampass == NULL || ldap_state == NULL || entry == NULL) {
932 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
936 if (ldap_state->ldap_struct == NULL) {
937 DEBUG(0, ("init_sam_from_ldap: ldap_state->ldap_struct is NULL!\n"));
941 get_single_attribute(ldap_state->ldap_struct, entry, "uid", username);
942 DEBUG(2, ("Entry found for user: %s\n", username));
944 pstrcpy(nt_username, username);
946 pstrcpy(domain, lp_workgroup());
948 pdb_set_username(sampass, username, PDB_SET);
950 pdb_set_domain(sampass, domain, PDB_DEFAULT);
951 pdb_set_nt_username(sampass, nt_username, PDB_SET);
953 get_single_attribute(ldap_state->ldap_struct, entry, "rid", temp);
954 user_rid = (uint32)atol(temp);
956 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
958 if (!get_single_attribute(ldap_state->ldap_struct, entry, "primaryGroupID", temp)) {
961 group_rid = (uint32)atol(temp);
962 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
967 * If so configured, try and get the values from LDAP
970 if (!lp_ldap_trust_ids() || (!get_unix_attributes(ldap_state, sampass, entry))) {
973 * Otherwise just ask the system getpw() calls.
976 pw = getpwnam_alloc(username);
978 if (! ldap_state->permit_non_unix_accounts) {
979 DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\n", username));
984 pdb_set_uid(sampass, uid, PDB_SET);
986 pdb_set_gid(sampass, gid, PDB_SET);
988 pdb_set_unix_homedir(sampass, pw->pw_dir, PDB_SET);
994 if (group_rid == 0 && pdb_get_init_flags(sampass,PDB_GID) != PDB_DEFAULT) {
996 gid = pdb_get_gid(sampass);
997 /* call the mapping code here */
998 if(pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) {
999 pdb_set_group_sid(sampass, &map.sid, PDB_SET);
1002 pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid), PDB_SET);
1006 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdLastSet", temp)) {
1007 /* leave as default */
1009 pass_last_set_time = (time_t) atol(temp);
1010 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1013 if (!get_single_attribute(ldap_state->ldap_struct, entry, "logonTime", temp)) {
1014 /* leave as default */
1016 logon_time = (time_t) atol(temp);
1017 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1020 if (!get_single_attribute(ldap_state->ldap_struct, entry, "logoffTime", temp)) {
1021 /* leave as default */
1023 logoff_time = (time_t) atol(temp);
1024 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1027 if (!get_single_attribute(ldap_state->ldap_struct, entry, "kickoffTime", temp)) {
1028 /* leave as default */
1030 kickoff_time = (time_t) atol(temp);
1031 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1034 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdCanChange", temp)) {
1035 /* leave as default */
1037 pass_can_change_time = (time_t) atol(temp);
1038 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1041 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdMustChange", temp)) {
1042 /* leave as default */
1044 pass_must_change_time = (time_t) atol(temp);
1045 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1048 /* recommend that 'gecos' and 'displayName' should refer to the same
1049 * attribute OID. userFullName depreciated, only used by Samba
1050 * primary rules of LDAP: don't make a new attribute when one is already defined
1051 * that fits your needs; using cn then displayName rather than 'userFullName'
1054 if (!get_single_attribute(ldap_state->ldap_struct, entry, "cn", fullname)) {
1055 if (!get_single_attribute(ldap_state->ldap_struct, entry, "displayName", fullname)) {
1056 /* leave as default */
1058 pdb_set_fullname(sampass, fullname, PDB_SET);
1061 pdb_set_fullname(sampass, fullname, PDB_SET);
1064 if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDrive", dir_drive)) {
1065 pdb_set_dir_drive(sampass, talloc_sub_specified(sampass->mem_ctx,
1071 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1074 if (!get_single_attribute(ldap_state->ldap_struct, entry, "smbHome", homedir)) {
1075 pdb_set_homedir(sampass, talloc_sub_specified(sampass->mem_ctx,
1081 pdb_set_homedir(sampass, homedir, PDB_SET);
1084 if (!get_single_attribute(ldap_state->ldap_struct, entry, "scriptPath", logon_script)) {
1085 pdb_set_logon_script(sampass, talloc_sub_specified(sampass->mem_ctx,
1091 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1094 if (!get_single_attribute(ldap_state->ldap_struct, entry, "profilePath", profile_path)) {
1095 pdb_set_profile_path(sampass, talloc_sub_specified(sampass->mem_ctx,
1101 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1104 if (!get_single_attribute(ldap_state->ldap_struct, entry, "description", acct_desc)) {
1105 /* leave as default */
1107 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1110 if (!get_single_attribute(ldap_state->ldap_struct, entry, "userWorkstations", workstations)) {
1111 /* leave as default */;
1113 pdb_set_workstations(sampass, workstations, PDB_SET);
1116 /* FIXME: hours stuff should be cleaner */
1120 memset(hours, 0xff, hours_len);
1122 if (!get_single_attribute (ldap_state->ldap_struct, entry, "lmPassword", temp)) {
1123 /* leave as default */
1125 pdb_gethexpwd(temp, smblmpwd);
1126 memset((char *)temp, '\0', strlen(temp)+1);
1127 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
1129 ZERO_STRUCT(smblmpwd);
1132 if (!get_single_attribute (ldap_state->ldap_struct, entry, "ntPassword", temp)) {
1133 /* leave as default */
1135 pdb_gethexpwd(temp, smbntpwd);
1136 memset((char *)temp, '\0', strlen(temp)+1);
1137 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
1139 ZERO_STRUCT(smbntpwd);
1142 if (!get_single_attribute (ldap_state->ldap_struct, entry, "acctFlags", temp)) {
1143 acct_ctrl |= ACB_NORMAL;
1145 acct_ctrl = pdb_decode_acct_ctrl(temp);
1148 acct_ctrl |= ACB_NORMAL;
1150 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1153 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1154 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1156 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1158 /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
1159 /* pdb_set_unknown_5(sampass, unknown5, PDB_SET); */
1160 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
1162 pdb_set_hours(sampass, hours, PDB_SET);
1167 static BOOL need_ldap_mod(BOOL pdb_add, const SAM_ACCOUNT * sampass, enum pdb_elements element) {
1169 return (!IS_SAM_DEFAULT(sampass, element));
1171 return IS_SAM_CHANGED(sampass, element);
1175 /**********************************************************************
1176 Initialize SAM_ACCOUNT from an LDAP query
1177 (Based on init_buffer_from_sam in pdb_tdb.c)
1178 *********************************************************************/
1179 static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
1180 LDAPMod *** mods, int ldap_op,
1182 const SAM_ACCOUNT * sampass)
1187 if (mods == NULL || sampass == NULL) {
1188 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
1195 * took out adding "objectclass: sambaAccount"
1196 * do this on a per-mod basis
1198 if (need_ldap_mod(pdb_add, sampass, PDB_USERNAME)) {
1199 make_a_mod(mods, ldap_op, "uid", pdb_get_username(sampass));
1200 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
1203 if ((rid = pdb_get_user_rid(sampass))!=0 ) {
1204 if (need_ldap_mod(pdb_add, sampass, PDB_USERSID)) {
1205 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1206 make_a_mod(mods, ldap_op, "rid", temp);
1208 } else if (!IS_SAM_DEFAULT(sampass, PDB_UID)) {
1209 rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass));
1210 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1211 make_a_mod(mods, ldap_op, "rid", temp);
1212 } else if (ldap_state->permit_non_unix_accounts) {
1213 rid = ldapsam_get_next_available_nua_rid(ldap_state);
1215 DEBUG(0, ("NO user RID specified on account %s, and findining next available NUA RID failed, cannot store!\n", pdb_get_username(sampass)));
1218 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1219 make_a_mod(mods, ldap_op, "rid", temp);
1221 DEBUG(0, ("NO user RID specified on account %s, cannot store!\n", pdb_get_username(sampass)));
1227 if ((rid = pdb_get_group_rid(sampass))!=0 ) {
1228 if (need_ldap_mod(pdb_add, sampass, PDB_GROUPSID)) {
1229 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1230 make_a_mod(mods, ldap_op, "primaryGroupID", temp);
1232 } else if (!IS_SAM_DEFAULT(sampass, PDB_GID)) {
1233 rid = pdb_gid_to_group_rid(pdb_get_gid(sampass));
1234 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1235 make_a_mod(mods, ldap_op, "primaryGroupID", temp);
1236 } else if (ldap_state->permit_non_unix_accounts) {
1237 rid = DOMAIN_GROUP_RID_USERS;
1238 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1239 make_a_mod(mods, ldap_op, "primaryGroupID", temp);
1241 DEBUG(0, ("NO group RID specified on account %s, cannot store!\n", pdb_get_username(sampass)));
1246 /* displayName, cn, and gecos should all be the same
1247 * most easily accomplished by giving them the same OID
1248 * gecos isn't set here b/c it should be handled by the
1251 if (need_ldap_mod(pdb_add, sampass, PDB_FULLNAME)) {
1252 make_a_mod(mods, ldap_op, "displayName", pdb_get_fullname(sampass));
1253 make_a_mod(mods, ldap_op, "cn", pdb_get_fullname(sampass));
1255 if (need_ldap_mod(pdb_add, sampass, PDB_ACCTDESC)) {
1256 make_a_mod(mods, ldap_op, "description", pdb_get_acct_desc(sampass));
1258 if (need_ldap_mod(pdb_add, sampass, PDB_WORKSTATIONS)) {
1259 make_a_mod(mods, ldap_op, "userWorkstations", pdb_get_workstations(sampass));
1262 * Only updates fields which have been set (not defaults from smb.conf)
1265 if (need_ldap_mod(pdb_add, sampass, PDB_SMBHOME)) {
1266 make_a_mod(mods, ldap_op, "smbHome", pdb_get_homedir(sampass));
1269 if (need_ldap_mod(pdb_add, sampass, PDB_DRIVE)) {
1270 make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dir_drive(sampass));
1273 if (need_ldap_mod(pdb_add, sampass, PDB_LOGONSCRIPT)) {
1274 make_a_mod(mods, ldap_op, "scriptPath", pdb_get_logon_script(sampass));
1277 if (need_ldap_mod(pdb_add, sampass, PDB_PROFILE))
1278 make_a_mod(mods, ldap_op, "profilePath", pdb_get_profile_path(sampass));
1280 if (need_ldap_mod(pdb_add, sampass, PDB_LOGONTIME)) {
1281 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
1282 make_a_mod(mods, ldap_op, "logonTime", temp);
1285 if (need_ldap_mod(pdb_add, sampass, PDB_LOGOFFTIME)) {
1286 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
1287 make_a_mod(mods, ldap_op, "logoffTime", temp);
1290 if (need_ldap_mod(pdb_add, sampass, PDB_KICKOFFTIME)) {
1291 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
1292 make_a_mod(mods, ldap_op, "kickoffTime", temp);
1296 if (need_ldap_mod(pdb_add, sampass, PDB_CANCHANGETIME)) {
1297 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
1298 make_a_mod(mods, ldap_op, "pwdCanChange", temp);
1301 if (need_ldap_mod(pdb_add, sampass, PDB_MUSTCHANGETIME)) {
1302 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
1303 make_a_mod(mods, ldap_op, "pwdMustChange", temp);
1306 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))||
1307 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
1309 if (need_ldap_mod(pdb_add, sampass, PDB_LMPASSWD)) {
1310 pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass));
1311 make_a_mod (mods, ldap_op, "lmPassword", temp);
1314 if (need_ldap_mod(pdb_add, sampass, PDB_NTPASSWD)) {
1315 pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass));
1316 make_a_mod (mods, ldap_op, "ntPassword", temp);
1319 if (need_ldap_mod(pdb_add, sampass, PDB_PASSLASTSET)) {
1320 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
1321 make_a_mod(mods, ldap_op, "pwdLastSet", temp);
1325 /* FIXME: Hours stuff goes in LDAP */
1326 if (need_ldap_mod(pdb_add, sampass, PDB_ACCTCTRL)) {
1327 make_a_mod (mods, ldap_op, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
1328 NEW_PW_FORMAT_SPACE_PADDED_LEN));
1335 /**********************************************************************
1336 Connect to LDAP server and find the next available RID.
1337 *********************************************************************/
1338 static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 top_rid)
1340 LDAPMessage *result;
1341 uint32 final_rid = (top_rid & (~USER_RID_TYPE)) + RID_MULTIPLIER;
1346 if (final_rid < ldap_state->low_nua_rid || final_rid > ldap_state->high_nua_rid) {
1350 if (ldapsam_search_one_user_by_rid(ldap_state, final_rid, &result) != LDAP_SUCCESS) {
1351 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid));
1352 ldap_msgfree(result);
1356 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
1357 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid));
1358 ldap_msgfree(result);
1362 DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid, final_rid));
1363 ldap_msgfree(result);
1367 /**********************************************************************
1368 Extract the RID from an LDAP entry
1369 *********************************************************************/
1370 static uint32 entry_to_user_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry) {
1372 SAM_ACCOUNT *user = NULL;
1373 if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
1377 if (init_sam_from_ldap(ldap_state, user, entry)) {
1378 rid = pdb_get_user_rid(user);
1382 pdb_free_sam(&user);
1383 if (rid >= ldap_state->low_nua_rid && rid <= ldap_state->high_nua_rid) {
1390 /**********************************************************************
1391 Connect to LDAP server and find the next available RID.
1392 *********************************************************************/
1393 static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state)
1397 LDAPMessage *result;
1399 char *final_filter = NULL;
1404 pstrcpy(filter, lp_ldap_filter());
1405 all_string_sub(filter, "%u", "*", sizeof(pstring));
1408 asprintf(&final_filter, "(&(%s)(&(rid>=%d)(rid<=%d)))", filter, ldap_state->low_nua_rid, ldap_state->high_nua_rid);
1410 final_filter = strdup(filter);
1412 DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter));
1414 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1415 LDAP_SCOPE_SUBTREE, final_filter, (char **)attr, 0,
1418 if (rc != LDAP_SUCCESS) {
1419 DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc)));
1420 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1423 ldap_msgfree(result);
1428 count = ldap_count_entries(ldap_state->ldap_struct, result);
1429 DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count));
1432 DEBUG(3, ("LDAP search returned no records, assuming no non-unix-accounts present!: %s\n", ldap_err2string(rc)));
1433 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1435 ldap_msgfree(result);
1437 return ldap_state->low_nua_rid;
1441 entry = ldap_first_entry(ldap_state->ldap_struct,result);
1443 top_rid = entry_to_user_rid(ldap_state, entry);
1445 while ((entry = ldap_next_entry(ldap_state->ldap_struct, entry))) {
1447 rid = entry_to_user_rid(ldap_state, entry);
1448 if (rid > top_rid) {
1453 ldap_msgfree(result);
1455 if (top_rid < ldap_state->low_nua_rid)
1456 top_rid = ldap_state->low_nua_rid;
1461 /**********************************************************************
1462 Connect to LDAP server and find the next available RID.
1463 *********************************************************************/
1464 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state) {
1465 uint32 next_nua_rid;
1468 top_nua_rid = search_top_nua_rid(ldap_state);
1470 next_nua_rid = check_nua_rid_is_avail(ldap_state,
1473 return next_nua_rid;
1476 /**********************************************************************
1477 Connect to LDAP server for password enumeration
1478 *********************************************************************/
1479 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
1481 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1485 pstrcpy(filter, lp_ldap_filter());
1486 all_string_sub(filter, "%u", "*", sizeof(pstring));
1488 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1489 LDAP_SCOPE_SUBTREE, filter, (char **)attr, 0,
1490 &ldap_state->result);
1492 if (rc != LDAP_SUCCESS) {
1493 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
1494 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1495 ldap_msgfree(ldap_state->result);
1496 ldap_state->result = NULL;
1497 return NT_STATUS_UNSUCCESSFUL;
1500 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
1501 ldap_count_entries(ldap_state->ldap_struct,
1502 ldap_state->result)));
1504 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
1505 ldap_state->result);
1506 ldap_state->index = 0;
1508 return NT_STATUS_OK;
1511 /**********************************************************************
1512 End enumeration of the LDAP password list
1513 *********************************************************************/
1514 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1516 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1517 if (ldap_state->result) {
1518 ldap_msgfree(ldap_state->result);
1519 ldap_state->result = NULL;
1523 /**********************************************************************
1524 Get the next entry in the LDAP password database
1525 *********************************************************************/
1526 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
1528 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1529 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1532 /* The rebind proc needs this *HACK*. We are not multithreaded, so
1533 this will work, but it's not nice. */
1534 static_ldap_state = ldap_state;
1537 if (!ldap_state->entry)
1540 ldap_state->index++;
1541 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
1543 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
1547 return NT_STATUS_OK;
1550 /**********************************************************************
1551 Get SAM_ACCOUNT entry from LDAP by username
1552 *********************************************************************/
1553 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
1555 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1556 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1557 LDAPMessage *result;
1560 if (ldapsam_search_one_user_by_name(ldap_state, sname, &result) != LDAP_SUCCESS) {
1561 return NT_STATUS_UNSUCCESSFUL;
1563 if (ldap_count_entries(ldap_state->ldap_struct, result) < 1) {
1565 ("We don't find this user [%s] count=%d\n", sname,
1566 ldap_count_entries(ldap_state->ldap_struct, result)));
1567 return NT_STATUS_UNSUCCESSFUL;
1569 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1571 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1572 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1573 ldap_msgfree(result);
1574 return NT_STATUS_UNSUCCESSFUL;
1576 ldap_msgfree(result);
1579 ldap_msgfree(result);
1584 /**********************************************************************
1585 Get SAM_ACCOUNT entry from LDAP by rid
1586 *********************************************************************/
1587 static NTSTATUS ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
1589 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1590 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1591 LDAPMessage *result;
1594 if (ldapsam_search_one_user_by_rid(ldap_state, rid, &result) != LDAP_SUCCESS) {
1595 return NT_STATUS_UNSUCCESSFUL;
1598 if (ldap_count_entries(ldap_state->ldap_struct, result) < 1) {
1600 ("We don't find this rid [%i] count=%d\n", rid,
1601 ldap_count_entries(ldap_state->ldap_struct, result)));
1602 return NT_STATUS_UNSUCCESSFUL;
1605 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1607 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1608 DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
1609 ldap_msgfree(result);
1610 return NT_STATUS_UNSUCCESSFUL;
1612 ldap_msgfree(result);
1615 ldap_msgfree(result);
1620 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
1623 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
1624 return NT_STATUS_UNSUCCESSFUL;
1625 return ldapsam_getsampwrid(my_methods, user, rid);
1628 /********************************************************************
1629 Do the actual modification - also change a plaittext passord if
1631 **********************************************************************/
1633 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1634 SAM_ACCOUNT *newpwd, char *dn,
1635 LDAPMod **mods, int ldap_op, BOOL pdb_add)
1637 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1640 if (!my_methods || !newpwd || !dn) {
1641 return NT_STATUS_INVALID_PARAMETER;
1645 DEBUG(5,("mods is empty: nothing to modify\n"));
1646 /* may be password change below however */
1651 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account");
1652 rc = ldapsam_add(ldap_state, dn, mods);
1654 case LDAP_MOD_REPLACE:
1655 rc = ldapsam_modify(ldap_state, dn ,mods);
1658 DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
1659 return NT_STATUS_UNSUCCESSFUL;
1662 if (rc!=LDAP_SUCCESS) {
1664 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1667 ("failed to %s user dn= %s with: %s\n\t%s\n",
1668 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
1669 dn, ldap_err2string(rc),
1672 return NT_STATUS_UNSUCCESSFUL;
1676 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
1677 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))&&
1678 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_OFF)&&
1679 need_ldap_mod(pdb_add, newpwd, PDB_PLAINTEXT_PW)&&
1680 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1684 struct berval *retdata;
1686 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1687 DEBUG(0,("ber_alloc_t returns NULL\n"));
1688 return NT_STATUS_UNSUCCESSFUL;
1690 ber_printf (ber, "{");
1691 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID,dn);
1692 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, pdb_get_plaintext_passwd(newpwd));
1693 ber_printf (ber, "N}");
1695 if ((rc = ber_flatten (ber, &bv))<0) {
1696 DEBUG(0,("ber_flatten returns a value <0\n"));
1697 return NT_STATUS_UNSUCCESSFUL;
1702 if ((rc = ldapsam_extended_operation(ldap_state, LDAP_EXOP_X_MODIFY_PASSWD,
1703 bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) {
1704 DEBUG(0,("LDAP Password could not be changed for user %s: %s\n",
1705 pdb_get_username(newpwd),ldap_err2string(rc)));
1707 DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1709 ber_bvfree(retdata);
1710 ber_memfree(retoid);
1715 DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n"));
1716 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */
1717 return NT_STATUS_OK;
1720 /**********************************************************************
1721 Delete entry from LDAP for username
1722 *********************************************************************/
1723 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
1725 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1730 LDAPMessage *result;
1733 DEBUG(0, ("sam_acct was NULL!\n"));
1734 return NT_STATUS_UNSUCCESSFUL;
1737 sname = pdb_get_username(sam_acct);
1739 DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
1741 rc = ldapsam_search_one_user_by_name(ldap_state, sname, &result);
1742 if (ldap_count_entries (ldap_state->ldap_struct, result) == 0) {
1743 DEBUG (0, ("User doesn't exit!\n"));
1744 ldap_msgfree (result);
1745 return NT_STATUS_UNSUCCESSFUL;
1748 entry = ldap_first_entry (ldap_state->ldap_struct, result);
1749 dn = ldap_get_dn (ldap_state->ldap_struct, entry);
1750 ldap_msgfree(result);
1752 rc = ldapsam_delete(ldap_state, dn);
1755 if (rc != LDAP_SUCCESS) {
1757 ldap_get_option (ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
1758 DEBUG (0,("failed to delete user with uid = %s with: %s\n\t%s\n",
1759 sname, ldap_err2string (rc), ld_error));
1761 return NT_STATUS_UNSUCCESSFUL;
1764 DEBUG (2,("successfully deleted uid = %s from the LDAP database\n", sname));
1765 return NT_STATUS_OK;
1768 /**********************************************************************
1770 *********************************************************************/
1771 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1773 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1774 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1777 LDAPMessage *result;
1781 if (!init_ldap_from_sam(ldap_state, &mods, LDAP_MOD_REPLACE, False, newpwd)) {
1782 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1783 ldap_msgfree(result);
1784 return NT_STATUS_UNSUCCESSFUL;
1788 DEBUG(4,("mods is empty: nothing to update for user: %s\n",pdb_get_username(newpwd)));
1789 return NT_STATUS_OK;
1792 rc = ldapsam_search_one_user_by_name(ldap_state, pdb_get_username(newpwd), &result);
1794 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
1795 DEBUG(0, ("No user to modify!\n"));
1796 ldap_msgfree(result);
1797 return NT_STATUS_UNSUCCESSFUL;
1800 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1801 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
1802 ldap_msgfree(result);
1804 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, False);
1805 if (NT_STATUS_IS_ERR(ret)) {
1806 DEBUG(0,("failed to modify user with uid = %s\n",
1807 pdb_get_username(newpwd)));
1808 ldap_mods_free(mods,1);
1814 ("successfully modified uid = %s in the LDAP database\n",
1815 pdb_get_username(newpwd)));
1816 ldap_mods_free(mods, 1);
1817 return NT_STATUS_OK;
1820 /**********************************************************************
1821 Add SAM_ACCOUNT to LDAP
1822 *********************************************************************/
1823 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1825 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1826 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1829 LDAPMessage *result = NULL;
1831 LDAPMod **mods = NULL;
1835 const char *username = pdb_get_username(newpwd);
1836 if (!username || !*username) {
1837 DEBUG(0, ("Cannot add user without a username!\n"));
1838 return NT_STATUS_UNSUCCESSFUL;
1841 rc = ldapsam_search_one_user_by_name (ldap_state, username, &result);
1843 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
1844 DEBUG(0,("User already in the base, with samba properties\n"));
1845 ldap_msgfree(result);
1846 return NT_STATUS_UNSUCCESSFUL;
1848 ldap_msgfree(result);
1850 slprintf (filter, sizeof (filter) - 1, "uid=%s", username);
1851 rc = ldapsam_search_one_user(ldap_state, filter, &result);
1852 num_result = ldap_count_entries(ldap_state->ldap_struct, result);
1854 if (num_result > 1) {
1855 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
1856 ldap_msgfree(result);
1857 return NT_STATUS_UNSUCCESSFUL;
1860 /* Check if we need to update an existing entry */
1861 if (num_result == 1) {
1865 DEBUG(3,("User exists without samba properties: adding them\n"));
1866 ldap_op = LDAP_MOD_REPLACE;
1867 entry = ldap_first_entry (ldap_state->ldap_struct, result);
1868 tmp = ldap_get_dn (ldap_state->ldap_struct, entry);
1869 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
1872 /* Check if we need to add an entry */
1873 DEBUG(3,("Adding new user\n"));
1874 ldap_op = LDAP_MOD_ADD;
1875 if (username[strlen(username)-1] == '$') {
1876 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
1878 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
1882 ldap_msgfree(result);
1884 if (!init_ldap_from_sam(ldap_state, &mods, ldap_op, True, newpwd)) {
1885 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
1886 ldap_mods_free(mods, 1);
1887 return NT_STATUS_UNSUCCESSFUL;
1891 DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
1892 return NT_STATUS_UNSUCCESSFUL;
1895 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
1897 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, True);
1898 if (NT_STATUS_IS_ERR(ret)) {
1899 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
1900 pdb_get_username(newpwd),dn));
1901 ldap_mods_free(mods,1);
1905 DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd)));
1906 ldap_mods_free(mods, 1);
1907 return NT_STATUS_OK;
1910 static NTSTATUS lsapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
1911 DOM_SID sid, BOOL with_priv)
1913 return get_group_map_from_sid(sid, map, with_priv) ?
1914 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1917 static NTSTATUS lsapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
1918 gid_t gid, BOOL with_priv)
1920 return get_group_map_from_gid(gid, map, with_priv) ?
1921 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1924 static NTSTATUS lsapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
1925 char *name, BOOL with_priv)
1927 return get_group_map_from_ntname(name, map, with_priv) ?
1928 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1931 static NTSTATUS lsapsam_add_group_mapping_entry(struct pdb_methods *methods,
1934 return add_mapping_entry(map, TDB_INSERT) ?
1935 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1938 static NTSTATUS lsapsam_update_group_mapping_entry(struct pdb_methods *methods,
1941 return add_mapping_entry(map, TDB_REPLACE) ?
1942 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1945 static NTSTATUS lsapsam_delete_group_mapping_entry(struct pdb_methods *methods,
1948 return group_map_remove(sid) ?
1949 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1952 static NTSTATUS lsapsam_enum_group_mapping(struct pdb_methods *methods,
1953 enum SID_NAME_USE sid_name_use,
1954 GROUP_MAP **rmap, int *num_entries,
1955 BOOL unix_only, BOOL with_priv)
1957 return enum_group_mapping(sid_name_use, rmap, num_entries, unix_only,
1959 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1962 static void free_private_data(void **vp)
1964 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
1966 ldapsam_close(*ldap_state);
1968 if ((*ldap_state)->bind_secret) {
1969 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
1972 ldapsam_close(*ldap_state);
1974 SAFE_FREE((*ldap_state)->bind_dn);
1975 SAFE_FREE((*ldap_state)->bind_secret);
1979 /* No need to free any further, as it is talloc()ed */
1982 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
1985 struct ldapsam_privates *ldap_state;
1987 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
1991 (*pdb_method)->name = "ldapsam";
1993 (*pdb_method)->setsampwent = ldapsam_setsampwent;
1994 (*pdb_method)->endsampwent = ldapsam_endsampwent;
1995 (*pdb_method)->getsampwent = ldapsam_getsampwent;
1996 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
1997 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
1998 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
1999 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
2000 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
2001 (*pdb_method)->getgrsid = lsapsam_getgrsid;
2002 (*pdb_method)->getgrgid = lsapsam_getgrgid;
2003 (*pdb_method)->getgrnam = lsapsam_getgrnam;
2004 (*pdb_method)->add_group_mapping_entry = lsapsam_add_group_mapping_entry;
2005 (*pdb_method)->update_group_mapping_entry = lsapsam_update_group_mapping_entry;
2006 (*pdb_method)->delete_group_mapping_entry = lsapsam_delete_group_mapping_entry;
2007 (*pdb_method)->enum_group_mapping = lsapsam_enum_group_mapping;
2009 /* TODO: Setup private data and free */
2011 ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct ldapsam_privates));
2014 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
2015 return NT_STATUS_NO_MEMORY;
2019 ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
2020 #ifdef WITH_LDAP_SAMCONFIG
2022 int ldap_port = lp_ldap_port();
2024 /* remap default port if not using SSL (ie clear or TLS) */
2025 if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
2029 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);
2030 if (!ldap_state->uri) {
2031 return NT_STATUS_NO_MEMORY;
2035 ldap_state->uri = "ldap://localhost";
2039 (*pdb_method)->private_data = ldap_state;
2041 (*pdb_method)->free_private_data = free_private_data;
2043 return NT_STATUS_OK;
2046 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2049 struct ldapsam_privates *ldap_state;
2050 uint32 low_nua_uid, high_nua_uid;
2052 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) {
2056 (*pdb_method)->name = "ldapsam_nua";
2058 ldap_state = (*pdb_method)->private_data;
2060 ldap_state->permit_non_unix_accounts = True;
2062 if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) {
2063 DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n"));
2064 return NT_STATUS_UNSUCCESSFUL;
2067 ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid);
2069 ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid);
2071 return NT_STATUS_OK;
2077 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2079 DEBUG(0, ("ldap not detected at configure time, ldapsam not availalble!\n"));
2080 return NT_STATUS_UNSUCCESSFUL;
2083 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2085 DEBUG(0, ("ldap not dectected at configure time, ldapsam_nua not available!\n"));
2086 return NT_STATUS_UNSUCCESSFUL;