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
32 * persistent connections: if using NSS LDAP, many connections are made
33 * however, using only one within Samba would be nice
35 * Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
37 * Other LDAP based login attributes: accountExpires, etc.
38 * (should be the domain of Samba proper, but the sam_password/SAM_ACCOUNT
39 * structures don't have fields for some of these attributes)
41 * SSL is done, but can't get the certificate based authentication to work
42 * against on my test platform (Linux 2.4, OpenLDAP 2.x)
45 /* NOTE: this will NOT work against an Active Directory server
46 * due to the fact that the two password fields cannot be retrieved
47 * from a server; recommend using security = domain in this situation
55 #define SAM_ACCOUNT struct sam_passwd
58 struct ldapsam_privates {
67 /* retrive-once info */
70 BOOL permit_non_unix_accounts;
79 #define LDAPSAM_DONT_PING_TIME 10 /* ping only all 10 seconds */
81 static struct ldapsam_privates *static_ldap_state;
83 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state);
85 /*******************************************************************
86 find the ldap password
87 ******************************************************************/
88 static BOOL fetch_ldapsam_pw(char **dn, char** pw)
93 *dn = smb_xstrdup(lp_ldap_admin_dn());
95 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
97 DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
100 *pw=secrets_fetch(key, &size);
102 /* Upgrade 2.2 style entry */
104 char* old_style_key = strdup(*dn);
106 fstring old_style_pw;
108 if (!old_style_key) {
109 DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n"));
113 for (p=old_style_key; *p; p++)
114 if (*p == ',') *p = '/';
116 data=secrets_fetch(old_style_key, &size);
117 if (!size && size < sizeof(old_style_pw)) {
118 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
119 SAFE_FREE(old_style_key);
124 strncpy(old_style_pw, data, size);
125 old_style_pw[size] = 0;
129 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
130 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
131 SAFE_FREE(old_style_key);
135 if (!secrets_delete(old_style_key)) {
136 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
139 SAFE_FREE(old_style_key);
141 *pw = smb_xstrdup(old_style_pw);
147 static const char *attr[] = {"uid", "pwdLastSet", "logonTime",
148 "logoffTime", "kickoffTime", "cn",
149 "pwdCanChange", "pwdMustChange",
150 "displayName", "homeDrive",
151 "smbHome", "scriptPath",
152 "profilePath", "description",
153 "userWorkstations", "rid",
154 "primaryGroupID", "lmPassword",
155 "ntPassword", "acctFlags",
156 "domain", "objectClass",
157 "uidNumber", "gidNumber",
158 "homeDirectory", NULL };
160 /*******************************************************************
161 open a connection to the ldap server.
162 ******************************************************************/
163 static int ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct)
165 int rc = LDAP_SUCCESS;
167 BOOL ldap_v3 = False;
169 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
170 DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri));
172 if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) {
173 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
179 /* Parse the string manually */
185 const char *p = ldap_state->uri;
186 SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
188 /* skip leading "URL:" (if any) */
189 if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
193 sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port);
196 if (strequal(protocol, "ldap")) {
198 } else if (strequal(protocol, "ldaps")) {
201 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
205 if ((*ldap_struct = ldap_init(host, port)) == NULL) {
206 DEBUG(0, ("ldap_init failed !\n"));
207 return LDAP_OPERATIONS_ERROR;
210 if (strequal(protocol, "ldaps")) {
211 #ifdef LDAP_OPT_X_TLS
212 int tls = LDAP_OPT_X_TLS_HARD;
213 if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
215 DEBUG(0, ("Failed to setup a TLS session\n"));
218 DEBUG(3,("LDAPS option set...!\n"));
220 DEBUG(0,("ldapsam_open_connection: Secure connection not supported by LDAP client libraries!\n"));
221 return LDAP_OPERATIONS_ERROR;
227 if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
229 if (version != LDAP_VERSION3)
231 version = LDAP_VERSION3;
232 if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
240 if (lp_ldap_ssl() == LDAP_SSL_START_TLS) {
241 #ifdef LDAP_OPT_X_TLS
243 if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
245 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
246 ldap_err2string(rc)));
249 DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
252 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
253 return LDAP_OPERATIONS_ERROR;
256 DEBUG(0,("ldapsam_open_connection: StartTLS not supported by LDAP client libraries!\n"));
257 return LDAP_OPERATIONS_ERROR;
261 DEBUG(2, ("ldapsam_open_connection: connection opened\n"));
266 /*******************************************************************
267 a rebind function for authenticated referrals
268 This version takes a void* that we can shove useful stuff in :-)
269 ******************************************************************/
270 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
272 static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
273 int *methodp, int freeit, void *arg)
275 struct ldapsam_privates *ldap_state = arg;
277 /** @TODO Should we be doing something to check what servers we rebind to?
278 Could we get a referral to a machine that we don't want to give our
279 username and password to? */
283 memset(*credp, '\0', strlen(*credp));
286 DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
287 ldap_state->bind_dn));
289 *whop = strdup(ldap_state->bind_dn);
291 return LDAP_NO_MEMORY;
293 *credp = strdup(ldap_state->bind_secret);
296 return LDAP_NO_MEMORY;
298 *methodp = LDAP_AUTH_SIMPLE;
302 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
304 /*******************************************************************
305 a rebind function for authenticated referrals
306 This version takes a void* that we can shove useful stuff in :-)
307 and actually does the connection.
308 ******************************************************************/
309 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
310 static int rebindproc_connect_with_state (LDAP *ldap_struct,
311 LDAP_CONST char *url,
313 ber_int_t msgid, void *arg)
315 struct ldapsam_privates *ldap_state = arg;
317 DEBUG(5,("rebindproc_connect_with_state: Rebinding as \"%s\"\n",
318 ldap_state->bind_dn));
320 /** @TODO Should we be doing something to check what servers we rebind to?
321 Could we get a referral to a machine that we don't want to give our
322 username and password to? */
324 rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
328 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
330 /*******************************************************************
331 Add a rebind function for authenticated referrals
332 ******************************************************************/
333 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
335 # if LDAP_SET_REBIND_PROC_ARGS == 2
336 static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
337 int *method, int freeit )
339 return rebindproc_with_state(ldap_struct, whop, credp,
340 method, freeit, static_ldap_state);
343 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
344 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
346 /*******************************************************************
347 a rebind function for authenticated referrals
348 this also does the connection, but no void*.
349 ******************************************************************/
350 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
351 # if LDAP_SET_REBIND_PROC_ARGS == 2
352 static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
355 return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid,
358 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
359 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
361 /*******************************************************************
362 connect to the ldap server under system privilege.
363 ******************************************************************/
364 static int ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct)
370 /* The rebind proc needs this *HACK*. We are not multithreaded, so
371 this will work, but it's not nice. */
372 static_ldap_state = ldap_state;
374 /* get the password */
375 if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
377 DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
378 return LDAP_INVALID_CREDENTIALS;
381 ldap_state->bind_dn = ldap_dn;
382 ldap_state->bind_secret = ldap_secret;
384 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
385 (OpenLDAP) doesnt' seem to support it */
387 DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
388 ldap_state->uri, ldap_dn));
390 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
391 # if LDAP_SET_REBIND_PROC_ARGS == 2
392 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);
394 # if LDAP_SET_REBIND_PROC_ARGS == 3
395 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);
397 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
398 # if LDAP_SET_REBIND_PROC_ARGS == 2
399 ldap_set_rebind_proc(ldap_struct, &rebindproc);
401 # if LDAP_SET_REBIND_PROC_ARGS == 3
402 ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);
404 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
406 rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
408 if (rc != LDAP_SUCCESS) {
410 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
413 ("failed to bind to server with dn= %s Error: %s\n\t%s\n",
414 ldap_dn, ldap_err2string(rc),
420 DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n"));
424 /**********************************************************************
425 Connect to LDAP server
426 *********************************************************************/
427 static int ldapsam_open(struct ldapsam_privates *ldap_state)
430 SMB_ASSERT(ldap_state);
432 #ifndef NO_LDAP_SECURITY
433 if (geteuid() != 0) {
434 DEBUG(0, ("ldapsam_open: cannot access LDAP when not root..\n"));
435 return LDAP_INSUFFICIENT_ACCESS;
439 if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + LDAPSAM_DONT_PING_TIME) < time(NULL))) {
440 struct sockaddr_un addr;
443 if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
444 getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
445 /* the other end has died. reopen. */
446 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
447 ldap_state->ldap_struct = NULL;
448 ldap_state->last_ping = (time_t)0;
450 ldap_state->last_ping = time(NULL);
454 if (ldap_state->ldap_struct != NULL) {
455 DEBUG(5,("ldapsam_open: allready connected to the LDAP server\n"));
459 if ((rc = ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct))) {
463 if ((rc = ldapsam_connect_system(ldap_state, ldap_state->ldap_struct))) {
464 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
465 ldap_state->ldap_struct = NULL;
470 ldap_state->last_ping = time(NULL);
471 DEBUG(4,("The LDAP server is succesful connected\n"));
476 /**********************************************************************
477 Disconnect from LDAP server
478 *********************************************************************/
479 static NTSTATUS ldapsam_close(struct ldapsam_privates *ldap_state)
482 return NT_STATUS_INVALID_PARAMETER;
484 if (ldap_state->ldap_struct != NULL) {
485 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
486 ldap_state->ldap_struct = NULL;
489 DEBUG(5,("The connection to the LDAP server was closed\n"));
490 /* maybe free the results here --metze */
495 static int ldapsam_retry_open(struct ldapsam_privates *ldap_state, int *attempts)
499 SMB_ASSERT(ldap_state && attempts);
501 if (*attempts != 0) {
502 /* we retry after 0.5, 2, 4.5, 8, 12.5, 18, 24.5 seconds */
503 msleep((((*attempts)*(*attempts))/2)*1000);
507 if ((rc = ldapsam_open(ldap_state))) {
508 DEBUG(0,("Connection to LDAP Server failed for the %d try!\n",*attempts));
516 static int ldapsam_search(struct ldapsam_privates *ldap_state,
517 const char *base, int scope, const char *filter,
518 const char *attrs[], int attrsonly,
521 int rc = LDAP_SERVER_DOWN;
524 SMB_ASSERT(ldap_state);
526 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
528 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
531 rc = ldap_search_s(ldap_state->ldap_struct, base, scope,
532 filter, attrs, attrsonly, res);
535 if (rc == LDAP_SERVER_DOWN) {
536 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
537 ldapsam_close(ldap_state);
543 static int ldapsam_modify(struct ldapsam_privates *ldap_state, char *dn, LDAPMod *attrs[])
545 int rc = LDAP_SERVER_DOWN;
551 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
553 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
556 rc = ldap_modify_s(ldap_state->ldap_struct, dn, attrs);
559 if (rc == LDAP_SERVER_DOWN) {
560 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
561 ldapsam_close(ldap_state);
567 static int ldapsam_add(struct ldapsam_privates *ldap_state, const char *dn, LDAPMod *attrs[])
569 int rc = LDAP_SERVER_DOWN;
575 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
577 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
580 rc = ldap_add_s(ldap_state->ldap_struct, dn, attrs);
583 if (rc == LDAP_SERVER_DOWN) {
584 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
585 ldapsam_close(ldap_state);
591 static int ldapsam_delete(struct ldapsam_privates *ldap_state, char *dn)
593 int rc = LDAP_SERVER_DOWN;
599 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
601 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
604 rc = ldap_delete_s(ldap_state->ldap_struct, dn);
607 if (rc == LDAP_SERVER_DOWN) {
608 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
609 ldapsam_close(ldap_state);
615 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)
617 int rc = LDAP_SERVER_DOWN;
623 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
625 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
628 rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata, serverctrls, clientctrls, retoidp, retdatap);
631 if (rc == LDAP_SERVER_DOWN) {
632 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
633 ldapsam_close(ldap_state);
639 /*******************************************************************
640 run the search by name.
641 ******************************************************************/
642 static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, const char *filter, LDAPMessage ** result)
644 int scope = LDAP_SCOPE_SUBTREE;
647 DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter));
649 rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope, filter, attr, 0, result);
651 if (rc != LDAP_SUCCESS) {
652 DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n",
653 ldap_err2string (rc)));
654 DEBUG(3,("ldapsam_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(),
661 /*******************************************************************
662 run the search by name.
663 ******************************************************************/
664 static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, const char *user,
665 LDAPMessage ** result)
668 char *escape_user = escape_ldap_string_alloc(user);
671 return LDAP_NO_MEMORY;
675 * in the filter expression, replace %u with the real name
676 * so in ldap filter, %u MUST exist :-)
678 pstrcpy(filter, lp_ldap_filter());
681 * have to use this here because $ is filtered out
686 all_string_sub(filter, "%u", escape_user, sizeof(pstring));
687 SAFE_FREE(escape_user);
689 return ldapsam_search_one_user(ldap_state, filter, result);
692 /*******************************************************************
693 run the search by uid.
694 ******************************************************************/
695 static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state,
697 LDAPMessage ** result)
703 /* Get the username from the system and look that up in the LDAP */
705 if ((user = getpwuid_alloc(uid)) == NULL) {
706 DEBUG(3,("ldapsam_search_one_user_by_uid: Failed to locate uid [%d]\n", uid));
707 return LDAP_NO_SUCH_OBJECT;
710 pstrcpy(filter, lp_ldap_filter());
712 escape_user = escape_ldap_string_alloc(user->pw_name);
715 return LDAP_NO_MEMORY;
718 all_string_sub(filter, "%u", escape_user, sizeof(pstring));
721 SAFE_FREE(escape_user);
723 return ldapsam_search_one_user(ldap_state, filter, result);
726 /*******************************************************************
727 run the search by rid.
728 ******************************************************************/
729 static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state,
731 LDAPMessage ** result)
736 /* check if the user rid exsists, if not, try searching on the uid */
738 snprintf(filter, sizeof(filter) - 1, "rid=%i", rid);
739 rc = ldapsam_search_one_user(ldap_state, filter, result);
741 if (rc != LDAP_SUCCESS)
742 rc = ldapsam_search_one_user_by_uid(ldap_state,
743 fallback_pdb_user_rid_to_uid(rid),
749 /*******************************************************************
750 search an attribute and return the first value found.
751 ******************************************************************/
752 static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
753 const char *attribute, pstring value)
757 if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
759 DEBUG (10, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute));
764 pstrcpy(value, values[0]);
765 ldap_value_free(values);
766 #ifdef DEBUG_PASSWORDS
767 DEBUG (100, ("get_single_attribute: [%s] = [%s]\n", attribute, value));
772 /************************************************************************
773 Routine to manage the LDAPMod structure array
774 manage memory used by the array, by each struct, and values
776 ************************************************************************/
777 static void make_a_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
785 if (attribute == NULL || *attribute == '\0')
789 /* Why do we need this??? -- vl */
790 if (value == NULL || *value == '\0')
796 mods = (LDAPMod **) malloc(sizeof(LDAPMod *));
799 DEBUG(0, ("make_a_mod: out of memory!\n"));
805 for (i = 0; mods[i] != NULL; ++i) {
806 if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute))
812 mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *));
815 DEBUG(0, ("make_a_mod: out of memory!\n"));
818 mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
821 DEBUG(0, ("make_a_mod: out of memory!\n"));
824 mods[i]->mod_op = modop;
825 mods[i]->mod_values = NULL;
826 mods[i]->mod_type = strdup(attribute);
833 if (mods[i]->mod_values != NULL) {
834 for (; mods[i]->mod_values[j] != NULL; j++);
836 mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values,
837 (j + 2) * sizeof (char *));
839 if (mods[i]->mod_values == NULL) {
840 DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
843 mods[i]->mod_values[j] = strdup(value);
844 mods[i]->mod_values[j + 1] = NULL;
849 /*******************************************************************
850 Delete complete object or objectclass and attrs from
851 object found in search_result depending on lp_ldap_delete_dn
852 ******************************************************************/
853 static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
855 const char *objectclass,
860 LDAPMod **mods = NULL;
862 BerElement *ptr = NULL;
864 rc = ldap_count_entries(ldap_state->ldap_struct, result);
867 DEBUG(0, ("Entry must exist exactly once!\n"));
868 return NT_STATUS_UNSUCCESSFUL;
871 entry = ldap_first_entry(ldap_state->ldap_struct, result);
872 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
874 if (lp_ldap_delete_dn()) {
875 NTSTATUS ret = NT_STATUS_OK;
876 rc = ldapsam_delete(ldap_state, dn);
878 if (rc != LDAP_SUCCESS) {
879 DEBUG(0, ("Could not delete object %s\n", dn));
880 ret = NT_STATUS_UNSUCCESSFUL;
886 /* Ok, delete only the SAM attributes */
888 for (name = ldap_first_attribute(ldap_state->ldap_struct, entry, &ptr);
890 name = ldap_next_attribute(ldap_state->ldap_struct, entry, ptr)) {
894 /* We are only allowed to delete the attributes that
897 for (attrib = attrs; *attrib != NULL; attrib++) {
898 if (StrCaseCmp(*attrib, name) == 0) {
899 DEBUG(10, ("deleting attribute %s\n", name));
900 make_a_mod(&mods, LDAP_MOD_DELETE, name, NULL);
911 make_a_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
913 rc = ldapsam_modify(ldap_state, dn, mods);
914 ldap_mods_free(mods, 1);
916 if (rc != LDAP_SUCCESS) {
917 DEBUG(0, ("could not delete attributes for %s, error: %s\n",
918 dn, ldap_err2string(rc)));
920 return NT_STATUS_UNSUCCESSFUL;
927 /* New Interface is being implemented here */
929 /**********************************************************************
930 Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
931 *********************************************************************/
932 static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
933 SAM_ACCOUNT * sampass,
943 if ((ldap_values = ldap_get_values (ldap_state->ldap_struct, entry, "objectClass")) == NULL) {
944 DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
948 for (values=ldap_values;*values;values++) {
949 if (strcasecmp(*values, "posixAccount") == 0) {
954 if (!*values) { /*end of array, no posixAccount */
955 DEBUG(10, ("user does not have posixAcccount attributes\n"));
956 ldap_value_free(ldap_values);
959 ldap_value_free(ldap_values);
961 if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDirectory", homedir))
964 if (!get_single_attribute(ldap_state->ldap_struct, entry, "uidNumber", temp))
967 uid = (uid_t)atol(temp);
969 if (!get_single_attribute(ldap_state->ldap_struct, entry, "gidNumber", temp))
972 gid = (gid_t)atol(temp);
974 pdb_set_unix_homedir(sampass, homedir, PDB_SET);
975 pdb_set_uid(sampass, uid, PDB_SET);
976 pdb_set_gid(sampass, gid, PDB_SET);
978 DEBUG(10, ("user has posixAcccount attributes\n"));
983 /**********************************************************************
984 Initialize SAM_ACCOUNT from an LDAP query
985 (Based on init_sam_from_buffer in pdb_tdb.c)
986 *********************************************************************/
987 static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
988 SAM_ACCOUNT * sampass,
995 pass_can_change_time,
996 pass_must_change_time;
1011 uint8 smblmpwd[LM_HASH_LEN],
1012 smbntpwd[NT_HASH_LEN];
1013 uint16 acct_ctrl = 0,
1016 uint8 hours[MAX_HOURS_LEN];
1019 gid_t gid = getegid();
1023 * do a little initialization
1027 nt_username[0] = '\0';
1030 dir_drive[0] = '\0';
1031 logon_script[0] = '\0';
1032 profile_path[0] = '\0';
1033 acct_desc[0] = '\0';
1034 munged_dial[0] = '\0';
1035 workstations[0] = '\0';
1038 if (sampass == NULL || ldap_state == NULL || entry == NULL) {
1039 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
1043 if (ldap_state->ldap_struct == NULL) {
1044 DEBUG(0, ("init_sam_from_ldap: ldap_state->ldap_struct is NULL!\n"));
1048 get_single_attribute(ldap_state->ldap_struct, entry, "uid", username);
1049 DEBUG(2, ("Entry found for user: %s\n", username));
1051 pstrcpy(nt_username, username);
1053 pstrcpy(domain, lp_workgroup());
1055 pdb_set_username(sampass, username, PDB_SET);
1057 pdb_set_domain(sampass, domain, PDB_DEFAULT);
1058 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1060 get_single_attribute(ldap_state->ldap_struct, entry, "rid", temp);
1061 user_rid = (uint32)atol(temp);
1063 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1065 if (!get_single_attribute(ldap_state->ldap_struct, entry, "primaryGroupID", temp)) {
1068 group_rid = (uint32)atol(temp);
1069 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1074 * If so configured, try and get the values from LDAP
1077 if (!lp_ldap_trust_ids() || (!get_unix_attributes(ldap_state, sampass, entry))) {
1080 * Otherwise just ask the system getpw() calls.
1083 pw = getpwnam_alloc(username);
1085 if (! ldap_state->permit_non_unix_accounts) {
1086 DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\n", username));
1091 pdb_set_uid(sampass, uid, PDB_SET);
1093 pdb_set_gid(sampass, gid, PDB_SET);
1095 pdb_set_unix_homedir(sampass, pw->pw_dir, PDB_SET);
1101 if (group_rid == 0 && pdb_get_init_flags(sampass,PDB_GID) != PDB_DEFAULT) {
1103 gid = pdb_get_gid(sampass);
1104 /* call the mapping code here */
1105 if(pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) {
1106 pdb_set_group_sid(sampass, &map.sid, PDB_SET);
1109 pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid), PDB_SET);
1113 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdLastSet", temp)) {
1114 /* leave as default */
1116 pass_last_set_time = (time_t) atol(temp);
1117 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1120 if (!get_single_attribute(ldap_state->ldap_struct, entry, "logonTime", temp)) {
1121 /* leave as default */
1123 logon_time = (time_t) atol(temp);
1124 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1127 if (!get_single_attribute(ldap_state->ldap_struct, entry, "logoffTime", temp)) {
1128 /* leave as default */
1130 logoff_time = (time_t) atol(temp);
1131 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1134 if (!get_single_attribute(ldap_state->ldap_struct, entry, "kickoffTime", temp)) {
1135 /* leave as default */
1137 kickoff_time = (time_t) atol(temp);
1138 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1141 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdCanChange", temp)) {
1142 /* leave as default */
1144 pass_can_change_time = (time_t) atol(temp);
1145 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1148 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdMustChange", temp)) {
1149 /* leave as default */
1151 pass_must_change_time = (time_t) atol(temp);
1152 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1155 /* recommend that 'gecos' and 'displayName' should refer to the same
1156 * attribute OID. userFullName depreciated, only used by Samba
1157 * primary rules of LDAP: don't make a new attribute when one is already defined
1158 * that fits your needs; using cn then displayName rather than 'userFullName'
1161 if (!get_single_attribute(ldap_state->ldap_struct, entry,
1162 "displayName", fullname)) {
1163 if (!get_single_attribute(ldap_state->ldap_struct, entry,
1165 /* leave as default */
1167 pdb_set_fullname(sampass, fullname, PDB_SET);
1170 pdb_set_fullname(sampass, fullname, PDB_SET);
1173 if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDrive", dir_drive)) {
1174 pdb_set_dir_drive(sampass, talloc_sub_specified(sampass->mem_ctx,
1180 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1183 if (!get_single_attribute(ldap_state->ldap_struct, entry, "smbHome", homedir)) {
1184 pdb_set_homedir(sampass, talloc_sub_specified(sampass->mem_ctx,
1190 pdb_set_homedir(sampass, homedir, PDB_SET);
1193 if (!get_single_attribute(ldap_state->ldap_struct, entry, "scriptPath", logon_script)) {
1194 pdb_set_logon_script(sampass, talloc_sub_specified(sampass->mem_ctx,
1200 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1203 if (!get_single_attribute(ldap_state->ldap_struct, entry, "profilePath", profile_path)) {
1204 pdb_set_profile_path(sampass, talloc_sub_specified(sampass->mem_ctx,
1210 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1213 if (!get_single_attribute(ldap_state->ldap_struct, entry, "description", acct_desc)) {
1214 /* leave as default */
1216 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1219 if (!get_single_attribute(ldap_state->ldap_struct, entry, "userWorkstations", workstations)) {
1220 /* leave as default */;
1222 pdb_set_workstations(sampass, workstations, PDB_SET);
1225 /* FIXME: hours stuff should be cleaner */
1229 memset(hours, 0xff, hours_len);
1231 if (!get_single_attribute (ldap_state->ldap_struct, entry, "lmPassword", temp)) {
1232 /* leave as default */
1234 pdb_gethexpwd(temp, smblmpwd);
1235 memset((char *)temp, '\0', strlen(temp)+1);
1236 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
1238 ZERO_STRUCT(smblmpwd);
1241 if (!get_single_attribute (ldap_state->ldap_struct, entry, "ntPassword", temp)) {
1242 /* leave as default */
1244 pdb_gethexpwd(temp, smbntpwd);
1245 memset((char *)temp, '\0', strlen(temp)+1);
1246 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
1248 ZERO_STRUCT(smbntpwd);
1251 if (!get_single_attribute (ldap_state->ldap_struct, entry, "acctFlags", temp)) {
1252 acct_ctrl |= ACB_NORMAL;
1254 acct_ctrl = pdb_decode_acct_ctrl(temp);
1257 acct_ctrl |= ACB_NORMAL;
1259 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1262 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1263 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1265 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1267 /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
1268 /* pdb_set_unknown_5(sampass, unknown5, PDB_SET); */
1269 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
1271 pdb_set_hours(sampass, hours, PDB_SET);
1276 /**********************************************************************
1277 An LDAP modification is needed in two cases:
1278 * If we are updating the record AND the attribute is CHANGED.
1279 * If we are adding the record AND it is SET or CHANGED (ie not default)
1280 *********************************************************************/
1281 static BOOL need_ldap_mod(BOOL pdb_add, const SAM_ACCOUNT * sampass, enum pdb_elements element) {
1283 return (!IS_SAM_DEFAULT(sampass, element));
1285 return IS_SAM_CHANGED(sampass, element);
1289 /**********************************************************************
1290 Set attribute to newval in LDAP, regardless of what value the
1291 attribute had in LDAP before.
1292 *********************************************************************/
1293 static void make_ldap_mod(LDAP *ldap_struct, LDAPMessage *existing,
1295 const SAM_ACCOUNT *sampass, BOOL pdb_add,
1296 enum pdb_elements element,
1297 const char *attribute, const char *newval)
1299 char **values = NULL;
1301 if (!need_ldap_mod(pdb_add, sampass, element)) {
1305 if (existing != NULL) {
1306 values = ldap_get_values(ldap_struct, existing, attribute);
1309 if ((values != NULL) && (values[0] != NULL) &&
1310 strcmp(values[0], newval) == 0) {
1312 /* Believe it or not, but LDAP will deny a delete and
1313 an add at the same time if the values are the
1316 ldap_value_free(values);
1320 /* Regardless of the real operation (add or modify)
1321 we add the new value here. We rely on deleting
1322 the old value, should it exist. */
1324 if ((newval != NULL) && (strlen(newval) > 0)) {
1325 make_a_mod(mods, LDAP_MOD_ADD, attribute, newval);
1328 if (values == NULL) {
1329 /* There has been no value before, so don't delete it.
1330 Here's a possible race: We might end up with
1331 duplicate attributes */
1335 /* By deleting exactly the value we found in the entry this
1336 should be race-free in the sense that the LDAP-Server will
1337 deny the complete operation if somebody changed the
1338 attribute behind our back. */
1340 make_a_mod(mods, LDAP_MOD_DELETE, attribute, values[0]);
1341 ldap_value_free(values);
1344 /**********************************************************************
1345 Initialize SAM_ACCOUNT from an LDAP query
1346 (Based on init_buffer_from_sam in pdb_tdb.c)
1347 *********************************************************************/
1348 static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
1349 LDAPMessage *existing,
1350 LDAPMod *** mods, const SAM_ACCOUNT * sampass,
1356 if (mods == NULL || sampass == NULL) {
1357 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
1364 * took out adding "objectclass: sambaAccount"
1365 * do this on a per-mod basis
1367 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1368 PDB_USERNAME, "uid", pdb_get_username(sampass));
1369 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
1371 rid = pdb_get_user_rid(sampass);
1374 if (!IS_SAM_DEFAULT(sampass, PDB_UID)) {
1375 rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass));
1376 } else if (ldap_state->permit_non_unix_accounts) {
1377 rid = ldapsam_get_next_available_nua_rid(ldap_state);
1379 DEBUG(0, ("NO user RID specified on account %s, and "
1380 "findining next available NUA RID failed, "
1382 pdb_get_username(sampass)));
1383 ldap_mods_free(*mods, 1);
1387 DEBUG(0, ("NO user RID specified on account %s, "
1388 "cannot store!\n", pdb_get_username(sampass)));
1389 ldap_mods_free(*mods, 1);
1394 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1395 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1396 PDB_USERSID, "rid", temp);
1399 rid = pdb_get_group_rid(sampass);
1402 if (!IS_SAM_DEFAULT(sampass, PDB_GID)) {
1403 rid = pdb_gid_to_group_rid(pdb_get_gid(sampass));
1404 } else if (ldap_state->permit_non_unix_accounts) {
1405 rid = DOMAIN_GROUP_RID_USERS;
1407 DEBUG(0, ("NO group RID specified on account %s, "
1408 "cannot store!\n", pdb_get_username(sampass)));
1409 ldap_mods_free(*mods, 1);
1414 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1415 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1416 PDB_GROUPSID, "primaryGroupID", temp);
1418 /* displayName, cn, and gecos should all be the same
1419 * most easily accomplished by giving them the same OID
1420 * gecos isn't set here b/c it should be handled by the
1422 * We change displayName only and fall back to cn if
1423 * it does not exist.
1426 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1427 PDB_FULLNAME, "displayName",
1428 pdb_get_fullname(sampass));
1430 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1431 PDB_ACCTDESC, "description",
1432 pdb_get_acct_desc(sampass));
1434 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1435 PDB_WORKSTATIONS, "userWorkstations",
1436 pdb_get_workstations(sampass));
1438 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1439 PDB_SMBHOME, "smbHome",
1440 pdb_get_homedir(sampass));
1442 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1443 PDB_DRIVE, "homeDrive",
1444 pdb_get_dir_drive(sampass));
1446 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1447 PDB_LOGONSCRIPT, "scriptPath",
1448 pdb_get_logon_script(sampass));
1450 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1451 PDB_PROFILE, "profilePath",
1452 pdb_get_profile_path(sampass));
1454 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
1455 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1456 PDB_LOGONTIME, "logonTime", temp);
1458 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
1459 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1460 PDB_LOGOFFTIME, "logoffTime", temp);
1462 slprintf (temp, sizeof (temp) - 1, "%li",
1463 pdb_get_kickoff_time(sampass));
1464 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1465 PDB_KICKOFFTIME, "kickoffTime", temp);
1467 slprintf (temp, sizeof (temp) - 1, "%li",
1468 pdb_get_pass_can_change_time(sampass));
1469 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1470 PDB_CANCHANGETIME, "pwdCanChange", temp);
1472 slprintf (temp, sizeof (temp) - 1, "%li",
1473 pdb_get_pass_must_change_time(sampass));
1474 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1475 PDB_MUSTCHANGETIME, "pwdMustChange", temp);
1477 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))||
1478 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
1480 pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass),
1481 pdb_get_acct_ctrl(sampass));
1482 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1483 PDB_LMPASSWD, "lmPassword", temp);
1485 pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass),
1486 pdb_get_acct_ctrl(sampass));
1487 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1488 PDB_NTPASSWD, "ntPassword", temp);
1490 slprintf (temp, sizeof (temp) - 1, "%li",
1491 pdb_get_pass_last_set_time(sampass));
1492 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1493 PDB_PASSLASTSET, "pwdLastSet", temp);
1496 /* FIXME: Hours stuff goes in LDAP */
1497 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass, pdb_add,
1498 PDB_ACCTCTRL, "acctFlags",
1499 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
1500 NEW_PW_FORMAT_SPACE_PADDED_LEN));
1505 /**********************************************************************
1506 Connect to LDAP server and find the next available RID.
1507 *********************************************************************/
1508 static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 top_rid)
1510 LDAPMessage *result;
1511 uint32 final_rid = (top_rid & (~USER_RID_TYPE)) + RID_MULTIPLIER;
1516 if (final_rid < ldap_state->low_nua_rid || final_rid > ldap_state->high_nua_rid) {
1520 if (ldapsam_search_one_user_by_rid(ldap_state, final_rid, &result) != LDAP_SUCCESS) {
1521 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid));
1525 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
1526 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid));
1527 ldap_msgfree(result);
1531 DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid, final_rid));
1532 ldap_msgfree(result);
1536 /**********************************************************************
1537 Extract the RID from an LDAP entry
1538 *********************************************************************/
1539 static uint32 entry_to_user_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry) {
1541 SAM_ACCOUNT *user = NULL;
1542 if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
1546 if (init_sam_from_ldap(ldap_state, user, entry)) {
1547 rid = pdb_get_user_rid(user);
1551 pdb_free_sam(&user);
1552 if (rid >= ldap_state->low_nua_rid && rid <= ldap_state->high_nua_rid) {
1559 /**********************************************************************
1560 Connect to LDAP server and find the next available RID.
1561 *********************************************************************/
1562 static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state)
1566 LDAPMessage *result;
1568 char *final_filter = NULL;
1573 pstrcpy(filter, lp_ldap_filter());
1574 all_string_sub(filter, "%u", "*", sizeof(pstring));
1577 asprintf(&final_filter, "(&(%s)(&(rid>=%d)(rid<=%d)))", filter, ldap_state->low_nua_rid, ldap_state->high_nua_rid);
1579 final_filter = strdup(filter);
1581 DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter));
1583 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1584 LDAP_SCOPE_SUBTREE, final_filter, attr, 0,
1587 if (rc != LDAP_SUCCESS) {
1588 DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc)));
1589 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1596 count = ldap_count_entries(ldap_state->ldap_struct, result);
1597 DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count));
1600 DEBUG(3, ("LDAP search returned no records, assuming no non-unix-accounts present!: %s\n", ldap_err2string(rc)));
1601 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1603 ldap_msgfree(result);
1605 return ldap_state->low_nua_rid;
1609 entry = ldap_first_entry(ldap_state->ldap_struct,result);
1611 top_rid = entry_to_user_rid(ldap_state, entry);
1613 while ((entry = ldap_next_entry(ldap_state->ldap_struct, entry))) {
1615 rid = entry_to_user_rid(ldap_state, entry);
1616 if (rid > top_rid) {
1621 ldap_msgfree(result);
1623 if (top_rid < ldap_state->low_nua_rid)
1624 top_rid = ldap_state->low_nua_rid;
1629 /**********************************************************************
1630 Connect to LDAP server and find the next available RID.
1631 *********************************************************************/
1632 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state) {
1633 uint32 next_nua_rid;
1636 top_nua_rid = search_top_nua_rid(ldap_state);
1638 next_nua_rid = check_nua_rid_is_avail(ldap_state,
1641 return next_nua_rid;
1644 /**********************************************************************
1645 Connect to LDAP server for password enumeration
1646 *********************************************************************/
1647 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
1649 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1653 pstrcpy(filter, lp_ldap_filter());
1654 all_string_sub(filter, "%u", "*", sizeof(pstring));
1656 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1657 LDAP_SCOPE_SUBTREE, filter, attr, 0,
1658 &ldap_state->result);
1660 if (rc != LDAP_SUCCESS) {
1661 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
1662 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1663 ldap_msgfree(ldap_state->result);
1664 ldap_state->result = NULL;
1665 return NT_STATUS_UNSUCCESSFUL;
1668 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
1669 ldap_count_entries(ldap_state->ldap_struct,
1670 ldap_state->result)));
1672 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
1673 ldap_state->result);
1674 ldap_state->index = 0;
1676 return NT_STATUS_OK;
1679 /**********************************************************************
1680 End enumeration of the LDAP password list
1681 *********************************************************************/
1682 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1684 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1685 if (ldap_state->result) {
1686 ldap_msgfree(ldap_state->result);
1687 ldap_state->result = NULL;
1691 /**********************************************************************
1692 Get the next entry in the LDAP password database
1693 *********************************************************************/
1694 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
1696 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1697 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1700 /* The rebind proc needs this *HACK*. We are not multithreaded, so
1701 this will work, but it's not nice. */
1702 static_ldap_state = ldap_state;
1705 if (!ldap_state->entry)
1708 ldap_state->index++;
1709 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
1711 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
1715 return NT_STATUS_OK;
1718 /**********************************************************************
1719 Get SAM_ACCOUNT entry from LDAP by username
1720 *********************************************************************/
1721 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
1723 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1724 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1725 LDAPMessage *result;
1729 if (ldapsam_search_one_user_by_name(ldap_state, sname, &result) != LDAP_SUCCESS) {
1730 return NT_STATUS_NO_SUCH_USER;
1733 count = ldap_count_entries(ldap_state->ldap_struct, result);
1737 ("We don't find this user [%s] count=%d\n", sname,
1739 return NT_STATUS_NO_SUCH_USER;
1740 } else if (count > 1) {
1742 ("Duplicate entries for this user [%s] Failing. count=%d\n", sname,
1744 return NT_STATUS_NO_SUCH_USER;
1747 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1749 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1750 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1751 ldap_msgfree(result);
1752 return NT_STATUS_NO_SUCH_USER;
1754 ldap_msgfree(result);
1757 ldap_msgfree(result);
1762 /**********************************************************************
1763 Get SAM_ACCOUNT entry from LDAP by rid
1764 *********************************************************************/
1765 static NTSTATUS ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
1767 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1768 struct ldapsam_privates *ldap_state =
1769 (struct ldapsam_privates *)my_methods->private_data;
1770 LDAPMessage *result;
1774 if (ldapsam_search_one_user_by_rid(ldap_state, rid, &result) != LDAP_SUCCESS) {
1775 return NT_STATUS_NO_SUCH_USER;
1778 count = ldap_count_entries(ldap_state->ldap_struct, result);
1782 ("We don't find this rid [%i] count=%d\n", rid,
1784 return NT_STATUS_NO_SUCH_USER;
1785 } else if (count > 1) {
1787 ("More than one user with rid [%i]. Failing. count=%d\n", rid,
1789 return NT_STATUS_NO_SUCH_USER;
1792 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1794 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1795 DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
1796 ldap_msgfree(result);
1797 return NT_STATUS_NO_SUCH_USER;
1799 ldap_msgfree(result);
1802 ldap_msgfree(result);
1807 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
1810 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
1811 return NT_STATUS_NO_SUCH_USER;
1812 return ldapsam_getsampwrid(my_methods, user, rid);
1815 /********************************************************************
1816 Do the actual modification - also change a plaittext passord if
1818 **********************************************************************/
1820 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1821 SAM_ACCOUNT *newpwd, char *dn,
1822 LDAPMod **mods, int ldap_op, BOOL pdb_add)
1824 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1827 if (!my_methods || !newpwd || !dn) {
1828 return NT_STATUS_INVALID_PARAMETER;
1832 DEBUG(5,("mods is empty: nothing to modify\n"));
1833 /* may be password change below however */
1838 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account");
1839 rc = ldapsam_add(ldap_state, dn, mods);
1841 case LDAP_MOD_REPLACE:
1842 rc = ldapsam_modify(ldap_state, dn ,mods);
1845 DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
1846 return NT_STATUS_UNSUCCESSFUL;
1849 if (rc!=LDAP_SUCCESS) {
1851 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1854 ("failed to %s user dn= %s with: %s\n\t%s\n",
1855 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
1856 dn, ldap_err2string(rc),
1859 return NT_STATUS_UNSUCCESSFUL;
1863 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
1864 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))&&
1865 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_OFF)&&
1866 need_ldap_mod(pdb_add, newpwd, PDB_PLAINTEXT_PW)&&
1867 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1871 struct berval *retdata;
1873 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1874 DEBUG(0,("ber_alloc_t returns NULL\n"));
1875 return NT_STATUS_UNSUCCESSFUL;
1877 ber_printf (ber, "{");
1878 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID,dn);
1879 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, pdb_get_plaintext_passwd(newpwd));
1880 ber_printf (ber, "N}");
1882 if ((rc = ber_flatten (ber, &bv))<0) {
1883 DEBUG(0,("ber_flatten returns a value <0\n"));
1884 return NT_STATUS_UNSUCCESSFUL;
1889 if ((rc = ldapsam_extended_operation(ldap_state, LDAP_EXOP_X_MODIFY_PASSWD,
1890 bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) {
1891 DEBUG(0,("LDAP Password could not be changed for user %s: %s\n",
1892 pdb_get_username(newpwd),ldap_err2string(rc)));
1894 DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1896 ber_bvfree(retdata);
1897 ber_memfree(retoid);
1902 DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n"));
1903 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */
1904 return NT_STATUS_OK;
1907 /**********************************************************************
1908 Delete entry from LDAP for username
1909 *********************************************************************/
1910 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
1912 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1915 LDAPMessage *result;
1917 const char *sam_user_attrs[] =
1918 { "lmPassword", "ntPassword", "pwdLastSet", "logonTime", "logoffTime",
1919 "kickoffTime", "pwdCanChange", "pwdMustChange", "acctFlags",
1920 "displayName", "smbHome", "homeDrive", "scriptPath", "profilePath",
1921 "userWorkstations", "primaryGroupID", "domain", "rid", NULL };
1924 DEBUG(0, ("sam_acct was NULL!\n"));
1925 return NT_STATUS_INVALID_PARAMETER;
1928 sname = pdb_get_username(sam_acct);
1930 DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
1932 rc = ldapsam_search_one_user_by_name(ldap_state, sname, &result);
1933 if (rc != LDAP_SUCCESS) {
1934 return NT_STATUS_NO_SUCH_USER;
1937 ret = ldapsam_delete_entry(ldap_state, result, "sambaAccount",
1939 ldap_msgfree(result);
1943 /**********************************************************************
1945 *********************************************************************/
1946 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1948 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1949 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1952 LDAPMessage *result;
1956 rc = ldapsam_search_one_user_by_name(ldap_state, pdb_get_username(newpwd), &result);
1957 if (rc != LDAP_SUCCESS) {
1958 return NT_STATUS_UNSUCCESSFUL;
1961 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
1962 DEBUG(0, ("No user to modify!\n"));
1963 ldap_msgfree(result);
1964 return NT_STATUS_UNSUCCESSFUL;
1967 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1968 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
1970 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd, False)) {
1971 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1972 ldap_msgfree(result);
1973 return NT_STATUS_UNSUCCESSFUL;
1976 ldap_msgfree(result);
1979 DEBUG(4,("mods is empty: nothing to update for user: %s\n",
1980 pdb_get_username(newpwd)));
1981 ldap_mods_free(mods, 1);
1982 return NT_STATUS_OK;
1985 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, False);
1986 ldap_mods_free(mods,1);
1988 if (NT_STATUS_IS_ERR(ret)) {
1989 DEBUG(0,("failed to modify user with uid = %s\n",
1990 pdb_get_username(newpwd)));
1994 DEBUG(2, ("successfully modified uid = %s in the LDAP database\n",
1995 pdb_get_username(newpwd)));
1996 return NT_STATUS_OK;
1999 /**********************************************************************
2000 Add SAM_ACCOUNT to LDAP
2001 *********************************************************************/
2002 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
2004 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2005 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2008 LDAPMessage *result = NULL;
2009 LDAPMessage *entry = NULL;
2011 LDAPMod **mods = NULL;
2015 const char *username = pdb_get_username(newpwd);
2016 if (!username || !*username) {
2017 DEBUG(0, ("Cannot add user without a username!\n"));
2018 return NT_STATUS_INVALID_PARAMETER;
2021 rc = ldapsam_search_one_user_by_name (ldap_state, username, &result);
2022 if (rc != LDAP_SUCCESS) {
2023 return NT_STATUS_UNSUCCESSFUL;
2026 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
2027 DEBUG(0,("User '%s' already in the base, with samba properties\n",
2029 ldap_msgfree(result);
2030 return NT_STATUS_UNSUCCESSFUL;
2032 ldap_msgfree(result);
2034 slprintf (filter, sizeof (filter) - 1, "uid=%s", username);
2035 rc = ldapsam_search_one_user(ldap_state, filter, &result);
2036 if (rc != LDAP_SUCCESS) {
2037 return NT_STATUS_UNSUCCESSFUL;
2040 num_result = ldap_count_entries(ldap_state->ldap_struct, result);
2042 if (num_result > 1) {
2043 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
2044 ldap_msgfree(result);
2045 return NT_STATUS_UNSUCCESSFUL;
2048 /* Check if we need to update an existing entry */
2049 if (num_result == 1) {
2052 DEBUG(3,("User exists without samba properties: adding them\n"));
2053 ldap_op = LDAP_MOD_REPLACE;
2054 entry = ldap_first_entry (ldap_state->ldap_struct, result);
2055 tmp = ldap_get_dn (ldap_state->ldap_struct, entry);
2056 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
2059 /* Check if we need to add an entry */
2060 DEBUG(3,("Adding new user\n"));
2061 ldap_op = LDAP_MOD_ADD;
2062 if (username[strlen(username)-1] == '$') {
2063 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
2065 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
2069 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd, True)) {
2070 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
2071 ldap_msgfree(result);
2072 ldap_mods_free(mods, 1);
2073 return NT_STATUS_UNSUCCESSFUL;
2076 ldap_msgfree(result);
2079 DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
2080 return NT_STATUS_UNSUCCESSFUL;
2083 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
2085 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, True);
2086 if (NT_STATUS_IS_ERR(ret)) {
2087 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
2088 pdb_get_username(newpwd),dn));
2089 ldap_mods_free(mods,1);
2093 DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd)));
2094 ldap_mods_free(mods, 1);
2095 return NT_STATUS_OK;
2098 static void free_private_data(void **vp)
2100 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
2102 ldapsam_close(*ldap_state);
2104 if ((*ldap_state)->bind_secret) {
2105 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
2108 ldapsam_close(*ldap_state);
2110 SAFE_FREE((*ldap_state)->bind_dn);
2111 SAFE_FREE((*ldap_state)->bind_secret);
2115 /* No need to free any further, as it is talloc()ed */
2118 static const char *group_attr[] = {"cn", "ntSid", "ntGroupType",
2120 "displayName", "description",
2123 static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
2125 LDAPMessage ** result)
2127 int scope = LDAP_SCOPE_SUBTREE;
2130 DEBUG(2, ("ldapsam_search_one_group: searching for:[%s]\n", filter));
2132 rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope,
2133 filter, group_attr, 0, result);
2135 if (rc != LDAP_SUCCESS) {
2136 DEBUG(0, ("ldapsam_search_one_group: "
2137 "Problem during the LDAP search: %s\n",
2138 ldap_err2string(rc)));
2139 DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
2140 lp_ldap_suffix(), filter));
2146 static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
2147 GROUP_MAP *map, LDAPMessage *entry)
2151 if (ldap_state == NULL || map == NULL || entry == NULL ||
2152 ldap_state->ldap_struct == NULL) {
2153 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
2157 if (!get_single_attribute(ldap_state->ldap_struct, entry, "gidNumber",
2159 DEBUG(0, ("Mandatory attribute gidNumber not found\n"));
2162 DEBUG(2, ("Entry found for group: %s\n", temp));
2164 map->gid = (gid_t)atol(temp);
2166 if (!get_single_attribute(ldap_state->ldap_struct, entry, "ntSid",
2168 DEBUG(0, ("Mandatory attribute ntSid not found\n"));
2171 string_to_sid(&map->sid, temp);
2173 if (!get_single_attribute(ldap_state->ldap_struct, entry, "ntGroupType",
2175 DEBUG(0, ("Mandatory attribute ntGroupType not found\n"));
2178 map->sid_name_use = (uint32)atol(temp);
2180 if ((map->sid_name_use < SID_NAME_USER) ||
2181 (map->sid_name_use > SID_NAME_UNKNOWN)) {
2182 DEBUG(0, ("Unknown Group type: %d\n", map->sid_name_use));
2186 if (!get_single_attribute(ldap_state->ldap_struct, entry, "displayName",
2188 DEBUG(3, ("Attribute displayName not found\n"));
2191 fstrcpy(map->nt_name, temp);
2193 if (!get_single_attribute(ldap_state->ldap_struct, entry, "description",
2195 DEBUG(3, ("Attribute description not found\n"));
2197 if (!get_single_attribute(ldap_state->ldap_struct, entry, "cn",
2199 DEBUG(0, ("Attributes cn not found either "
2200 "for gidNumber(%i)\n",map->gid));
2204 fstrcpy(map->comment, temp);
2206 map->systemaccount = 0;
2207 init_privilege(&map->priv_set);
2212 static BOOL init_ldap_from_group(struct ldapsam_privates *ldap_state,
2213 LDAPMod ***mods, int ldap_op,
2214 const GROUP_MAP *map)
2218 if (mods == NULL || map == NULL) {
2219 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
2225 sid_to_string(tmp, &map->sid);
2226 make_a_mod(mods, ldap_op, "ntSid", tmp);
2228 snprintf(tmp, sizeof(tmp)-1, "%i", map->sid_name_use);
2229 make_a_mod(mods, ldap_op, "ntGroupType", tmp);
2231 make_a_mod(mods, ldap_op, "displayName", map->nt_name);
2232 make_a_mod(mods, ldap_op, "description", map->comment);
2237 static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
2241 struct ldapsam_privates *ldap_state =
2242 (struct ldapsam_privates *)methods->private_data;
2243 LDAPMessage *result;
2247 if (ldapsam_search_one_group(ldap_state, filter, &result)
2249 return NT_STATUS_NO_SUCH_GROUP;
2252 count = ldap_count_entries(ldap_state->ldap_struct, result);
2255 DEBUG(4, ("Did not find group for filter %s\n", filter));
2256 return NT_STATUS_NO_SUCH_GROUP;
2260 DEBUG(1, ("Duplicate entries for filter %s: count=%d\n",
2262 return NT_STATUS_NO_SUCH_GROUP;
2265 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2268 ldap_msgfree(result);
2269 return NT_STATUS_UNSUCCESSFUL;
2272 if (!init_group_from_ldap(ldap_state, map, entry)) {
2273 DEBUG(1, ("init_group_from_ldap failed for group filter %s\n",
2275 ldap_msgfree(result);
2276 return NT_STATUS_NO_SUCH_GROUP;
2279 ldap_msgfree(result);
2280 return NT_STATUS_OK;
2283 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
2284 DOM_SID sid, BOOL with_priv)
2288 snprintf(filter, sizeof(filter)-1,
2289 "(&(objectClass=sambaGroupMapping)(ntSid=%s))",
2290 sid_string_static(&sid));
2292 return ldapsam_getgroup(methods, filter, map);
2295 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
2296 gid_t gid, BOOL with_priv)
2300 snprintf(filter, sizeof(filter)-1,
2301 "(&(objectClass=sambaGroupMapping)(gidNumber=%d))",
2304 return ldapsam_getgroup(methods, filter, map);
2307 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
2308 char *name, BOOL with_priv)
2312 /* TODO: Escaping of name? */
2314 snprintf(filter, sizeof(filter)-1,
2315 "(&(objectClass=sambaGroupMapping)(|(displayName=%s)(cn=%s)))",
2318 return ldapsam_getgroup(methods, filter, map);
2321 static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
2323 LDAPMessage **result)
2327 snprintf(filter, sizeof(filter)-1,
2328 "(&(objectClass=posixGroup)(gidNumber=%i))", gid);
2330 return ldapsam_search_one_group(ldap_state, filter, result);
2333 static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
2336 struct ldapsam_privates *ldap_state =
2337 (struct ldapsam_privates *)methods->private_data;
2338 LDAPMessage *result = NULL;
2339 LDAPMod **mods = NULL;
2349 if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
2350 map->gid, False))) {
2351 DEBUG(0, ("Group %i already exists in LDAP\n", map->gid));
2352 return NT_STATUS_UNSUCCESSFUL;
2355 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
2356 if (rc != LDAP_SUCCESS) {
2357 return NT_STATUS_UNSUCCESSFUL;
2360 if (ldap_count_entries(ldap_state->ldap_struct, result) != 1) {
2361 DEBUG(2, ("Group %i must exist exactly once in LDAP\n",
2363 ldap_msgfree(result);
2364 return NT_STATUS_UNSUCCESSFUL;
2367 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2368 tmp = ldap_get_dn(ldap_state->ldap_struct, entry);
2371 ldap_msgfree(result);
2373 if (!init_ldap_from_group(ldap_state, &mods, LDAP_MOD_ADD, map)) {
2374 DEBUG(0, ("init_ldap_from_group failed!\n"));
2375 ldap_mods_free(mods, 1);
2376 return NT_STATUS_UNSUCCESSFUL;
2380 DEBUG(0, ("mods is empty\n"));
2381 return NT_STATUS_UNSUCCESSFUL;
2384 make_a_mod(&mods, LDAP_MOD_ADD, "objectClass",
2385 "sambaGroupMapping");
2387 rc = ldapsam_modify(ldap_state, dn, mods);
2388 ldap_mods_free(mods, 1);
2390 if (rc != LDAP_SUCCESS) {
2391 DEBUG(0, ("failed to modify group %i\n", map->gid));
2392 return NT_STATUS_UNSUCCESSFUL;
2395 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
2396 return NT_STATUS_OK;
2399 static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
2402 struct ldapsam_privates *ldap_state =
2403 (struct ldapsam_privates *)methods->private_data;
2406 LDAPMessage *result;
2410 if (!init_ldap_from_group(ldap_state, &mods, LDAP_MOD_REPLACE, map)) {
2411 DEBUG(0, ("init_ldap_from_group failed\n"));
2412 return NT_STATUS_UNSUCCESSFUL;
2416 DEBUG(4, ("mods is empty: nothing to do\n"));
2417 return NT_STATUS_UNSUCCESSFUL;
2420 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
2422 if (rc != LDAP_SUCCESS) {
2423 ldap_mods_free(mods, 1);
2424 return NT_STATUS_UNSUCCESSFUL;
2427 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
2428 DEBUG(0, ("No group to modify!\n"));
2429 ldap_msgfree(result);
2430 ldap_mods_free(mods, 1);
2431 return NT_STATUS_UNSUCCESSFUL;
2434 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2435 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
2436 ldap_msgfree(result);
2438 rc = ldapsam_modify(ldap_state, dn, mods);
2440 ldap_mods_free(mods, 1);
2442 if (rc != LDAP_SUCCESS) {
2443 DEBUG(0, ("failed to modify group %i\n", map->gid));
2446 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
2447 return NT_STATUS_OK;
2450 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
2453 struct ldapsam_privates *ldap_state =
2454 (struct ldapsam_privates *)methods->private_data;
2455 pstring sidstring, filter;
2456 LDAPMessage *result;
2460 const char *sam_group_attrs[] = { "ntSid", "ntGroupType",
2461 "description", "displayName",
2463 sid_to_string(sidstring, &sid);
2464 snprintf(filter, sizeof(filter)-1,
2465 "(&(objectClass=sambaGroupMapping)(ntSid=%s))", sidstring);
2467 rc = ldapsam_search_one_group(ldap_state, filter, &result);
2469 if (rc != LDAP_SUCCESS) {
2470 return NT_STATUS_NO_SUCH_GROUP;
2473 ret = ldapsam_delete_entry(ldap_state, result, "sambaGroupMapping",
2475 ldap_msgfree(result);
2479 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
2482 struct ldapsam_privates *ldap_state =
2483 (struct ldapsam_privates *)my_methods->private_data;
2484 const char *filter = "(objectClass=sambaGroupMapping)";
2487 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
2488 LDAP_SCOPE_SUBTREE, filter,
2489 group_attr, 0, &ldap_state->result);
2491 if (rc != LDAP_SUCCESS) {
2492 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
2493 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
2494 ldap_msgfree(ldap_state->result);
2495 ldap_state->result = NULL;
2496 return NT_STATUS_UNSUCCESSFUL;
2499 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
2500 ldap_count_entries(ldap_state->ldap_struct,
2501 ldap_state->result)));
2503 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
2504 ldap_state->result);
2505 ldap_state->index = 0;
2507 return NT_STATUS_OK;
2510 static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
2512 ldapsam_endsampwent(my_methods);
2515 static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
2518 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2519 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2522 /* The rebind proc needs this *HACK*. We are not multithreaded, so
2523 this will work, but it's not nice. */
2524 static_ldap_state = ldap_state;
2527 if (!ldap_state->entry)
2530 ldap_state->index++;
2531 bret = init_group_from_ldap(ldap_state, map, ldap_state->entry);
2533 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
2537 return NT_STATUS_OK;
2540 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
2541 enum SID_NAME_USE sid_name_use,
2542 GROUP_MAP **rmap, int *num_entries,
2543 BOOL unix_only, BOOL with_priv)
2553 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
2554 DEBUG(0, ("Unable to open passdb\n"));
2555 return NT_STATUS_ACCESS_DENIED;
2558 while (NT_STATUS_IS_OK(nt_status = ldapsam_getsamgrent(methods, &map))) {
2559 if (sid_name_use != SID_NAME_UNKNOWN &&
2560 sid_name_use != map.sid_name_use) {
2561 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
2564 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
2565 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name));
2569 mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP));
2571 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
2573 return NT_STATUS_UNSUCCESSFUL;
2578 mapt[entries] = map;
2583 ldapsam_endsamgrent(methods);
2585 *num_entries = entries;
2587 return NT_STATUS_OK;
2590 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2593 struct ldapsam_privates *ldap_state;
2595 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
2599 (*pdb_method)->name = "ldapsam";
2601 (*pdb_method)->setsampwent = ldapsam_setsampwent;
2602 (*pdb_method)->endsampwent = ldapsam_endsampwent;
2603 (*pdb_method)->getsampwent = ldapsam_getsampwent;
2604 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
2605 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
2606 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
2607 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
2608 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
2610 (*pdb_method)->getgrsid = ldapsam_getgrsid;
2611 (*pdb_method)->getgrgid = ldapsam_getgrgid;
2612 (*pdb_method)->getgrnam = ldapsam_getgrnam;
2613 (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
2614 (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
2615 (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
2616 (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
2618 /* TODO: Setup private data and free */
2620 ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct ldapsam_privates));
2623 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
2624 return NT_STATUS_NO_MEMORY;
2628 ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
2629 #ifdef WITH_LDAP_SAMCONFIG
2631 int ldap_port = lp_ldap_port();
2633 /* remap default port if not using SSL (ie clear or TLS) */
2634 if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
2638 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);
2639 if (!ldap_state->uri) {
2640 return NT_STATUS_NO_MEMORY;
2644 ldap_state->uri = "ldap://localhost";
2648 (*pdb_method)->private_data = ldap_state;
2650 (*pdb_method)->free_private_data = free_private_data;
2652 return NT_STATUS_OK;
2655 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2658 struct ldapsam_privates *ldap_state;
2659 uint32 low_nua_uid, high_nua_uid;
2661 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) {
2665 (*pdb_method)->name = "ldapsam_nua";
2667 ldap_state = (*pdb_method)->private_data;
2669 ldap_state->permit_non_unix_accounts = True;
2671 if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) {
2672 DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n"));
2673 return NT_STATUS_UNSUCCESSFUL;
2676 ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid);
2678 ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid);
2680 return NT_STATUS_OK;
2683 int pdb_ldap_init(void)
2685 smb_register_passdb("ldapsam", pdb_init_ldapsam, PASSDB_INTERFACE_VERSION);
2686 smb_register_passdb("ldapsam_nua", pdb_init_ldapsam_nua, PASSDB_INTERFACE_VERSION);