2 Unix SMB/CIFS mplementation.
3 LDAP protocol helper functions for SAMBA
4 Copyright (C) Jean François Micouleau 1998
5 Copyright (C) Gerald Carter 2001-2003
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.
27 * persistent connections: if using NSS LDAP, many connections are made
28 * however, using only one within Samba would be nice
30 * Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
32 * Other LDAP based login attributes: accountExpires, etc.
33 * (should be the domain of Samba proper, but the sam_password/SAM_ACCOUNT
34 * structures don't have fields for some of these attributes)
36 * SSL is done, but can't get the certificate based authentication to work
37 * against on my test platform (Linux 2.4, OpenLDAP 2.x)
40 /* NOTE: this will NOT work against an Active Directory server
41 * due to the fact that the two password fields cannot be retrieved
42 * from a server; recommend using security = domain in this situation
49 #define DBGC_CLASS DBGC_PASSDB
54 #ifndef LDAP_OPT_SUCCESS
55 #define LDAP_OPT_SUCCESS 0
58 #if defined(LDAP_EXOP_X_MODIFY_PASSWD) && !defined(LDAP_EXOP_MODIFY_PASSWD)
59 #define LDAP_EXOP_MODIFY_PASSWD LDAP_EXOP_X_MODIFY_PASSWD
60 #elif !defined(LDAP_EXOP_MODIFY_PASSWD)
61 #define "1.3.6.1.4.1.4203.1.11.1"
64 #if defined(LDAP_EXOP_X_MODIFY_PASSWD_ID) && !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
65 #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID LDAP_EXOP_X_MODIFY_PASSWD_ID
66 #elif !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
67 #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U)
70 #if defined(LDAP_EXOP_X_MODIFY_PASSWD_NEW) && !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
71 #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW LDAP_EXOP_X_MODIFY_PASSWD_NEW
72 #elif !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
73 #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U)
77 #define SAM_ACCOUNT struct sam_passwd
82 struct ldapsam_privates {
83 struct smbldap_state *smbldap_state;
90 const char *domain_name;
93 /* configuration items */
96 BOOL permit_non_unix_accounts;
98 uint32 low_allocated_user_rid;
99 uint32 high_allocated_user_rid;
101 uint32 low_allocated_group_rid;
102 uint32 high_allocated_group_rid;
106 #define SMBLDAP_DONT_PING_TIME 10 /* ping only all 10 seconds */
107 #define SMBLDAP_NUM_RETRIES 8 /* retry only 8 times */
109 /**********************************************************************
110 get the attribute name given a user schame version
111 **********************************************************************/
113 static const char* get_userattr_key2string( int schema_ver, int key )
115 switch ( schema_ver )
117 case SCHEMAVER_SAMBAACCOUNT:
118 return get_attr_key2string( attrib_map_v22, key );
120 case SCHEMAVER_SAMBASAMACCOUNT:
121 return get_attr_key2string( attrib_map_v30, key );
124 DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
130 /**********************************************************************
131 return the list of attribute names given a user schema version
132 **********************************************************************/
134 static char** get_userattr_list( int schema_ver )
136 switch ( schema_ver )
138 case SCHEMAVER_SAMBAACCOUNT:
139 return get_attr_list( attrib_map_v22 );
141 case SCHEMAVER_SAMBASAMACCOUNT:
142 return get_attr_list( attrib_map_v30 );
144 DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
151 /**********************************************************************
152 Some varients of the LDAP rebind code do not pass in the third 'arg'
153 pointer to a void*, so we try and work around it by assuming that the
154 value of the 'LDAP *' pointer is the same as the one we had passed in
155 **********************************************************************/
157 struct smbldap_state_lookup {
159 struct smbldap_state *smbldap_state;
160 struct smbldap_state_lookup *prev, *next;
163 static struct smbldap_state_lookup *smbldap_state_lookup_list;
165 static struct smbldap_state *smbldap_find_state(LDAP *ld)
167 struct smbldap_state_lookup *t;
169 for (t = smbldap_state_lookup_list; t; t = t->next) {
171 return t->smbldap_state;
177 static void smbldap_delete_state(struct smbldap_state *smbldap_state)
179 struct smbldap_state_lookup *t;
181 for (t = smbldap_state_lookup_list; t; t = t->next) {
182 if (t->smbldap_state == smbldap_state) {
183 DLIST_REMOVE(smbldap_state_lookup_list, t);
189 static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state)
191 struct smbldap_state *tmp_ldap_state;
192 struct smbldap_state_lookup *t;
193 struct smbldap_state_lookup *tmp;
195 if ((tmp_ldap_state = smbldap_find_state(ld))) {
196 SMB_ASSERT(tmp_ldap_state == smbldap_state);
200 t = smb_xmalloc(sizeof(*t));
203 DLIST_ADD_END(smbldap_state_lookup_list, t, tmp);
205 t->smbldap_state = smbldap_state;
208 /*******************************************************************
209 open a connection to the ldap server.
210 ******************************************************************/
211 static int smbldap_open_connection (struct smbldap_state *ldap_state)
214 int rc = LDAP_SUCCESS;
216 BOOL ldap_v3 = False;
217 LDAP **ldap_struct = &ldap_state->ldap_struct;
219 #ifdef HAVE_LDAP_INITIALIZE
220 DEBUG(10, ("smbldap_open_connection: %s\n", ldap_state->uri));
222 if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) {
223 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
228 /* Parse the string manually */
234 const char *p = ldap_state->uri;
235 SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
237 /* skip leading "URL:" (if any) */
238 if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
242 sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port);
245 if (strequal(protocol, "ldap")) {
247 } else if (strequal(protocol, "ldaps")) {
250 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
254 if ((*ldap_struct = ldap_init(host, port)) == NULL) {
255 DEBUG(0, ("ldap_init failed !\n"));
256 return LDAP_OPERATIONS_ERROR;
259 if (strequal(protocol, "ldaps")) {
260 #ifdef LDAP_OPT_X_TLS
261 int tls = LDAP_OPT_X_TLS_HARD;
262 if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
264 DEBUG(0, ("Failed to setup a TLS session\n"));
267 DEBUG(3,("LDAPS option set...!\n"));
269 DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
270 return LDAP_OPERATIONS_ERROR;
276 /* Store the LDAP pointer in a lookup list */
278 smbldap_store_state(*ldap_struct, ldap_state);
280 /* Upgrade to LDAPv3 if possible */
282 if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
284 if (version != LDAP_VERSION3)
286 version = LDAP_VERSION3;
287 if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
295 if (lp_ldap_ssl() == LDAP_SSL_START_TLS) {
296 #ifdef LDAP_OPT_X_TLS
298 if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
300 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
301 ldap_err2string(rc)));
304 DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
307 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
308 return LDAP_OPERATIONS_ERROR;
311 DEBUG(0,("smbldap_open_connection: StartTLS not supported by LDAP client libraries!\n"));
312 return LDAP_OPERATIONS_ERROR;
316 DEBUG(2, ("smbldap_open_connection: connection opened\n"));
321 /*******************************************************************
322 a rebind function for authenticated referrals
323 This version takes a void* that we can shove useful stuff in :-)
324 ******************************************************************/
325 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
327 static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
328 int *methodp, int freeit, void *arg)
330 struct smbldap_state *ldap_state = arg;
332 /** @TODO Should we be doing something to check what servers we rebind to?
333 Could we get a referral to a machine that we don't want to give our
334 username and password to? */
338 memset(*credp, '\0', strlen(*credp));
341 DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
342 ldap_state->bind_dn));
344 *whop = strdup(ldap_state->bind_dn);
346 return LDAP_NO_MEMORY;
348 *credp = strdup(ldap_state->bind_secret);
351 return LDAP_NO_MEMORY;
353 *methodp = LDAP_AUTH_SIMPLE;
357 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
359 /*******************************************************************
360 a rebind function for authenticated referrals
361 This version takes a void* that we can shove useful stuff in :-)
362 and actually does the connection.
363 ******************************************************************/
364 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
365 static int rebindproc_connect_with_state (LDAP *ldap_struct,
366 LDAP_CONST char *url,
368 ber_int_t msgid, void *arg)
370 struct smbldap_state *ldap_state = arg;
372 DEBUG(5,("rebindproc_connect_with_state: Rebinding as \"%s\"\n",
373 ldap_state->bind_dn));
375 /** @TODO Should we be doing something to check what servers we rebind to?
376 Could we get a referral to a machine that we don't want to give our
377 username and password to? */
379 rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
383 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
385 /*******************************************************************
386 Add a rebind function for authenticated referrals
387 ******************************************************************/
388 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
390 # if LDAP_SET_REBIND_PROC_ARGS == 2
391 static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
392 int *method, int freeit )
394 struct smbldap_state *ldap_state = smbldap_find_state(ldap_struct);
396 return rebindproc_with_state(ldap_struct, whop, credp,
397 method, freeit, ldap_state);
400 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
401 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
403 /*******************************************************************
404 a rebind function for authenticated referrals
405 this also does the connection, but no void*.
406 ******************************************************************/
407 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
408 # if LDAP_SET_REBIND_PROC_ARGS == 2
409 static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
412 struct smbldap_state *ldap_state = smbldap_find_state(ld);
414 return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid,
417 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
418 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
420 /*******************************************************************
421 connect to the ldap server under system privilege.
422 ******************************************************************/
423 static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_struct)
429 /* get the password */
430 if (!fetch_ldap_pw(&ldap_dn, &ldap_secret))
432 DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
433 return LDAP_INVALID_CREDENTIALS;
436 ldap_state->bind_dn = ldap_dn;
437 ldap_state->bind_secret = ldap_secret;
439 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
440 (OpenLDAP) doesnt' seem to support it */
442 DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
443 ldap_state->uri, ldap_dn));
445 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
446 # if LDAP_SET_REBIND_PROC_ARGS == 2
447 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);
449 # if LDAP_SET_REBIND_PROC_ARGS == 3
450 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);
452 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
453 # if LDAP_SET_REBIND_PROC_ARGS == 2
454 ldap_set_rebind_proc(ldap_struct, &rebindproc);
456 # if LDAP_SET_REBIND_PROC_ARGS == 3
457 ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);
459 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
461 rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
463 if (rc != LDAP_SUCCESS) {
464 char *ld_error = NULL;
465 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
467 DEBUG(ldap_state->num_failures ? 2 : 0,
468 ("failed to bind to server with dn= %s Error: %s\n\t%s\n",
469 ldap_dn ? ldap_dn : "(unknown)", ldap_err2string(rc),
470 ld_error ? ld_error : "(unknown)"));
472 ldap_state->num_failures++;
476 ldap_state->num_failures = 0;
478 DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));
482 /**********************************************************************
483 Connect to LDAP server (called before every ldap operation)
484 *********************************************************************/
485 static int smbldap_open(struct smbldap_state *ldap_state)
488 SMB_ASSERT(ldap_state);
490 #ifndef NO_LDAP_SECURITY
491 if (geteuid() != 0) {
492 DEBUG(0, ("smbldap_open: cannot access LDAP when not root..\n"));
493 return LDAP_INSUFFICIENT_ACCESS;
497 if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {
498 struct sockaddr_un addr;
499 socklen_t len = sizeof(addr);
501 if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
502 getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
503 /* the other end has died. reopen. */
504 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
505 ldap_state->ldap_struct = NULL;
506 ldap_state->last_ping = (time_t)0;
508 ldap_state->last_ping = time(NULL);
512 if (ldap_state->ldap_struct != NULL) {
513 DEBUG(5,("smbldap_open: already connected to the LDAP server\n"));
517 if ((rc = smbldap_open_connection(ldap_state))) {
521 if ((rc = smbldap_connect_system(ldap_state, ldap_state->ldap_struct))) {
522 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
523 ldap_state->ldap_struct = NULL;
528 ldap_state->last_ping = time(NULL);
529 DEBUG(4,("The LDAP server is succesful connected\n"));
534 /**********************************************************************
535 Disconnect from LDAP server
536 *********************************************************************/
537 static NTSTATUS smbldap_close(struct smbldap_state *ldap_state)
540 return NT_STATUS_INVALID_PARAMETER;
542 if (ldap_state->ldap_struct != NULL) {
543 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
544 ldap_state->ldap_struct = NULL;
547 smbldap_delete_state(ldap_state);
549 DEBUG(5,("The connection to the LDAP server was closed\n"));
550 /* maybe free the results here --metze */
557 static int smbldap_retry_open(struct smbldap_state *ldap_state, int *attempts)
561 SMB_ASSERT(ldap_state && attempts);
563 if (*attempts != 0) {
564 unsigned int sleep_time;
567 /* Sleep for a random timeout */
568 rand_byte = (char)(sys_random());
570 sleep_time = (((*attempts)*(*attempts))/2)*rand_byte*2;
571 /* we retry after (0.5, 1, 2, 3, 4.5, 6) seconds
574 DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n",
580 if ((rc = smbldap_open(ldap_state))) {
581 DEBUG(1,("Connection to LDAP Server failed for the %d try!\n",*attempts));
589 /*********************************************************************
590 ********************************************************************/
592 static int smbldap_search(struct smbldap_state *ldap_state,
593 const char *base, int scope, const char *filter,
594 char *attrs[], int attrsonly,
597 int rc = LDAP_SERVER_DOWN;
601 SMB_ASSERT(ldap_state);
603 if (push_utf8_allocate(&utf8_filter, filter) == (size_t)-1) {
604 return LDAP_NO_MEMORY;
607 while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
609 if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
612 rc = ldap_search_s(ldap_state->ldap_struct, base, scope,
613 utf8_filter, attrs, attrsonly, res);
616 if (rc == LDAP_SERVER_DOWN) {
617 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
618 smbldap_close(ldap_state);
621 SAFE_FREE(utf8_filter);
625 static int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
627 int rc = LDAP_SERVER_DOWN;
631 SMB_ASSERT(ldap_state);
633 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
634 return LDAP_NO_MEMORY;
637 while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
639 if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
642 rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
645 if (rc == LDAP_SERVER_DOWN) {
646 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
647 smbldap_close(ldap_state);
654 static int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
656 int rc = LDAP_SERVER_DOWN;
660 SMB_ASSERT(ldap_state);
662 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
663 return LDAP_NO_MEMORY;
666 while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
668 if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
671 rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
674 if (rc == LDAP_SERVER_DOWN) {
675 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
676 smbldap_close(ldap_state);
683 static int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
685 int rc = LDAP_SERVER_DOWN;
689 SMB_ASSERT(ldap_state);
691 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
692 return LDAP_NO_MEMORY;
695 while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
697 if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
700 rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
703 if (rc == LDAP_SERVER_DOWN) {
704 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
705 smbldap_close(ldap_state);
712 static int smbldap_extended_operation(struct smbldap_state *ldap_state,
713 LDAP_CONST char *reqoid, struct berval *reqdata,
714 LDAPControl **serverctrls, LDAPControl **clientctrls,
715 char **retoidp, struct berval **retdatap)
717 int rc = LDAP_SERVER_DOWN;
723 while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
725 if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
728 rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata,
729 serverctrls, clientctrls, retoidp, retdatap);
732 if (rc == LDAP_SERVER_DOWN) {
733 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
734 smbldap_close(ldap_state);
740 /*******************************************************************
741 run the search by name.
742 ******************************************************************/
743 static int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter,
744 char **search_attr, LDAPMessage ** result)
746 int scope = LDAP_SCOPE_SUBTREE;
749 DEBUG(2, ("smbldap_search_suffix: searching for:[%s]\n", filter));
751 rc = smbldap_search(ldap_state, lp_ldap_suffix(), scope, filter, search_attr, 0, result);
753 if (rc != LDAP_SUCCESS) {
754 char *ld_error = NULL;
755 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
757 DEBUG(0,("smbldap_search_suffix: Problem during the LDAP search: %s (%s)\n",
758 ld_error?ld_error:"(unknown)", ldap_err2string (rc)));
759 DEBUG(3,("smbldap_search_suffix: Query was: %s, %s\n", lp_ldap_suffix(),
767 /*******************************************************************
768 generate the LDAP search filter for the objectclass based on the
769 version of the schema we are using
770 ******************************************************************/
772 static const char* get_objclass_filter( int schema_ver )
774 static fstring objclass_filter;
778 case SCHEMAVER_SAMBAACCOUNT:
779 snprintf( objclass_filter, sizeof(objclass_filter)-1, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT );
781 case SCHEMAVER_SAMBASAMACCOUNT:
782 snprintf( objclass_filter, sizeof(objclass_filter)-1, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
785 DEBUG(0,("pdb_ldapsam: get_objclass_filter(): Invalid schema version specified!\n"));
789 return objclass_filter;
792 /*******************************************************************
793 run the search by name.
794 ******************************************************************/
795 static int ldapsam_search_suffix_by_name (struct ldapsam_privates *ldap_state,
797 LDAPMessage ** result, char **attr)
800 char *escape_user = escape_ldap_string_alloc(user);
803 return LDAP_NO_MEMORY;
807 * in the filter expression, replace %u with the real name
808 * so in ldap filter, %u MUST exist :-)
810 snprintf(filter, sizeof(filter)-1, "(&%s%s)", lp_ldap_filter(),
811 get_objclass_filter(ldap_state->schema_ver));
814 * have to use this here because $ is filtered out
819 all_string_sub(filter, "%u", escape_user, sizeof(pstring));
820 SAFE_FREE(escape_user);
822 return smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
825 /*******************************************************************
826 run the search by rid.
827 ******************************************************************/
828 static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
829 uint32 rid, LDAPMessage ** result,
835 /* check if the user rid exists, if not, try searching on the uid */
837 snprintf(filter, sizeof(filter)-1, "(&(rid=%i)%s)", rid,
838 get_objclass_filter(ldap_state->schema_ver));
840 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
845 /*******************************************************************
846 run the search by SID.
847 ******************************************************************/
848 static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
849 const DOM_SID *sid, LDAPMessage ** result,
856 /* check if the user rid exsists, if not, try searching on the uid */
858 snprintf(filter, sizeof(filter)-1, "(&(%s=%s)%s)",
859 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
860 sid_to_string(sid_string, sid),
861 get_objclass_filter(ldap_state->schema_ver));
863 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
868 /*******************************************************************
869 search an attribute and return the first value found.
870 ******************************************************************/
871 static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
872 const char *attribute, pstring value)
881 if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
882 DEBUG (10, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute));
887 if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, sizeof(pstring)) == (size_t)-1)
889 DEBUG(1, ("get_single_attribute: string conversion of [%s] = [%s] failed!\n",
890 attribute, values[0]));
891 ldap_value_free(values);
895 ldap_value_free(values);
896 #ifdef DEBUG_PASSWORDS
897 DEBUG (100, ("get_single_attribute: [%s] = [%s]\n", attribute, value));
902 /**********************************************************************
903 Set attribute to newval in LDAP, regardless of what value the
904 attribute had in LDAP before.
905 *********************************************************************/
906 static void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
908 const char *attribute, const char *newval)
910 char **values = NULL;
912 if (existing != NULL) {
913 values = ldap_get_values(ldap_struct, existing, attribute);
916 /* all of our string attributes are case insensitive */
918 if ((values != NULL) && (values[0] != NULL) &&
919 StrCaseCmp(values[0], newval) == 0)
922 /* Believe it or not, but LDAP will deny a delete and
923 an add at the same time if the values are the
926 ldap_value_free(values);
930 /* Regardless of the real operation (add or modify)
931 we add the new value here. We rely on deleting
932 the old value, should it exist. */
934 if ((newval != NULL) && (strlen(newval) > 0)) {
935 smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
938 if (values == NULL) {
939 /* There has been no value before, so don't delete it.
940 Here's a possible race: We might end up with
941 duplicate attributes */
945 /* By deleting exactly the value we found in the entry this
946 should be race-free in the sense that the LDAP-Server will
947 deny the complete operation if somebody changed the
948 attribute behind our back. */
950 smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, values[0]);
951 ldap_value_free(values);
954 /*******************************************************************
955 Delete complete object or objectclass and attrs from
956 object found in search_result depending on lp_ldap_delete_dn
957 ******************************************************************/
958 static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
960 const char *objectclass,
965 LDAPMod **mods = NULL;
967 BerElement *ptr = NULL;
969 rc = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
972 DEBUG(0, ("Entry must exist exactly once!\n"));
973 return NT_STATUS_UNSUCCESSFUL;
976 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
977 dn = ldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
979 if (lp_ldap_delete_dn()) {
980 NTSTATUS ret = NT_STATUS_OK;
981 rc = smbldap_delete(ldap_state->smbldap_state, dn);
983 if (rc != LDAP_SUCCESS) {
984 DEBUG(0, ("Could not delete object %s\n", dn));
985 ret = NT_STATUS_UNSUCCESSFUL;
991 /* Ok, delete only the SAM attributes */
993 for (name = ldap_first_attribute(ldap_state->smbldap_state->ldap_struct, entry, &ptr);
995 name = ldap_next_attribute(ldap_state->smbldap_state->ldap_struct, entry, ptr))
999 /* We are only allowed to delete the attributes that
1002 for (attrib = attrs; *attrib != NULL; attrib++)
1004 if (StrCaseCmp(*attrib, name) == 0) {
1005 DEBUG(10, ("deleting attribute %s\n", name));
1006 smbldap_set_mod(&mods, LDAP_MOD_DELETE, name, NULL);
1017 smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
1019 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
1020 ldap_mods_free(mods, True);
1022 if (rc != LDAP_SUCCESS) {
1023 char *ld_error = NULL;
1024 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1027 DEBUG(0, ("could not delete attributes for %s, error: %s (%s)\n",
1028 dn, ldap_err2string(rc), ld_error?ld_error:"unknown"));
1029 SAFE_FREE(ld_error);
1031 return NT_STATUS_UNSUCCESSFUL;
1035 return NT_STATUS_OK;
1038 /**********************************************************************
1039 Search for the domain info entry
1040 *********************************************************************/
1041 static int ldapsam_search_domain_info(struct ldapsam_privates *ldap_state,
1042 LDAPMessage ** result)
1048 snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))",
1050 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
1051 ldap_state->domain_name);
1053 DEBUG(2, ("Searching for:[%s]\n", filter));
1056 attr_list = get_attr_list( dominfo_attr_list );
1057 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
1058 attr_list , result);
1059 free_attr_list( attr_list );
1061 if (rc != LDAP_SUCCESS) {
1062 DEBUG(2,("Problem during LDAPsearch: %s\n", ldap_err2string (rc)));
1063 DEBUG(2,("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1069 /**********************************************************************
1070 If this entry is is the 'allocated' range, extract the RID and return
1071 it, so we can find the 'next' rid to allocate.
1073 Do this, no matter what type of object holds the RID - be it a user,
1074 group or somthing else.
1075 *********************************************************************/
1076 static uint32 entry_to_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry, int rid_type)
1082 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1083 LDAP_ATTRIBUTE_SID, sid_string))
1088 if (!string_to_sid(&dom_sid, sid_string)) {
1092 if (!sid_peek_check_rid(&dom_sid, get_global_sam_sid(), &rid)) {
1093 /* not our domain, so we don't care */
1099 if (rid >= ldap_state->low_allocated_user_rid &&
1100 rid <= ldap_state->high_allocated_user_rid) {
1104 case GROUP_RID_TYPE:
1105 if (rid >= ldap_state->low_allocated_group_rid &&
1106 rid <= ldap_state->high_allocated_group_rid) {
1115 /**********************************************************************
1116 Connect to LDAP server and find the next available 'allocated' RID.
1118 The search is done 'per type' as we allocate seperate pools for the
1119 EVEN and ODD (user and group) RIDs.
1121 This is only done once, so that we can fill out the sambaDomain.
1122 *********************************************************************/
1123 static uint32 search_next_allocated_rid(struct ldapsam_privates *ldap_state, int rid_type)
1126 LDAPMessage *result;
1132 char *sid_attr[] = {LDAP_ATTRIBUTE_SID, NULL};
1135 snprintf( filter, sizeof(filter)-1, "(%s=*)", LDAP_ATTRIBUTE_SID );
1137 DEBUG(2, ("search_top_allocated_rid: searching for:[%s]\n", filter));
1139 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
1142 if (rc != LDAP_SUCCESS) {
1143 DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc)));
1144 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1150 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1151 DEBUG(2, ("search_top_allocated_rid: %d entries in the base!\n", count));
1154 DEBUG(3, ("LDAP search returned no records, assuming no allocated RIDs present!: %s\n", ldap_err2string(rc)));
1155 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1157 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,result);
1159 top_rid = entry_to_rid(ldap_state, entry, rid_type);
1161 while ((entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct, entry))) {
1163 rid = entry_to_rid(ldap_state, entry, rid_type);
1164 if (((rid & ~RID_TYPE_MASK) == rid_type) && (rid > top_rid)) {
1172 if (top_rid < ldap_state->low_allocated_user_rid) {
1173 return ldap_state->low_allocated_user_rid;
1176 case GROUP_RID_TYPE:
1177 if (top_rid < ldap_state->low_allocated_group_rid)
1178 return ldap_state->low_allocated_group_rid;
1182 next_rid = (top_rid & ~RID_TYPE_MASK) + rid_type + RID_MULTIPLIER;
1186 if (next_rid > ldap_state->high_allocated_user_rid) {
1190 case GROUP_RID_TYPE:
1191 if (next_rid > ldap_state->high_allocated_group_rid) {
1199 /**********************************************************************
1200 Add the sambaDomain to LDAP, so we don't have to search for this stuff
1201 again. This is a once-add operation for now.
1203 TODO: Add other attributes, and allow modification.
1204 *********************************************************************/
1205 static NTSTATUS add_new_domain_info(struct ldapsam_privates *ldap_state)
1209 LDAPMod **mods = NULL;
1212 LDAPMessage *result = NULL;
1216 uint32 next_allocated_user_rid;
1217 uint32 next_allocated_group_rid;
1219 next_allocated_user_rid = search_next_allocated_rid(ldap_state, USER_RID_TYPE);
1220 if (!next_allocated_user_rid) {
1221 return NT_STATUS_UNSUCCESSFUL;
1224 next_allocated_group_rid = search_next_allocated_rid(ldap_state, GROUP_RID_TYPE);
1225 if (!next_allocated_group_rid) {
1226 return NT_STATUS_UNSUCCESSFUL;
1229 slprintf (filter, sizeof (filter) - 1, "(&(%s=%s)(objectclass=%s))",
1230 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
1231 ldap_state->domain_name, LDAP_OBJ_DOMINFO);
1233 attr_list = get_attr_list( dominfo_attr_list );
1234 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
1235 attr_list, &result);
1236 free_attr_list( attr_list );
1238 if (rc != LDAP_SUCCESS) {
1239 return NT_STATUS_UNSUCCESSFUL;
1242 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1244 if (num_result > 1) {
1245 DEBUG (0, ("More than domain with that name exists: bailing out!\n"));
1246 ldap_msgfree(result);
1247 return NT_STATUS_UNSUCCESSFUL;
1250 /* Check if we need to add an entry */
1251 DEBUG(3,("Adding new domain\n"));
1252 ldap_op = LDAP_MOD_ADD;
1253 snprintf(dn, sizeof(dn), "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
1254 ldap_state->domain_name, lp_ldap_suffix());
1256 /* Free original search */
1257 ldap_msgfree(result);
1259 /* make the changes - the entry *must* not already have samba attributes */
1260 smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
1261 ldap_state->domain_name);
1263 sid_to_string(tmp, &ldap_state->domain_sid);
1264 smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), tmp);
1266 snprintf(tmp, sizeof(tmp)-1, "%i", next_allocated_user_rid);
1267 smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), tmp);
1269 snprintf(tmp, sizeof(tmp)-1, "%i", next_allocated_group_rid);
1270 smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID), tmp);
1272 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
1277 rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
1279 case LDAP_MOD_REPLACE:
1280 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
1283 DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
1284 return NT_STATUS_INVALID_PARAMETER;
1287 if (rc!=LDAP_SUCCESS) {
1288 char *ld_error = NULL;
1289 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1292 ("failed to %s domain dn= %s with: %s\n\t%s\n",
1293 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
1294 dn, ldap_err2string(rc),
1295 ld_error?ld_error:"unknown"));
1296 SAFE_FREE(ld_error);
1298 ldap_mods_free(mods, True);
1299 return NT_STATUS_UNSUCCESSFUL;
1302 DEBUG(2,("added: domain = %s in the LDAP database\n", ldap_state->domain_name));
1303 ldap_mods_free(mods, True);
1304 return NT_STATUS_OK;
1307 /**********************************************************************
1308 Even if the sambaAccount attribute in LDAP tells us that this RID is
1309 safe to use, always check before use.
1310 *********************************************************************/
1311 static BOOL sid_in_use(struct ldapsam_privates *ldap_state,
1312 const DOM_SID *sid, int *error)
1316 LDAPMessage *result = NULL;
1319 char *sid_attr[] = {LDAP_ATTRIBUTE_SID, NULL};
1321 slprintf(filter, sizeof(filter)-1, "(%s=%s)", LDAP_ATTRIBUTE_SID, sid_to_string(sid_string, sid));
1323 rc = smbldap_search_suffix(ldap_state->smbldap_state,
1324 filter, sid_attr, &result);
1326 if (rc != LDAP_SUCCESS) {
1327 char *ld_error = NULL;
1328 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
1329 DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n",
1330 sid_string, ld_error));
1331 SAFE_FREE(ld_error);
1337 if ((count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result)) > 0) {
1338 DEBUG(3, ("Sid %s already in use - trying next RID\n",
1340 ldap_msgfree(result);
1344 ldap_msgfree(result);
1346 /* good, sid is not in use */
1350 /**********************************************************************
1351 Set the new nextRid attribute, and return one we can use.
1353 This also checks that this RID is actually free - in case the admin
1354 manually stole it :-).
1355 *********************************************************************/
1356 static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *rid, int rid_type)
1358 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1360 LDAPMessage *result = NULL;
1361 LDAPMessage *entry = NULL;
1363 LDAPMod **mods = NULL;
1365 fstring old_rid_string;
1366 fstring next_rid_string;
1370 if ( ldap_state->schema_ver != SCHEMAVER_SAMBASAMACCOUNT ) {
1371 DEBUG(0, ("Allocated RIDs require the %s objectclass used by 'ldapsam'\n",
1372 LDAP_OBJ_SAMBASAMACCOUNT));
1373 return NT_STATUS_UNSUCCESSFUL;
1376 while (attempts < 10)
1379 if (ldapsam_search_domain_info(ldap_state, &result)) {
1383 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) < 1) {
1384 DEBUG(3, ("Got no domain info entries for domain %s\n",
1385 ldap_state->domain_name));
1386 ldap_msgfree(result);
1387 if (NT_STATUS_IS_OK(ret = add_new_domain_info(ldap_state))) {
1390 DEBUG(0, ("Adding domain info failed with %s\n", nt_errstr(ret)));
1395 if ((count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result)) > 1) {
1396 DEBUG(0, ("Got too many (%d) domain info entries for domain %s\n",
1397 count, ldap_state->domain_name));
1398 ldap_msgfree(result);
1402 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1404 ldap_msgfree(result);
1408 if ((dn = ldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry)) == NULL) {
1409 DEBUG(0, ("Could not get domain info DN\n"));
1410 ldap_msgfree(result);
1414 /* yes, we keep 2 seperate counters, to avoid stomping on the two
1415 different sets of algorithmic RIDs */
1419 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1420 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
1424 ldap_msgfree(result);
1428 case GROUP_RID_TYPE:
1429 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1430 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
1434 ldap_msgfree(result);
1440 /* This is the core of the whole routine. If we had
1441 scheme-style closures, there would be a *lot* less code
1443 *rid = (uint32)atol(old_rid_string);
1444 next_rid = *rid+RID_MULTIPLIER;
1446 slprintf(next_rid_string, sizeof(next_rid_string)-1, "%d", next_rid);
1450 if (next_rid > ldap_state->high_allocated_user_rid) {
1451 return NT_STATUS_UNSUCCESSFUL;
1454 /* Try to make the modification atomically by enforcing the
1455 old value in the delete mod. */
1456 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods,
1457 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
1461 case GROUP_RID_TYPE:
1462 if (next_rid > ldap_state->high_allocated_group_rid) {
1463 return NT_STATUS_UNSUCCESSFUL;
1466 /* Try to make the modification atomically by enforcing the
1467 old value in the delete mod. */
1468 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods,
1469 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
1474 if ((rc = ldap_modify_s(ldap_state->smbldap_state->ldap_struct, dn, mods)) == LDAP_SUCCESS) {
1477 pstring domain_sid_string;
1480 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, result,
1481 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID),
1484 ldap_mods_free(mods, True);
1486 ldap_msgfree(result);
1490 if (!string_to_sid(&dom_sid, domain_sid_string)) {
1491 ldap_mods_free(mods, True);
1493 ldap_msgfree(result);
1497 ldap_mods_free(mods, True);
1500 ldap_msgfree(result);
1502 sid_copy(&sid, &dom_sid);
1503 sid_append_rid(&sid, *rid);
1505 /* check RID is not in use */
1506 if (sid_in_use(ldap_state, &sid, &error)) {
1513 return NT_STATUS_OK;
1516 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
1517 DEBUG(2, ("Failed to modify rid: %s\n", ld_error));
1518 SAFE_FREE(ld_error);
1520 ldap_mods_free(mods, True);
1526 ldap_msgfree(result);
1530 /* Sleep for a random timeout */
1531 unsigned sleeptime = (sys_random()*sys_getpid()*attempts);
1539 DEBUG(0, ("Failed to set new RID\n"));
1543 /* New Interface is being implemented here */
1545 /**********************************************************************
1546 Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
1547 *********************************************************************/
1548 static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
1549 SAM_ACCOUNT * sampass,
1550 LDAPMessage * entry,
1558 if ((ldap_values = ldap_get_values (ldap_state->smbldap_state->ldap_struct, entry, "objectClass")) == NULL) {
1559 DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
1563 for (values=ldap_values;*values;values++) {
1564 if (strcasecmp(*values, LDAP_OBJ_POSIXACCOUNT ) == 0) {
1569 if (!*values) { /*end of array, no posixAccount */
1570 DEBUG(10, ("user does not have %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
1571 ldap_value_free(ldap_values);
1574 ldap_value_free(ldap_values);
1576 if ( !get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1577 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_UNIX_HOME), homedir) )
1582 if ( !get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1583 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_GIDNUMBER), temp) )
1588 *gid = (gid_t)atol(temp);
1590 pdb_set_unix_homedir(sampass, homedir, PDB_SET);
1592 DEBUG(10, ("user has %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
1598 /**********************************************************************
1599 Initialize SAM_ACCOUNT from an LDAP query
1600 (Based on init_sam_from_buffer in pdb_tdb.c)
1601 *********************************************************************/
1602 static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
1603 SAM_ACCOUNT * sampass,
1604 LDAPMessage * entry)
1610 pass_can_change_time,
1611 pass_must_change_time;
1624 uint8 smblmpwd[LM_HASH_LEN],
1625 smbntpwd[NT_HASH_LEN];
1626 uint16 acct_ctrl = 0,
1629 uint8 hours[MAX_HOURS_LEN];
1632 gid_t gid = getegid();
1635 * do a little initialization
1639 nt_username[0] = '\0';
1642 dir_drive[0] = '\0';
1643 logon_script[0] = '\0';
1644 profile_path[0] = '\0';
1645 acct_desc[0] = '\0';
1646 munged_dial[0] = '\0';
1647 workstations[0] = '\0';
1650 if (sampass == NULL || ldap_state == NULL || entry == NULL) {
1651 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
1655 if (ldap_state->smbldap_state->ldap_struct == NULL) {
1656 DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->ldap_struct is NULL!\n"));
1660 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, "uid", username)) {
1661 DEBUG(1, ("No uid attribute found for this user!\n"));
1665 DEBUG(2, ("Entry found for user: %s\n", username));
1667 pstrcpy(nt_username, username);
1669 pstrcpy(domain, ldap_state->domain_name);
1671 pdb_set_username(sampass, username, PDB_SET);
1673 pdb_set_domain(sampass, domain, PDB_DEFAULT);
1674 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1676 /* deal with different attributes between the schema first */
1678 if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT )
1680 if (get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1681 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), temp))
1683 pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
1686 if (get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1687 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_SID), temp))
1689 pdb_set_group_sid_from_string(sampass, temp, PDB_SET);
1693 pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
1700 if (get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1701 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), temp))
1703 user_rid = (uint32)atol(temp);
1704 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1707 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1708 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_RID), temp))
1710 pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
1714 group_rid = (uint32)atol(temp);
1716 /* for some reason, we often have 0 as a primary group RID.
1717 Make sure that we treat this just as a 'default' value */
1719 if ( group_rid > 0 )
1720 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
1722 pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
1726 if (pdb_get_init_flags(sampass,PDB_USERSID) == PDB_DEFAULT) {
1727 DEBUG(1, ("no %s or %s attribute found for this user %s\n",
1728 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
1729 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
1736 * If so configured, try and get the values from LDAP
1739 if (lp_ldap_trust_ids() && (get_unix_attributes(ldap_state, sampass, entry, &gid)))
1741 if (pdb_get_init_flags(sampass,PDB_GROUPSID) == PDB_DEFAULT)
1744 /* call the mapping code here */
1745 if(pdb_getgrgid(&map, gid)) {
1746 pdb_set_group_sid(sampass, &map.sid, PDB_SET);
1749 pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid), PDB_SET);
1754 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1755 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), temp))
1757 /* leave as default */
1759 pass_last_set_time = (time_t) atol(temp);
1760 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
1763 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1764 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp))
1766 /* leave as default */
1768 logon_time = (time_t) atol(temp);
1769 pdb_set_logon_time(sampass, logon_time, PDB_SET);
1772 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1773 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp))
1775 /* leave as default */
1777 logoff_time = (time_t) atol(temp);
1778 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
1781 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1782 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp))
1784 /* leave as default */
1786 kickoff_time = (time_t) atol(temp);
1787 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
1790 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1791 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp))
1793 /* leave as default */
1795 pass_can_change_time = (time_t) atol(temp);
1796 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
1799 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1800 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp))
1802 /* leave as default */
1804 pass_must_change_time = (time_t) atol(temp);
1805 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
1808 /* recommend that 'gecos' and 'displayName' should refer to the same
1809 * attribute OID. userFullName depreciated, only used by Samba
1810 * primary rules of LDAP: don't make a new attribute when one is already defined
1811 * that fits your needs; using cn then displayName rather than 'userFullName'
1814 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1815 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME), fullname))
1817 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1818 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_CN), fullname))
1820 /* leave as default */
1822 pdb_set_fullname(sampass, fullname, PDB_SET);
1825 pdb_set_fullname(sampass, fullname, PDB_SET);
1828 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1829 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), dir_drive))
1831 pdb_set_dir_drive(sampass, talloc_sub_specified(sampass->mem_ctx,
1837 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
1840 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1841 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), homedir))
1843 pdb_set_homedir(sampass, talloc_sub_specified(sampass->mem_ctx,
1849 pdb_set_homedir(sampass, homedir, PDB_SET);
1852 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1853 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), logon_script))
1855 pdb_set_logon_script(sampass, talloc_sub_specified(sampass->mem_ctx,
1861 pdb_set_logon_script(sampass, logon_script, PDB_SET);
1864 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1865 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), profile_path))
1867 pdb_set_profile_path(sampass, talloc_sub_specified(sampass->mem_ctx,
1873 pdb_set_profile_path(sampass, profile_path, PDB_SET);
1876 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1877 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC), acct_desc))
1879 /* leave as default */
1881 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
1884 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
1885 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), workstations))
1887 /* leave as default */;
1889 pdb_set_workstations(sampass, workstations, PDB_SET);
1892 /* FIXME: hours stuff should be cleaner */
1896 memset(hours, 0xff, hours_len);
1898 if (!get_single_attribute (ldap_state->smbldap_state->ldap_struct, entry,
1899 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), temp))
1901 /* leave as default */
1903 pdb_gethexpwd(temp, smblmpwd);
1904 memset((char *)temp, '\0', strlen(temp)+1);
1905 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
1907 ZERO_STRUCT(smblmpwd);
1910 if (!get_single_attribute (ldap_state->smbldap_state->ldap_struct, entry,
1911 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), temp))
1913 /* leave as default */
1915 pdb_gethexpwd(temp, smbntpwd);
1916 memset((char *)temp, '\0', strlen(temp)+1);
1917 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
1919 ZERO_STRUCT(smbntpwd);
1922 if (!get_single_attribute (ldap_state->smbldap_state->ldap_struct, entry,
1923 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), temp))
1925 acct_ctrl |= ACB_NORMAL;
1927 acct_ctrl = pdb_decode_acct_ctrl(temp);
1930 acct_ctrl |= ACB_NORMAL;
1932 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
1935 pdb_set_hours_len(sampass, hours_len, PDB_SET);
1936 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
1938 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
1940 /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
1941 /* pdb_set_unknown_5(sampass, unknown5, PDB_SET); */
1942 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
1944 pdb_set_hours(sampass, hours, PDB_SET);
1949 /**********************************************************************
1950 Initialize SAM_ACCOUNT from an LDAP query
1951 (Based on init_buffer_from_sam in pdb_tdb.c)
1952 *********************************************************************/
1953 static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
1954 LDAPMessage *existing,
1955 LDAPMod *** mods, SAM_ACCOUNT * sampass,
1956 BOOL (*need_update)(const SAM_ACCOUNT *,
1962 if (mods == NULL || sampass == NULL) {
1963 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
1970 * took out adding "objectclass: sambaAccount"
1971 * do this on a per-mod basis
1973 if (need_update(sampass, PDB_USERNAME))
1974 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1975 "uid", pdb_get_username(sampass));
1977 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
1979 if (pdb_get_init_flags(sampass, PDB_USERSID) == PDB_DEFAULT) {
1980 if (ldap_state->permit_non_unix_accounts) {
1981 if (!NT_STATUS_IS_OK(ldapsam_next_rid(ldap_state, &rid, USER_RID_TYPE))) {
1982 DEBUG(0, ("NO user RID specified on account %s, and "
1983 "finding next available NUA RID failed, "
1985 pdb_get_username(sampass)));
1986 ldap_mods_free(*mods, True);
1990 DEBUG(0, ("NO user RID specified on account %s, "
1991 "cannot store!\n", pdb_get_username(sampass)));
1992 ldap_mods_free(*mods, True);
1996 /* now that we have figured out the RID, always store it, as
1997 the schema requires it (either as a SID or a RID) */
1999 if (!pdb_set_user_sid_from_rid(sampass, rid, PDB_CHANGED)) {
2000 DEBUG(0, ("Could not store RID back onto SAM_ACCOUNT for user %s!\n",
2001 pdb_get_username(sampass)));
2002 ldap_mods_free(*mods, True);
2007 /* only update the RID if we actually need to */
2008 if (need_update(sampass, PDB_USERSID))
2011 fstring dom_sid_string;
2012 const DOM_SID *user_sid = pdb_get_user_sid(sampass);
2014 switch ( ldap_state->schema_ver )
2016 case SCHEMAVER_SAMBAACCOUNT:
2017 if (!sid_peek_check_rid(get_global_sam_sid(), user_sid, &rid)) {
2018 DEBUG(1, ("User's SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
2019 sid_to_string(sid_string, user_sid),
2020 sid_to_string(dom_sid_string, get_global_sam_sid())));
2023 slprintf(temp, sizeof(temp) - 1, "%i", rid);
2024 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2025 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
2029 case SCHEMAVER_SAMBASAMACCOUNT:
2030 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2031 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
2032 sid_to_string(sid_string, user_sid));
2036 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
2041 /* we don't need to store the primary group RID - so leaving it
2042 'free' to hang off the unix primary group makes life easier */
2044 if (need_update(sampass, PDB_GROUPSID))
2047 fstring dom_sid_string;
2048 const DOM_SID *group_sid = pdb_get_group_sid(sampass);
2050 switch ( ldap_state->schema_ver )
2052 case SCHEMAVER_SAMBAACCOUNT:
2053 if (!sid_peek_check_rid(get_global_sam_sid(), group_sid, &rid)) {
2054 DEBUG(1, ("User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
2055 sid_to_string(sid_string, group_sid),
2056 sid_to_string(dom_sid_string, get_global_sam_sid())));
2060 slprintf(temp, sizeof(temp) - 1, "%i", rid);
2061 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2062 get_userattr_key2string(ldap_state->schema_ver,
2063 LDAP_ATTR_PRIMARY_GROUP_RID), temp);
2066 case SCHEMAVER_SAMBASAMACCOUNT:
2067 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2068 get_userattr_key2string(ldap_state->schema_ver,
2069 LDAP_ATTR_PRIMARY_GROUP_SID), sid_to_string(sid_string, group_sid));
2073 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
2079 /* displayName, cn, and gecos should all be the same
2080 * most easily accomplished by giving them the same OID
2081 * gecos isn't set here b/c it should be handled by the
2083 * We change displayName only and fall back to cn if
2084 * it does not exist.
2087 if (need_update(sampass, PDB_FULLNAME))
2088 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2089 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME),
2090 pdb_get_fullname(sampass));
2092 if (need_update(sampass, PDB_ACCTDESC))
2093 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2094 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC),
2095 pdb_get_acct_desc(sampass));
2097 if (need_update(sampass, PDB_WORKSTATIONS))
2098 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2099 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS),
2100 pdb_get_workstations(sampass));
2102 if (need_update(sampass, PDB_SMBHOME))
2103 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2104 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH),
2105 pdb_get_homedir(sampass));
2107 if (need_update(sampass, PDB_DRIVE))
2108 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2109 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE),
2110 pdb_get_dir_drive(sampass));
2112 if (need_update(sampass, PDB_LOGONSCRIPT))
2113 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2114 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT),
2115 pdb_get_logon_script(sampass));
2117 if (need_update(sampass, PDB_PROFILE))
2118 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2119 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH),
2120 pdb_get_profile_path(sampass));
2122 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
2123 if (need_update(sampass, PDB_LOGONTIME))
2124 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2125 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
2127 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
2128 if (need_update(sampass, PDB_LOGOFFTIME))
2129 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2130 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
2132 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
2133 if (need_update(sampass, PDB_KICKOFFTIME))
2134 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2135 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
2137 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
2138 if (need_update(sampass, PDB_CANCHANGETIME))
2139 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2140 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
2142 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
2143 if (need_update(sampass, PDB_MUSTCHANGETIME))
2144 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2145 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp);
2147 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
2148 || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY))
2151 pdb_sethexpwd(temp, pdb_get_lanman_passwd(sampass),
2152 pdb_get_acct_ctrl(sampass));
2154 if (need_update(sampass, PDB_LMPASSWD))
2155 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2156 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
2159 pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass),
2160 pdb_get_acct_ctrl(sampass));
2162 if (need_update(sampass, PDB_NTPASSWD))
2163 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2164 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
2167 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
2168 if (need_update(sampass, PDB_PASSLASTSET))
2169 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2170 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET),
2174 /* FIXME: Hours stuff goes in LDAP */
2176 if (need_update(sampass, PDB_ACCTCTRL))
2177 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
2178 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO),
2179 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
2186 /**********************************************************************
2187 Connect to LDAP server for password enumeration
2188 *********************************************************************/
2189 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
2191 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2196 snprintf( filter, sizeof(filter)-1, "(&%s%s)", lp_ldap_filter(),
2197 get_objclass_filter(ldap_state->schema_ver));
2198 all_string_sub(filter, "%u", "*", sizeof(pstring));
2200 attr_list = get_userattr_list(ldap_state->schema_ver);
2201 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
2202 attr_list, &ldap_state->result);
2203 free_attr_list( attr_list );
2205 if (rc != LDAP_SUCCESS) {
2206 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
2207 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
2208 ldap_msgfree(ldap_state->result);
2209 ldap_state->result = NULL;
2210 return NT_STATUS_UNSUCCESSFUL;
2213 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
2214 ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
2215 ldap_state->result)));
2217 ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
2218 ldap_state->result);
2219 ldap_state->index = 0;
2221 return NT_STATUS_OK;
2224 /**********************************************************************
2225 End enumeration of the LDAP password list
2226 *********************************************************************/
2227 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
2229 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2230 if (ldap_state->result) {
2231 ldap_msgfree(ldap_state->result);
2232 ldap_state->result = NULL;
2236 /**********************************************************************
2237 Get the next entry in the LDAP password database
2238 *********************************************************************/
2239 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
2241 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2242 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2246 if (!ldap_state->entry)
2249 ldap_state->index++;
2250 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
2252 ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
2256 return NT_STATUS_OK;
2259 /**********************************************************************
2260 Get SAM_ACCOUNT entry from LDAP by username
2261 *********************************************************************/
2262 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
2264 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2265 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2266 LDAPMessage *result;
2272 attr_list = get_userattr_list( ldap_state->schema_ver );
2273 rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
2274 free_attr_list( attr_list );
2276 if ( rc != LDAP_SUCCESS )
2277 return NT_STATUS_NO_SUCH_USER;
2279 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2283 ("Unable to locate user [%s] count=%d\n", sname,
2285 return NT_STATUS_NO_SUCH_USER;
2286 } else if (count > 1) {
2288 ("Duplicate entries for this user [%s] Failing. count=%d\n", sname,
2290 return NT_STATUS_NO_SUCH_USER;
2293 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
2295 if (!init_sam_from_ldap(ldap_state, user, entry)) {
2296 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
2297 ldap_msgfree(result);
2298 return NT_STATUS_NO_SUCH_USER;
2300 ldap_msgfree(result);
2303 ldap_msgfree(result);
2308 /**********************************************************************
2309 Get SAM_ACCOUNT entry from LDAP by SID
2310 *********************************************************************/
2311 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
2313 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2314 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2315 LDAPMessage *result;
2322 switch ( ldap_state->schema_ver )
2324 case SCHEMAVER_SAMBASAMACCOUNT:
2325 attr_list = get_userattr_list(ldap_state->schema_ver);
2326 rc = ldapsam_search_suffix_by_sid(ldap_state, sid, &result, attr_list);
2327 free_attr_list( attr_list );
2329 if ( rc != LDAP_SUCCESS )
2330 return NT_STATUS_NO_SUCH_USER;
2333 case SCHEMAVER_SAMBAACCOUNT:
2336 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) {
2337 return NT_STATUS_NO_SUCH_USER;
2340 attr_list = get_userattr_list(ldap_state->schema_ver);
2341 rc = ldapsam_search_suffix_by_rid(ldap_state, rid, &result, attr_list );
2342 free_attr_list( attr_list );
2344 if ( rc != LDAP_SUCCESS )
2345 return NT_STATUS_NO_SUCH_USER;
2350 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2355 ("Unable to locate SID [%s] count=%d\n", sid_to_string(sid_string, sid),
2357 ldap_msgfree(result);
2358 return NT_STATUS_NO_SUCH_USER;
2363 ("More than one user with SID [%s]. Failing. count=%d\n", sid_to_string(sid_string, sid),
2365 ldap_msgfree(result);
2366 return NT_STATUS_NO_SUCH_USER;
2369 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
2372 if (!init_sam_from_ldap(ldap_state, user, entry)) {
2373 DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
2374 ldap_msgfree(result);
2375 return NT_STATUS_NO_SUCH_USER;
2379 ldap_msgfree(result);
2383 /********************************************************************
2384 Do the actual modification - also change a plaittext passord if
2386 **********************************************************************/
2388 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
2389 SAM_ACCOUNT *newpwd, char *dn,
2390 LDAPMod **mods, int ldap_op,
2391 BOOL (*need_update)(const SAM_ACCOUNT *,
2394 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2397 if (!my_methods || !newpwd || !dn) {
2398 return NT_STATUS_INVALID_PARAMETER;
2402 DEBUG(5,("mods is empty: nothing to modify\n"));
2403 /* may be password change below however */
2408 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_ACCOUNT);
2409 rc = smbldap_add(ldap_state->smbldap_state,
2412 case LDAP_MOD_REPLACE:
2413 rc = smbldap_modify(ldap_state->smbldap_state,
2417 DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
2418 return NT_STATUS_INVALID_PARAMETER;
2421 if (rc!=LDAP_SUCCESS) {
2422 char *ld_error = NULL;
2423 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
2426 ("failed to %s user dn= %s with: %s\n\t%s\n",
2427 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
2428 dn, ldap_err2string(rc),
2429 ld_error?ld_error:"unknown"));
2430 SAFE_FREE(ld_error);
2431 return NT_STATUS_UNSUCCESSFUL;
2435 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) &&
2436 (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) &&
2437 need_update(newpwd, PDB_PLAINTEXT_PW) &&
2438 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
2442 struct berval *retdata;
2443 char *utf8_password;
2446 if (push_utf8_allocate(&utf8_password, pdb_get_plaintext_passwd(newpwd)) == (size_t)-1) {
2447 return NT_STATUS_NO_MEMORY;
2450 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
2451 return NT_STATUS_NO_MEMORY;
2454 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
2455 DEBUG(0,("ber_alloc_t returns NULL\n"));
2456 SAFE_FREE(utf8_password);
2457 return NT_STATUS_UNSUCCESSFUL;
2460 ber_printf (ber, "{");
2461 ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn);
2462 ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password);
2463 ber_printf (ber, "N}");
2465 if ((rc = ber_flatten (ber, &bv))<0) {
2466 DEBUG(0,("ber_flatten returns a value <0\n"));
2469 SAFE_FREE(utf8_password);
2470 return NT_STATUS_UNSUCCESSFUL;
2474 SAFE_FREE(utf8_password);
2477 if ((rc = smbldap_extended_operation(ldap_state->smbldap_state,
2478 LDAP_EXOP_MODIFY_PASSWD,
2479 bv, NULL, NULL, &retoid,
2480 &retdata)) != LDAP_SUCCESS) {
2481 DEBUG(0,("LDAP Password could not be changed for user %s: %s\n",
2482 pdb_get_username(newpwd),ldap_err2string(rc)));
2484 DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
2485 #ifdef DEBUG_PASSWORD
2486 DEBUG(100,("LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd)));
2488 ber_bvfree(retdata);
2489 ber_memfree(retoid);
2493 return NT_STATUS_OK;
2496 /**********************************************************************
2497 Delete entry from LDAP for username
2498 *********************************************************************/
2499 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
2501 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2504 LDAPMessage *result;
2510 DEBUG(0, ("sam_acct was NULL!\n"));
2511 return NT_STATUS_INVALID_PARAMETER;
2514 sname = pdb_get_username(sam_acct);
2516 DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
2518 attr_list= get_userattr_list( ldap_state->schema_ver );
2519 rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
2521 if (rc != LDAP_SUCCESS) {
2522 free_attr_list( attr_list );
2523 return NT_STATUS_NO_SUCH_USER;
2526 switch ( ldap_state->schema_ver )
2528 case SCHEMAVER_SAMBASAMACCOUNT:
2529 fstrcpy( objclass, LDAP_OBJ_SAMBASAMACCOUNT );
2532 case SCHEMAVER_SAMBAACCOUNT:
2533 fstrcpy( objclass, LDAP_OBJ_SAMBAACCOUNT );
2536 fstrcpy( objclass, "UNKNOWN" );
2537 DEBUG(0,("ldapsam_delete_sam_account: Unknown schema version specified!\n"));
2541 ret = ldapsam_delete_entry(ldap_state, result, objclass, attr_list );
2542 ldap_msgfree(result);
2543 free_attr_list( attr_list );
2548 /**********************************************************************
2549 Helper function to determine for update_sam_account whether
2550 we need LDAP modification.
2551 *********************************************************************/
2552 static BOOL element_is_changed(const SAM_ACCOUNT *sampass,
2553 enum pdb_elements element)
2555 return IS_SAM_CHANGED(sampass, element);
2558 /**********************************************************************
2560 *********************************************************************/
2561 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
2563 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2564 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2567 LDAPMessage *result;
2572 attr_list = get_userattr_list(ldap_state->schema_ver);
2573 rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
2574 free_attr_list( attr_list );
2575 if (rc != LDAP_SUCCESS)
2576 return NT_STATUS_UNSUCCESSFUL;
2578 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
2579 DEBUG(0, ("No user to modify!\n"));
2580 ldap_msgfree(result);
2581 return NT_STATUS_UNSUCCESSFUL;
2584 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
2585 dn = ldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
2587 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
2588 element_is_changed)) {
2589 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
2590 ldap_msgfree(result);
2591 return NT_STATUS_UNSUCCESSFUL;
2594 ldap_msgfree(result);
2597 DEBUG(4,("mods is empty: nothing to update for user: %s\n",
2598 pdb_get_username(newpwd)));
2599 ldap_mods_free(mods, True);
2600 return NT_STATUS_OK;
2603 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed);
2604 ldap_mods_free(mods,True);
2606 if (!NT_STATUS_IS_OK(ret)) {
2607 char *ld_error = NULL;
2608 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
2610 DEBUG(0,("failed to modify user with uid = %s, error: %s (%s)\n",
2611 pdb_get_username(newpwd), ld_error?ld_error:"(unknwon)", ldap_err2string(rc)));
2612 SAFE_FREE(ld_error);
2616 DEBUG(2, ("successfully modified uid = %s in the LDAP database\n",
2617 pdb_get_username(newpwd)));
2618 return NT_STATUS_OK;
2621 /**********************************************************************
2622 Helper function to determine for update_sam_account whether
2623 we need LDAP modification.
2624 *********************************************************************/
2625 static BOOL element_is_set_or_changed(const SAM_ACCOUNT *sampass,
2626 enum pdb_elements element)
2628 return (IS_SAM_SET(sampass, element) ||
2629 IS_SAM_CHANGED(sampass, element));
2632 /**********************************************************************
2633 Add SAM_ACCOUNT to LDAP
2634 *********************************************************************/
2636 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
2638 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2639 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2641 LDAPMessage *result = NULL;
2642 LDAPMessage *entry = NULL;
2644 LDAPMod **mods = NULL;
2649 const char *username = pdb_get_username(newpwd);
2652 if (!username || !*username) {
2653 DEBUG(0, ("Cannot add user without a username!\n"));
2654 return NT_STATUS_INVALID_PARAMETER;
2657 /* free this list after the second search or in case we exit on failure */
2659 attr_list = get_userattr_list(ldap_state->schema_ver);
2660 rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
2662 if (rc != LDAP_SUCCESS) {
2663 free_attr_list( attr_list );
2664 return NT_STATUS_UNSUCCESSFUL;
2667 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
2668 DEBUG(0,("User '%s' already in the base, with samba attributes\n",
2670 ldap_msgfree(result);
2671 free_attr_list( attr_list );
2672 return NT_STATUS_UNSUCCESSFUL;
2674 ldap_msgfree(result);
2676 /* does the entry already exist but without a samba rttibutes?
2677 we don't really care what attributes are returned here */
2679 escape_user = escape_ldap_string_alloc( username );
2680 pstrcpy( filter, lp_ldap_filter() );
2681 all_string_sub( filter, "%u", escape_user, sizeof(filter) );
2682 SAFE_FREE( escape_user );
2684 rc = smbldap_search_suffix(ldap_state->smbldap_state,
2685 filter, attr_list, &result);
2686 free_attr_list( attr_list );
2688 if ( rc != LDAP_SUCCESS )
2689 return NT_STATUS_UNSUCCESSFUL;
2691 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2693 if (num_result > 1) {
2694 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
2695 ldap_msgfree(result);
2696 return NT_STATUS_UNSUCCESSFUL;
2699 /* Check if we need to update an existing entry */
2700 if (num_result == 1) {
2703 DEBUG(3,("User exists without samba attributes: adding them\n"));
2704 ldap_op = LDAP_MOD_REPLACE;
2705 entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
2706 tmp = ldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
2707 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
2710 /* Check if we need to add an entry */
2711 DEBUG(3,("Adding new user\n"));
2712 ldap_op = LDAP_MOD_ADD;
2713 if (username[strlen(username)-1] == '$') {
2714 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
2716 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
2720 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
2721 element_is_set_or_changed)) {
2722 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
2723 ldap_msgfree(result);
2724 return NT_STATUS_UNSUCCESSFUL;
2727 ldap_msgfree(result);
2730 DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
2731 return NT_STATUS_UNSUCCESSFUL;
2733 switch ( ldap_state->schema_ver )
2735 case SCHEMAVER_SAMBAACCOUNT:
2736 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT);
2738 case SCHEMAVER_SAMBASAMACCOUNT:
2739 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
2742 DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
2746 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, element_is_set_or_changed);
2747 if (!NT_STATUS_IS_OK(ret)) {
2748 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
2749 pdb_get_username(newpwd),dn));
2750 ldap_mods_free(mods, True);
2754 DEBUG(2,("added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
2755 ldap_mods_free(mods, True);
2757 return NT_STATUS_OK;
2760 /**********************************************************************
2762 *********************************************************************/
2764 static void smbldap_free_struct(struct smbldap_state **ldap_state)
2766 smbldap_close(*ldap_state);
2768 if ((*ldap_state)->bind_secret) {
2769 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
2772 SAFE_FREE((*ldap_state)->bind_dn);
2773 SAFE_FREE((*ldap_state)->bind_secret);
2777 /* No need to free any further, as it is talloc()ed */
2781 /**********************************************************************
2783 *********************************************************************/
2785 static void free_private_data(void **vp)
2787 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
2789 smbldap_free_struct(&(*ldap_state)->smbldap_state);
2793 /* No need to free any further, as it is talloc()ed */
2796 /**********************************************************************
2797 *********************************************************************/
2799 static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
2801 LDAPMessage ** result)
2803 int scope = LDAP_SCOPE_SUBTREE;
2807 DEBUG(2, ("ldapsam_search_one_group: searching for:[%s]\n", filter));
2810 attr_list = get_attr_list(groupmap_attr_list);
2811 rc = smbldap_search(ldap_state->smbldap_state,
2812 lp_ldap_group_suffix (), scope,
2813 filter, attr_list, 0, result);
2814 free_attr_list( attr_list );
2816 if (rc != LDAP_SUCCESS) {
2817 char *ld_error = NULL;
2818 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
2820 DEBUG(0, ("ldapsam_search_one_group: "
2821 "Problem during the LDAP search: LDAP error: %s (%s)",
2822 ld_error?ld_error:"(unknown)", ldap_err2string(rc)));
2823 DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
2824 lp_ldap_group_suffix(), filter));
2825 SAFE_FREE(ld_error);
2831 /**********************************************************************
2832 *********************************************************************/
2834 static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
2835 GROUP_MAP *map, LDAPMessage *entry)
2839 if (ldap_state == NULL || map == NULL || entry == NULL ||
2840 ldap_state->smbldap_state->ldap_struct == NULL)
2842 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
2846 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
2847 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER), temp))
2849 DEBUG(0, ("Mandatory attribute %s not found\n",
2850 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER)));
2853 DEBUG(2, ("Entry found for group: %s\n", temp));
2855 map->gid = (gid_t)atol(temp);
2857 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
2858 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID), temp))
2860 DEBUG(0, ("Mandatory attribute %s not found\n",
2861 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID)));
2864 string_to_sid(&map->sid, temp);
2866 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
2867 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), temp))
2869 DEBUG(0, ("Mandatory attribute %s not found\n",
2870 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
2873 map->sid_name_use = (uint32)atol(temp);
2875 if ((map->sid_name_use < SID_NAME_USER) ||
2876 (map->sid_name_use > SID_NAME_UNKNOWN)) {
2877 DEBUG(0, ("Unknown Group type: %d\n", map->sid_name_use));
2881 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
2882 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), temp))
2885 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
2886 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_CN), temp))
2888 DEBUG(0, ("Attributes cn not found either "
2889 "for gidNumber(%i)\n",map->gid));
2893 fstrcpy(map->nt_name, temp);
2895 if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
2896 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), temp))
2900 fstrcpy(map->comment, temp);
2905 /**********************************************************************
2906 *********************************************************************/
2908 static BOOL init_ldap_from_group(LDAP *ldap_struct,
2909 LDAPMessage *existing,
2911 const GROUP_MAP *map)
2915 if (mods == NULL || map == NULL) {
2916 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
2922 sid_to_string(tmp, &map->sid);
2923 smbldap_make_mod(ldap_struct, existing, mods,
2924 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID), tmp);
2925 snprintf(tmp, sizeof(tmp)-1, "%i", map->sid_name_use);
2926 smbldap_make_mod(ldap_struct, existing, mods,
2927 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), tmp);
2929 smbldap_make_mod(ldap_struct, existing, mods,
2930 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), map->nt_name);
2931 smbldap_make_mod(ldap_struct, existing, mods,
2932 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), map->comment);
2937 /**********************************************************************
2938 *********************************************************************/
2940 static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
2944 struct ldapsam_privates *ldap_state =
2945 (struct ldapsam_privates *)methods->private_data;
2946 LDAPMessage *result;
2950 if (ldapsam_search_one_group(ldap_state, filter, &result)
2952 return NT_STATUS_NO_SUCH_GROUP;
2955 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2958 DEBUG(4, ("Did not find group for filter %s\n", filter));
2959 return NT_STATUS_NO_SUCH_GROUP;
2963 DEBUG(1, ("Duplicate entries for filter %s: count=%d\n",
2965 return NT_STATUS_NO_SUCH_GROUP;
2968 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
2971 ldap_msgfree(result);
2972 return NT_STATUS_UNSUCCESSFUL;
2975 if (!init_group_from_ldap(ldap_state, map, entry)) {
2976 DEBUG(1, ("init_group_from_ldap failed for group filter %s\n",
2978 ldap_msgfree(result);
2979 return NT_STATUS_NO_SUCH_GROUP;
2982 ldap_msgfree(result);
2983 return NT_STATUS_OK;
2986 /**********************************************************************
2987 *********************************************************************/
2989 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
2994 snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))",
2996 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
2997 sid_string_static(&sid));
2999 return ldapsam_getgroup(methods, filter, map);
3002 /**********************************************************************
3003 *********************************************************************/
3005 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
3010 snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%d))",
3012 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
3015 return ldapsam_getgroup(methods, filter, map);
3018 /**********************************************************************
3019 *********************************************************************/
3021 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
3026 /* TODO: Escaping of name? */
3028 snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
3030 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), name,
3031 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN), name);
3033 return ldapsam_getgroup(methods, filter, map);
3036 /**********************************************************************
3037 *********************************************************************/
3039 static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
3041 LDAPMessage **result)
3045 snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%i))",
3046 LDAP_OBJ_POSIXGROUP,
3047 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
3050 return ldapsam_search_one_group(ldap_state, filter, result);
3053 /**********************************************************************
3054 *********************************************************************/
3056 static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
3059 struct ldapsam_privates *ldap_state =
3060 (struct ldapsam_privates *)methods->private_data;
3061 LDAPMessage *result = NULL;
3062 LDAPMod **mods = NULL;
3072 if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
3074 DEBUG(0, ("Group %i already exists in LDAP\n", map->gid));
3075 return NT_STATUS_UNSUCCESSFUL;
3078 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
3079 if (rc != LDAP_SUCCESS) {
3080 return NT_STATUS_UNSUCCESSFUL;
3083 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 1) {
3084 DEBUG(2, ("Group %i must exist exactly once in LDAP\n",
3086 ldap_msgfree(result);
3087 return NT_STATUS_UNSUCCESSFUL;
3090 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
3091 tmp = ldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
3095 if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
3096 result, &mods, map)) {
3097 DEBUG(0, ("init_ldap_from_group failed!\n"));
3098 ldap_mods_free(mods, True);
3099 ldap_msgfree(result);
3100 return NT_STATUS_UNSUCCESSFUL;
3103 ldap_msgfree(result);
3106 DEBUG(0, ("mods is empty\n"));
3107 return NT_STATUS_UNSUCCESSFUL;
3110 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP );
3112 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3113 ldap_mods_free(mods, True);
3115 if (rc != LDAP_SUCCESS) {
3116 char *ld_error = NULL;
3117 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
3119 DEBUG(0, ("failed to add group %i error: %s (%s)\n", map->gid,
3120 ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
3121 SAFE_FREE(ld_error);
3122 return NT_STATUS_UNSUCCESSFUL;
3125 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
3126 return NT_STATUS_OK;
3129 /**********************************************************************
3130 *********************************************************************/
3132 static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
3135 struct ldapsam_privates *ldap_state =
3136 (struct ldapsam_privates *)methods->private_data;
3139 LDAPMessage *result;
3143 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
3145 if (rc != LDAP_SUCCESS) {
3146 return NT_STATUS_UNSUCCESSFUL;
3149 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
3150 DEBUG(0, ("No group to modify!\n"));
3151 ldap_msgfree(result);
3152 return NT_STATUS_UNSUCCESSFUL;
3155 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
3156 dn = ldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
3158 if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
3159 result, &mods, map)) {
3160 DEBUG(0, ("init_ldap_from_group failed\n"));
3161 ldap_msgfree(result);
3162 return NT_STATUS_UNSUCCESSFUL;
3165 ldap_msgfree(result);
3168 DEBUG(4, ("mods is empty: nothing to do\n"));
3169 return NT_STATUS_UNSUCCESSFUL;
3172 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3174 ldap_mods_free(mods, True);
3176 if (rc != LDAP_SUCCESS) {
3177 char *ld_error = NULL;
3178 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
3180 DEBUG(0, ("failed to modify group %i error: %s (%s)\n", map->gid,
3181 ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
3182 SAFE_FREE(ld_error);
3185 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
3186 return NT_STATUS_OK;
3189 /**********************************************************************
3190 *********************************************************************/
3192 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
3195 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data;
3196 pstring sidstring, filter;
3197 LDAPMessage *result;
3202 sid_to_string(sidstring, &sid);
3204 snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))",
3205 LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID, sidstring);
3207 rc = ldapsam_search_one_group(ldap_state, filter, &result);
3209 if (rc != LDAP_SUCCESS) {
3210 return NT_STATUS_NO_SUCH_GROUP;
3213 attr_list = get_attr_list( groupmap_attr_list_to_delete );
3214 ret = ldapsam_delete_entry(ldap_state, result, LDAP_OBJ_GROUPMAP, attr_list);
3215 free_attr_list ( attr_list );
3217 ldap_msgfree(result);
3222 /**********************************************************************
3223 *********************************************************************/
3225 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update)
3227 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
3232 snprintf( filter, sizeof(filter)-1, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
3233 attr_list = get_attr_list( groupmap_attr_list );
3234 rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
3235 LDAP_SCOPE_SUBTREE, filter,
3236 attr_list, 0, &ldap_state->result);
3237 free_attr_list( attr_list );
3239 if (rc != LDAP_SUCCESS) {
3240 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
3241 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_group_suffix(), filter));
3242 ldap_msgfree(ldap_state->result);
3243 ldap_state->result = NULL;
3244 return NT_STATUS_UNSUCCESSFUL;
3247 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
3248 ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
3249 ldap_state->result)));
3251 ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result);
3252 ldap_state->index = 0;
3254 return NT_STATUS_OK;
3257 /**********************************************************************
3258 *********************************************************************/
3260 static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
3262 ldapsam_endsampwent(my_methods);
3265 /**********************************************************************
3266 *********************************************************************/
3268 static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
3271 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
3272 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
3276 if (!ldap_state->entry)
3279 ldap_state->index++;
3280 bret = init_group_from_ldap(ldap_state, map, ldap_state->entry);
3282 ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
3286 return NT_STATUS_OK;
3289 /**********************************************************************
3290 *********************************************************************/
3292 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
3293 enum SID_NAME_USE sid_name_use,
3294 GROUP_MAP **rmap, int *num_entries,
3305 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
3306 DEBUG(0, ("Unable to open passdb\n"));
3307 return NT_STATUS_ACCESS_DENIED;
3310 while (NT_STATUS_IS_OK(nt_status = ldapsam_getsamgrent(methods, &map))) {
3311 if (sid_name_use != SID_NAME_UNKNOWN &&
3312 sid_name_use != map.sid_name_use) {
3313 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
3316 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
3317 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name));
3321 mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP));
3323 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
3325 return NT_STATUS_UNSUCCESSFUL;
3330 mapt[entries] = map;
3335 ldapsam_endsamgrent(methods);
3337 *num_entries = entries;
3339 return NT_STATUS_OK;
3342 /**********************************************************************
3343 Intitalise the 'general' ldap structures, on which ldap operations may be conducted
3344 *********************************************************************/
3346 static NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_state **smbldap_state)
3348 *smbldap_state = talloc_zero(mem_ctx, sizeof(**smbldap_state));
3349 if (!*smbldap_state) {
3350 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
3351 return NT_STATUS_NO_MEMORY;
3355 (*smbldap_state)->uri = talloc_strdup(mem_ctx, location);
3357 (*smbldap_state)->uri = "ldap://localhost";
3359 return NT_STATUS_OK;
3362 /**********************************************************************
3363 Intitalise the parts of the pdb_context that are common to all pdb_ldap modes
3364 *********************************************************************/
3366 static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method,
3367 const char *location)
3370 struct ldapsam_privates *ldap_state;
3372 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
3376 (*pdb_method)->name = "ldapsam";
3378 (*pdb_method)->setsampwent = ldapsam_setsampwent;
3379 (*pdb_method)->endsampwent = ldapsam_endsampwent;
3380 (*pdb_method)->getsampwent = ldapsam_getsampwent;
3381 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
3382 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
3383 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
3384 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
3385 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
3387 (*pdb_method)->getgrsid = ldapsam_getgrsid;
3388 (*pdb_method)->getgrgid = ldapsam_getgrgid;
3389 (*pdb_method)->getgrnam = ldapsam_getgrnam;
3390 (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
3391 (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
3392 (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
3393 (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
3395 /* TODO: Setup private data and free */
3397 ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(*ldap_state));
3399 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
3400 return NT_STATUS_NO_MEMORY;
3403 if (!NT_STATUS_IS_OK(nt_status =
3404 smbldap_init(pdb_context->mem_ctx, location,
3405 &ldap_state->smbldap_state)));
3407 ldap_state->domain_name = talloc_strdup(pdb_context->mem_ctx, get_global_sam_name());
3408 if (!ldap_state->domain_name) {
3409 return NT_STATUS_NO_MEMORY;
3412 sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
3414 (*pdb_method)->private_data = ldap_state;
3416 (*pdb_method)->free_private_data = free_private_data;
3418 return NT_STATUS_OK;
3421 /**********************************************************************
3422 Initialise the 'compat' mode for pdb_ldap
3423 *********************************************************************/
3425 static NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
3428 struct ldapsam_privates *ldap_state;
3430 #ifndef WITH_LDAP_SAMCONFIG
3431 location = "ldap://localhost";
3434 int ldap_port = lp_ldap_port();
3436 /* remap default port if not using SSL (ie clear or TLS) */
3437 if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
3441 location = talloc_asprintf(pdb_context->mem_ctx, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON ? "ldaps" : "ldap", lp_ldap_server(), ldap_port);
3443 return NT_STATUS_NO_MEMORY;
3448 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
3452 (*pdb_method)->name = "ldapsam_compat";
3454 ldap_state = (*pdb_method)->private_data;
3455 ldap_state->schema_ver = SCHEMAVER_SAMBAACCOUNT;
3457 return NT_STATUS_OK;
3460 /**********************************************************************
3461 Initialise the normal mode for pdb_ldap
3462 *********************************************************************/
3464 static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
3467 struct ldapsam_privates *ldap_state;
3468 uint32 low_idmap_uid, high_idmap_uid;
3469 uint32 low_idmap_gid, high_idmap_gid;
3471 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
3475 (*pdb_method)->name = "ldapsam";
3477 ldap_state = (*pdb_method)->private_data;
3478 ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
3479 ldap_state->permit_non_unix_accounts = False;
3481 /* check for non-unix account ranges */
3483 if (lp_idmap_uid(&low_idmap_uid, &high_idmap_uid)
3484 && lp_idmap_gid(&low_idmap_gid, &high_idmap_gid))
3486 DEBUG(2, ("Enabling non-unix account ranges\n"));
3488 ldap_state->permit_non_unix_accounts = True;
3490 ldap_state->low_allocated_user_rid = fallback_pdb_uid_to_user_rid(low_idmap_uid);
3491 ldap_state->high_allocated_user_rid = fallback_pdb_uid_to_user_rid(high_idmap_uid);
3492 ldap_state->low_allocated_group_rid = pdb_gid_to_group_rid(low_idmap_gid);
3493 ldap_state->high_allocated_group_rid = pdb_gid_to_group_rid(high_idmap_gid);
3496 return NT_STATUS_OK;
3499 NTSTATUS pdb_ldap_init(void)
3502 if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam", pdb_init_ldapsam)))
3505 if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_compat", pdb_init_ldapsam_compat)))
3508 return NT_STATUS_OK;