2 Unix SMB/CIFS implementation.
3 LDAP protocol helper functions for SAMBA
4 Copyright (C) Jean François Micouleau 1998
5 Copyright (C) Gerald Carter 2001
6 Copyright (C) Shahms King 2001
7 Copyright (C) Andrew Bartlett 2002
8 Copyright (C) Stefan (metze) Metzmacher 2002
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #define DBGC_CLASS DBGC_PASSDB
33 * persistent connections: if using NSS LDAP, many connections are made
34 * however, using only one within Samba would be nice
36 * Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
38 * Other LDAP based login attributes: accountExpires, etc.
39 * (should be the domain of Samba proper, but the sam_password/SAM_ACCOUNT
40 * structures don't have fields for some of these attributes)
42 * SSL is done, but can't get the certificate based authentication to work
43 * against on my test platform (Linux 2.4, OpenLDAP 2.x)
46 /* NOTE: this will NOT work against an Active Directory server
47 * due to the fact that the two password fields cannot be retrieved
48 * from a server; recommend using security = domain in this situation
56 #define SAM_ACCOUNT struct sam_passwd
59 struct ldapsam_privates {
68 /* retrive-once info */
71 BOOL permit_non_unix_accounts;
80 #define LDAPSAM_DONT_PING_TIME 10 /* ping only all 10 seconds */
82 static struct ldapsam_privates *static_ldap_state;
84 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state);
86 /*******************************************************************
87 find the ldap password
88 ******************************************************************/
89 static BOOL fetch_ldapsam_pw(char **dn, char** pw)
94 *dn = smb_xstrdup(lp_ldap_admin_dn());
96 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
98 DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
101 *pw=secrets_fetch(key, &size);
103 /* Upgrade 2.2 style entry */
105 char* old_style_key = strdup(*dn);
107 fstring old_style_pw;
109 if (!old_style_key) {
110 DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n"));
114 for (p=old_style_key; *p; p++)
115 if (*p == ',') *p = '/';
117 data=secrets_fetch(old_style_key, &size);
118 if (!size && size < sizeof(old_style_pw)) {
119 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
120 SAFE_FREE(old_style_key);
125 strncpy(old_style_pw, data, size);
126 old_style_pw[size] = 0;
130 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
131 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
132 SAFE_FREE(old_style_key);
136 if (!secrets_delete(old_style_key)) {
137 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
140 SAFE_FREE(old_style_key);
142 *pw = smb_xstrdup(old_style_pw);
148 static const char *attr[] = {"uid", "pwdLastSet", "logonTime",
149 "logoffTime", "kickoffTime", "cn",
150 "pwdCanChange", "pwdMustChange",
151 "displayName", "homeDrive",
152 "smbHome", "scriptPath",
153 "profilePath", "description",
154 "userWorkstations", "rid",
155 "primaryGroupID", "lmPassword",
156 "ntPassword", "acctFlags",
157 "domain", "objectClass",
158 "uidNumber", "gidNumber",
159 "homeDirectory", NULL };
161 /*******************************************************************
162 open a connection to the ldap server.
163 ******************************************************************/
164 static int ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct)
166 int rc = LDAP_SUCCESS;
168 BOOL ldap_v3 = False;
170 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
171 DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri));
173 if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) {
174 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
180 /* Parse the string manually */
186 const char *p = ldap_state->uri;
187 SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
189 /* skip leading "URL:" (if any) */
190 if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
194 sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port);
197 if (strequal(protocol, "ldap")) {
199 } else if (strequal(protocol, "ldaps")) {
202 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
206 if ((*ldap_struct = ldap_init(host, port)) == NULL) {
207 DEBUG(0, ("ldap_init failed !\n"));
208 return LDAP_OPERATIONS_ERROR;
211 if (strequal(protocol, "ldaps")) {
212 #ifdef LDAP_OPT_X_TLS
213 int tls = LDAP_OPT_X_TLS_HARD;
214 if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
216 DEBUG(0, ("Failed to setup a TLS session\n"));
219 DEBUG(3,("LDAPS option set...!\n"));
221 DEBUG(0,("ldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
222 return LDAP_OPERATIONS_ERROR;
228 if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
230 if (version != LDAP_VERSION3)
232 version = LDAP_VERSION3;
233 if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
241 if (lp_ldap_ssl() == LDAP_SSL_START_TLS) {
242 #ifdef LDAP_OPT_X_TLS
244 if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
246 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
247 ldap_err2string(rc)));
250 DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
253 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
254 return LDAP_OPERATIONS_ERROR;
257 DEBUG(0,("ldap_open_connection: StartTLS not supported by LDAP client libraries!\n"));
258 return LDAP_OPERATIONS_ERROR;
262 DEBUG(2, ("ldap_open_connection: connection opened\n"));
267 /*******************************************************************
268 a rebind function for authenticated referrals
269 This version takes a void* that we can shove useful stuff in :-)
270 ******************************************************************/
271 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
273 static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
274 int *methodp, int freeit, void *arg)
276 struct ldapsam_privates *ldap_state = arg;
278 /** @TODO Should we be doing something to check what servers we rebind to?
279 Could we get a referral to a machine that we don't want to give our
280 username and password to? */
284 memset(*credp, '\0', strlen(*credp));
287 DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
288 ldap_state->bind_dn));
290 *whop = strdup(ldap_state->bind_dn);
292 return LDAP_NO_MEMORY;
294 *credp = strdup(ldap_state->bind_secret);
297 return LDAP_NO_MEMORY;
299 *methodp = LDAP_AUTH_SIMPLE;
303 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
305 /*******************************************************************
306 a rebind function for authenticated referrals
307 This version takes a void* that we can shove useful stuff in :-)
308 and actually does the connection.
309 ******************************************************************/
310 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
311 static int rebindproc_connect_with_state (LDAP *ldap_struct,
312 LDAP_CONST char *url,
314 ber_int_t msgid, void *arg)
316 struct ldapsam_privates *ldap_state = arg;
318 DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
319 ldap_state->bind_dn));
321 /** @TODO Should we be doing something to check what servers we rebind to?
322 Could we get a referral to a machine that we don't want to give our
323 username and password to? */
325 rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
329 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
331 /*******************************************************************
332 Add a rebind function for authenticated referrals
333 ******************************************************************/
334 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
336 # if LDAP_SET_REBIND_PROC_ARGS == 2
337 static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
338 int *method, int freeit )
340 return rebindproc_with_state(ldap_struct, whop, credp,
341 method, freeit, static_ldap_state);
344 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
345 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
347 /*******************************************************************
348 a rebind function for authenticated referrals
349 this also does the connection, but no void*.
350 ******************************************************************/
351 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
352 # if LDAP_SET_REBIND_PROC_ARGS == 2
353 static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
356 return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid,
359 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
360 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
362 /*******************************************************************
363 connect to the ldap server under system privilege.
364 ******************************************************************/
365 static int ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct)
371 /* The rebind proc needs this *HACK*. We are not multithreaded, so
372 this will work, but it's not nice. */
373 static_ldap_state = ldap_state;
375 /* get the password */
376 if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
378 DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
379 return LDAP_INVALID_CREDENTIALS;
382 ldap_state->bind_dn = ldap_dn;
383 ldap_state->bind_secret = ldap_secret;
385 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
386 (OpenLDAP) doesnt' seem to support it */
388 DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n",
391 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
392 # if LDAP_SET_REBIND_PROC_ARGS == 2
393 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);
395 # if LDAP_SET_REBIND_PROC_ARGS == 3
396 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);
398 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
399 # if LDAP_SET_REBIND_PROC_ARGS == 2
400 ldap_set_rebind_proc(ldap_struct, &rebindproc);
402 # if LDAP_SET_REBIND_PROC_ARGS == 3
403 ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);
405 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
407 rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
409 if (rc != LDAP_SUCCESS) {
410 DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
414 DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n"));
418 /**********************************************************************
419 Connect to LDAP server
420 *********************************************************************/
421 static int ldapsam_open(struct ldapsam_privates *ldap_state)
424 SMB_ASSERT(ldap_state);
426 #ifndef NO_LDAP_SECURITY
427 if (geteuid() != 0) {
428 DEBUG(0, ("ldapsam_open: cannot access LDAP when not root..\n"));
429 return LDAP_INSUFFICIENT_ACCESS;
433 if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + LDAPSAM_DONT_PING_TIME) < time(NULL))) {
434 struct sockaddr_un addr;
437 if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
438 getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
439 /* the other end has died. reopen. */
440 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
441 ldap_state->ldap_struct = NULL;
442 ldap_state->last_ping = (time_t)0;
444 ldap_state->last_ping = time(NULL);
448 if (ldap_state->ldap_struct != NULL) {
449 DEBUG(5,("ldapsam_open: allready connected to the LDAP server\n"));
453 if ((rc = ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct))) {
457 if ((rc = ldapsam_connect_system(ldap_state, ldap_state->ldap_struct))) {
458 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
459 ldap_state->ldap_struct = NULL;
464 ldap_state->last_ping = time(NULL);
465 DEBUG(4,("The LDAP server is succesful connected\n"));
470 /**********************************************************************
471 Disconnect from LDAP server
472 *********************************************************************/
473 static NTSTATUS ldapsam_close(struct ldapsam_privates *ldap_state)
476 return NT_STATUS_INVALID_PARAMETER;
478 if (ldap_state->ldap_struct != NULL) {
479 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
480 ldap_state->ldap_struct = NULL;
483 DEBUG(5,("The connection to the LDAP server was closed\n"));
484 /* maybe free the results here --metze */
489 static int ldapsam_retry_open(struct ldapsam_privates *ldap_state, int *attempts)
493 SMB_ASSERT(ldap_state && attempts);
495 if (*attempts != 0) {
496 /* we retry after 0.5, 2, 4.5, 8, 12.5, 18, 24.5 seconds */
497 msleep((((*attempts)*(*attempts))/2)*1000);
501 if ((rc = ldapsam_open(ldap_state))) {
502 DEBUG(0,("Connection to LDAP Server failed for the %d try!\n",*attempts));
510 static int ldapsam_search(struct ldapsam_privates *ldap_state,
511 const char *base, int scope, const char *filter,
512 const char *attrs[], int attrsonly,
515 int rc = LDAP_SERVER_DOWN;
518 SMB_ASSERT(ldap_state);
520 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
522 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
525 rc = ldap_search_s(ldap_state->ldap_struct, base, scope,
526 filter, attrs, attrsonly, res);
529 if (rc == LDAP_SERVER_DOWN) {
530 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
531 ldapsam_close(ldap_state);
537 static int ldapsam_modify(struct ldapsam_privates *ldap_state, char *dn, LDAPMod *attrs[])
539 int rc = LDAP_SERVER_DOWN;
545 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
547 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
550 rc = ldap_modify_s(ldap_state->ldap_struct, dn, attrs);
553 if (rc == LDAP_SERVER_DOWN) {
554 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
555 ldapsam_close(ldap_state);
561 static int ldapsam_add(struct ldapsam_privates *ldap_state, const char *dn, LDAPMod *attrs[])
563 int rc = LDAP_SERVER_DOWN;
569 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
571 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
574 rc = ldap_add_s(ldap_state->ldap_struct, dn, attrs);
577 if (rc == LDAP_SERVER_DOWN) {
578 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
579 ldapsam_close(ldap_state);
585 static int ldapsam_delete(struct ldapsam_privates *ldap_state, char *dn)
587 int rc = LDAP_SERVER_DOWN;
593 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
595 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
598 rc = ldap_delete_s(ldap_state->ldap_struct, dn);
601 if (rc == LDAP_SERVER_DOWN) {
602 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
603 ldapsam_close(ldap_state);
609 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)
611 int rc = LDAP_SERVER_DOWN;
617 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
619 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
622 rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata, serverctrls, clientctrls, retoidp, retdatap);
625 if (rc == LDAP_SERVER_DOWN) {
626 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
627 ldapsam_close(ldap_state);
633 /*******************************************************************
634 run the search by name.
635 ******************************************************************/
636 static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, const char *filter, LDAPMessage ** result)
638 int scope = LDAP_SCOPE_SUBTREE;
641 DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter));
643 rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope, filter, attr, 0, result);
645 if (rc != LDAP_SUCCESS) {
646 DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n",
647 ldap_err2string (rc)));
648 DEBUG(3,("ldapsam_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(),
655 /*******************************************************************
656 run the search by name.
657 ******************************************************************/
658 static int ldapsam_search_one_user_by_name (struct ldapsam_privates *ldap_state, const char *user,
659 LDAPMessage ** result)
664 * in the filter expression, replace %u with the real name
665 * so in ldap filter, %u MUST exist :-)
667 pstrcpy(filter, lp_ldap_filter());
670 * have to use this here because $ is filtered out
673 all_string_sub(filter, "%u", user, sizeof(pstring));
675 return ldapsam_search_one_user(ldap_state, filter, result);
678 /*******************************************************************
679 run the search by uid.
680 ******************************************************************/
681 static int ldapsam_search_one_user_by_uid(struct ldapsam_privates *ldap_state,
683 LDAPMessage ** result)
688 /* Get the username from the system and look that up in the LDAP */
690 if ((user = getpwuid_alloc(uid)) == NULL) {
691 DEBUG(3,("ldapsam_search_one_user_by_uid: Failed to locate uid [%d]\n", uid));
692 return LDAP_NO_SUCH_OBJECT;
695 pstrcpy(filter, lp_ldap_filter());
697 all_string_sub(filter, "%u", user->pw_name, sizeof(pstring));
701 return ldapsam_search_one_user(ldap_state, filter, result);
704 /*******************************************************************
705 run the search by rid.
706 ******************************************************************/
707 static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state,
709 LDAPMessage ** result)
714 /* check if the user rid exsists, if not, try searching on the uid */
716 snprintf(filter, sizeof(filter) - 1, "rid=%i", rid);
717 rc = ldapsam_search_one_user(ldap_state, filter, result);
719 if (rc != LDAP_SUCCESS)
720 rc = ldapsam_search_one_user_by_uid(ldap_state,
721 fallback_pdb_user_rid_to_uid(rid),
727 /*******************************************************************
728 search an attribute and return the first value found.
729 ******************************************************************/
730 static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
731 const char *attribute, pstring value)
735 if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
737 DEBUG (10, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute));
742 pstrcpy(value, values[0]);
743 ldap_value_free(values);
744 #ifdef DEBUG_PASSWORDS
745 DEBUG (100, ("get_single_attribute: [%s] = [%s]\n", attribute, value));
750 /************************************************************************
751 Routine to manage the LDAPMod structure array
752 manage memory used by the array, by each struct, and values
754 ************************************************************************/
755 static void make_a_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
763 if (attribute == NULL || *attribute == '\0')
766 if (value == NULL || *value == '\0')
771 mods = (LDAPMod **) malloc(sizeof(LDAPMod *));
774 DEBUG(0, ("make_a_mod: out of memory!\n"));
780 for (i = 0; mods[i] != NULL; ++i) {
781 if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute))
787 mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *));
790 DEBUG(0, ("make_a_mod: out of memory!\n"));
793 mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
796 DEBUG(0, ("make_a_mod: out of memory!\n"));
799 mods[i]->mod_op = modop;
800 mods[i]->mod_values = NULL;
801 mods[i]->mod_type = strdup(attribute);
808 if (mods[i]->mod_values != NULL) {
809 for (; mods[i]->mod_values[j] != NULL; j++);
811 mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values,
812 (j + 2) * sizeof (char *));
814 if (mods[i]->mod_values == NULL) {
815 DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
818 mods[i]->mod_values[j] = strdup(value);
819 mods[i]->mod_values[j + 1] = NULL;
824 /* New Interface is being implemented here */
826 /**********************************************************************
827 Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
828 *********************************************************************/
829 static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
830 SAM_ACCOUNT * sampass,
840 if ((ldap_values = ldap_get_values (ldap_state->ldap_struct, entry, "objectClass")) == NULL) {
841 DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
845 for (values=ldap_values;*values;values++) {
846 if (strcasecmp(*values, "posixAccount") == 0) {
851 if (!*values) { /*end of array, no posixAccount */
852 DEBUG(10, ("user does not have posixAcccount attributes\n"));
853 ldap_value_free(ldap_values);
856 ldap_value_free(ldap_values);
858 if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDirectory", homedir))
861 if (!get_single_attribute(ldap_state->ldap_struct, entry, "uidNumber", temp))
864 uid = (uid_t)atol(temp);
866 if (!get_single_attribute(ldap_state->ldap_struct, entry, "gidNumber", temp))
869 gid = (gid_t)atol(temp);
871 pdb_set_unix_homedir(sampass, homedir, PDB_SET);
872 pdb_set_uid(sampass, uid, PDB_SET);
873 pdb_set_gid(sampass, gid, PDB_SET);
875 DEBUG(10, ("user has posixAcccount attributes\n"));
880 /**********************************************************************
881 Initialize SAM_ACCOUNT from an LDAP query
882 (Based on init_sam_from_buffer in pdb_tdb.c)
883 *********************************************************************/
884 static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
885 SAM_ACCOUNT * sampass,
892 pass_can_change_time,
893 pass_must_change_time;
908 uint8 smblmpwd[LM_HASH_LEN],
909 smbntpwd[NT_HASH_LEN];
913 uint8 hours[MAX_HOURS_LEN];
916 gid_t gid = getegid();
920 * do a little initialization
924 nt_username[0] = '\0';
928 logon_script[0] = '\0';
929 profile_path[0] = '\0';
931 munged_dial[0] = '\0';
932 workstations[0] = '\0';
935 if (sampass == NULL || ldap_state == NULL || entry == NULL) {
936 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
940 if (ldap_state->ldap_struct == NULL) {
941 DEBUG(0, ("init_sam_from_ldap: ldap_state->ldap_struct is NULL!\n"));
945 get_single_attribute(ldap_state->ldap_struct, entry, "uid", username);
946 DEBUG(2, ("Entry found for user: %s\n", username));
948 pstrcpy(nt_username, username);
950 pstrcpy(domain, lp_workgroup());
952 pdb_set_username(sampass, username, PDB_SET);
954 pdb_set_domain(sampass, domain, PDB_DEFAULT);
955 pdb_set_nt_username(sampass, nt_username, PDB_SET);
957 get_single_attribute(ldap_state->ldap_struct, entry, "rid", temp);
958 user_rid = (uint32)atol(temp);
960 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
962 if (!get_single_attribute(ldap_state->ldap_struct, entry, "primaryGroupID", temp)) {
965 group_rid = (uint32)atol(temp);
966 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
971 * If so configured, try and get the values from LDAP
974 if (!lp_ldap_trust_ids() || (!get_unix_attributes(ldap_state, sampass, entry))) {
977 * Otherwise just ask the system getpw() calls.
980 pw = getpwnam_alloc(username);
982 if (! ldap_state->permit_non_unix_accounts) {
983 DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\n", username));
988 pdb_set_uid(sampass, uid, PDB_SET);
990 pdb_set_gid(sampass, gid, PDB_SET);
992 pdb_set_unix_homedir(sampass, pw->pw_dir, PDB_SET);
998 if (group_rid == 0 && pdb_get_init_flags(sampass,PDB_GID) != PDB_DEFAULT) {
1000 gid = pdb_get_gid(sampass);
1001 /* call the mapping code here */
1002 if(pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) {
1003 pdb_set_group_sid(sampass, &map.sid, PDB_SET);
1006 pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid), PDB_SET);
1010 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdLastSet", temp)) {
1011 /* leave as default */
1013 pass_last_set_time = (time_t) atol(temp);
1014 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1017 if (!get_single_attribute(ldap_state->ldap_struct, entry, "logonTime", temp)) {
1018 /* leave as default */
1020 logon_time = (time_t) atol(temp);
1021 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1024 if (!get_single_attribute(ldap_state->ldap_struct, entry, "logoffTime", temp)) {
1025 /* leave as default */
1027 logoff_time = (time_t) atol(temp);
1028 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1031 if (!get_single_attribute(ldap_state->ldap_struct, entry, "kickoffTime", temp)) {
1032 /* leave as default */
1034 kickoff_time = (time_t) atol(temp);
1035 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1038 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdCanChange", temp)) {
1039 /* leave as default */
1041 pass_can_change_time = (time_t) atol(temp);
1042 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1045 if (!get_single_attribute(ldap_state->ldap_struct, entry, "pwdMustChange", temp)) {
1046 /* leave as default */
1048 pass_must_change_time = (time_t) atol(temp);
1049 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1052 /* recommend that 'gecos' and 'displayName' should refer to the same
1053 * attribute OID. userFullName depreciated, only used by Samba
1054 * primary rules of LDAP: don't make a new attribute when one is already defined
1055 * that fits your needs; using cn then displayName rather than 'userFullName'
1058 if (!get_single_attribute(ldap_state->ldap_struct, entry, "cn", fullname)) {
1059 if (!get_single_attribute(ldap_state->ldap_struct, entry, "displayName", fullname)) {
1060 /* leave as default */
1062 pdb_set_fullname(sampass, fullname, PDB_SET);
1065 pdb_set_fullname(sampass, fullname, PDB_SET);
1068 if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDrive", dir_drive)) {
1069 pdb_set_dir_drive(sampass, talloc_sub_specified(sampass->mem_ctx,
1075 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1078 if (!get_single_attribute(ldap_state->ldap_struct, entry, "smbHome", homedir)) {
1079 pdb_set_homedir(sampass, talloc_sub_specified(sampass->mem_ctx,
1085 pdb_set_homedir(sampass, homedir, PDB_SET);
1088 if (!get_single_attribute(ldap_state->ldap_struct, entry, "scriptPath", logon_script)) {
1089 pdb_set_logon_script(sampass, talloc_sub_specified(sampass->mem_ctx,
1095 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1098 if (!get_single_attribute(ldap_state->ldap_struct, entry, "profilePath", profile_path)) {
1099 pdb_set_profile_path(sampass, talloc_sub_specified(sampass->mem_ctx,
1105 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1108 if (!get_single_attribute(ldap_state->ldap_struct, entry, "description", acct_desc)) {
1109 /* leave as default */
1111 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1114 if (!get_single_attribute(ldap_state->ldap_struct, entry, "userWorkstations", workstations)) {
1115 /* leave as default */;
1117 pdb_set_workstations(sampass, workstations, PDB_SET);
1120 /* FIXME: hours stuff should be cleaner */
1124 memset(hours, 0xff, hours_len);
1126 if (!get_single_attribute (ldap_state->ldap_struct, entry, "lmPassword", temp)) {
1127 /* leave as default */
1129 pdb_gethexpwd(temp, smblmpwd);
1130 memset((char *)temp, '\0', strlen(temp)+1);
1131 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
1133 ZERO_STRUCT(smblmpwd);
1136 if (!get_single_attribute (ldap_state->ldap_struct, entry, "ntPassword", temp)) {
1137 /* leave as default */
1139 pdb_gethexpwd(temp, smbntpwd);
1140 memset((char *)temp, '\0', strlen(temp)+1);
1141 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
1143 ZERO_STRUCT(smbntpwd);
1146 if (!get_single_attribute (ldap_state->ldap_struct, entry, "acctFlags", temp)) {
1147 acct_ctrl |= ACB_NORMAL;
1149 acct_ctrl = pdb_decode_acct_ctrl(temp);
1152 acct_ctrl |= ACB_NORMAL;
1154 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1157 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1158 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1160 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1162 /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
1163 /* pdb_set_unknown_5(sampass, unknown5, PDB_SET); */
1164 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
1166 pdb_set_hours(sampass, hours, PDB_SET);
1171 static BOOL need_ldap_mod(BOOL pdb_add, const SAM_ACCOUNT * sampass, enum pdb_elements element) {
1173 return (!IS_SAM_DEFAULT(sampass, element));
1175 return IS_SAM_CHANGED(sampass, element);
1179 /**********************************************************************
1180 Initialize SAM_ACCOUNT from an LDAP query
1181 (Based on init_buffer_from_sam in pdb_tdb.c)
1182 *********************************************************************/
1183 static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
1184 LDAPMod *** mods, int ldap_op,
1186 const SAM_ACCOUNT * sampass)
1191 if (mods == NULL || sampass == NULL) {
1192 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
1199 * took out adding "objectclass: sambaAccount"
1200 * do this on a per-mod basis
1202 if (need_ldap_mod(pdb_add, sampass, PDB_USERNAME)) {
1203 make_a_mod(mods, ldap_op, "uid", pdb_get_username(sampass));
1204 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
1207 if ((rid = pdb_get_user_rid(sampass))!=0 ) {
1208 if (need_ldap_mod(pdb_add, sampass, PDB_USERSID)) {
1209 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1210 make_a_mod(mods, ldap_op, "rid", temp);
1212 } else if (!IS_SAM_DEFAULT(sampass, PDB_UID)) {
1213 rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass));
1214 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1215 make_a_mod(mods, ldap_op, "rid", temp);
1216 } else if (ldap_state->permit_non_unix_accounts) {
1217 rid = ldapsam_get_next_available_nua_rid(ldap_state);
1219 DEBUG(0, ("NO user RID specified on account %s, and findining next available NUA RID failed, cannot store!\n", pdb_get_username(sampass)));
1222 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1223 make_a_mod(mods, ldap_op, "rid", temp);
1225 DEBUG(0, ("NO user RID specified on account %s, cannot store!\n", pdb_get_username(sampass)));
1231 if ((rid = pdb_get_group_rid(sampass))!=0 ) {
1232 if (need_ldap_mod(pdb_add, sampass, PDB_GROUPSID)) {
1233 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1234 make_a_mod(mods, ldap_op, "primaryGroupID", temp);
1236 } else if (!IS_SAM_DEFAULT(sampass, PDB_GID)) {
1237 rid = pdb_gid_to_group_rid(pdb_get_gid(sampass));
1238 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1239 make_a_mod(mods, ldap_op, "primaryGroupID", temp);
1240 } else if (ldap_state->permit_non_unix_accounts) {
1241 rid = DOMAIN_GROUP_RID_USERS;
1242 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1243 make_a_mod(mods, ldap_op, "primaryGroupID", temp);
1245 DEBUG(0, ("NO group RID specified on account %s, cannot store!\n", pdb_get_username(sampass)));
1250 /* displayName, cn, and gecos should all be the same
1251 * most easily accomplished by giving them the same OID
1252 * gecos isn't set here b/c it should be handled by the
1255 if (need_ldap_mod(pdb_add, sampass, PDB_FULLNAME)) {
1256 make_a_mod(mods, ldap_op, "displayName", pdb_get_fullname(sampass));
1257 make_a_mod(mods, ldap_op, "cn", pdb_get_fullname(sampass));
1259 if (need_ldap_mod(pdb_add, sampass, PDB_ACCTDESC)) {
1260 make_a_mod(mods, ldap_op, "description", pdb_get_acct_desc(sampass));
1262 if (need_ldap_mod(pdb_add, sampass, PDB_WORKSTATIONS)) {
1263 make_a_mod(mods, ldap_op, "userWorkstations", pdb_get_workstations(sampass));
1266 * Only updates fields which have been set (not defaults from smb.conf)
1269 if (need_ldap_mod(pdb_add, sampass, PDB_SMBHOME)) {
1270 make_a_mod(mods, ldap_op, "smbHome", pdb_get_homedir(sampass));
1273 if (need_ldap_mod(pdb_add, sampass, PDB_DRIVE)) {
1274 make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dir_drive(sampass));
1277 if (need_ldap_mod(pdb_add, sampass, PDB_LOGONSCRIPT)) {
1278 make_a_mod(mods, ldap_op, "scriptPath", pdb_get_logon_script(sampass));
1281 if (need_ldap_mod(pdb_add, sampass, PDB_PROFILE))
1282 make_a_mod(mods, ldap_op, "profilePath", pdb_get_profile_path(sampass));
1284 if (need_ldap_mod(pdb_add, sampass, PDB_LOGONTIME)) {
1285 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
1286 make_a_mod(mods, ldap_op, "logonTime", temp);
1289 if (need_ldap_mod(pdb_add, sampass, PDB_LOGOFFTIME)) {
1290 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
1291 make_a_mod(mods, ldap_op, "logoffTime", temp);
1294 if (need_ldap_mod(pdb_add, sampass, PDB_KICKOFFTIME)) {
1295 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
1296 make_a_mod(mods, ldap_op, "kickoffTime", temp);
1300 if (need_ldap_mod(pdb_add, sampass, PDB_CANCHANGETIME)) {
1301 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
1302 make_a_mod(mods, ldap_op, "pwdCanChange", temp);
1305 if (need_ldap_mod(pdb_add, sampass, PDB_MUSTCHANGETIME)) {
1306 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
1307 make_a_mod(mods, ldap_op, "pwdMustChange", temp);
1310 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))||
1311 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
1313 if (need_ldap_mod(pdb_add, sampass, PDB_LMPASSWD)) {
1314 pdb_sethexpwd (temp, pdb_get_lanman_passwd(sampass), pdb_get_acct_ctrl(sampass));
1315 make_a_mod (mods, ldap_op, "lmPassword", temp);
1318 if (need_ldap_mod(pdb_add, sampass, PDB_NTPASSWD)) {
1319 pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass), pdb_get_acct_ctrl(sampass));
1320 make_a_mod (mods, ldap_op, "ntPassword", temp);
1323 if (need_ldap_mod(pdb_add, sampass, PDB_PASSLASTSET)) {
1324 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
1325 make_a_mod(mods, ldap_op, "pwdLastSet", temp);
1329 /* FIXME: Hours stuff goes in LDAP */
1330 if (need_ldap_mod(pdb_add, sampass, PDB_ACCTCTRL)) {
1331 make_a_mod (mods, ldap_op, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass),
1332 NEW_PW_FORMAT_SPACE_PADDED_LEN));
1339 /**********************************************************************
1340 Connect to LDAP server and find the next available RID.
1341 *********************************************************************/
1342 static uint32 check_nua_rid_is_avail(struct ldapsam_privates *ldap_state, uint32 top_rid)
1344 LDAPMessage *result;
1345 uint32 final_rid = (top_rid & (~USER_RID_TYPE)) + RID_MULTIPLIER;
1350 if (final_rid < ldap_state->low_nua_rid || final_rid > ldap_state->high_nua_rid) {
1354 if (ldapsam_search_one_user_by_rid(ldap_state, final_rid, &result) != LDAP_SUCCESS) {
1355 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid, final_rid));
1359 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
1360 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid, final_rid));
1361 ldap_msgfree(result);
1365 DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid, final_rid));
1366 ldap_msgfree(result);
1370 /**********************************************************************
1371 Extract the RID from an LDAP entry
1372 *********************************************************************/
1373 static uint32 entry_to_user_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry) {
1375 SAM_ACCOUNT *user = NULL;
1376 if (!NT_STATUS_IS_OK(pdb_init_sam(&user))) {
1380 if (init_sam_from_ldap(ldap_state, user, entry)) {
1381 rid = pdb_get_user_rid(user);
1385 pdb_free_sam(&user);
1386 if (rid >= ldap_state->low_nua_rid && rid <= ldap_state->high_nua_rid) {
1393 /**********************************************************************
1394 Connect to LDAP server and find the next available RID.
1395 *********************************************************************/
1396 static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state)
1400 LDAPMessage *result;
1402 char *final_filter = NULL;
1407 pstrcpy(filter, lp_ldap_filter());
1408 all_string_sub(filter, "%u", "*", sizeof(pstring));
1411 asprintf(&final_filter, "(&(%s)(&(rid>=%d)(rid<=%d)))", filter, ldap_state->low_nua_rid, ldap_state->high_nua_rid);
1413 final_filter = strdup(filter);
1415 DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter));
1417 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1418 LDAP_SCOPE_SUBTREE, final_filter, attr, 0,
1421 if (rc != LDAP_SUCCESS) {
1422 DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc)));
1423 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1430 count = ldap_count_entries(ldap_state->ldap_struct, result);
1431 DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count));
1434 DEBUG(3, ("LDAP search returned no records, assuming no non-unix-accounts present!: %s\n", ldap_err2string(rc)));
1435 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter));
1437 ldap_msgfree(result);
1439 return ldap_state->low_nua_rid;
1443 entry = ldap_first_entry(ldap_state->ldap_struct,result);
1445 top_rid = entry_to_user_rid(ldap_state, entry);
1447 while ((entry = ldap_next_entry(ldap_state->ldap_struct, entry))) {
1449 rid = entry_to_user_rid(ldap_state, entry);
1450 if (rid > top_rid) {
1455 ldap_msgfree(result);
1457 if (top_rid < ldap_state->low_nua_rid)
1458 top_rid = ldap_state->low_nua_rid;
1463 /**********************************************************************
1464 Connect to LDAP server and find the next available RID.
1465 *********************************************************************/
1466 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state) {
1467 uint32 next_nua_rid;
1470 top_nua_rid = search_top_nua_rid(ldap_state);
1472 next_nua_rid = check_nua_rid_is_avail(ldap_state,
1475 return next_nua_rid;
1478 /**********************************************************************
1479 Connect to LDAP server for password enumeration
1480 *********************************************************************/
1481 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
1483 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1487 pstrcpy(filter, lp_ldap_filter());
1488 all_string_sub(filter, "%u", "*", sizeof(pstring));
1490 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
1491 LDAP_SCOPE_SUBTREE, filter, attr, 0,
1492 &ldap_state->result);
1494 if (rc != LDAP_SUCCESS) {
1495 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
1496 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1497 ldap_msgfree(ldap_state->result);
1498 ldap_state->result = NULL;
1499 return NT_STATUS_UNSUCCESSFUL;
1502 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
1503 ldap_count_entries(ldap_state->ldap_struct,
1504 ldap_state->result)));
1506 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
1507 ldap_state->result);
1508 ldap_state->index = 0;
1510 return NT_STATUS_OK;
1513 /**********************************************************************
1514 End enumeration of the LDAP password list
1515 *********************************************************************/
1516 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1518 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1519 if (ldap_state->result) {
1520 ldap_msgfree(ldap_state->result);
1521 ldap_state->result = NULL;
1525 /**********************************************************************
1526 Get the next entry in the LDAP password database
1527 *********************************************************************/
1528 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
1530 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1531 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1534 /* The rebind proc needs this *HACK*. We are not multithreaded, so
1535 this will work, but it's not nice. */
1536 static_ldap_state = ldap_state;
1539 if (!ldap_state->entry)
1542 ldap_state->index++;
1543 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
1545 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
1549 return NT_STATUS_OK;
1552 /**********************************************************************
1553 Get SAM_ACCOUNT entry from LDAP by username
1554 *********************************************************************/
1555 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
1557 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1558 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1559 LDAPMessage *result;
1562 if (ldapsam_search_one_user_by_name(ldap_state, sname, &result) != LDAP_SUCCESS) {
1563 return NT_STATUS_NO_SUCH_USER;
1565 if (ldap_count_entries(ldap_state->ldap_struct, result) < 1) {
1567 ("We don't find this user [%s] count=%d\n", sname,
1568 ldap_count_entries(ldap_state->ldap_struct, result)));
1569 return NT_STATUS_NO_SUCH_USER;
1571 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1573 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1574 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1575 ldap_msgfree(result);
1576 return NT_STATUS_NO_SUCH_USER;
1578 ldap_msgfree(result);
1581 ldap_msgfree(result);
1586 /**********************************************************************
1587 Get SAM_ACCOUNT entry from LDAP by rid
1588 *********************************************************************/
1589 static NTSTATUS ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
1591 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1592 struct ldapsam_privates *ldap_state =
1593 (struct ldapsam_privates *)my_methods->private_data;
1594 LDAPMessage *result;
1597 if (ldapsam_search_one_user_by_rid(ldap_state, rid, &result) != LDAP_SUCCESS) {
1598 return NT_STATUS_NO_SUCH_USER;
1601 if (ldap_count_entries(ldap_state->ldap_struct, result) < 1) {
1603 ("We don't find this rid [%i] count=%d\n", rid,
1604 ldap_count_entries(ldap_state->ldap_struct, result)));
1605 return NT_STATUS_NO_SUCH_USER;
1608 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1610 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1611 DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
1612 ldap_msgfree(result);
1613 return NT_STATUS_NO_SUCH_USER;
1615 ldap_msgfree(result);
1618 ldap_msgfree(result);
1623 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
1626 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
1627 return NT_STATUS_NO_SUCH_USER;
1628 return ldapsam_getsampwrid(my_methods, user, rid);
1631 /********************************************************************
1632 Do the actual modification - also change a plaittext passord if
1634 **********************************************************************/
1636 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1637 SAM_ACCOUNT *newpwd, char *dn,
1638 LDAPMod **mods, int ldap_op, BOOL pdb_add)
1640 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1643 if (!my_methods || !newpwd || !dn) {
1644 return NT_STATUS_INVALID_PARAMETER;
1648 DEBUG(5,("mods is empty: nothing to modify\n"));
1649 /* may be password change below however */
1654 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "account");
1655 rc = ldapsam_add(ldap_state, dn, mods);
1657 case LDAP_MOD_REPLACE:
1658 rc = ldapsam_modify(ldap_state, dn ,mods);
1661 DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
1662 return NT_STATUS_UNSUCCESSFUL;
1665 if (rc!=LDAP_SUCCESS) {
1667 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1670 ("failed to %s user dn= %s with: %s\n\t%s\n",
1671 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
1672 dn, ldap_err2string(rc),
1675 return NT_STATUS_UNSUCCESSFUL;
1679 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
1680 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))&&
1681 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_OFF)&&
1682 need_ldap_mod(pdb_add, newpwd, PDB_PLAINTEXT_PW)&&
1683 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1687 struct berval *retdata;
1689 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1690 DEBUG(0,("ber_alloc_t returns NULL\n"));
1691 return NT_STATUS_UNSUCCESSFUL;
1693 ber_printf (ber, "{");
1694 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID,dn);
1695 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, pdb_get_plaintext_passwd(newpwd));
1696 ber_printf (ber, "N}");
1698 if ((rc = ber_flatten (ber, &bv))<0) {
1699 DEBUG(0,("ber_flatten returns a value <0\n"));
1700 return NT_STATUS_UNSUCCESSFUL;
1705 if ((rc = ldapsam_extended_operation(ldap_state, LDAP_EXOP_X_MODIFY_PASSWD,
1706 bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) {
1707 DEBUG(0,("LDAP Password could not be changed for user %s: %s\n",
1708 pdb_get_username(newpwd),ldap_err2string(rc)));
1710 DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1712 ber_bvfree(retdata);
1713 ber_memfree(retoid);
1718 DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n"));
1719 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */
1720 return NT_STATUS_OK;
1723 /**********************************************************************
1724 Delete entry from LDAP for username
1725 *********************************************************************/
1726 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
1728 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1733 LDAPMessage *result;
1736 DEBUG(0, ("sam_acct was NULL!\n"));
1737 return NT_STATUS_INVALID_PARAMETER;
1740 sname = pdb_get_username(sam_acct);
1742 DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
1744 rc = ldapsam_search_one_user_by_name(ldap_state, sname, &result);
1745 if (rc != LDAP_SUCCESS) {
1746 return NT_STATUS_NO_SUCH_USER;
1749 if (ldap_count_entries (ldap_state->ldap_struct, result) == 0) {
1750 DEBUG (0, ("User doesn't exit!\n"));
1751 ldap_msgfree (result);
1752 return NT_STATUS_NO_SUCH_USER;
1755 entry = ldap_first_entry (ldap_state->ldap_struct, result);
1756 dn = ldap_get_dn (ldap_state->ldap_struct, entry);
1757 ldap_msgfree(result);
1759 rc = ldapsam_delete(ldap_state, dn);
1762 if (rc != LDAP_SUCCESS) {
1764 ldap_get_option (ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
1765 DEBUG (0,("failed to delete user with uid = %s with: %s\n\t%s\n",
1766 sname, ldap_err2string (rc), ld_error));
1768 return NT_STATUS_CANNOT_DELETE;
1771 DEBUG (2,("successfully deleted uid = %s from the LDAP database\n", sname));
1772 return NT_STATUS_OK;
1775 /**********************************************************************
1777 *********************************************************************/
1778 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1780 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1781 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1784 LDAPMessage *result;
1788 if (!init_ldap_from_sam(ldap_state, &mods, LDAP_MOD_REPLACE, False, newpwd)) {
1789 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1790 ldap_msgfree(result);
1791 return NT_STATUS_UNSUCCESSFUL;
1795 DEBUG(4,("mods is empty: nothing to update for user: %s\n",pdb_get_username(newpwd)));
1796 return NT_STATUS_OK;
1799 rc = ldapsam_search_one_user_by_name(ldap_state, pdb_get_username(newpwd), &result);
1800 if (rc != LDAP_SUCCESS) {
1801 return NT_STATUS_UNSUCCESSFUL;
1804 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
1805 DEBUG(0, ("No user to modify!\n"));
1806 ldap_msgfree(result);
1807 return NT_STATUS_UNSUCCESSFUL;
1810 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1811 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
1812 ldap_msgfree(result);
1814 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, False);
1815 if (NT_STATUS_IS_ERR(ret)) {
1816 DEBUG(0,("failed to modify user with uid = %s\n",
1817 pdb_get_username(newpwd)));
1818 ldap_mods_free(mods,1);
1824 ("successfully modified uid = %s in the LDAP database\n",
1825 pdb_get_username(newpwd)));
1826 ldap_mods_free(mods, 1);
1827 return NT_STATUS_OK;
1830 /**********************************************************************
1831 Add SAM_ACCOUNT to LDAP
1832 *********************************************************************/
1833 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
1835 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1836 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1839 LDAPMessage *result = NULL;
1841 LDAPMod **mods = NULL;
1845 const char *username = pdb_get_username(newpwd);
1846 if (!username || !*username) {
1847 DEBUG(0, ("Cannot add user without a username!\n"));
1848 return NT_STATUS_INVALID_PARAMETER;
1851 rc = ldapsam_search_one_user_by_name (ldap_state, username, &result);
1852 if (rc != LDAP_SUCCESS) {
1853 return NT_STATUS_UNSUCCESSFUL;
1856 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
1857 DEBUG(0,("User already in the base, with samba properties\n"));
1858 ldap_msgfree(result);
1859 return NT_STATUS_UNSUCCESSFUL;
1861 ldap_msgfree(result);
1863 slprintf (filter, sizeof (filter) - 1, "uid=%s", username);
1864 rc = ldapsam_search_one_user(ldap_state, filter, &result);
1865 if (rc != LDAP_SUCCESS) {
1866 return NT_STATUS_UNSUCCESSFUL;
1869 num_result = ldap_count_entries(ldap_state->ldap_struct, result);
1871 if (num_result > 1) {
1872 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
1873 ldap_msgfree(result);
1874 return NT_STATUS_UNSUCCESSFUL;
1877 /* Check if we need to update an existing entry */
1878 if (num_result == 1) {
1882 DEBUG(3,("User exists without samba properties: adding them\n"));
1883 ldap_op = LDAP_MOD_REPLACE;
1884 entry = ldap_first_entry (ldap_state->ldap_struct, result);
1885 tmp = ldap_get_dn (ldap_state->ldap_struct, entry);
1886 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
1889 /* Check if we need to add an entry */
1890 DEBUG(3,("Adding new user\n"));
1891 ldap_op = LDAP_MOD_ADD;
1892 if (username[strlen(username)-1] == '$') {
1893 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
1895 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
1899 ldap_msgfree(result);
1901 if (!init_ldap_from_sam(ldap_state, &mods, ldap_op, True, newpwd)) {
1902 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
1903 ldap_mods_free(mods, 1);
1904 return NT_STATUS_UNSUCCESSFUL;
1908 DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
1909 return NT_STATUS_UNSUCCESSFUL;
1912 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
1914 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, True);
1915 if (NT_STATUS_IS_ERR(ret)) {
1916 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
1917 pdb_get_username(newpwd),dn));
1918 ldap_mods_free(mods,1);
1922 DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd)));
1923 ldap_mods_free(mods, 1);
1924 return NT_STATUS_OK;
1927 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
1928 DOM_SID sid, BOOL with_priv)
1930 return get_group_map_from_sid(sid, map, with_priv) ?
1931 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1934 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
1935 gid_t gid, BOOL with_priv)
1937 return get_group_map_from_gid(gid, map, with_priv) ?
1938 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1941 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
1942 char *name, BOOL with_priv)
1944 return get_group_map_from_ntname(name, map, with_priv) ?
1945 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1948 static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
1951 return add_mapping_entry(map, TDB_INSERT) ?
1952 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1955 static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
1958 return add_mapping_entry(map, TDB_REPLACE) ?
1959 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1962 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
1965 return group_map_remove(sid) ?
1966 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1969 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
1970 enum SID_NAME_USE sid_name_use,
1971 GROUP_MAP **rmap, int *num_entries,
1972 BOOL unix_only, BOOL with_priv)
1974 return enum_group_mapping(sid_name_use, rmap, num_entries, unix_only,
1976 NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1979 static void free_private_data(void **vp)
1981 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
1983 ldapsam_close(*ldap_state);
1985 if ((*ldap_state)->bind_secret) {
1986 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
1989 ldapsam_close(*ldap_state);
1991 SAFE_FREE((*ldap_state)->bind_dn);
1992 SAFE_FREE((*ldap_state)->bind_secret);
1996 /* No need to free any further, as it is talloc()ed */
1999 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2002 struct ldapsam_privates *ldap_state;
2004 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
2008 (*pdb_method)->name = "ldapsam";
2010 (*pdb_method)->setsampwent = ldapsam_setsampwent;
2011 (*pdb_method)->endsampwent = ldapsam_endsampwent;
2012 (*pdb_method)->getsampwent = ldapsam_getsampwent;
2013 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
2014 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
2015 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
2016 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
2017 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
2018 (*pdb_method)->getgrsid = ldapsam_getgrsid;
2019 (*pdb_method)->getgrgid = ldapsam_getgrgid;
2020 (*pdb_method)->getgrnam = ldapsam_getgrnam;
2021 (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
2022 (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
2023 (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
2024 (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
2026 /* TODO: Setup private data and free */
2028 ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct ldapsam_privates));
2031 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
2032 return NT_STATUS_NO_MEMORY;
2036 ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
2037 #ifdef WITH_LDAP_SAMCONFIG
2039 int ldap_port = lp_ldap_port();
2041 /* remap default port if not using SSL (ie clear or TLS) */
2042 if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
2046 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);
2047 if (!ldap_state->uri) {
2048 return NT_STATUS_NO_MEMORY;
2052 ldap_state->uri = "ldap://localhost";
2056 (*pdb_method)->private_data = ldap_state;
2058 (*pdb_method)->free_private_data = free_private_data;
2060 return NT_STATUS_OK;
2063 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2066 struct ldapsam_privates *ldap_state;
2067 uint32 low_nua_uid, high_nua_uid;
2069 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) {
2073 (*pdb_method)->name = "ldapsam_nua";
2075 ldap_state = (*pdb_method)->private_data;
2077 ldap_state->permit_non_unix_accounts = True;
2079 if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) {
2080 DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n"));
2081 return NT_STATUS_UNSUCCESSFUL;
2084 ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid);
2086 ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid);
2088 return NT_STATUS_OK;
2094 NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2096 DEBUG(0, ("ldap not detected at configure time, ldapsam not availalble!\n"));
2097 return NT_STATUS_UNSUCCESSFUL;
2100 NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
2102 DEBUG(0, ("ldap not dectected at configure time, ldapsam_nua not available!\n"));
2103 return NT_STATUS_UNSUCCESSFUL;