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,("ldapsam_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,("ldapsam_open_connection: StartTLS not supported by LDAP client libraries!\n"));
258 return LDAP_OPERATIONS_ERROR;
262 DEBUG(2, ("ldapsam_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,("rebind_proc_with_state: 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,("rebindproc_connect_with_state: 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 %s as \"%s\"\n",
389 ldap_state->uri, ldap_dn));
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) {
411 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
414 ("failed to bind to server with dn= %s Error: %s\n\t%s\n",
415 ldap_dn, ldap_err2string(rc),
421 DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n"));
425 /**********************************************************************
426 Connect to LDAP server
427 *********************************************************************/
428 static int ldapsam_open(struct ldapsam_privates *ldap_state)
431 SMB_ASSERT(ldap_state);
433 #ifndef NO_LDAP_SECURITY
434 if (geteuid() != 0) {
435 DEBUG(0, ("ldapsam_open: cannot access LDAP when not root..\n"));
436 return LDAP_INSUFFICIENT_ACCESS;
440 if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + LDAPSAM_DONT_PING_TIME) < time(NULL))) {
441 struct sockaddr_un addr;
444 if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
445 getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
446 /* the other end has died. reopen. */
447 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
448 ldap_state->ldap_struct = NULL;
449 ldap_state->last_ping = (time_t)0;
451 ldap_state->last_ping = time(NULL);
455 if (ldap_state->ldap_struct != NULL) {
456 DEBUG(5,("ldapsam_open: allready connected to the LDAP server\n"));
460 if ((rc = ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct))) {
464 if ((rc = ldapsam_connect_system(ldap_state, ldap_state->ldap_struct))) {
465 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
466 ldap_state->ldap_struct = NULL;
471 ldap_state->last_ping = time(NULL);
472 DEBUG(4,("The LDAP server is succesful connected\n"));
477 /**********************************************************************
478 Disconnect from LDAP server
479 *********************************************************************/
480 static NTSTATUS ldapsam_close(struct ldapsam_privates *ldap_state)
483 return NT_STATUS_INVALID_PARAMETER;
485 if (ldap_state->ldap_struct != NULL) {
486 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
487 ldap_state->ldap_struct = NULL;
490 DEBUG(5,("The connection to the LDAP server was closed\n"));
491 /* maybe free the results here --metze */
496 static int ldapsam_retry_open(struct ldapsam_privates *ldap_state, int *attempts)
500 SMB_ASSERT(ldap_state && attempts);
502 if (*attempts != 0) {
503 /* we retry after 0.5, 2, 4.5, 8, 12.5, 18, 24.5 seconds */
504 msleep((((*attempts)*(*attempts))/2)*1000);
508 if ((rc = ldapsam_open(ldap_state))) {
509 DEBUG(0,("Connection to LDAP Server failed for the %d try!\n",*attempts));
517 static int ldapsam_search(struct ldapsam_privates *ldap_state,
518 const char *base, int scope, const char *filter,
519 const char *attrs[], int attrsonly,
522 int rc = LDAP_SERVER_DOWN;
525 SMB_ASSERT(ldap_state);
527 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
529 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
532 rc = ldap_search_s(ldap_state->ldap_struct, base, scope,
533 filter, attrs, attrsonly, res);
536 if (rc == LDAP_SERVER_DOWN) {
537 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
538 ldapsam_close(ldap_state);
544 static int ldapsam_modify(struct ldapsam_privates *ldap_state, char *dn, LDAPMod *attrs[])
546 int rc = LDAP_SERVER_DOWN;
552 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
554 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
557 rc = ldap_modify_s(ldap_state->ldap_struct, dn, attrs);
560 if (rc == LDAP_SERVER_DOWN) {
561 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
562 ldapsam_close(ldap_state);
568 static int ldapsam_add(struct ldapsam_privates *ldap_state, const char *dn, LDAPMod *attrs[])
570 int rc = LDAP_SERVER_DOWN;
576 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
578 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
581 rc = ldap_add_s(ldap_state->ldap_struct, dn, attrs);
584 if (rc == LDAP_SERVER_DOWN) {
585 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
586 ldapsam_close(ldap_state);
592 static int ldapsam_delete(struct ldapsam_privates *ldap_state, char *dn)
594 int rc = LDAP_SERVER_DOWN;
600 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
602 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
605 rc = ldap_delete_s(ldap_state->ldap_struct, dn);
608 if (rc == LDAP_SERVER_DOWN) {
609 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
610 ldapsam_close(ldap_state);
616 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)
618 int rc = LDAP_SERVER_DOWN;
624 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
626 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
629 rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata, serverctrls, clientctrls, retoidp, retdatap);
632 if (rc == LDAP_SERVER_DOWN) {
633 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
634 ldapsam_close(ldap_state);
640 /*******************************************************************
641 run the search by name.
642 ******************************************************************/
643 static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, const char *filter, LDAPMessage ** result)
645 int scope = LDAP_SCOPE_SUBTREE;
648 DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter));
650 rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope, filter, attr, 0, result);
652 if (rc != LDAP_SUCCESS) {
653 DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n",
654 ldap_err2string (rc)));
655 DEBUG(3,("ldapsam_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(),
662 /*******************************************************************
663 run the search by name.
664 ******************************************************************/
665 static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, const char *user,
666 LDAPMessage ** result)
669 char *escape_user = escape_ldap_string_alloc(user);
672 return LDAP_NO_MEMORY;
676 * in the filter expression, replace %u with the real name
677 * so in ldap filter, %u MUST exist :-)
679 pstrcpy(filter, lp_ldap_filter());
682 * have to use this here because $ is filtered out
687 all_string_sub(filter, "%u", escape_user, sizeof(pstring));
688 SAFE_FREE(escape_user);
690 return ldapsam_search_one_user(ldap_state, filter, result);
693 /*******************************************************************
694 run the search by uid.
695 ******************************************************************/
696 static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state,
698 LDAPMessage ** result)
704 /* Get the username from the system and look that up in the LDAP */
706 if ((user = getpwuid_alloc(uid)) == NULL) {
707 DEBUG(3,("ldapsam_search_one_user_by_uid: Failed to locate uid [%d]\n", uid));
708 return LDAP_NO_SUCH_OBJECT;
711 pstrcpy(filter, lp_ldap_filter());
713 escape_user = escape_ldap_string_alloc(user->pw_name);
716 return LDAP_NO_MEMORY;
719 all_string_sub(filter, "%u", escape_user, sizeof(pstring));
722 SAFE_FREE(escape_user);
724 return ldapsam_search_one_user(ldap_state, filter, result);
727 /*******************************************************************
728 run the search by rid.
729 ******************************************************************/
730 static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state,
732 LDAPMessage ** result)
737 /* check if the user rid exsists, if not, try searching on the uid */
739 snprintf(filter, sizeof(filter) - 1, "rid=%i", rid);
740 rc = ldapsam_search_one_user(ldap_state, filter, result);
742 if (rc != LDAP_SUCCESS)
743 rc = ldapsam_search_one_user_by_uid(ldap_state,
744 fallback_pdb_user_rid_to_uid(rid),
750 /*******************************************************************
751 search an attribute and return the first value found.
752 ******************************************************************/
753 static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
754 const char *attribute, pstring value)
758 if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
760 DEBUG (10, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute));
765 pstrcpy(value, values[0]);
766 ldap_value_free(values);
767 #ifdef DEBUG_PASSWORDS
768 DEBUG (100, ("get_single_attribute: [%s] = [%s]\n", attribute, value));
773 /************************************************************************
774 Routine to manage the LDAPMod structure array
775 manage memory used by the array, by each struct, and values
777 ************************************************************************/
778 static void make_a_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
786 if (attribute == NULL || *attribute == '\0')
790 /* Why do we need this??? -- vl */
791 if (value == NULL || *value == '\0')
797 mods = (LDAPMod **) malloc(sizeof(LDAPMod *));
800 DEBUG(0, ("make_a_mod: out of memory!\n"));
806 for (i = 0; mods[i] != NULL; ++i) {
807 if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute))
813 mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *));
816 DEBUG(0, ("make_a_mod: out of memory!\n"));
819 mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
822 DEBUG(0, ("make_a_mod: out of memory!\n"));
825 mods[i]->mod_op = modop;
826 mods[i]->mod_values = NULL;
827 mods[i]->mod_type = strdup(attribute);
834 if (mods[i]->mod_values != NULL) {
835 for (; mods[i]->mod_values[j] != NULL; j++);
837 mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values,
838 (j + 2) * sizeof (char *));
840 if (mods[i]->mod_values == NULL) {
841 DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
844 mods[i]->mod_values[j] = strdup(value);
845 mods[i]->mod_values[j + 1] = NULL;
850 /*******************************************************************
851 Delete complete object or objectclass and attrs from
852 object found in search_result depending on lp_ldap_del_only_sam
853 ******************************************************************/
854 static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
856 const char *objectclass,
861 LDAPMod **mods = NULL;
863 BerElement *ptr = NULL;
865 rc = ldap_count_entries(ldap_state->ldap_struct, result);
868 DEBUG(0, ("Entry must exist exactly once!\n"));
869 return NT_STATUS_UNSUCCESSFUL;
872 entry = ldap_first_entry(ldap_state->ldap_struct, result);
873 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
875 if (!lp_ldap_del_only_sam()) {
876 NTSTATUS ret = NT_STATUS_OK;
877 rc = ldapsam_delete(ldap_state, dn);
879 if (rc != LDAP_SUCCESS) {
880 DEBUG(0, ("Could not delete object %s\n", dn));
881 ret = NT_STATUS_UNSUCCESSFUL;
887 /* Ok, delete only the SAM attributes */
889 for (name = ldap_first_attribute(ldap_state->ldap_struct, entry, &ptr);
891 name = ldap_next_attribute(ldap_state->ldap_struct, entry, ptr)) {
895 /* We are only allowed to delete the attributes that
898 for (attrib = attrs; *attrib != NULL; attrib++) {
899 if (StrCaseCmp(*attrib, name) == 0) {
900 DEBUG(10, ("deleting attribute %s\n", name));
901 make_a_mod(&mods, LDAP_MOD_DELETE, name, NULL);
912 make_a_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
914 rc = ldapsam_modify(ldap_state, dn, mods);
915 ldap_mods_free(mods, 1);
917 if (rc != LDAP_SUCCESS) {
918 DEBUG(0, ("could not delete attributes for %s, error: %s\n",
919 dn, ldap_err2string(rc)));
921 return NT_STATUS_UNSUCCESSFUL;
928 /* New Interface is being implemented here */
930 /**********************************************************************
931 Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
932 *********************************************************************/
933 static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
934 SAM_ACCOUNT * sampass,
944 if ((ldap_values = ldap_get_values (ldap_state->ldap_struct, entry, "objectClass")) == NULL) {
945 DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
949 for (values=ldap_values;*values;values++) {
950 if (strcasecmp(*values, "posixAccount") == 0) {
955 if (!*values) { /*end of array, no posixAccount */
956 DEBUG(10, ("user does not have posixAcccount attributes\n"));
957 ldap_value_free(ldap_values);
960 ldap_value_free(ldap_values);
962 if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDirectory", homedir))
965 if (!get_single_attribute(ldap_state->ldap_struct, entry, "uidNumber", temp))
968 uid = (uid_t)atol(temp);
970 if (!get_single_attribute(ldap_state->ldap_struct, entry, "gidNumber", temp))
973 gid = (gid_t)atol(temp);
975 pdb_set_unix_homedir(sampass, homedir, PDB_SET);
976 pdb_set_uid(sampass, uid, PDB_SET);
977 pdb_set_gid(sampass, gid, PDB_SET);
979 DEBUG(10, ("user has posixAcccount attributes\n"));
984 /**********************************************************************
985 Initialize SAM_ACCOUNT from an LDAP query
986 (Based on init_sam_from_buffer in pdb_tdb.c)
987 *********************************************************************/
988 static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
989 SAM_ACCOUNT * sampass,
996 pass_can_change_time,
997 pass_must_change_time;
1012 uint8 smblmpwd[LM_HASH_LEN],
1013 smbntpwd[NT_HASH_LEN];
1014 uint16 acct_ctrl = 0,
1017 uint8 hours[MAX_HOURS_LEN];
1020 gid_t gid = getegid();
1024 * do a little initialization
1028 nt_username[0] = '\0';
1031 dir_drive[0] = '\0';
1032 logon_script[0] = '\0';
1033 profile_path[0] = '\0';
1034 acct_desc[0] = '\0';
1035 munged_dial[0] = '\0';
1036 workstations[0] = '\0';
1039 if (sampass == NULL || ldap_state == NULL || entry == NULL) {
1040 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
1044 if (ldap_state->ldap_struct == NULL) {
1045 DEBUG(0, ("init_sam_from_ldap: ldap_state->ldap_struct is NULL!\n"));
1049 get_single_attribute(ldap_state->ldap_struct, entry, "uid", username);
1050 DEBUG(2, ("Entry found for user: %s\n", username));
1052 pstrcpy(nt_username, username);
1054 pstrcpy(domain, lp_workgroup());
1056 pdb_set_username(sampass, username, PDB_SET);
1058 pdb_set_domain(sampass, domain, PDB_DEFAULT);
1059 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1061 get_single_attribute(ldap_state->ldap_struct, entry, "rid", temp);
1062 user_rid = (uint32)atol(temp);
1064 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1066 if (!get_single_attribute(ldap_state->ldap_struct, entry, "primaryGroupID", temp)) {
1069 group_rid = (uint32)atol(temp);
1070 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1075 * If so configured, try and get the values from LDAP
1078 if (!lp_ldap_trust_ids() || (!get_unix_attributes(ldap_state, sampass, entry))) {
1081 * Otherwise just ask the system getpw() calls.
1084 pw = getpwnam_alloc(username);
1086 if (! ldap_state->permit_non_unix_accounts) {
1087 DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\n", username));
1092 pdb_set_uid(sampass, uid, PDB_SET);
1094 pdb_set_gid(sampass, gid, PDB_SET);
1096 pdb_set_unix_homedir(sampass, pw->pw_dir, PDB_SET);
1102 if (group_rid == 0 && pdb_get_init_flags(sampass,PDB_GID) != PDB_DEFAULT) {
1104 gid = pdb_get_gid(sampass);
1105 /* call the mapping code here */
1106 if(pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) {
1107 pdb_set_group_sid(sampass, &map.sid, PDB_SET);
1110 pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid), PDB_SET);
1114 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdLastSet", temp)) {
1115 /* leave as default */
1117 pass_last_set_time = (time_t) atol(temp);
1118 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1121 if (!get_single_attribute(ldap_state->ldap_struct, entry, "logonTime", temp)) {
1122 /* leave as default */
1124 logon_time = (time_t) atol(temp);
1125 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1128 if (!get_single_attribute(ldap_state->ldap_struct, entry, "logoffTime", temp)) {
1129 /* leave as default */
1131 logoff_time = (time_t) atol(temp);
1132 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1135 if (!get_single_attribute(ldap_state->ldap_struct, entry, "kickoffTime", temp)) {
1136 /* leave as default */
1138 kickoff_time = (time_t) atol(temp);
1139 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1142 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdCanChange", temp)) {
1143 /* leave as default */
1145 pass_can_change_time = (time_t) atol(temp);
1146 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1149 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdMustChange", temp)) {
1150 /* leave as default */
1152 pass_must_change_time = (time_t) atol(temp);
1153 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1156 /* recommend that 'gecos' and 'displayName' should refer to the same
1157 * attribute OID. userFullName depreciated, only used by Samba
1158 * primary rules of LDAP: don't make a new attribute when one is already defined
1159 * that fits your needs; using cn then displayName rather than 'userFullName'
1162 if (!get_single_attribute(ldap_state->ldap_struct, entry,
1163 "displayName", fullname)) {
1164 if (!get_single_attribute(ldap_state->ldap_struct, entry,
1166 /* leave as default */
1168 pdb_set_fullname(sampass, fullname, PDB_SET);
1171 pdb_set_fullname(sampass, fullname, PDB_SET);
1174 if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDrive", dir_drive)) {
1175 pdb_set_dir_drive(sampass, talloc_sub_specified(sampass->mem_ctx,
1181 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1184 if (!get_single_attribute(ldap_state->ldap_struct, entry, "smbHome", homedir)) {
1185 pdb_set_homedir(sampass, talloc_sub_specified(sampass->mem_ctx,
1191 pdb_set_homedir(sampass, homedir, PDB_SET);
1194 if (!get_single_attribute(ldap_state->ldap_struct, entry, "scriptPath", logon_script)) {
1195 pdb_set_logon_script(sampass, talloc_sub_specified(sampass->mem_ctx,
1201 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1204 if (!get_single_attribute(ldap_state->ldap_struct, entry, "profilePath", profile_path)) {
1205 pdb_set_profile_path(sampass, talloc_sub_specified(sampass->mem_ctx,
1211 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1214 if (!get_single_attribute(ldap_state->ldap_struct, entry, "description", acct_desc)) {
1215 /* leave as default */
1217 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1220 if (!get_single_attribute(ldap_state->ldap_struct, entry, "userWorkstations", workstations)) {
1221 /* leave as default */;
1223 pdb_set_workstations(sampass, workstations, PDB_SET);
1226 /* FIXME: hours stuff should be cleaner */
1230 memset(hours, 0xff, hours_len);
1232 if (!get_single_attribute (ldap_state->ldap_struct, entry, "lmPassword", temp)) {
1233 /* leave as default */
1235 pdb_gethexpwd(temp, smblmpwd);
1236 memset((char *)temp, '\0', strlen(temp)+1);
1237 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
1239 ZERO_STRUCT(smblmpwd);
1242 if (!get_single_attribute (ldap_state->ldap_struct, entry, "ntPassword", temp)) {
1243 /* leave as default */
1245 pdb_gethexpwd(temp, smbntpwd);
1246 memset((char *)temp, '\0', strlen(temp)+1);
1247 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
1249 ZERO_STRUCT(smbntpwd);
1252 if (!get_single_attribute (ldap_state->ldap_struct, entry, "acctFlags", temp)) {
1253 acct_ctrl |= ACB_NORMAL;
1255 acct_ctrl = pdb_decode_acct_ctrl(temp);
1258 acct_ctrl |= ACB_NORMAL;
1260 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1263 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1264 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1266 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1268 /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
1269 /* pdb_set_unknown_5(sampass, unknown5, PDB_SET); */
1270 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
1272 pdb_set_hours(sampass, hours, PDB_SET);
1277 static BOOL need_ldap_mod(BOOL pdb_add, const SAM_ACCOUNT * sampass, enum pdb_elements element) {
1279 return (!IS_SAM_DEFAULT(sampass, element));
1281 return IS_SAM_CHANGED(sampass, element);
1285 /**********************************************************************
1286 Set attribute to newval in LDAP, regardless of what value the
1287 attribute had in LDAP before.
1288 *********************************************************************/
1289 static void make_ldap_mod(LDAP *ldap_struct, LDAPMessage *existing,
1291 const SAM_ACCOUNT *sampass,
1292 enum pdb_elements element,
1293 const char *attribute, const char *newval)
1295 char **values = NULL;
1297 if (!IS_SAM_CHANGED(sampass, element)) {
1301 if (existing != NULL) {
1302 values = ldap_get_values(ldap_struct, existing, attribute);
1305 if ((values != NULL) && (values[0] != NULL) &&
1306 strcmp(values[0], newval) == 0) {
1308 /* Believe it or not, but LDAP will deny a delete and
1309 an add at the same time if the values are the
1312 ldap_value_free(values);
1316 /* Regardless of the real operation (add or modify)
1317 we add the new value here. We rely on deleting
1318 the old value, should it exist. */
1320 if ((newval != NULL) && (strlen(newval) > 0)) {
1321 make_a_mod(mods, LDAP_MOD_ADD, attribute, newval);
1324 if (values == NULL) {
1325 /* There has been no value before, so don't delete it.
1326 Here's a possible race: We might end up with
1327 duplicate attributes */
1331 /* By deleting exactly the value we found in the entry this
1332 should be race-free in the sense that the LDAP-Server will
1333 deny the complete operation if somebody changed the
1334 attribute behind our back. */
1336 make_a_mod(mods, LDAP_MOD_DELETE, attribute, values[0]);
1337 ldap_value_free(values);
1340 /**********************************************************************
1341 Initialize SAM_ACCOUNT from an LDAP query
1342 (Based on init_buffer_from_sam in pdb_tdb.c)
1343 *********************************************************************/
1344 static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
1345 LDAPMessage *existing,
1346 LDAPMod *** mods, const SAM_ACCOUNT * sampass)
1351 if (mods == NULL || sampass == NULL) {
1352 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
1359 * took out adding "objectclass: sambaAccount"
1360 * do this on a per-mod basis
1362 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1363 PDB_USERNAME, "uid", pdb_get_username(sampass));
1364 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
1366 rid = pdb_get_user_rid(sampass);
1369 if (!IS_SAM_DEFAULT(sampass, PDB_UID)) {
1370 rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass));
1371 } else if (ldap_state->permit_non_unix_accounts) {
1372 rid = ldapsam_get_next_available_nua_rid(ldap_state);
1374 DEBUG(0, ("NO user RID specified on account %s, and "
1375 "findining next available NUA RID failed, "
1377 pdb_get_username(sampass)));
1378 ldap_mods_free(*mods, 1);
1382 DEBUG(0, ("NO user RID specified on account %s, "
1383 "cannot store!\n", pdb_get_username(sampass)));
1384 ldap_mods_free(*mods, 1);
1389 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1390 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1391 PDB_USERSID, "rid", temp);
1394 rid = pdb_get_group_rid(sampass);
1397 if (!IS_SAM_DEFAULT(sampass, PDB_GID)) {
1398 rid = pdb_gid_to_group_rid(pdb_get_gid(sampass));
1399 } else if (ldap_state->permit_non_unix_accounts) {
1400 rid = DOMAIN_GROUP_RID_USERS;
1402 DEBUG(0, ("NO group RID specified on account %s, "
1403 "cannot store!\n", pdb_get_username(sampass)));
1404 ldap_mods_free(*mods, 1);
1409 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1410 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1411 PDB_GROUPSID, "primaryGroupID", temp);
1413 /* displayName, cn, and gecos should all be the same
1414 * most easily accomplished by giving them the same OID
1415 * gecos isn't set here b/c it should be handled by the
1417 * We change displayName only and fall back to cn if
1418 * it does not exist.
1421 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1422 PDB_FULLNAME, "displayName",
1423 pdb_get_fullname(sampass));
1425 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1426 PDB_ACCTDESC, "description",
1427 pdb_get_acct_desc(sampass));
1429 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1430 PDB_WORKSTATIONS, "userWorkstations",
1431 pdb_get_workstations(sampass));
1433 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1434 PDB_SMBHOME, "smbHome",
1435 pdb_get_homedir(sampass));
1437 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1438 PDB_DRIVE, "homeDrive",
1439 pdb_get_dir_drive(sampass));
1441 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1442 PDB_LOGONSCRIPT, "scriptPath",
1443 pdb_get_logon_script(sampass));
1445 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1446 PDB_PROFILE, "profilePath",
1447 pdb_get_profile_path(sampass));
1449 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
1450 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1451 PDB_LOGONTIME, "logonTime", temp);
1453 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
1454 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1455 PDB_LOGOFFTIME, "logoffTime", temp);
1457 slprintf (temp, sizeof (temp) - 1, "%li",
1458 pdb_get_kickoff_time(sampass));
1459 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1460 PDB_KICKOFFTIME, "kickoffTime", temp);
1462 slprintf (temp, sizeof (temp) - 1, "%li",
1463 pdb_get_pass_can_change_time(sampass));
1464 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1465 PDB_CANCHANGETIME, "pwdCanChange", temp);
1467 slprintf (temp, sizeof (temp) - 1, "%li",
1468 pdb_get_pass_must_change_time(sampass));
1469 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1470 PDB_MUSTCHANGETIME, "pwdMustChange", temp);
1472 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))||
1473 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
1475 pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass),
1476 pdb_get_acct_ctrl(sampass));
1477 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1478 PDB_LMPASSWD, "lmPassword", temp);
1480 pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass),
1481 pdb_get_acct_ctrl(sampass));
1482 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1483 PDB_NTPASSWD, "ntPassword", temp);
1485 slprintf (temp, sizeof (temp) - 1, "%li",
1486 pdb_get_pass_last_set_time(sampass));
1487 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1488 PDB_PASSLASTSET, "pwdLastSet", temp);
1491 /* FIXME: Hours stuff goes in LDAP */
1492 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1493 PDB_ACCTCTRL, "acctFlags",
1494 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
1495 NEW_PW_FORMAT_SPACE_PADDED_LEN));
1500 /**********************************************************************
1501 Connect to LDAP server and find the next available RID.
1502 *********************************************************************/
1503 static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 top_rid)
1505 LDAPMessage *result;
1506 uint32 final_rid = (top_rid & (~USER_RID_TYPE)) + RID_MULTIPLIER;
1511 if (final_rid < ldap_state->low_nua_rid || final_rid > ldap_state->high_nua_rid) {
1515 if (ldapsam_search_one_user_by_rid(ldap_state, final_rid, &result) != LDAP_SUCCESS) {
1516 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid));
1520 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
1521 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid));
1522 ldap_msgfree(result);
1526 DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid, final_rid));
1527 ldap_msgfree(result);
1531 /**********************************************************************
1532 Extract the RID from an LDAP entry
1533 *********************************************************************/
1534 static uint32 entry_to_user_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry) {
1536 SAM_ACCOUNT *user = NULL;
1537 if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
1541 if (init_sam_from_ldap(ldap_state, user, entry)) {
1542 rid = pdb_get_user_rid(user);
1546 pdb_free_sam(&user);
1547 if (rid >= ldap_state->low_nua_rid && rid <= ldap_state->high_nua_rid) {
1554 /**********************************************************************
1555 Connect to LDAP server and find the next available RID.
1556 *********************************************************************/
1557 static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state)
1561 LDAPMessage *result;
1563 char *final_filter = NULL;
1568 pstrcpy(filter, lp_ldap_filter());
1569 all_string_sub(filter, "%u", "*", sizeof(pstring));
1572 asprintf(&final_filter, "(&(%s)(&(rid>=%d)(rid<=%d)))", filter, ldap_state->low_nua_rid, ldap_state->high_nua_rid);
1574 final_filter = strdup(filter);
1576 DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter));
1578 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1579 LDAP_SCOPE_SUBTREE, final_filter, attr, 0,
1582 if (rc != LDAP_SUCCESS) {
1583 DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc)));
1584 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1591 count = ldap_count_entries(ldap_state->ldap_struct, result);
1592 DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count));
1595 DEBUG(3, ("LDAP search returned no records, assuming no non-unix-accounts present!: %s\n", ldap_err2string(rc)));
1596 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1598 ldap_msgfree(result);
1600 return ldap_state->low_nua_rid;
1604 entry = ldap_first_entry(ldap_state->ldap_struct,result);
1606 top_rid = entry_to_user_rid(ldap_state, entry);
1608 while ((entry = ldap_next_entry(ldap_state->ldap_struct, entry))) {
1610 rid = entry_to_user_rid(ldap_state, entry);
1611 if (rid > top_rid) {
1616 ldap_msgfree(result);
1618 if (top_rid < ldap_state->low_nua_rid)
1619 top_rid = ldap_state->low_nua_rid;
1624 /**********************************************************************
1625 Connect to LDAP server and find the next available RID.
1626 *********************************************************************/
1627 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state) {
1628 uint32 next_nua_rid;
1631 top_nua_rid = search_top_nua_rid(ldap_state);
1633 next_nua_rid = check_nua_rid_is_avail(ldap_state,
1636 return next_nua_rid;
1639 /**********************************************************************
1640 Connect to LDAP server for password enumeration
1641 *********************************************************************/
1642 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
1644 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1648 pstrcpy(filter, lp_ldap_filter());
1649 all_string_sub(filter, "%u", "*", sizeof(pstring));
1651 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1652 LDAP_SCOPE_SUBTREE, filter, attr, 0,
1653 &ldap_state->result);
1655 if (rc != LDAP_SUCCESS) {
1656 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
1657 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1658 ldap_msgfree(ldap_state->result);
1659 ldap_state->result = NULL;
1660 return NT_STATUS_UNSUCCESSFUL;
1663 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
1664 ldap_count_entries(ldap_state->ldap_struct,
1665 ldap_state->result)));
1667 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
1668 ldap_state->result);
1669 ldap_state->index = 0;
1671 return NT_STATUS_OK;
1674 /**********************************************************************
1675 End enumeration of the LDAP password list
1676 *********************************************************************/
1677 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1679 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1680 if (ldap_state->result) {
1681 ldap_msgfree(ldap_state->result);
1682 ldap_state->result = NULL;
1686 /**********************************************************************
1687 Get the next entry in the LDAP password database
1688 *********************************************************************/
1689 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
1691 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1692 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1695 /* The rebind proc needs this *HACK*. We are not multithreaded, so
1696 this will work, but it's not nice. */
1697 static_ldap_state = ldap_state;
1700 if (!ldap_state->entry)
1703 ldap_state->index++;
1704 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
1706 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
1710 return NT_STATUS_OK;
1713 /**********************************************************************
1714 Get SAM_ACCOUNT entry from LDAP by username
1715 *********************************************************************/
1716 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
1718 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1719 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1720 LDAPMessage *result;
1724 if (ldapsam_search_one_user_by_name(ldap_state, sname, &result) != LDAP_SUCCESS) {
1725 return NT_STATUS_NO_SUCH_USER;
1728 count = ldap_count_entries(ldap_state->ldap_struct, result);
1732 ("We don't find this user [%s] count=%d\n", sname,
1734 return NT_STATUS_NO_SUCH_USER;
1735 } else if (count > 1) {
1737 ("Duplicate entries for this user [%s] Failing. count=%d\n", sname,
1739 return NT_STATUS_NO_SUCH_USER;
1742 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1744 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1745 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1746 ldap_msgfree(result);
1747 return NT_STATUS_NO_SUCH_USER;
1749 ldap_msgfree(result);
1752 ldap_msgfree(result);
1757 /**********************************************************************
1758 Get SAM_ACCOUNT entry from LDAP by rid
1759 *********************************************************************/
1760 static NTSTATUS ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
1762 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1763 struct ldapsam_privates *ldap_state =
1764 (struct ldapsam_privates *)my_methods->private_data;
1765 LDAPMessage *result;
1769 if (ldapsam_search_one_user_by_rid(ldap_state, rid, &result) != LDAP_SUCCESS) {
1770 return NT_STATUS_NO_SUCH_USER;
1773 count = ldap_count_entries(ldap_state->ldap_struct, result);
1777 ("We don't find this rid [%i] count=%d\n", rid,
1779 return NT_STATUS_NO_SUCH_USER;
1780 } else if (count > 1) {
1782 ("More than one user with rid [%i]. Failing. count=%d\n", rid,
1784 return NT_STATUS_NO_SUCH_USER;
1787 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1789 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1790 DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
1791 ldap_msgfree(result);
1792 return NT_STATUS_NO_SUCH_USER;
1794 ldap_msgfree(result);
1797 ldap_msgfree(result);
1802 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
1805 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
1806 return NT_STATUS_NO_SUCH_USER;
1807 return ldapsam_getsampwrid(my_methods, user, rid);
1810 /********************************************************************
1811 Do the actual modification - also change a plaittext passord if
1813 **********************************************************************/
1815 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1816 SAM_ACCOUNT *newpwd, char *dn,
1817 LDAPMod **mods, int ldap_op, BOOL pdb_add)
1819 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1822 if (!my_methods || !newpwd || !dn) {
1823 return NT_STATUS_INVALID_PARAMETER;
1827 DEBUG(5,("mods is empty: nothing to modify\n"));
1828 /* may be password change below however */
1833 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account");
1834 rc = ldapsam_add(ldap_state, dn, mods);
1836 case LDAP_MOD_REPLACE:
1837 rc = ldapsam_modify(ldap_state, dn ,mods);
1840 DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
1841 return NT_STATUS_UNSUCCESSFUL;
1844 if (rc!=LDAP_SUCCESS) {
1846 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1849 ("failed to %s user dn= %s with: %s\n\t%s\n",
1850 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
1851 dn, ldap_err2string(rc),
1854 return NT_STATUS_UNSUCCESSFUL;
1858 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
1859 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))&&
1860 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_OFF)&&
1861 need_ldap_mod(pdb_add, newpwd, PDB_PLAINTEXT_PW)&&
1862 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1866 struct berval *retdata;
1868 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1869 DEBUG(0,("ber_alloc_t returns NULL\n"));
1870 return NT_STATUS_UNSUCCESSFUL;
1872 ber_printf (ber, "{");
1873 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID,dn);
1874 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, pdb_get_plaintext_passwd(newpwd));
1875 ber_printf (ber, "N}");
1877 if ((rc = ber_flatten (ber, &bv))<0) {
1878 DEBUG(0,("ber_flatten returns a value <0\n"));
1879 return NT_STATUS_UNSUCCESSFUL;
1884 if ((rc = ldapsam_extended_operation(ldap_state, LDAP_EXOP_X_MODIFY_PASSWD,
1885 bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) {
1886 DEBUG(0,("LDAP Password could not be changed for user %s: %s\n",
1887 pdb_get_username(newpwd),ldap_err2string(rc)));
1889 DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1891 ber_bvfree(retdata);
1892 ber_memfree(retoid);
1897 DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n"));
1898 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */
1899 return NT_STATUS_OK;
1902 /**********************************************************************
1903 Delete entry from LDAP for username
1904 *********************************************************************/
1905 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
1907 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1910 LDAPMessage *result;
1912 const char *sam_user_attrs[] =
1913 { "lmPassword", "ntPassword", "pwdLastSet", "logonTime", "logoffTime",
1914 "kickoffTime", "pwdCanChange", "pwdMustChange", "acctFlags",
1915 "displayName", "smbHome", "homeDrive", "scriptPath", "profilePath",
1916 "userWorkstations", "primaryGroupID", "domain", "rid", NULL };
1919 DEBUG(0, ("sam_acct was NULL!\n"));
1920 return NT_STATUS_INVALID_PARAMETER;
1923 sname = pdb_get_username(sam_acct);
1925 DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
1927 rc = ldapsam_search_one_user_by_name(ldap_state, sname, &result);
1928 if (rc != LDAP_SUCCESS) {
1929 return NT_STATUS_NO_SUCH_USER;
1932 ret = ldapsam_delete_entry(ldap_state, result, "sambaAccount",
1934 ldap_msgfree(result);
1938 /**********************************************************************
1940 *********************************************************************/
1941 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1943 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1944 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1947 LDAPMessage *result;
1951 rc = ldapsam_search_one_user_by_name(ldap_state, pdb_get_username(newpwd), &result);
1952 if (rc != LDAP_SUCCESS) {
1953 return NT_STATUS_UNSUCCESSFUL;
1956 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
1957 DEBUG(0, ("No user to modify!\n"));
1958 ldap_msgfree(result);
1959 return NT_STATUS_UNSUCCESSFUL;
1962 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1963 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
1965 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd)) {
1966 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1967 ldap_msgfree(result);
1968 return NT_STATUS_UNSUCCESSFUL;
1971 ldap_msgfree(result);
1974 DEBUG(4,("mods is empty: nothing to update for user: %s\n",
1975 pdb_get_username(newpwd)));
1976 ldap_mods_free(mods, 1);
1977 return NT_STATUS_OK;
1980 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, False);
1981 ldap_mods_free(mods,1);
1983 if (NT_STATUS_IS_ERR(ret)) {
1984 DEBUG(0,("failed to modify user with uid = %s\n",
1985 pdb_get_username(newpwd)));
1989 DEBUG(2, ("successfully modified uid = %s in the LDAP database\n",
1990 pdb_get_username(newpwd)));
1991 return NT_STATUS_OK;
1994 /**********************************************************************
1995 Add SAM_ACCOUNT to LDAP
1996 *********************************************************************/
1997 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1999 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2000 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2003 LDAPMessage *result = NULL;
2004 LDAPMessage *entry = NULL;
2006 LDAPMod **mods = NULL;
2010 const char *username = pdb_get_username(newpwd);
2011 if (!username || !*username) {
2012 DEBUG(0, ("Cannot add user without a username!\n"));
2013 return NT_STATUS_INVALID_PARAMETER;
2016 rc = ldapsam_search_one_user_by_name (ldap_state, username, &result);
2017 if (rc != LDAP_SUCCESS) {
2018 return NT_STATUS_UNSUCCESSFUL;
2021 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
2022 DEBUG(0,("User '%s' already in the base, with samba properties\n",
2024 ldap_msgfree(result);
2025 return NT_STATUS_UNSUCCESSFUL;
2027 ldap_msgfree(result);
2029 slprintf (filter, sizeof (filter) - 1, "uid=%s", username);
2030 rc = ldapsam_search_one_user(ldap_state, filter, &result);
2031 if (rc != LDAP_SUCCESS) {
2032 return NT_STATUS_UNSUCCESSFUL;
2035 num_result = ldap_count_entries(ldap_state->ldap_struct, result);
2037 if (num_result > 1) {
2038 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
2039 ldap_msgfree(result);
2040 return NT_STATUS_UNSUCCESSFUL;
2043 /* Check if we need to update an existing entry */
2044 if (num_result == 1) {
2047 DEBUG(3,("User exists without samba properties: adding them\n"));
2048 ldap_op = LDAP_MOD_REPLACE;
2049 entry = ldap_first_entry (ldap_state->ldap_struct, result);
2050 tmp = ldap_get_dn (ldap_state->ldap_struct, entry);
2051 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
2054 /* Check if we need to add an entry */
2055 DEBUG(3,("Adding new user\n"));
2056 ldap_op = LDAP_MOD_ADD;
2057 if (username[strlen(username)-1] == '$') {
2058 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
2060 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
2064 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd)) {
2065 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
2066 ldap_msgfree(result);
2067 ldap_mods_free(mods, 1);
2068 return NT_STATUS_UNSUCCESSFUL;
2071 ldap_msgfree(result);
2074 DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
2075 return NT_STATUS_UNSUCCESSFUL;
2078 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
2080 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, True);
2081 if (NT_STATUS_IS_ERR(ret)) {
2082 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
2083 pdb_get_username(newpwd),dn));
2084 ldap_mods_free(mods,1);
2088 DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd)));
2089 ldap_mods_free(mods, 1);
2090 return NT_STATUS_OK;
2093 static void free_private_data(void **vp)
2095 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
2097 ldapsam_close(*ldap_state);
2099 if ((*ldap_state)->bind_secret) {
2100 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
2103 ldapsam_close(*ldap_state);
2105 SAFE_FREE((*ldap_state)->bind_dn);
2106 SAFE_FREE((*ldap_state)->bind_secret);
2110 /* No need to free any further, as it is talloc()ed */
2113 static const char *group_attr[] = {"gid", "ntSid", "ntGroupType",
2115 "displayName", "description",
2118 static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
2120 LDAPMessage ** result)
2122 int scope = LDAP_SCOPE_SUBTREE;
2125 DEBUG(2, ("ldapsam_search_one_group: searching for:[%s]\n", filter));
2127 rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope,
2128 filter, group_attr, 0, result);
2130 if (rc != LDAP_SUCCESS) {
2131 DEBUG(0, ("ldapsam_search_one_group: "
2132 "Problem during the LDAP search: %s\n",
2133 ldap_err2string(rc)));
2134 DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
2135 lp_ldap_suffix(), filter));
2141 static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
2142 GROUP_MAP *map, LDAPMessage *entry)
2146 if (ldap_state == NULL || map == NULL || entry == NULL ||
2147 ldap_state->ldap_struct == NULL) {
2148 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
2152 if (!get_single_attribute(ldap_state->ldap_struct, entry, "gidNumber",
2154 DEBUG(0, ("Mandatory attribute gidNumber not found\n"));
2157 DEBUG(2, ("Entry found for group: %s\n", temp));
2159 map->gid = (uint32)atol(temp);
2161 if (!get_single_attribute(ldap_state->ldap_struct, entry, "ntSid",
2163 DEBUG(0, ("Mandatory attribute ntSid not found\n"));
2166 string_to_sid(&map->sid, temp);
2168 if (!get_single_attribute(ldap_state->ldap_struct, entry, "ntGroupType",
2170 DEBUG(0, ("Mandatory attribute ntGroupType not found\n"));
2173 map->sid_name_use = (uint32)atol(temp);
2175 if ((map->sid_name_use < SID_NAME_USER) ||
2176 (map->sid_name_use > SID_NAME_UNKNOWN)) {
2177 DEBUG(0, ("Unknown Group type: %d\n", map->sid_name_use));
2181 if (!get_single_attribute(ldap_state->ldap_struct, entry, "displayName",
2183 DEBUG(3, ("Attribute displayName not found\n"));
2186 fstrcpy(map->nt_name, temp);
2188 if (!get_single_attribute(ldap_state->ldap_struct, entry, "description",
2190 DEBUG(3, ("Attribute description not found\n"));
2193 fstrcpy(map->comment, temp);
2195 map->systemaccount = 0;
2196 init_privilege(&map->priv_set);
2201 static BOOL init_ldap_from_group(struct ldapsam_privates *ldap_state,
2202 LDAPMod ***mods, int ldap_op,
2203 const GROUP_MAP *map)
2207 if (mods == NULL || map == NULL) {
2208 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
2214 sid_to_string(tmp, &map->sid);
2215 make_a_mod(mods, ldap_op, "ntSid", tmp);
2217 snprintf(tmp, sizeof(tmp)-1, "%i", map->sid_name_use);
2218 make_a_mod(mods, ldap_op, "ntGroupType", tmp);
2220 make_a_mod(mods, ldap_op, "displayName", map->nt_name);
2221 make_a_mod(mods, ldap_op, "description", map->comment);
2226 static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
2230 struct ldapsam_privates *ldap_state =
2231 (struct ldapsam_privates *)methods->private_data;
2232 LDAPMessage *result;
2236 if (ldapsam_search_one_group(ldap_state, filter, &result)
2238 return NT_STATUS_NO_SUCH_GROUP;
2241 count = ldap_count_entries(ldap_state->ldap_struct, result);
2244 DEBUG(4, ("Did not find group for filter %s\n", filter));
2245 return NT_STATUS_NO_SUCH_GROUP;
2249 DEBUG(1, ("Duplicate entries for filter %s: count=%d\n",
2251 return NT_STATUS_NO_SUCH_GROUP;
2254 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2257 ldap_msgfree(result);
2258 return NT_STATUS_UNSUCCESSFUL;
2261 if (!init_group_from_ldap(ldap_state, map, entry)) {
2262 DEBUG(1, ("init_group_from_ldap failed for group filter %s\n",
2264 ldap_msgfree(result);
2265 return NT_STATUS_NO_SUCH_GROUP;
2268 ldap_msgfree(result);
2269 return NT_STATUS_OK;
2272 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
2273 DOM_SID sid, BOOL with_priv)
2277 snprintf(filter, sizeof(filter)-1,
2278 "(&(objectClass=sambaGroupMapping)(ntSid=%s))",
2279 sid_string_static(&sid));
2281 return ldapsam_getgroup(methods, filter, map);
2284 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
2285 gid_t gid, BOOL with_priv)
2289 snprintf(filter, sizeof(filter)-1,
2290 "(&(objectClass=sambaGroupMapping)(gidNumber=%d))",
2293 return ldapsam_getgroup(methods, filter, map);
2296 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
2297 char *name, BOOL with_priv)
2301 /* TODO: Escaping of name? */
2303 snprintf(filter, sizeof(filter)-1,
2304 "(&(objectClass=sambaGroupMapping)(displayName=%s))",
2307 return ldapsam_getgroup(methods, filter, map);
2310 static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
2312 LDAPMessage **result)
2316 snprintf(filter, sizeof(filter)-1,
2317 "(&(objectClass=posixGroup)(gidNumber=%i))", gid);
2319 return ldapsam_search_one_group(ldap_state, filter, result);
2322 static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
2325 struct ldapsam_privates *ldap_state =
2326 (struct ldapsam_privates *)methods->private_data;
2327 LDAPMessage *result = NULL;
2328 LDAPMod **mods = NULL;
2338 if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
2339 map->gid, False))) {
2340 DEBUG(0, ("Group %i already exists in LDAP\n", map->gid));
2341 return NT_STATUS_UNSUCCESSFUL;
2344 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
2345 if (rc != LDAP_SUCCESS) {
2346 return NT_STATUS_UNSUCCESSFUL;
2349 if (ldap_count_entries(ldap_state->ldap_struct, result) != 1) {
2350 DEBUG(2, ("Group %i must exist exactly once in LDAP\n",
2352 ldap_msgfree(result);
2353 return NT_STATUS_UNSUCCESSFUL;
2356 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2357 tmp = ldap_get_dn(ldap_state->ldap_struct, entry);
2360 ldap_msgfree(result);
2362 if (!init_ldap_from_group(ldap_state, &mods, LDAP_MOD_ADD, map)) {
2363 DEBUG(0, ("init_ldap_from_group failed!\n"));
2364 ldap_mods_free(mods, 1);
2365 return NT_STATUS_UNSUCCESSFUL;
2369 DEBUG(0, ("mods is empty\n"));
2370 return NT_STATUS_UNSUCCESSFUL;
2373 make_a_mod(&mods, LDAP_MOD_ADD, "objectClass",
2374 "sambaGroupMapping");
2376 rc = ldapsam_modify(ldap_state, dn, mods);
2377 ldap_mods_free(mods, 1);
2379 if (rc != LDAP_SUCCESS) {
2380 DEBUG(0, ("failed to modify group %i\n", map->gid));
2381 return NT_STATUS_UNSUCCESSFUL;
2384 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
2385 return NT_STATUS_OK;
2388 static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
2391 struct ldapsam_privates *ldap_state =
2392 (struct ldapsam_privates *)methods->private_data;
2395 LDAPMessage *result;
2399 if (!init_ldap_from_group(ldap_state, &mods, LDAP_MOD_REPLACE, map)) {
2400 DEBUG(0, ("init_ldap_from_group failed\n"));
2401 return NT_STATUS_UNSUCCESSFUL;
2405 DEBUG(4, ("mods is empty: nothing to do\n"));
2406 return NT_STATUS_UNSUCCESSFUL;
2409 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
2411 if (rc != LDAP_SUCCESS) {
2412 ldap_mods_free(mods, 1);
2413 return NT_STATUS_UNSUCCESSFUL;
2416 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
2417 DEBUG(0, ("No group to modify!\n"));
2418 ldap_msgfree(result);
2419 ldap_mods_free(mods, 1);
2420 return NT_STATUS_UNSUCCESSFUL;
2423 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2424 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
2425 ldap_msgfree(result);
2427 rc = ldapsam_modify(ldap_state, dn, mods);
2429 ldap_mods_free(mods, 1);
2431 if (rc != LDAP_SUCCESS) {
2432 DEBUG(0, ("failed to modify group %i\n", map->gid));
2435 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
2436 return NT_STATUS_OK;
2439 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
2442 struct ldapsam_privates *ldap_state =
2443 (struct ldapsam_privates *)methods->private_data;
2444 pstring sidstring, filter;
2445 LDAPMessage *result;
2449 const char *sam_group_attrs[] = { "ntSid", "ntGroupType",
2450 "description", "displayName",
2452 sid_to_string(sidstring, &sid);
2453 snprintf(filter, sizeof(filter)-1,
2454 "(&(objectClass=sambaGroupMapping)(ntSid=%s))", sidstring);
2456 rc = ldapsam_search_one_group(ldap_state, filter, &result);
2458 if (rc != LDAP_SUCCESS) {
2459 return NT_STATUS_NO_SUCH_GROUP;
2462 ret = ldapsam_delete_entry(ldap_state, result, "sambaGroupMapping",
2464 ldap_msgfree(result);
2468 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
2471 struct ldapsam_privates *ldap_state =
2472 (struct ldapsam_privates *)my_methods->private_data;
2473 const char *filter = "(objectClass=sambaGroupMapping)";
2476 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
2477 LDAP_SCOPE_SUBTREE, filter,
2478 group_attr, 0, &ldap_state->result);
2480 if (rc != LDAP_SUCCESS) {
2481 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
2482 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
2483 ldap_msgfree(ldap_state->result);
2484 ldap_state->result = NULL;
2485 return NT_STATUS_UNSUCCESSFUL;
2488 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
2489 ldap_count_entries(ldap_state->ldap_struct,
2490 ldap_state->result)));
2492 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
2493 ldap_state->result);
2494 ldap_state->index = 0;
2496 return NT_STATUS_OK;
2499 static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
2501 ldapsam_endsampwent(my_methods);
2504 static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
2507 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2508 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2511 /* The rebind proc needs this *HACK*. We are not multithreaded, so
2512 this will work, but it's not nice. */
2513 static_ldap_state = ldap_state;
2516 if (!ldap_state->entry)
2519 ldap_state->index++;
2520 bret = init_group_from_ldap(ldap_state, map, ldap_state->entry);
2522 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
2526 return NT_STATUS_OK;
2529 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
2530 enum SID_NAME_USE sid_name_use,
2531 GROUP_MAP **rmap, int *num_entries,
2532 BOOL unix_only, BOOL with_priv)
2542 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
2543 DEBUG(0, ("Unable to open passdb\n"));
2544 return NT_STATUS_ACCESS_DENIED;
2547 while (NT_STATUS_IS_OK(nt_status = ldapsam_getsamgrent(methods, &map))) {
2548 if (sid_name_use != SID_NAME_UNKNOWN &&
2549 sid_name_use != map.sid_name_use) {
2550 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
2553 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
2554 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name));
2558 mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP));
2560 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
2562 return NT_STATUS_UNSUCCESSFUL;
2567 mapt[entries] = map;
2572 ldapsam_endsamgrent(methods);
2574 *num_entries = entries;
2576 return NT_STATUS_OK;
2579 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2582 struct ldapsam_privates *ldap_state;
2584 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
2588 (*pdb_method)->name = "ldapsam";
2590 (*pdb_method)->setsampwent = ldapsam_setsampwent;
2591 (*pdb_method)->endsampwent = ldapsam_endsampwent;
2592 (*pdb_method)->getsampwent = ldapsam_getsampwent;
2593 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
2594 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
2595 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
2596 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
2597 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
2599 (*pdb_method)->getgrsid = ldapsam_getgrsid;
2600 (*pdb_method)->getgrgid = ldapsam_getgrgid;
2601 (*pdb_method)->getgrnam = ldapsam_getgrnam;
2602 (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
2603 (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
2604 (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
2605 (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
2607 /* TODO: Setup private data and free */
2609 ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct ldapsam_privates));
2612 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
2613 return NT_STATUS_NO_MEMORY;
2617 ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
2618 #ifdef WITH_LDAP_SAMCONFIG
2620 int ldap_port = lp_ldap_port();
2622 /* remap default port if not using SSL (ie clear or TLS) */
2623 if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
2627 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);
2628 if (!ldap_state->uri) {
2629 return NT_STATUS_NO_MEMORY;
2633 ldap_state->uri = "ldap://localhost";
2637 (*pdb_method)->private_data = ldap_state;
2639 (*pdb_method)->free_private_data = free_private_data;
2641 return NT_STATUS_OK;
2644 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2647 struct ldapsam_privates *ldap_state;
2648 uint32 low_nua_uid, high_nua_uid;
2650 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) {
2654 (*pdb_method)->name = "ldapsam_nua";
2656 ldap_state = (*pdb_method)->private_data;
2658 ldap_state->permit_non_unix_accounts = True;
2660 if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) {
2661 DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n"));
2662 return NT_STATUS_UNSUCCESSFUL;
2665 ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid);
2667 ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid);
2669 return NT_STATUS_OK;
2675 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2677 DEBUG(0, ("ldap not detected at configure time, ldapsam not availalble!\n"));
2678 return NT_STATUS_UNSUCCESSFUL;
2681 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2683 DEBUG(0, ("ldap not dectected at configure time, ldapsam_nua not available!\n"));
2684 return NT_STATUS_UNSUCCESSFUL;