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, "cn", fullname)) {
1162 if (!get_single_attribute(ldap_state->ldap_struct, entry, "displayName", fullname)) {
1163 /* leave as default */
1165 pdb_set_fullname(sampass, fullname, PDB_SET);
1168 pdb_set_fullname(sampass, fullname, PDB_SET);
1171 if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDrive", dir_drive)) {
1172 pdb_set_dir_drive(sampass, talloc_sub_specified(sampass->mem_ctx,
1178 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1181 if (!get_single_attribute(ldap_state->ldap_struct, entry, "smbHome", homedir)) {
1182 pdb_set_homedir(sampass, talloc_sub_specified(sampass->mem_ctx,
1188 pdb_set_homedir(sampass, homedir, PDB_SET);
1191 if (!get_single_attribute(ldap_state->ldap_struct, entry, "scriptPath", logon_script)) {
1192 pdb_set_logon_script(sampass, talloc_sub_specified(sampass->mem_ctx,
1198 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1201 if (!get_single_attribute(ldap_state->ldap_struct, entry, "profilePath", profile_path)) {
1202 pdb_set_profile_path(sampass, talloc_sub_specified(sampass->mem_ctx,
1208 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1211 if (!get_single_attribute(ldap_state->ldap_struct, entry, "description", acct_desc)) {
1212 /* leave as default */
1214 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1217 if (!get_single_attribute(ldap_state->ldap_struct, entry, "userWorkstations", workstations)) {
1218 /* leave as default */;
1220 pdb_set_workstations(sampass, workstations, PDB_SET);
1223 /* FIXME: hours stuff should be cleaner */
1227 memset(hours, 0xff, hours_len);
1229 if (!get_single_attribute (ldap_state->ldap_struct, entry, "lmPassword", temp)) {
1230 /* leave as default */
1232 pdb_gethexpwd(temp, smblmpwd);
1233 memset((char *)temp, '\0', strlen(temp)+1);
1234 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
1236 ZERO_STRUCT(smblmpwd);
1239 if (!get_single_attribute (ldap_state->ldap_struct, entry, "ntPassword", temp)) {
1240 /* leave as default */
1242 pdb_gethexpwd(temp, smbntpwd);
1243 memset((char *)temp, '\0', strlen(temp)+1);
1244 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
1246 ZERO_STRUCT(smbntpwd);
1249 if (!get_single_attribute (ldap_state->ldap_struct, entry, "acctFlags", temp)) {
1250 acct_ctrl |= ACB_NORMAL;
1252 acct_ctrl = pdb_decode_acct_ctrl(temp);
1255 acct_ctrl |= ACB_NORMAL;
1257 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1260 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1261 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1263 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1265 /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
1266 /* pdb_set_unknown_5(sampass, unknown5, PDB_SET); */
1267 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
1269 pdb_set_hours(sampass, hours, PDB_SET);
1274 static BOOL need_ldap_mod(BOOL pdb_add, const SAM_ACCOUNT * sampass, enum pdb_elements element) {
1276 return (!IS_SAM_DEFAULT(sampass, element));
1278 return IS_SAM_CHANGED(sampass, element);
1282 /**********************************************************************
1283 Initialize SAM_ACCOUNT from an LDAP query
1284 (Based on init_buffer_from_sam in pdb_tdb.c)
1285 *********************************************************************/
1286 static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
1287 LDAPMod *** mods, int ldap_op,
1289 const SAM_ACCOUNT * sampass)
1294 if (mods == NULL || sampass == NULL) {
1295 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
1302 * took out adding "objectclass: sambaAccount"
1303 * do this on a per-mod basis
1305 if (need_ldap_mod(pdb_add, sampass, PDB_USERNAME)) {
1306 make_a_mod(mods, ldap_op, "uid", pdb_get_username(sampass));
1307 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
1310 if ((rid = pdb_get_user_rid(sampass))!=0 ) {
1311 if (need_ldap_mod(pdb_add, sampass, PDB_USERSID)) {
1312 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1313 make_a_mod(mods, ldap_op, "rid", temp);
1315 } else if (!IS_SAM_DEFAULT(sampass, PDB_UID)) {
1316 rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass));
1317 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1318 make_a_mod(mods, ldap_op, "rid", temp);
1319 } else if (ldap_state->permit_non_unix_accounts) {
1320 rid = ldapsam_get_next_available_nua_rid(ldap_state);
1322 DEBUG(0, ("NO user RID specified on account %s, and findining next available NUA RID failed, cannot store!\n", pdb_get_username(sampass)));
1325 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1326 make_a_mod(mods, ldap_op, "rid", temp);
1328 DEBUG(0, ("NO user RID specified on account %s, cannot store!\n", pdb_get_username(sampass)));
1334 if ((rid = pdb_get_group_rid(sampass))!=0 ) {
1335 if (need_ldap_mod(pdb_add, sampass, PDB_GROUPSID)) {
1336 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1337 make_a_mod(mods, ldap_op, "primaryGroupID", temp);
1339 } else if (!IS_SAM_DEFAULT(sampass, PDB_GID)) {
1340 rid = pdb_gid_to_group_rid(pdb_get_gid(sampass));
1341 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1342 make_a_mod(mods, ldap_op, "primaryGroupID", temp);
1343 } else if (ldap_state->permit_non_unix_accounts) {
1344 rid = DOMAIN_GROUP_RID_USERS;
1345 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1346 make_a_mod(mods, ldap_op, "primaryGroupID", temp);
1348 DEBUG(0, ("NO group RID specified on account %s, cannot store!\n", pdb_get_username(sampass)));
1353 /* displayName, cn, and gecos should all be the same
1354 * most easily accomplished by giving them the same OID
1355 * gecos isn't set here b/c it should be handled by the
1358 if (need_ldap_mod(pdb_add, sampass, PDB_FULLNAME)) {
1359 make_a_mod(mods, ldap_op, "displayName", pdb_get_fullname(sampass));
1360 make_a_mod(mods, ldap_op, "cn", pdb_get_fullname(sampass));
1362 if (need_ldap_mod(pdb_add, sampass, PDB_ACCTDESC)) {
1363 make_a_mod(mods, ldap_op, "description", pdb_get_acct_desc(sampass));
1365 if (need_ldap_mod(pdb_add, sampass, PDB_WORKSTATIONS)) {
1366 make_a_mod(mods, ldap_op, "userWorkstations", pdb_get_workstations(sampass));
1369 * Only updates fields which have been set (not defaults from smb.conf)
1372 if (need_ldap_mod(pdb_add, sampass, PDB_SMBHOME)) {
1373 make_a_mod(mods, ldap_op, "smbHome", pdb_get_homedir(sampass));
1376 if (need_ldap_mod(pdb_add, sampass, PDB_DRIVE)) {
1377 make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dir_drive(sampass));
1380 if (need_ldap_mod(pdb_add, sampass, PDB_LOGONSCRIPT)) {
1381 make_a_mod(mods, ldap_op, "scriptPath", pdb_get_logon_script(sampass));
1384 if (need_ldap_mod(pdb_add, sampass, PDB_PROFILE))
1385 make_a_mod(mods, ldap_op, "profilePath", pdb_get_profile_path(sampass));
1387 if (need_ldap_mod(pdb_add, sampass, PDB_LOGONTIME)) {
1388 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
1389 make_a_mod(mods, ldap_op, "logonTime", temp);
1392 if (need_ldap_mod(pdb_add, sampass, PDB_LOGOFFTIME)) {
1393 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
1394 make_a_mod(mods, ldap_op, "logoffTime", temp);
1397 if (need_ldap_mod(pdb_add, sampass, PDB_KICKOFFTIME)) {
1398 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
1399 make_a_mod(mods, ldap_op, "kickoffTime", temp);
1403 if (need_ldap_mod(pdb_add, sampass, PDB_CANCHANGETIME)) {
1404 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
1405 make_a_mod(mods, ldap_op, "pwdCanChange", temp);
1408 if (need_ldap_mod(pdb_add, sampass, PDB_MUSTCHANGETIME)) {
1409 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
1410 make_a_mod(mods, ldap_op, "pwdMustChange", temp);
1413 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))||
1414 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
1416 if (need_ldap_mod(pdb_add, sampass, PDB_LMPASSWD)) {
1417 pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass));
1418 make_a_mod (mods, ldap_op, "lmPassword", temp);
1421 if (need_ldap_mod(pdb_add, sampass, PDB_NTPASSWD)) {
1422 pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass));
1423 make_a_mod (mods, ldap_op, "ntPassword", temp);
1426 if (need_ldap_mod(pdb_add, sampass, PDB_PASSLASTSET)) {
1427 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
1428 make_a_mod(mods, ldap_op, "pwdLastSet", temp);
1432 /* FIXME: Hours stuff goes in LDAP */
1433 if (need_ldap_mod(pdb_add, sampass, PDB_ACCTCTRL)) {
1434 make_a_mod (mods, ldap_op, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
1435 NEW_PW_FORMAT_SPACE_PADDED_LEN));
1442 /**********************************************************************
1443 Connect to LDAP server and find the next available RID.
1444 *********************************************************************/
1445 static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 top_rid)
1447 LDAPMessage *result;
1448 uint32 final_rid = (top_rid & (~USER_RID_TYPE)) + RID_MULTIPLIER;
1453 if (final_rid < ldap_state->low_nua_rid || final_rid > ldap_state->high_nua_rid) {
1457 if (ldapsam_search_one_user_by_rid(ldap_state, final_rid, &result) != LDAP_SUCCESS) {
1458 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid));
1462 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
1463 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid));
1464 ldap_msgfree(result);
1468 DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid, final_rid));
1469 ldap_msgfree(result);
1473 /**********************************************************************
1474 Extract the RID from an LDAP entry
1475 *********************************************************************/
1476 static uint32 entry_to_user_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry) {
1478 SAM_ACCOUNT *user = NULL;
1479 if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
1483 if (init_sam_from_ldap(ldap_state, user, entry)) {
1484 rid = pdb_get_user_rid(user);
1488 pdb_free_sam(&user);
1489 if (rid >= ldap_state->low_nua_rid && rid <= ldap_state->high_nua_rid) {
1496 /**********************************************************************
1497 Connect to LDAP server and find the next available RID.
1498 *********************************************************************/
1499 static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state)
1503 LDAPMessage *result;
1505 char *final_filter = NULL;
1510 pstrcpy(filter, lp_ldap_filter());
1511 all_string_sub(filter, "%u", "*", sizeof(pstring));
1514 asprintf(&final_filter, "(&(%s)(&(rid>=%d)(rid<=%d)))", filter, ldap_state->low_nua_rid, ldap_state->high_nua_rid);
1516 final_filter = strdup(filter);
1518 DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter));
1520 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1521 LDAP_SCOPE_SUBTREE, final_filter, attr, 0,
1524 if (rc != LDAP_SUCCESS) {
1525 DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc)));
1526 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1533 count = ldap_count_entries(ldap_state->ldap_struct, result);
1534 DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count));
1537 DEBUG(3, ("LDAP search returned no records, assuming no non-unix-accounts present!: %s\n", ldap_err2string(rc)));
1538 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1540 ldap_msgfree(result);
1542 return ldap_state->low_nua_rid;
1546 entry = ldap_first_entry(ldap_state->ldap_struct,result);
1548 top_rid = entry_to_user_rid(ldap_state, entry);
1550 while ((entry = ldap_next_entry(ldap_state->ldap_struct, entry))) {
1552 rid = entry_to_user_rid(ldap_state, entry);
1553 if (rid > top_rid) {
1558 ldap_msgfree(result);
1560 if (top_rid < ldap_state->low_nua_rid)
1561 top_rid = ldap_state->low_nua_rid;
1566 /**********************************************************************
1567 Connect to LDAP server and find the next available RID.
1568 *********************************************************************/
1569 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state) {
1570 uint32 next_nua_rid;
1573 top_nua_rid = search_top_nua_rid(ldap_state);
1575 next_nua_rid = check_nua_rid_is_avail(ldap_state,
1578 return next_nua_rid;
1581 /**********************************************************************
1582 Connect to LDAP server for password enumeration
1583 *********************************************************************/
1584 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
1586 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1590 pstrcpy(filter, lp_ldap_filter());
1591 all_string_sub(filter, "%u", "*", sizeof(pstring));
1593 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1594 LDAP_SCOPE_SUBTREE, filter, attr, 0,
1595 &ldap_state->result);
1597 if (rc != LDAP_SUCCESS) {
1598 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
1599 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1600 ldap_msgfree(ldap_state->result);
1601 ldap_state->result = NULL;
1602 return NT_STATUS_UNSUCCESSFUL;
1605 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
1606 ldap_count_entries(ldap_state->ldap_struct,
1607 ldap_state->result)));
1609 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
1610 ldap_state->result);
1611 ldap_state->index = 0;
1613 return NT_STATUS_OK;
1616 /**********************************************************************
1617 End enumeration of the LDAP password list
1618 *********************************************************************/
1619 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1621 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1622 if (ldap_state->result) {
1623 ldap_msgfree(ldap_state->result);
1624 ldap_state->result = NULL;
1628 /**********************************************************************
1629 Get the next entry in the LDAP password database
1630 *********************************************************************/
1631 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
1633 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1634 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1637 /* The rebind proc needs this *HACK*. We are not multithreaded, so
1638 this will work, but it's not nice. */
1639 static_ldap_state = ldap_state;
1642 if (!ldap_state->entry)
1645 ldap_state->index++;
1646 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
1648 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
1652 return NT_STATUS_OK;
1655 /**********************************************************************
1656 Get SAM_ACCOUNT entry from LDAP by username
1657 *********************************************************************/
1658 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
1660 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1661 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1662 LDAPMessage *result;
1666 if (ldapsam_search_one_user_by_name(ldap_state, sname, &result) != LDAP_SUCCESS) {
1667 return NT_STATUS_NO_SUCH_USER;
1670 count = ldap_count_entries(ldap_state->ldap_struct, result);
1674 ("We don't find this user [%s] count=%d\n", sname,
1676 return NT_STATUS_NO_SUCH_USER;
1677 } else if (count > 1) {
1679 ("Duplicate entries for this user [%s] Failing. count=%d\n", sname,
1681 return NT_STATUS_NO_SUCH_USER;
1684 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1686 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1687 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1688 ldap_msgfree(result);
1689 return NT_STATUS_NO_SUCH_USER;
1691 ldap_msgfree(result);
1694 ldap_msgfree(result);
1699 /**********************************************************************
1700 Get SAM_ACCOUNT entry from LDAP by rid
1701 *********************************************************************/
1702 static NTSTATUS ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
1704 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1705 struct ldapsam_privates *ldap_state =
1706 (struct ldapsam_privates *)my_methods->private_data;
1707 LDAPMessage *result;
1711 if (ldapsam_search_one_user_by_rid(ldap_state, rid, &result) != LDAP_SUCCESS) {
1712 return NT_STATUS_NO_SUCH_USER;
1715 count = ldap_count_entries(ldap_state->ldap_struct, result);
1719 ("We don't find this rid [%i] count=%d\n", rid,
1721 return NT_STATUS_NO_SUCH_USER;
1722 } else if (count > 1) {
1724 ("More than one user with rid [%i]. Failing. count=%d\n", rid,
1726 return NT_STATUS_NO_SUCH_USER;
1729 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1731 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1732 DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
1733 ldap_msgfree(result);
1734 return NT_STATUS_NO_SUCH_USER;
1736 ldap_msgfree(result);
1739 ldap_msgfree(result);
1744 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
1747 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
1748 return NT_STATUS_NO_SUCH_USER;
1749 return ldapsam_getsampwrid(my_methods, user, rid);
1752 /********************************************************************
1753 Do the actual modification - also change a plaittext passord if
1755 **********************************************************************/
1757 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1758 SAM_ACCOUNT *newpwd, char *dn,
1759 LDAPMod **mods, int ldap_op, BOOL pdb_add)
1761 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1764 if (!my_methods || !newpwd || !dn) {
1765 return NT_STATUS_INVALID_PARAMETER;
1769 DEBUG(5,("mods is empty: nothing to modify\n"));
1770 /* may be password change below however */
1775 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account");
1776 rc = ldapsam_add(ldap_state, dn, mods);
1778 case LDAP_MOD_REPLACE:
1779 rc = ldapsam_modify(ldap_state, dn ,mods);
1782 DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
1783 return NT_STATUS_UNSUCCESSFUL;
1786 if (rc!=LDAP_SUCCESS) {
1788 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1791 ("failed to %s user dn= %s with: %s\n\t%s\n",
1792 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
1793 dn, ldap_err2string(rc),
1796 return NT_STATUS_UNSUCCESSFUL;
1800 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
1801 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))&&
1802 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_OFF)&&
1803 need_ldap_mod(pdb_add, newpwd, PDB_PLAINTEXT_PW)&&
1804 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1808 struct berval *retdata;
1810 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1811 DEBUG(0,("ber_alloc_t returns NULL\n"));
1812 return NT_STATUS_UNSUCCESSFUL;
1814 ber_printf (ber, "{");
1815 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID,dn);
1816 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, pdb_get_plaintext_passwd(newpwd));
1817 ber_printf (ber, "N}");
1819 if ((rc = ber_flatten (ber, &bv))<0) {
1820 DEBUG(0,("ber_flatten returns a value <0\n"));
1821 return NT_STATUS_UNSUCCESSFUL;
1826 if ((rc = ldapsam_extended_operation(ldap_state, LDAP_EXOP_X_MODIFY_PASSWD,
1827 bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) {
1828 DEBUG(0,("LDAP Password could not be changed for user %s: %s\n",
1829 pdb_get_username(newpwd),ldap_err2string(rc)));
1831 DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1833 ber_bvfree(retdata);
1834 ber_memfree(retoid);
1839 DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n"));
1840 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */
1841 return NT_STATUS_OK;
1844 /**********************************************************************
1845 Delete entry from LDAP for username
1846 *********************************************************************/
1847 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
1849 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1852 LDAPMessage *result;
1854 const char *sam_user_attrs[] =
1855 { "lmPassword", "ntPassword", "pwdLastSet", "logonTime", "logoffTime",
1856 "kickoffTime", "pwdCanChange", "pwdMustChange", "acctFlags",
1857 "displayName", "smbHome", "homeDrive", "scriptPath", "profilePath",
1858 "userWorkstations", "primaryGroupID", "domain", "rid", NULL };
1861 DEBUG(0, ("sam_acct was NULL!\n"));
1862 return NT_STATUS_INVALID_PARAMETER;
1865 sname = pdb_get_username(sam_acct);
1867 DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
1869 rc = ldapsam_search_one_user_by_name(ldap_state, sname, &result);
1870 if (rc != LDAP_SUCCESS) {
1871 return NT_STATUS_NO_SUCH_USER;
1874 ret = ldapsam_delete_entry(ldap_state, result, "sambaAccount",
1876 ldap_msgfree(result);
1880 /**********************************************************************
1882 *********************************************************************/
1883 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1885 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1886 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1889 LDAPMessage *result;
1893 if (!init_ldap_from_sam(ldap_state, &mods, LDAP_MOD_REPLACE, False, newpwd)) {
1894 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1895 return NT_STATUS_UNSUCCESSFUL;
1899 DEBUG(4,("mods is empty: nothing to update for user: %s\n",pdb_get_username(newpwd)));
1900 return NT_STATUS_OK;
1903 rc = ldapsam_search_one_user_by_name(ldap_state, pdb_get_username(newpwd), &result);
1904 if (rc != LDAP_SUCCESS) {
1905 ldap_mods_free(mods, 1);
1906 return NT_STATUS_UNSUCCESSFUL;
1909 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
1910 DEBUG(0, ("No user to modify!\n"));
1911 ldap_msgfree(result);
1912 ldap_mods_free(mods, 1);
1913 return NT_STATUS_UNSUCCESSFUL;
1916 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1917 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
1918 ldap_msgfree(result);
1920 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, False);
1921 if (NT_STATUS_IS_ERR(ret)) {
1922 DEBUG(0,("failed to modify user with uid = %s\n",
1923 pdb_get_username(newpwd)));
1924 ldap_mods_free(mods,1);
1930 ("successfully modified uid = %s in the LDAP database\n",
1931 pdb_get_username(newpwd)));
1932 ldap_mods_free(mods, 1);
1933 return NT_STATUS_OK;
1936 /**********************************************************************
1937 Add SAM_ACCOUNT to LDAP
1938 *********************************************************************/
1939 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1941 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1942 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1945 LDAPMessage *result = NULL;
1947 LDAPMod **mods = NULL;
1951 const char *username = pdb_get_username(newpwd);
1952 if (!username || !*username) {
1953 DEBUG(0, ("Cannot add user without a username!\n"));
1954 return NT_STATUS_INVALID_PARAMETER;
1957 rc = ldapsam_search_one_user_by_name (ldap_state, username, &result);
1958 if (rc != LDAP_SUCCESS) {
1959 return NT_STATUS_UNSUCCESSFUL;
1962 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
1963 DEBUG(0,("User '%s' already in the base, with samba properties\n",
1965 ldap_msgfree(result);
1966 return NT_STATUS_UNSUCCESSFUL;
1968 ldap_msgfree(result);
1970 slprintf (filter, sizeof (filter) - 1, "uid=%s", username);
1971 rc = ldapsam_search_one_user(ldap_state, filter, &result);
1972 if (rc != LDAP_SUCCESS) {
1973 return NT_STATUS_UNSUCCESSFUL;
1976 num_result = ldap_count_entries(ldap_state->ldap_struct, result);
1978 if (num_result > 1) {
1979 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
1980 ldap_msgfree(result);
1981 return NT_STATUS_UNSUCCESSFUL;
1984 /* Check if we need to update an existing entry */
1985 if (num_result == 1) {
1989 DEBUG(3,("User exists without samba properties: adding them\n"));
1990 ldap_op = LDAP_MOD_REPLACE;
1991 entry = ldap_first_entry (ldap_state->ldap_struct, result);
1992 tmp = ldap_get_dn (ldap_state->ldap_struct, entry);
1993 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
1996 /* Check if we need to add an entry */
1997 DEBUG(3,("Adding new user\n"));
1998 ldap_op = LDAP_MOD_ADD;
1999 if (username[strlen(username)-1] == '$') {
2000 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
2002 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
2006 ldap_msgfree(result);
2008 if (!init_ldap_from_sam(ldap_state, &mods, ldap_op, True, newpwd)) {
2009 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
2010 ldap_mods_free(mods, 1);
2011 return NT_STATUS_UNSUCCESSFUL;
2015 DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
2016 return NT_STATUS_UNSUCCESSFUL;
2019 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
2021 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, True);
2022 if (NT_STATUS_IS_ERR(ret)) {
2023 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
2024 pdb_get_username(newpwd),dn));
2025 ldap_mods_free(mods,1);
2029 DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd)));
2030 ldap_mods_free(mods, 1);
2031 return NT_STATUS_OK;
2034 static void free_private_data(void **vp)
2036 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
2038 ldapsam_close(*ldap_state);
2040 if ((*ldap_state)->bind_secret) {
2041 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
2044 ldapsam_close(*ldap_state);
2046 SAFE_FREE((*ldap_state)->bind_dn);
2047 SAFE_FREE((*ldap_state)->bind_secret);
2051 /* No need to free any further, as it is talloc()ed */
2054 static const char *group_attr[] = {"gid", "ntSid", "ntGroupType",
2056 "displayName", "description",
2059 static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
2061 LDAPMessage ** result)
2063 int scope = LDAP_SCOPE_SUBTREE;
2066 DEBUG(2, ("ldapsam_search_one_group: searching for:[%s]\n", filter));
2068 rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope,
2069 filter, group_attr, 0, result);
2071 if (rc != LDAP_SUCCESS) {
2072 DEBUG(0, ("ldapsam_search_one_group: "
2073 "Problem during the LDAP search: %s\n",
2074 ldap_err2string(rc)));
2075 DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
2076 lp_ldap_suffix(), filter));
2082 static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
2083 GROUP_MAP *map, LDAPMessage *entry)
2087 if (ldap_state == NULL || map == NULL || entry == NULL ||
2088 ldap_state->ldap_struct == NULL) {
2089 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
2093 if (!get_single_attribute(ldap_state->ldap_struct, entry, "gidNumber",
2095 DEBUG(0, ("Mandatory attribute gidNumber not found\n"));
2098 DEBUG(2, ("Entry found for group: %s\n", temp));
2100 map->gid = (uint32)atol(temp);
2102 if (!get_single_attribute(ldap_state->ldap_struct, entry, "ntSid",
2104 DEBUG(0, ("Mandatory attribute ntSid not found\n"));
2107 string_to_sid(&map->sid, temp);
2109 if (!get_single_attribute(ldap_state->ldap_struct, entry, "ntGroupType",
2111 DEBUG(0, ("Mandatory attribute ntGroupType not found\n"));
2114 map->sid_name_use = (uint32)atol(temp);
2116 if ((map->sid_name_use < SID_NAME_USER) ||
2117 (map->sid_name_use > SID_NAME_UNKNOWN)) {
2118 DEBUG(0, ("Unknown Group type: %d\n", map->sid_name_use));
2122 if (!get_single_attribute(ldap_state->ldap_struct, entry, "displayName",
2124 DEBUG(3, ("Attribute displayName not found\n"));
2127 fstrcpy(map->nt_name, temp);
2129 if (!get_single_attribute(ldap_state->ldap_struct, entry, "description",
2131 DEBUG(3, ("Attribute description not found\n"));
2134 fstrcpy(map->comment, temp);
2136 map->systemaccount = 0;
2137 init_privilege(&map->priv_set);
2142 static BOOL init_ldap_from_group(struct ldapsam_privates *ldap_state,
2143 LDAPMod ***mods, int ldap_op,
2144 const GROUP_MAP *map)
2148 if (mods == NULL || map == NULL) {
2149 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
2155 sid_to_string(tmp, &map->sid);
2156 make_a_mod(mods, ldap_op, "ntSid", tmp);
2158 snprintf(tmp, sizeof(tmp)-1, "%i", map->sid_name_use);
2159 make_a_mod(mods, ldap_op, "ntGroupType", tmp);
2161 make_a_mod(mods, ldap_op, "displayName", map->nt_name);
2162 make_a_mod(mods, ldap_op, "description", map->comment);
2167 static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
2171 struct ldapsam_privates *ldap_state =
2172 (struct ldapsam_privates *)methods->private_data;
2173 LDAPMessage *result;
2177 if (ldapsam_search_one_group(ldap_state, filter, &result)
2179 return NT_STATUS_NO_SUCH_GROUP;
2182 count = ldap_count_entries(ldap_state->ldap_struct, result);
2185 DEBUG(4, ("Did not find group for filter %s\n", filter));
2186 return NT_STATUS_NO_SUCH_GROUP;
2190 DEBUG(1, ("Duplicate entries for filter %s: count=%d\n",
2192 return NT_STATUS_NO_SUCH_GROUP;
2195 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2198 ldap_msgfree(result);
2199 return NT_STATUS_UNSUCCESSFUL;
2202 if (!init_group_from_ldap(ldap_state, map, entry)) {
2203 DEBUG(1, ("init_group_from_ldap failed for group filter %s\n",
2205 ldap_msgfree(result);
2206 return NT_STATUS_NO_SUCH_GROUP;
2209 ldap_msgfree(result);
2210 return NT_STATUS_OK;
2213 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
2214 DOM_SID sid, BOOL with_priv)
2218 snprintf(filter, sizeof(filter)-1,
2219 "(&(objectClass=sambaGroupMapping)(ntSid=%s))",
2220 sid_string_static(&sid));
2222 return ldapsam_getgroup(methods, filter, map);
2225 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
2226 gid_t gid, BOOL with_priv)
2230 snprintf(filter, sizeof(filter)-1,
2231 "(&(objectClass=sambaGroupMapping)(gidNumber=%d))",
2234 return ldapsam_getgroup(methods, filter, map);
2237 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
2238 char *name, BOOL with_priv)
2242 /* TODO: Escaping of name? */
2244 snprintf(filter, sizeof(filter)-1,
2245 "(&(objectClass=sambaGroupMapping)(displayName=%s))",
2248 return ldapsam_getgroup(methods, filter, map);
2251 static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
2253 LDAPMessage **result)
2257 snprintf(filter, sizeof(filter)-1,
2258 "(&(objectClass=posixGroup)(gidNumber=%i))", gid);
2260 return ldapsam_search_one_group(ldap_state, filter, result);
2263 static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
2266 struct ldapsam_privates *ldap_state =
2267 (struct ldapsam_privates *)methods->private_data;
2268 LDAPMessage *result = NULL;
2269 LDAPMod **mods = NULL;
2279 if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
2280 map->gid, False))) {
2281 DEBUG(0, ("Group %i already exists in LDAP\n", map->gid));
2282 return NT_STATUS_UNSUCCESSFUL;
2285 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
2286 if (rc != LDAP_SUCCESS) {
2287 return NT_STATUS_UNSUCCESSFUL;
2290 if (ldap_count_entries(ldap_state->ldap_struct, result) != 1) {
2291 DEBUG(2, ("Group %i must exist exactly once in LDAP\n",
2293 ldap_msgfree(result);
2294 return NT_STATUS_UNSUCCESSFUL;
2297 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2298 tmp = ldap_get_dn(ldap_state->ldap_struct, entry);
2301 ldap_msgfree(result);
2303 if (!init_ldap_from_group(ldap_state, &mods, LDAP_MOD_ADD, map)) {
2304 DEBUG(0, ("init_ldap_from_group failed!\n"));
2305 ldap_mods_free(mods, 1);
2306 return NT_STATUS_UNSUCCESSFUL;
2310 DEBUG(0, ("mods is empty\n"));
2311 return NT_STATUS_UNSUCCESSFUL;
2314 make_a_mod(&mods, LDAP_MOD_ADD, "objectClass",
2315 "sambaGroupMapping");
2317 rc = ldapsam_modify(ldap_state, dn, mods);
2318 ldap_mods_free(mods, 1);
2320 if (rc != LDAP_SUCCESS) {
2321 DEBUG(0, ("failed to modify group %i\n", map->gid));
2322 return NT_STATUS_UNSUCCESSFUL;
2325 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
2326 return NT_STATUS_OK;
2329 static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
2332 struct ldapsam_privates *ldap_state =
2333 (struct ldapsam_privates *)methods->private_data;
2336 LDAPMessage *result;
2340 if (!init_ldap_from_group(ldap_state, &mods, LDAP_MOD_REPLACE, map)) {
2341 DEBUG(0, ("init_ldap_from_group failed\n"));
2342 return NT_STATUS_UNSUCCESSFUL;
2346 DEBUG(4, ("mods is empty: nothing to do\n"));
2347 return NT_STATUS_UNSUCCESSFUL;
2350 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
2352 if (rc != LDAP_SUCCESS) {
2353 ldap_mods_free(mods, 1);
2354 return NT_STATUS_UNSUCCESSFUL;
2357 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
2358 DEBUG(0, ("No group to modify!\n"));
2359 ldap_msgfree(result);
2360 ldap_mods_free(mods, 1);
2361 return NT_STATUS_UNSUCCESSFUL;
2364 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2365 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
2366 ldap_msgfree(result);
2368 rc = ldapsam_modify(ldap_state, dn, mods);
2370 ldap_mods_free(mods, 1);
2372 if (rc != LDAP_SUCCESS) {
2373 DEBUG(0, ("failed to modify group %i\n", map->gid));
2376 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
2377 return NT_STATUS_OK;
2380 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
2383 struct ldapsam_privates *ldap_state =
2384 (struct ldapsam_privates *)methods->private_data;
2385 pstring sidstring, filter;
2386 LDAPMessage *result;
2390 const char *sam_group_attrs[] = { "ntSid", "ntGroupType",
2391 "description", "displayName",
2393 sid_to_string(sidstring, &sid);
2394 snprintf(filter, sizeof(filter)-1,
2395 "(&(objectClass=sambaGroupMapping)(ntSid=%s))", sidstring);
2397 rc = ldapsam_search_one_group(ldap_state, filter, &result);
2399 if (rc != LDAP_SUCCESS) {
2400 return NT_STATUS_NO_SUCH_GROUP;
2403 ret = ldapsam_delete_entry(ldap_state, result, "sambaGroupMapping",
2405 ldap_msgfree(result);
2409 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
2412 struct ldapsam_privates *ldap_state =
2413 (struct ldapsam_privates *)my_methods->private_data;
2414 const char *filter = "(objectClass=sambaGroupMapping)";
2417 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
2418 LDAP_SCOPE_SUBTREE, filter,
2419 group_attr, 0, &ldap_state->result);
2421 if (rc != LDAP_SUCCESS) {
2422 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
2423 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
2424 ldap_msgfree(ldap_state->result);
2425 ldap_state->result = NULL;
2426 return NT_STATUS_UNSUCCESSFUL;
2429 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
2430 ldap_count_entries(ldap_state->ldap_struct,
2431 ldap_state->result)));
2433 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
2434 ldap_state->result);
2435 ldap_state->index = 0;
2437 return NT_STATUS_OK;
2440 static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
2442 ldapsam_endsampwent(my_methods);
2445 static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
2448 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2449 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2452 /* The rebind proc needs this *HACK*. We are not multithreaded, so
2453 this will work, but it's not nice. */
2454 static_ldap_state = ldap_state;
2457 if (!ldap_state->entry)
2460 ldap_state->index++;
2461 bret = init_group_from_ldap(ldap_state, map, ldap_state->entry);
2463 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
2467 return NT_STATUS_OK;
2470 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
2471 enum SID_NAME_USE sid_name_use,
2472 GROUP_MAP **rmap, int *num_entries,
2473 BOOL unix_only, BOOL with_priv)
2483 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
2484 DEBUG(0, ("Unable to open passdb\n"));
2485 return NT_STATUS_ACCESS_DENIED;
2488 while (NT_STATUS_IS_OK(nt_status = ldapsam_getsamgrent(methods, &map))) {
2489 if (sid_name_use != SID_NAME_UNKNOWN &&
2490 sid_name_use != map.sid_name_use) {
2491 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
2494 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
2495 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name));
2499 mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP));
2501 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
2503 return NT_STATUS_UNSUCCESSFUL;
2508 mapt[entries] = map;
2513 ldapsam_endsamgrent(methods);
2515 *num_entries = entries;
2517 return NT_STATUS_OK;
2520 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2523 struct ldapsam_privates *ldap_state;
2525 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
2529 (*pdb_method)->name = "ldapsam";
2531 (*pdb_method)->setsampwent = ldapsam_setsampwent;
2532 (*pdb_method)->endsampwent = ldapsam_endsampwent;
2533 (*pdb_method)->getsampwent = ldapsam_getsampwent;
2534 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
2535 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
2536 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
2537 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
2538 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
2540 (*pdb_method)->getgrsid = ldapsam_getgrsid;
2541 (*pdb_method)->getgrgid = ldapsam_getgrgid;
2542 (*pdb_method)->getgrnam = ldapsam_getgrnam;
2543 (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
2544 (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
2545 (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
2546 (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
2548 /* TODO: Setup private data and free */
2550 ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct ldapsam_privates));
2553 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
2554 return NT_STATUS_NO_MEMORY;
2558 ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
2559 #ifdef WITH_LDAP_SAMCONFIG
2561 int ldap_port = lp_ldap_port();
2563 /* remap default port if not using SSL (ie clear or TLS) */
2564 if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
2568 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);
2569 if (!ldap_state->uri) {
2570 return NT_STATUS_NO_MEMORY;
2574 ldap_state->uri = "ldap://localhost";
2578 (*pdb_method)->private_data = ldap_state;
2580 (*pdb_method)->free_private_data = free_private_data;
2582 return NT_STATUS_OK;
2585 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2588 struct ldapsam_privates *ldap_state;
2589 uint32 low_nua_uid, high_nua_uid;
2591 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) {
2595 (*pdb_method)->name = "ldapsam_nua";
2597 ldap_state = (*pdb_method)->private_data;
2599 ldap_state->permit_non_unix_accounts = True;
2601 if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) {
2602 DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n"));
2603 return NT_STATUS_UNSUCCESSFUL;
2606 ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid);
2608 ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid);
2610 return NT_STATUS_OK;
2613 int pdb_ldap_init(void)
2615 smb_register_passdb("ldapsam", pdb_init_ldapsam, PASSDB_INTERFACE_VERSION);
2616 smb_register_passdb("ldapsam_nua", pdb_init_ldapsam_nua, PASSDB_INTERFACE_VERSION);