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_del_only_sam
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_del_only_sam()) {
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 static BOOL need_ldap_mod(BOOL pdb_add, const SAM_ACCOUNT * sampass, enum pdb_elements element) {
1278 return (!IS_SAM_DEFAULT(sampass, element));
1280 return IS_SAM_CHANGED(sampass, element);
1284 /**********************************************************************
1285 Set attribute to newval in LDAP, regardless of what value the
1286 attribute had in LDAP before.
1287 *********************************************************************/
1288 static void make_ldap_mod(LDAP *ldap_struct, LDAPMessage *existing,
1290 const SAM_ACCOUNT *sampass,
1291 enum pdb_elements element,
1292 const char *attribute, const char *newval)
1294 char **values = NULL;
1296 if (!IS_SAM_CHANGED(sampass, element)) {
1300 if (existing != NULL) {
1301 values = ldap_get_values(ldap_struct, existing, attribute);
1304 if ((values != NULL) && (values[0] != NULL) &&
1305 strcmp(values[0], newval) == 0) {
1307 /* Believe it or not, but LDAP will deny a delete and
1308 an add at the same time if the values are the
1311 ldap_value_free(values);
1315 /* Regardless of the real operation (add or modify)
1316 we add the new value here. We rely on deleting
1317 the old value, should it exist. */
1319 if ((newval != NULL) && (strlen(newval) > 0)) {
1320 make_a_mod(mods, LDAP_MOD_ADD, attribute, newval);
1323 if (values == NULL) {
1324 /* There has been no value before, so don't delete it.
1325 Here's a possible race: We might end up with
1326 duplicate attributes */
1330 /* By deleting exactly the value we found in the entry this
1331 should be race-free in the sense that the LDAP-Server will
1332 deny the complete operation if somebody changed the
1333 attribute behind our back. */
1335 make_a_mod(mods, LDAP_MOD_DELETE, attribute, values[0]);
1336 ldap_value_free(values);
1339 /**********************************************************************
1340 Initialize SAM_ACCOUNT from an LDAP query
1341 (Based on init_buffer_from_sam in pdb_tdb.c)
1342 *********************************************************************/
1343 static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
1344 LDAPMessage *existing,
1345 LDAPMod *** mods, const SAM_ACCOUNT * sampass)
1350 if (mods == NULL || sampass == NULL) {
1351 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
1358 * took out adding "objectclass: sambaAccount"
1359 * do this on a per-mod basis
1361 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1362 PDB_USERNAME, "uid", pdb_get_username(sampass));
1363 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
1365 rid = pdb_get_user_rid(sampass);
1368 if (!IS_SAM_DEFAULT(sampass, PDB_UID)) {
1369 rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass));
1370 } else if (ldap_state->permit_non_unix_accounts) {
1371 rid = ldapsam_get_next_available_nua_rid(ldap_state);
1373 DEBUG(0, ("NO user RID specified on account %s, and "
1374 "findining next available NUA RID failed, "
1376 pdb_get_username(sampass)));
1377 ldap_mods_free(*mods, 1);
1381 DEBUG(0, ("NO user RID specified on account %s, "
1382 "cannot store!\n", pdb_get_username(sampass)));
1383 ldap_mods_free(*mods, 1);
1388 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1389 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1390 PDB_USERSID, "rid", temp);
1393 rid = pdb_get_group_rid(sampass);
1396 if (!IS_SAM_DEFAULT(sampass, PDB_GID)) {
1397 rid = pdb_gid_to_group_rid(pdb_get_gid(sampass));
1398 } else if (ldap_state->permit_non_unix_accounts) {
1399 rid = DOMAIN_GROUP_RID_USERS;
1401 DEBUG(0, ("NO group RID specified on account %s, "
1402 "cannot store!\n", pdb_get_username(sampass)));
1403 ldap_mods_free(*mods, 1);
1408 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1409 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1410 PDB_GROUPSID, "primaryGroupID", temp);
1412 /* displayName, cn, and gecos should all be the same
1413 * most easily accomplished by giving them the same OID
1414 * gecos isn't set here b/c it should be handled by the
1416 * We change displayName only and fall back to cn if
1417 * it does not exist.
1420 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1421 PDB_FULLNAME, "displayName",
1422 pdb_get_fullname(sampass));
1424 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1425 PDB_ACCTDESC, "description",
1426 pdb_get_acct_desc(sampass));
1428 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1429 PDB_WORKSTATIONS, "userWorkstations",
1430 pdb_get_workstations(sampass));
1432 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1433 PDB_SMBHOME, "smbHome",
1434 pdb_get_homedir(sampass));
1436 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1437 PDB_DRIVE, "homeDrive",
1438 pdb_get_dir_drive(sampass));
1440 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1441 PDB_LOGONSCRIPT, "scriptPath",
1442 pdb_get_logon_script(sampass));
1444 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1445 PDB_PROFILE, "profilePath",
1446 pdb_get_profile_path(sampass));
1448 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
1449 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1450 PDB_LOGONTIME, "logonTime", temp);
1452 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
1453 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1454 PDB_LOGOFFTIME, "logoffTime", temp);
1456 slprintf (temp, sizeof (temp) - 1, "%li",
1457 pdb_get_kickoff_time(sampass));
1458 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1459 PDB_KICKOFFTIME, "kickoffTime", temp);
1461 slprintf (temp, sizeof (temp) - 1, "%li",
1462 pdb_get_pass_can_change_time(sampass));
1463 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1464 PDB_CANCHANGETIME, "pwdCanChange", temp);
1466 slprintf (temp, sizeof (temp) - 1, "%li",
1467 pdb_get_pass_must_change_time(sampass));
1468 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1469 PDB_MUSTCHANGETIME, "pwdMustChange", temp);
1471 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))||
1472 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
1474 pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass),
1475 pdb_get_acct_ctrl(sampass));
1476 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1477 PDB_LMPASSWD, "lmPassword", temp);
1479 pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass),
1480 pdb_get_acct_ctrl(sampass));
1481 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1482 PDB_NTPASSWD, "ntPassword", temp);
1484 slprintf (temp, sizeof (temp) - 1, "%li",
1485 pdb_get_pass_last_set_time(sampass));
1486 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1487 PDB_PASSLASTSET, "pwdLastSet", temp);
1490 /* FIXME: Hours stuff goes in LDAP */
1491 make_ldap_mod(ldap_state->ldap_struct, existing, mods, sampass,
1492 PDB_ACCTCTRL, "acctFlags",
1493 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
1494 NEW_PW_FORMAT_SPACE_PADDED_LEN));
1499 /**********************************************************************
1500 Connect to LDAP server and find the next available RID.
1501 *********************************************************************/
1502 static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 top_rid)
1504 LDAPMessage *result;
1505 uint32 final_rid = (top_rid & (~USER_RID_TYPE)) + RID_MULTIPLIER;
1510 if (final_rid < ldap_state->low_nua_rid || final_rid > ldap_state->high_nua_rid) {
1514 if (ldapsam_search_one_user_by_rid(ldap_state, final_rid, &result) != LDAP_SUCCESS) {
1515 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid));
1519 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
1520 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid));
1521 ldap_msgfree(result);
1525 DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid, final_rid));
1526 ldap_msgfree(result);
1530 /**********************************************************************
1531 Extract the RID from an LDAP entry
1532 *********************************************************************/
1533 static uint32 entry_to_user_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry) {
1535 SAM_ACCOUNT *user = NULL;
1536 if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
1540 if (init_sam_from_ldap(ldap_state, user, entry)) {
1541 rid = pdb_get_user_rid(user);
1545 pdb_free_sam(&user);
1546 if (rid >= ldap_state->low_nua_rid && rid <= ldap_state->high_nua_rid) {
1553 /**********************************************************************
1554 Connect to LDAP server and find the next available RID.
1555 *********************************************************************/
1556 static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state)
1560 LDAPMessage *result;
1562 char *final_filter = NULL;
1567 pstrcpy(filter, lp_ldap_filter());
1568 all_string_sub(filter, "%u", "*", sizeof(pstring));
1571 asprintf(&final_filter, "(&(%s)(&(rid>=%d)(rid<=%d)))", filter, ldap_state->low_nua_rid, ldap_state->high_nua_rid);
1573 final_filter = strdup(filter);
1575 DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter));
1577 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1578 LDAP_SCOPE_SUBTREE, final_filter, attr, 0,
1581 if (rc != LDAP_SUCCESS) {
1582 DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc)));
1583 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1590 count = ldap_count_entries(ldap_state->ldap_struct, result);
1591 DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count));
1594 DEBUG(3, ("LDAP search returned no records, assuming no non-unix-accounts present!: %s\n", ldap_err2string(rc)));
1595 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1597 ldap_msgfree(result);
1599 return ldap_state->low_nua_rid;
1603 entry = ldap_first_entry(ldap_state->ldap_struct,result);
1605 top_rid = entry_to_user_rid(ldap_state, entry);
1607 while ((entry = ldap_next_entry(ldap_state->ldap_struct, entry))) {
1609 rid = entry_to_user_rid(ldap_state, entry);
1610 if (rid > top_rid) {
1615 ldap_msgfree(result);
1617 if (top_rid < ldap_state->low_nua_rid)
1618 top_rid = ldap_state->low_nua_rid;
1623 /**********************************************************************
1624 Connect to LDAP server and find the next available RID.
1625 *********************************************************************/
1626 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state) {
1627 uint32 next_nua_rid;
1630 top_nua_rid = search_top_nua_rid(ldap_state);
1632 next_nua_rid = check_nua_rid_is_avail(ldap_state,
1635 return next_nua_rid;
1638 /**********************************************************************
1639 Connect to LDAP server for password enumeration
1640 *********************************************************************/
1641 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
1643 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1647 pstrcpy(filter, lp_ldap_filter());
1648 all_string_sub(filter, "%u", "*", sizeof(pstring));
1650 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1651 LDAP_SCOPE_SUBTREE, filter, attr, 0,
1652 &ldap_state->result);
1654 if (rc != LDAP_SUCCESS) {
1655 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
1656 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1657 ldap_msgfree(ldap_state->result);
1658 ldap_state->result = NULL;
1659 return NT_STATUS_UNSUCCESSFUL;
1662 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
1663 ldap_count_entries(ldap_state->ldap_struct,
1664 ldap_state->result)));
1666 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
1667 ldap_state->result);
1668 ldap_state->index = 0;
1670 return NT_STATUS_OK;
1673 /**********************************************************************
1674 End enumeration of the LDAP password list
1675 *********************************************************************/
1676 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1678 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1679 if (ldap_state->result) {
1680 ldap_msgfree(ldap_state->result);
1681 ldap_state->result = NULL;
1685 /**********************************************************************
1686 Get the next entry in the LDAP password database
1687 *********************************************************************/
1688 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
1690 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1691 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1694 /* The rebind proc needs this *HACK*. We are not multithreaded, so
1695 this will work, but it's not nice. */
1696 static_ldap_state = ldap_state;
1699 if (!ldap_state->entry)
1702 ldap_state->index++;
1703 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
1705 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
1709 return NT_STATUS_OK;
1712 /**********************************************************************
1713 Get SAM_ACCOUNT entry from LDAP by username
1714 *********************************************************************/
1715 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
1717 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1718 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1719 LDAPMessage *result;
1723 if (ldapsam_search_one_user_by_name(ldap_state, sname, &result) != LDAP_SUCCESS) {
1724 return NT_STATUS_NO_SUCH_USER;
1727 count = ldap_count_entries(ldap_state->ldap_struct, result);
1731 ("We don't find this user [%s] count=%d\n", sname,
1733 return NT_STATUS_NO_SUCH_USER;
1734 } else if (count > 1) {
1736 ("Duplicate entries for this user [%s] Failing. count=%d\n", sname,
1738 return NT_STATUS_NO_SUCH_USER;
1741 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1743 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1744 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1745 ldap_msgfree(result);
1746 return NT_STATUS_NO_SUCH_USER;
1748 ldap_msgfree(result);
1751 ldap_msgfree(result);
1756 /**********************************************************************
1757 Get SAM_ACCOUNT entry from LDAP by rid
1758 *********************************************************************/
1759 static NTSTATUS ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
1761 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1762 struct ldapsam_privates *ldap_state =
1763 (struct ldapsam_privates *)my_methods->private_data;
1764 LDAPMessage *result;
1768 if (ldapsam_search_one_user_by_rid(ldap_state, rid, &result) != LDAP_SUCCESS) {
1769 return NT_STATUS_NO_SUCH_USER;
1772 count = ldap_count_entries(ldap_state->ldap_struct, result);
1776 ("We don't find this rid [%i] count=%d\n", rid,
1778 return NT_STATUS_NO_SUCH_USER;
1779 } else if (count > 1) {
1781 ("More than one user with rid [%i]. Failing. count=%d\n", rid,
1783 return NT_STATUS_NO_SUCH_USER;
1786 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1788 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1789 DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
1790 ldap_msgfree(result);
1791 return NT_STATUS_NO_SUCH_USER;
1793 ldap_msgfree(result);
1796 ldap_msgfree(result);
1801 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
1804 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
1805 return NT_STATUS_NO_SUCH_USER;
1806 return ldapsam_getsampwrid(my_methods, user, rid);
1809 /********************************************************************
1810 Do the actual modification - also change a plaittext passord if
1812 **********************************************************************/
1814 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1815 SAM_ACCOUNT *newpwd, char *dn,
1816 LDAPMod **mods, int ldap_op, BOOL pdb_add)
1818 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1821 if (!my_methods || !newpwd || !dn) {
1822 return NT_STATUS_INVALID_PARAMETER;
1826 DEBUG(5,("mods is empty: nothing to modify\n"));
1827 /* may be password change below however */
1832 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account");
1833 rc = ldapsam_add(ldap_state, dn, mods);
1835 case LDAP_MOD_REPLACE:
1836 rc = ldapsam_modify(ldap_state, dn ,mods);
1839 DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
1840 return NT_STATUS_UNSUCCESSFUL;
1843 if (rc!=LDAP_SUCCESS) {
1845 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1848 ("failed to %s user dn= %s with: %s\n\t%s\n",
1849 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
1850 dn, ldap_err2string(rc),
1853 return NT_STATUS_UNSUCCESSFUL;
1857 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
1858 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))&&
1859 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_OFF)&&
1860 need_ldap_mod(pdb_add, newpwd, PDB_PLAINTEXT_PW)&&
1861 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1865 struct berval *retdata;
1867 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1868 DEBUG(0,("ber_alloc_t returns NULL\n"));
1869 return NT_STATUS_UNSUCCESSFUL;
1871 ber_printf (ber, "{");
1872 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID,dn);
1873 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, pdb_get_plaintext_passwd(newpwd));
1874 ber_printf (ber, "N}");
1876 if ((rc = ber_flatten (ber, &bv))<0) {
1877 DEBUG(0,("ber_flatten returns a value <0\n"));
1878 return NT_STATUS_UNSUCCESSFUL;
1883 if ((rc = ldapsam_extended_operation(ldap_state, LDAP_EXOP_X_MODIFY_PASSWD,
1884 bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) {
1885 DEBUG(0,("LDAP Password could not be changed for user %s: %s\n",
1886 pdb_get_username(newpwd),ldap_err2string(rc)));
1888 DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1890 ber_bvfree(retdata);
1891 ber_memfree(retoid);
1896 DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n"));
1897 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */
1898 return NT_STATUS_OK;
1901 /**********************************************************************
1902 Delete entry from LDAP for username
1903 *********************************************************************/
1904 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
1906 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1909 LDAPMessage *result;
1911 const char *sam_user_attrs[] =
1912 { "lmPassword", "ntPassword", "pwdLastSet", "logonTime", "logoffTime",
1913 "kickoffTime", "pwdCanChange", "pwdMustChange", "acctFlags",
1914 "displayName", "smbHome", "homeDrive", "scriptPath", "profilePath",
1915 "userWorkstations", "primaryGroupID", "domain", "rid", NULL };
1918 DEBUG(0, ("sam_acct was NULL!\n"));
1919 return NT_STATUS_INVALID_PARAMETER;
1922 sname = pdb_get_username(sam_acct);
1924 DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
1926 rc = ldapsam_search_one_user_by_name(ldap_state, sname, &result);
1927 if (rc != LDAP_SUCCESS) {
1928 return NT_STATUS_NO_SUCH_USER;
1931 ret = ldapsam_delete_entry(ldap_state, result, "sambaAccount",
1933 ldap_msgfree(result);
1937 /**********************************************************************
1939 *********************************************************************/
1940 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1942 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1943 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1946 LDAPMessage *result;
1950 rc = ldapsam_search_one_user_by_name(ldap_state, pdb_get_username(newpwd), &result);
1951 if (rc != LDAP_SUCCESS) {
1952 return NT_STATUS_UNSUCCESSFUL;
1955 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
1956 DEBUG(0, ("No user to modify!\n"));
1957 ldap_msgfree(result);
1958 return NT_STATUS_UNSUCCESSFUL;
1961 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1962 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
1964 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd)) {
1965 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1966 ldap_msgfree(result);
1967 return NT_STATUS_UNSUCCESSFUL;
1970 ldap_msgfree(result);
1973 DEBUG(4,("mods is empty: nothing to update for user: %s\n",
1974 pdb_get_username(newpwd)));
1975 ldap_mods_free(mods, 1);
1976 return NT_STATUS_OK;
1979 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, False);
1980 ldap_mods_free(mods,1);
1982 if (NT_STATUS_IS_ERR(ret)) {
1983 DEBUG(0,("failed to modify user with uid = %s\n",
1984 pdb_get_username(newpwd)));
1988 DEBUG(2, ("successfully modified uid = %s in the LDAP database\n",
1989 pdb_get_username(newpwd)));
1990 return NT_STATUS_OK;
1993 /**********************************************************************
1994 Add SAM_ACCOUNT to LDAP
1995 *********************************************************************/
1996 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1998 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1999 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2002 LDAPMessage *result = NULL;
2003 LDAPMessage *entry = NULL;
2005 LDAPMod **mods = NULL;
2009 const char *username = pdb_get_username(newpwd);
2010 if (!username || !*username) {
2011 DEBUG(0, ("Cannot add user without a username!\n"));
2012 return NT_STATUS_INVALID_PARAMETER;
2015 rc = ldapsam_search_one_user_by_name (ldap_state, username, &result);
2016 if (rc != LDAP_SUCCESS) {
2017 return NT_STATUS_UNSUCCESSFUL;
2020 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
2021 DEBUG(0,("User '%s' already in the base, with samba properties\n",
2023 ldap_msgfree(result);
2024 return NT_STATUS_UNSUCCESSFUL;
2026 ldap_msgfree(result);
2028 slprintf (filter, sizeof (filter) - 1, "uid=%s", username);
2029 rc = ldapsam_search_one_user(ldap_state, filter, &result);
2030 if (rc != LDAP_SUCCESS) {
2031 return NT_STATUS_UNSUCCESSFUL;
2034 num_result = ldap_count_entries(ldap_state->ldap_struct, result);
2036 if (num_result > 1) {
2037 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
2038 ldap_msgfree(result);
2039 return NT_STATUS_UNSUCCESSFUL;
2042 /* Check if we need to update an existing entry */
2043 if (num_result == 1) {
2046 DEBUG(3,("User exists without samba properties: adding them\n"));
2047 ldap_op = LDAP_MOD_REPLACE;
2048 entry = ldap_first_entry (ldap_state->ldap_struct, result);
2049 tmp = ldap_get_dn (ldap_state->ldap_struct, entry);
2050 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
2053 /* Check if we need to add an entry */
2054 DEBUG(3,("Adding new user\n"));
2055 ldap_op = LDAP_MOD_ADD;
2056 if (username[strlen(username)-1] == '$') {
2057 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
2059 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
2063 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd)) {
2064 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
2065 ldap_msgfree(result);
2066 ldap_mods_free(mods, 1);
2067 return NT_STATUS_UNSUCCESSFUL;
2070 ldap_msgfree(result);
2073 DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
2074 return NT_STATUS_UNSUCCESSFUL;
2077 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
2079 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, True);
2080 if (NT_STATUS_IS_ERR(ret)) {
2081 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
2082 pdb_get_username(newpwd),dn));
2083 ldap_mods_free(mods,1);
2087 DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd)));
2088 ldap_mods_free(mods, 1);
2089 return NT_STATUS_OK;
2092 static void free_private_data(void **vp)
2094 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
2096 ldapsam_close(*ldap_state);
2098 if ((*ldap_state)->bind_secret) {
2099 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
2102 ldapsam_close(*ldap_state);
2104 SAFE_FREE((*ldap_state)->bind_dn);
2105 SAFE_FREE((*ldap_state)->bind_secret);
2109 /* No need to free any further, as it is talloc()ed */
2112 static const char *group_attr[] = {"cn", "ntSid", "ntGroupType",
2114 "displayName", "description",
2117 static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
2119 LDAPMessage ** result)
2121 int scope = LDAP_SCOPE_SUBTREE;
2124 DEBUG(2, ("ldapsam_search_one_group: searching for:[%s]\n", filter));
2126 rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope,
2127 filter, group_attr, 0, result);
2129 if (rc != LDAP_SUCCESS) {
2130 DEBUG(0, ("ldapsam_search_one_group: "
2131 "Problem during the LDAP search: %s\n",
2132 ldap_err2string(rc)));
2133 DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
2134 lp_ldap_suffix(), filter));
2140 static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
2141 GROUP_MAP *map, LDAPMessage *entry)
2145 if (ldap_state == NULL || map == NULL || entry == NULL ||
2146 ldap_state->ldap_struct == NULL) {
2147 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
2151 if (!get_single_attribute(ldap_state->ldap_struct, entry, "gidNumber",
2153 DEBUG(0, ("Mandatory attribute gidNumber not found\n"));
2156 DEBUG(2, ("Entry found for group: %s\n", temp));
2158 map->gid = (gid_t)atol(temp);
2160 if (!get_single_attribute(ldap_state->ldap_struct, entry, "ntSid",
2162 DEBUG(0, ("Mandatory attribute ntSid not found\n"));
2165 string_to_sid(&map->sid, temp);
2167 if (!get_single_attribute(ldap_state->ldap_struct, entry, "ntGroupType",
2169 DEBUG(0, ("Mandatory attribute ntGroupType not found\n"));
2172 map->sid_name_use = (uint32)atol(temp);
2174 if ((map->sid_name_use < SID_NAME_USER) ||
2175 (map->sid_name_use > SID_NAME_UNKNOWN)) {
2176 DEBUG(0, ("Unknown Group type: %d\n", map->sid_name_use));
2180 if (!get_single_attribute(ldap_state->ldap_struct, entry, "displayName",
2182 DEBUG(3, ("Attribute displayName not found\n"));
2185 fstrcpy(map->nt_name, temp);
2187 if (!get_single_attribute(ldap_state->ldap_struct, entry, "description",
2189 DEBUG(3, ("Attribute description not found\n"));
2191 if (!get_single_attribute(ldap_state->ldap_struct, entry, "cn",
2193 DEBUG(0, ("Attributes cn not found either "
2194 "for gidNumber(%i)\n",map->gid));
2198 fstrcpy(map->comment, temp);
2200 map->systemaccount = 0;
2201 init_privilege(&map->priv_set);
2206 static BOOL init_ldap_from_group(struct ldapsam_privates *ldap_state,
2207 LDAPMod ***mods, int ldap_op,
2208 const GROUP_MAP *map)
2212 if (mods == NULL || map == NULL) {
2213 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
2219 sid_to_string(tmp, &map->sid);
2220 make_a_mod(mods, ldap_op, "ntSid", tmp);
2222 snprintf(tmp, sizeof(tmp)-1, "%i", map->sid_name_use);
2223 make_a_mod(mods, ldap_op, "ntGroupType", tmp);
2225 make_a_mod(mods, ldap_op, "displayName", map->nt_name);
2226 make_a_mod(mods, ldap_op, "description", map->comment);
2231 static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
2235 struct ldapsam_privates *ldap_state =
2236 (struct ldapsam_privates *)methods->private_data;
2237 LDAPMessage *result;
2241 if (ldapsam_search_one_group(ldap_state, filter, &result)
2243 return NT_STATUS_NO_SUCH_GROUP;
2246 count = ldap_count_entries(ldap_state->ldap_struct, result);
2249 DEBUG(4, ("Did not find group for filter %s\n", filter));
2250 return NT_STATUS_NO_SUCH_GROUP;
2254 DEBUG(1, ("Duplicate entries for filter %s: count=%d\n",
2256 return NT_STATUS_NO_SUCH_GROUP;
2259 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2262 ldap_msgfree(result);
2263 return NT_STATUS_UNSUCCESSFUL;
2266 if (!init_group_from_ldap(ldap_state, map, entry)) {
2267 DEBUG(1, ("init_group_from_ldap failed for group filter %s\n",
2269 ldap_msgfree(result);
2270 return NT_STATUS_NO_SUCH_GROUP;
2273 ldap_msgfree(result);
2274 return NT_STATUS_OK;
2277 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
2278 DOM_SID sid, BOOL with_priv)
2282 snprintf(filter, sizeof(filter)-1,
2283 "(&(objectClass=sambaGroupMapping)(ntSid=%s))",
2284 sid_string_static(&sid));
2286 return ldapsam_getgroup(methods, filter, map);
2289 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
2290 gid_t gid, BOOL with_priv)
2294 snprintf(filter, sizeof(filter)-1,
2295 "(&(objectClass=sambaGroupMapping)(gidNumber=%d))",
2298 return ldapsam_getgroup(methods, filter, map);
2301 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
2302 char *name, BOOL with_priv)
2306 /* TODO: Escaping of name? */
2308 snprintf(filter, sizeof(filter)-1,
2309 "(&(objectClass=sambaGroupMapping)(|(displayName=%s)(cn=%s)))",
2312 return ldapsam_getgroup(methods, filter, map);
2315 static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
2317 LDAPMessage **result)
2321 snprintf(filter, sizeof(filter)-1,
2322 "(&(objectClass=posixGroup)(gidNumber=%i))", gid);
2324 return ldapsam_search_one_group(ldap_state, filter, result);
2327 static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
2330 struct ldapsam_privates *ldap_state =
2331 (struct ldapsam_privates *)methods->private_data;
2332 LDAPMessage *result = NULL;
2333 LDAPMod **mods = NULL;
2343 if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
2344 map->gid, False))) {
2345 DEBUG(0, ("Group %i already exists in LDAP\n", map->gid));
2346 return NT_STATUS_UNSUCCESSFUL;
2349 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
2350 if (rc != LDAP_SUCCESS) {
2351 return NT_STATUS_UNSUCCESSFUL;
2354 if (ldap_count_entries(ldap_state->ldap_struct, result) != 1) {
2355 DEBUG(2, ("Group %i must exist exactly once in LDAP\n",
2357 ldap_msgfree(result);
2358 return NT_STATUS_UNSUCCESSFUL;
2361 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2362 tmp = ldap_get_dn(ldap_state->ldap_struct, entry);
2365 ldap_msgfree(result);
2367 if (!init_ldap_from_group(ldap_state, &mods, LDAP_MOD_ADD, map)) {
2368 DEBUG(0, ("init_ldap_from_group failed!\n"));
2369 ldap_mods_free(mods, 1);
2370 return NT_STATUS_UNSUCCESSFUL;
2374 DEBUG(0, ("mods is empty\n"));
2375 return NT_STATUS_UNSUCCESSFUL;
2378 make_a_mod(&mods, LDAP_MOD_ADD, "objectClass",
2379 "sambaGroupMapping");
2381 rc = ldapsam_modify(ldap_state, dn, mods);
2382 ldap_mods_free(mods, 1);
2384 if (rc != LDAP_SUCCESS) {
2385 DEBUG(0, ("failed to modify group %i\n", map->gid));
2386 return NT_STATUS_UNSUCCESSFUL;
2389 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
2390 return NT_STATUS_OK;
2393 static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
2396 struct ldapsam_privates *ldap_state =
2397 (struct ldapsam_privates *)methods->private_data;
2400 LDAPMessage *result;
2404 if (!init_ldap_from_group(ldap_state, &mods, LDAP_MOD_REPLACE, map)) {
2405 DEBUG(0, ("init_ldap_from_group failed\n"));
2406 return NT_STATUS_UNSUCCESSFUL;
2410 DEBUG(4, ("mods is empty: nothing to do\n"));
2411 return NT_STATUS_UNSUCCESSFUL;
2414 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
2416 if (rc != LDAP_SUCCESS) {
2417 ldap_mods_free(mods, 1);
2418 return NT_STATUS_UNSUCCESSFUL;
2421 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
2422 DEBUG(0, ("No group to modify!\n"));
2423 ldap_msgfree(result);
2424 ldap_mods_free(mods, 1);
2425 return NT_STATUS_UNSUCCESSFUL;
2428 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2429 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
2430 ldap_msgfree(result);
2432 rc = ldapsam_modify(ldap_state, dn, mods);
2434 ldap_mods_free(mods, 1);
2436 if (rc != LDAP_SUCCESS) {
2437 DEBUG(0, ("failed to modify group %i\n", map->gid));
2440 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
2441 return NT_STATUS_OK;
2444 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
2447 struct ldapsam_privates *ldap_state =
2448 (struct ldapsam_privates *)methods->private_data;
2449 pstring sidstring, filter;
2450 LDAPMessage *result;
2454 const char *sam_group_attrs[] = { "ntSid", "ntGroupType",
2455 "description", "displayName",
2457 sid_to_string(sidstring, &sid);
2458 snprintf(filter, sizeof(filter)-1,
2459 "(&(objectClass=sambaGroupMapping)(ntSid=%s))", sidstring);
2461 rc = ldapsam_search_one_group(ldap_state, filter, &result);
2463 if (rc != LDAP_SUCCESS) {
2464 return NT_STATUS_NO_SUCH_GROUP;
2467 ret = ldapsam_delete_entry(ldap_state, result, "sambaGroupMapping",
2469 ldap_msgfree(result);
2473 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
2476 struct ldapsam_privates *ldap_state =
2477 (struct ldapsam_privates *)my_methods->private_data;
2478 const char *filter = "(objectClass=sambaGroupMapping)";
2481 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
2482 LDAP_SCOPE_SUBTREE, filter,
2483 group_attr, 0, &ldap_state->result);
2485 if (rc != LDAP_SUCCESS) {
2486 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
2487 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
2488 ldap_msgfree(ldap_state->result);
2489 ldap_state->result = NULL;
2490 return NT_STATUS_UNSUCCESSFUL;
2493 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
2494 ldap_count_entries(ldap_state->ldap_struct,
2495 ldap_state->result)));
2497 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
2498 ldap_state->result);
2499 ldap_state->index = 0;
2501 return NT_STATUS_OK;
2504 static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
2506 ldapsam_endsampwent(my_methods);
2509 static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
2512 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2513 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2516 /* The rebind proc needs this *HACK*. We are not multithreaded, so
2517 this will work, but it's not nice. */
2518 static_ldap_state = ldap_state;
2521 if (!ldap_state->entry)
2524 ldap_state->index++;
2525 bret = init_group_from_ldap(ldap_state, map, ldap_state->entry);
2527 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
2531 return NT_STATUS_OK;
2534 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
2535 enum SID_NAME_USE sid_name_use,
2536 GROUP_MAP **rmap, int *num_entries,
2537 BOOL unix_only, BOOL with_priv)
2547 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
2548 DEBUG(0, ("Unable to open passdb\n"));
2549 return NT_STATUS_ACCESS_DENIED;
2552 while (NT_STATUS_IS_OK(nt_status = ldapsam_getsamgrent(methods, &map))) {
2553 if (sid_name_use != SID_NAME_UNKNOWN &&
2554 sid_name_use != map.sid_name_use) {
2555 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
2558 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
2559 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name));
2563 mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP));
2565 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
2567 return NT_STATUS_UNSUCCESSFUL;
2572 mapt[entries] = map;
2577 ldapsam_endsamgrent(methods);
2579 *num_entries = entries;
2581 return NT_STATUS_OK;
2584 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2587 struct ldapsam_privates *ldap_state;
2589 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
2593 (*pdb_method)->name = "ldapsam";
2595 (*pdb_method)->setsampwent = ldapsam_setsampwent;
2596 (*pdb_method)->endsampwent = ldapsam_endsampwent;
2597 (*pdb_method)->getsampwent = ldapsam_getsampwent;
2598 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
2599 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
2600 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
2601 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
2602 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
2604 (*pdb_method)->getgrsid = ldapsam_getgrsid;
2605 (*pdb_method)->getgrgid = ldapsam_getgrgid;
2606 (*pdb_method)->getgrnam = ldapsam_getgrnam;
2607 (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
2608 (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
2609 (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
2610 (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
2612 /* TODO: Setup private data and free */
2614 ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct ldapsam_privates));
2617 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
2618 return NT_STATUS_NO_MEMORY;
2622 ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
2623 #ifdef WITH_LDAP_SAMCONFIG
2625 int ldap_port = lp_ldap_port();
2627 /* remap default port if not using SSL (ie clear or TLS) */
2628 if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
2632 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);
2633 if (!ldap_state->uri) {
2634 return NT_STATUS_NO_MEMORY;
2638 ldap_state->uri = "ldap://localhost";
2642 (*pdb_method)->private_data = ldap_state;
2644 (*pdb_method)->free_private_data = free_private_data;
2646 return NT_STATUS_OK;
2649 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2652 struct ldapsam_privates *ldap_state;
2653 uint32 low_nua_uid, high_nua_uid;
2655 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) {
2659 (*pdb_method)->name = "ldapsam_nua";
2661 ldap_state = (*pdb_method)->private_data;
2663 ldap_state->permit_non_unix_accounts = True;
2665 if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) {
2666 DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n"));
2667 return NT_STATUS_UNSUCCESSFUL;
2670 ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid);
2672 ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid);
2674 return NT_STATUS_OK;
2677 int pdb_ldap_init(void)
2679 smb_register_passdb("ldapsam", pdb_init_ldapsam, PASSDB_INTERFACE_VERSION);
2680 smb_register_passdb("ldapsam_nua", pdb_init_ldapsam_nua, PASSDB_INTERFACE_VERSION);