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
59 #define SAM_ACCOUNT struct sam_passwd
62 struct ldapsam_privates {
70 /* retrive-once info */
72 const char *domain_name;
75 /* configuration items */
78 BOOL permit_non_unix_accounts;
80 uint32 low_allocated_user_rid;
81 uint32 high_allocated_user_rid;
83 uint32 low_allocated_group_rid;
84 uint32 high_allocated_group_rid;
89 unsigned int num_failures;
92 #define LDAPSAM_DONT_PING_TIME 10 /* ping only all 10 seconds */
94 static struct ldapsam_privates *static_ldap_state;
96 /* specify schema versions between 2.2. and 3.0 */
98 #define SCHEMAVER_SAMBAACCOUNT 1
99 #define SCHEMAVER_SAMBASAMACCOUNT 2
101 /* objectclass names */
103 #define LDAP_OBJ_SAMBASAMACCOUNT "sambaSamAccount"
104 #define LDAP_OBJ_SAMBAACCOUNT "sambaAccount"
105 #define LDAP_OBJ_GROUPMAP "sambaGroupMapping"
106 #define LDAP_OBJ_DOMINFO "sambaDomain"
108 #define LDAP_OBJ_ACCOUNT "account"
109 #define LDAP_OBJ_POSIXACCOUNT "posixAccount"
110 #define LDAP_OBJ_POSIXGROUP "posixGroup"
112 /* some generic attributes that get reused a lot */
114 #define LDAP_ATTRIBUTE_SID "sambaSID"
116 /* attribute map table indexes */
118 #define LDAP_ATTR_LIST_END 0
119 #define LDAP_ATTR_UID 1
120 #define LDAP_ATTR_UIDNUMBER 2
121 #define LDAP_ATTR_GIDNUMBER 3
122 #define LDAP_ATTR_UNIX_HOME 4
123 #define LDAP_ATTR_PWD_LAST_SET 5
124 #define LDAP_ATTR_PWD_CAN_CHANGE 6
125 #define LDAP_ATTR_PWD_MUST_CHANGE 7
126 #define LDAP_ATTR_LOGON_TIME 8
127 #define LDAP_ATTR_LOGOFF_TIME 9
128 #define LDAP_ATTR_KICKOFF_TIME 10
129 #define LDAP_ATTR_CN 11
130 #define LDAP_ATTR_DISPLAY_NAME 12
131 #define LDAP_ATTR_HOME_PATH 13
132 #define LDAP_ATTR_LOGON_SCRIPT 14
133 #define LDAP_ATTR_PROFILE_PATH 15
134 #define LDAP_ATTR_DESC 16
135 #define LDAP_ATTR_USER_WKS 17
136 #define LDAP_ATTR_USER_SID 18
137 #define LDAP_ATTR_USER_RID 18
138 #define LDAP_ATTR_PRIMARY_GROUP_SID 19
139 #define LDAP_ATTR_PRIMARY_GROUP_RID 20
140 #define LDAP_ATTR_LMPW 21
141 #define LDAP_ATTR_NTPW 22
142 #define LDAP_ATTR_DOMAIN 23
143 #define LDAP_ATTR_OBJCLASS 24
144 #define LDAP_ATTR_ACB_INFO 25
145 #define LDAP_ATTR_NEXT_USERRID 26
146 #define LDAP_ATTR_NEXT_GROUPRID 27
147 #define LDAP_ATTR_DOM_SID 28
148 #define LDAP_ATTR_HOME_DRIVE 29
149 #define LDAP_ATTR_GROUP_SID 30
150 #define LDAP_ATTR_GROUP_TYPE 31
153 typedef struct _attrib_map_entry {
159 /* attributes used by Samba 2.2 */
161 static ATTRIB_MAP_ENTRY attrib_map_v22[] = {
162 { LDAP_ATTR_UID, "uid" },
163 { LDAP_ATTR_UIDNUMBER, "uidNumber" },
164 { LDAP_ATTR_GIDNUMBER, "gidNumber" },
165 { LDAP_ATTR_UNIX_HOME, "homeDirectory" },
166 { LDAP_ATTR_PWD_LAST_SET, "pwdLastSet" },
167 { LDAP_ATTR_PWD_CAN_CHANGE, "pwdCanChange" },
168 { LDAP_ATTR_PWD_MUST_CHANGE, "pwdMustChange" },
169 { LDAP_ATTR_LOGON_TIME, "logonTime" },
170 { LDAP_ATTR_LOGOFF_TIME, "logoffTime" },
171 { LDAP_ATTR_KICKOFF_TIME, "kickoffTime" },
172 { LDAP_ATTR_CN, "cn" },
173 { LDAP_ATTR_DISPLAY_NAME, "displayName" },
174 { LDAP_ATTR_HOME_PATH, "smbHome" },
175 { LDAP_ATTR_HOME_DRIVE, "homeDrives" },
176 { LDAP_ATTR_LOGON_SCRIPT, "scriptPath" },
177 { LDAP_ATTR_PROFILE_PATH, "profilePath" },
178 { LDAP_ATTR_DESC, "description" },
179 { LDAP_ATTR_USER_WKS, "userWorkstations"},
180 { LDAP_ATTR_USER_RID, "rid" },
181 { LDAP_ATTR_PRIMARY_GROUP_RID, "primaryGroupID"},
182 { LDAP_ATTR_LMPW, "lmPassword" },
183 { LDAP_ATTR_NTPW, "ntPassword" },
184 { LDAP_ATTR_DOMAIN, "domain" },
185 { LDAP_ATTR_OBJCLASS, "objectClass" },
186 { LDAP_ATTR_ACB_INFO, "acctFlags" },
187 { LDAP_ATTR_LIST_END, NULL }
190 /* attributes used by Samba 3.0's sambaSamAccount */
192 static ATTRIB_MAP_ENTRY attrib_map_v30[] = {
193 { LDAP_ATTR_UID, "uid" },
194 { LDAP_ATTR_UIDNUMBER, "uidNumber" },
195 { LDAP_ATTR_GIDNUMBER, "gidNumber" },
196 { LDAP_ATTR_UNIX_HOME, "homeDirectory" },
197 { LDAP_ATTR_PWD_LAST_SET, "sambaPwdLastSet" },
198 { LDAP_ATTR_PWD_CAN_CHANGE, "sambaPwdCanChange" },
199 { LDAP_ATTR_PWD_MUST_CHANGE, "sambaPwdMustChange" },
200 { LDAP_ATTR_LOGON_TIME, "sambaLogonTime" },
201 { LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" },
202 { LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" },
203 { LDAP_ATTR_CN, "cn" },
204 { LDAP_ATTR_DISPLAY_NAME, "displayName" },
205 { LDAP_ATTR_HOME_DRIVE, "sambaHoneDrive" },
206 { LDAP_ATTR_HOME_PATH, "sambaHomePath" },
207 { LDAP_ATTR_LOGON_SCRIPT, "sambaLogonScript" },
208 { LDAP_ATTR_PROFILE_PATH, "sambaProfilePath" },
209 { LDAP_ATTR_DESC, "description" },
210 { LDAP_ATTR_USER_WKS, "sambaUserWorkstations" },
211 { LDAP_ATTR_USER_SID, "sambaSID" },
212 { LDAP_ATTR_PRIMARY_GROUP_SID, "sambaPrimaryGroupSID" },
213 { LDAP_ATTR_LMPW, "sambaLMPassword" },
214 { LDAP_ATTR_NTPW, "sambaNTPassword" },
215 { LDAP_ATTR_DOMAIN, "sambaDomainName" },
216 { LDAP_ATTR_OBJCLASS, "objectClass" },
217 { LDAP_ATTR_ACB_INFO, "sambaAcctFlags" },
218 { LDAP_ATTR_LIST_END, NULL }
221 /* attributes used for alalocating RIDs */
223 static ATTRIB_MAP_ENTRY dominfo_attr_list[] = {
224 { LDAP_ATTR_DOMAIN, "sambaDomainName" },
225 { LDAP_ATTR_NEXT_USERRID, "sambaNextUserRid" },
226 { LDAP_ATTR_NEXT_GROUPRID, "sambaNextGroupRid" },
227 { LDAP_ATTR_DOM_SID, "sambaSID" },
228 { LDAP_ATTR_LIST_END, NULL },
231 /* Samba 3.0 group mapping attributes */
233 static ATTRIB_MAP_ENTRY groupmap_attr_list[] = {
234 { LDAP_ATTR_GIDNUMBER, "gidNumber" },
235 { LDAP_ATTR_GROUP_SID, "sambaSID" },
236 { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" },
237 { LDAP_ATTR_DESC, "description" },
238 { LDAP_ATTR_DISPLAY_NAME, "displayName" },
239 { LDAP_ATTR_CN, "cn" },
240 { LDAP_ATTR_LIST_END, NULL }
243 static ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[] = {
244 { LDAP_ATTR_GROUP_SID, "sambaSID" },
245 { LDAP_ATTR_GROUP_TYPE, "sambaGroupType" },
246 { LDAP_ATTR_DESC, "description" },
247 { LDAP_ATTR_DISPLAY_NAME, "displayName" },
248 { LDAP_ATTR_LIST_END, NULL }
251 /**********************************************************************
252 perform a simple table lookup and return the attribute name
253 **********************************************************************/
255 static const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
259 while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
260 if ( table[i].attrib == key )
261 return table[i].name;
268 /**********************************************************************
269 get the attribute name given a user schame version
270 **********************************************************************/
272 static const char* get_userattr_key2string( int schema_ver, int key )
274 switch ( schema_ver )
276 case SCHEMAVER_SAMBAACCOUNT:
277 return get_attr_key2string( attrib_map_v22, key );
279 case SCHEMAVER_SAMBASAMACCOUNT:
280 return get_attr_key2string( attrib_map_v30, key );
283 DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
289 /**********************************************************************
290 Return the list of attribute names from a mapping table
291 **********************************************************************/
293 static char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
298 while ( table[i].attrib != LDAP_ATTR_LIST_END )
302 names = (char**)malloc( sizeof(char*)*i );
304 DEBUG(0,("get_attr_list: out of memory\n"));
309 while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
310 names[i] = strdup( table[i].name );
318 /*********************************************************************
320 ********************************************************************/
322 static void free_attr_list( char **list )
330 SAFE_FREE( list[i] );
335 /**********************************************************************
336 return the list of attribute names given a user schema version
337 **********************************************************************/
339 static char** get_userattr_list( int schema_ver )
341 switch ( schema_ver )
343 case SCHEMAVER_SAMBAACCOUNT:
344 return get_attr_list( attrib_map_v22 );
346 case SCHEMAVER_SAMBASAMACCOUNT:
347 return get_attr_list( attrib_map_v30 );
349 DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
356 /*******************************************************************
357 find the ldap password
358 ******************************************************************/
359 static BOOL fetch_ldapsam_pw(char **dn, char** pw)
364 *dn = smb_xstrdup(lp_ldap_admin_dn());
366 if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
368 DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
371 *pw=secrets_fetch(key, &size);
375 /* Upgrade 2.2 style entry */
377 char* old_style_key = strdup(*dn);
379 fstring old_style_pw;
381 if (!old_style_key) {
382 DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n"));
386 for (p=old_style_key; *p; p++)
387 if (*p == ',') *p = '/';
389 data=secrets_fetch(old_style_key, &size);
390 if (!size && size < sizeof(old_style_pw)) {
391 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
392 SAFE_FREE(old_style_key);
397 strncpy(old_style_pw, data, size);
398 old_style_pw[size] = 0;
402 if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
403 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
404 SAFE_FREE(old_style_key);
408 if (!secrets_delete(old_style_key)) {
409 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
412 SAFE_FREE(old_style_key);
414 *pw = smb_xstrdup(old_style_pw);
420 /*******************************************************************
421 open a connection to the ldap server.
422 ******************************************************************/
423 static int ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct)
425 int rc = LDAP_SUCCESS;
427 BOOL ldap_v3 = False;
429 #ifdef HAVE_LDAP_INITIALIZE
430 DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri));
432 if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) {
433 DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
439 /* Parse the string manually */
445 const char *p = ldap_state->uri;
446 SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
448 /* skip leading "URL:" (if any) */
449 if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
453 sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port);
456 if (strequal(protocol, "ldap")) {
458 } else if (strequal(protocol, "ldaps")) {
461 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
465 if ((*ldap_struct = ldap_init(host, port)) == NULL) {
466 DEBUG(0, ("ldap_init failed !\n"));
467 return LDAP_OPERATIONS_ERROR;
470 if (strequal(protocol, "ldaps")) {
471 #ifdef LDAP_OPT_X_TLS
472 int tls = LDAP_OPT_X_TLS_HARD;
473 if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
475 DEBUG(0, ("Failed to setup a TLS session\n"));
478 DEBUG(3,("LDAPS option set...!\n"));
480 DEBUG(0,("ldapsam_open_connection: Secure connection not supported by LDAP client libraries!\n"));
481 return LDAP_OPERATIONS_ERROR;
487 if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
489 if (version != LDAP_VERSION3)
491 version = LDAP_VERSION3;
492 if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
500 if (lp_ldap_ssl() == LDAP_SSL_START_TLS) {
501 #ifdef LDAP_OPT_X_TLS
503 if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
505 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
506 ldap_err2string(rc)));
509 DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
512 DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
513 return LDAP_OPERATIONS_ERROR;
516 DEBUG(0,("ldapsam_open_connection: StartTLS not supported by LDAP client libraries!\n"));
517 return LDAP_OPERATIONS_ERROR;
521 DEBUG(2, ("ldapsam_open_connection: connection opened\n"));
526 /*******************************************************************
527 a rebind function for authenticated referrals
528 This version takes a void* that we can shove useful stuff in :-)
529 ******************************************************************/
530 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
532 static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
533 int *methodp, int freeit, void *arg)
535 struct ldapsam_privates *ldap_state = arg;
537 /** @TODO Should we be doing something to check what servers we rebind to?
538 Could we get a referral to a machine that we don't want to give our
539 username and password to? */
543 memset(*credp, '\0', strlen(*credp));
546 DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
547 ldap_state->bind_dn));
549 *whop = strdup(ldap_state->bind_dn);
551 return LDAP_NO_MEMORY;
553 *credp = strdup(ldap_state->bind_secret);
556 return LDAP_NO_MEMORY;
558 *methodp = LDAP_AUTH_SIMPLE;
562 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
564 /*******************************************************************
565 a rebind function for authenticated referrals
566 This version takes a void* that we can shove useful stuff in :-)
567 and actually does the connection.
568 ******************************************************************/
569 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
570 static int rebindproc_connect_with_state (LDAP *ldap_struct,
571 LDAP_CONST char *url,
573 ber_int_t msgid, void *arg)
575 struct ldapsam_privates *ldap_state = arg;
577 DEBUG(5,("rebindproc_connect_with_state: Rebinding as \"%s\"\n",
578 ldap_state->bind_dn));
580 /** @TODO Should we be doing something to check what servers we rebind to?
581 Could we get a referral to a machine that we don't want to give our
582 username and password to? */
584 rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
588 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
590 /*******************************************************************
591 Add a rebind function for authenticated referrals
592 ******************************************************************/
593 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
595 # if LDAP_SET_REBIND_PROC_ARGS == 2
596 static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
597 int *method, int freeit )
599 return rebindproc_with_state(ldap_struct, whop, credp,
600 method, freeit, static_ldap_state);
603 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
604 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
606 /*******************************************************************
607 a rebind function for authenticated referrals
608 this also does the connection, but no void*.
609 ******************************************************************/
610 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
611 # if LDAP_SET_REBIND_PROC_ARGS == 2
612 static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
615 return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid,
618 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
619 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
621 /*******************************************************************
622 connect to the ldap server under system privilege.
623 ******************************************************************/
624 static int ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct)
630 /* The rebind proc needs this *HACK*. We are not multithreaded, so
631 this will work, but it's not nice. */
632 static_ldap_state = ldap_state;
634 /* get the password */
635 if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
637 DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
638 return LDAP_INVALID_CREDENTIALS;
641 ldap_state->bind_dn = ldap_dn;
642 ldap_state->bind_secret = ldap_secret;
644 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
645 (OpenLDAP) doesnt' seem to support it */
647 DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
648 ldap_state->uri, ldap_dn));
650 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
651 # if LDAP_SET_REBIND_PROC_ARGS == 2
652 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);
654 # if LDAP_SET_REBIND_PROC_ARGS == 3
655 ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);
657 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
658 # if LDAP_SET_REBIND_PROC_ARGS == 2
659 ldap_set_rebind_proc(ldap_struct, &rebindproc);
661 # if LDAP_SET_REBIND_PROC_ARGS == 3
662 ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);
664 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
666 rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
668 if (rc != LDAP_SUCCESS) {
669 char *ld_error = NULL;
670 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
672 DEBUG(ldap_state->num_failures ? 2 : 0,
673 ("failed to bind to server with dn= %s Error: %s\n\t%s\n",
674 ldap_dn ? ld_error : "(unknown)", ldap_err2string(rc),
677 ldap_state->num_failures++;
681 ldap_state->num_failures = 0;
683 DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));
687 /**********************************************************************
688 Connect to LDAP server
689 *********************************************************************/
690 static int ldapsam_open(struct ldapsam_privates *ldap_state)
693 SMB_ASSERT(ldap_state);
695 #ifndef NO_LDAP_SECURITY
696 if (geteuid() != 0) {
697 DEBUG(0, ("ldapsam_open: cannot access LDAP when not root..\n"));
698 return LDAP_INSUFFICIENT_ACCESS;
702 if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + LDAPSAM_DONT_PING_TIME) < time(NULL))) {
703 struct sockaddr_un addr;
704 socklen_t len = sizeof(addr);
706 if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
707 getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
708 /* the other end has died. reopen. */
709 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
710 ldap_state->ldap_struct = NULL;
711 ldap_state->last_ping = (time_t)0;
713 ldap_state->last_ping = time(NULL);
717 if (ldap_state->ldap_struct != NULL) {
718 DEBUG(5,("ldapsam_open: already connected to the LDAP server\n"));
722 if ((rc = ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct))) {
726 if ((rc = ldapsam_connect_system(ldap_state, ldap_state->ldap_struct))) {
727 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
728 ldap_state->ldap_struct = NULL;
733 ldap_state->last_ping = time(NULL);
734 DEBUG(4,("The LDAP server is succesful connected\n"));
739 /**********************************************************************
740 Disconnect from LDAP server
741 *********************************************************************/
742 static NTSTATUS ldapsam_close(struct ldapsam_privates *ldap_state)
745 return NT_STATUS_INVALID_PARAMETER;
747 if (ldap_state->ldap_struct != NULL) {
748 ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
749 ldap_state->ldap_struct = NULL;
752 DEBUG(5,("The connection to the LDAP server was closed\n"));
753 /* maybe free the results here --metze */
758 static int ldapsam_retry_open(struct ldapsam_privates *ldap_state, int *attempts)
762 SMB_ASSERT(ldap_state && attempts);
764 if (*attempts != 0) {
765 unsigned int sleep_time;
768 /* Sleep for a random timeout */
769 rand_byte = (char)(sys_random());
771 sleep_time = (((*attempts)*(*attempts))/2)*rand_byte*2;
772 /* we retry after (0.5, 1, 2, 3, 4.5, 6) seconds
775 DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n",
781 if ((rc = ldapsam_open(ldap_state))) {
782 DEBUG(1,("Connection to LDAP Server failed for the %d try!\n",*attempts));
790 /*********************************************************************
791 ********************************************************************/
793 static int ldapsam_search(struct ldapsam_privates *ldap_state,
794 const char *base, int scope, const char *filter,
795 char *attrs[], int attrsonly,
798 int rc = LDAP_SERVER_DOWN;
802 SMB_ASSERT(ldap_state);
804 if (push_utf8_allocate(&utf8_filter, filter) == (size_t)-1) {
805 return LDAP_NO_MEMORY;
808 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
810 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
813 rc = ldap_search_s(ldap_state->ldap_struct, base, scope,
814 utf8_filter, attrs, attrsonly, res);
817 if (rc == LDAP_SERVER_DOWN) {
818 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
819 ldapsam_close(ldap_state);
822 SAFE_FREE(utf8_filter);
826 static int ldapsam_modify(struct ldapsam_privates *ldap_state, const char *dn, LDAPMod *attrs[])
828 int rc = LDAP_SERVER_DOWN;
832 SMB_ASSERT(ldap_state);
834 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
835 return LDAP_NO_MEMORY;
838 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
840 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
843 rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
846 if (rc == LDAP_SERVER_DOWN) {
847 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
848 ldapsam_close(ldap_state);
855 static int ldapsam_add(struct ldapsam_privates *ldap_state, const char *dn, LDAPMod *attrs[])
857 int rc = LDAP_SERVER_DOWN;
861 SMB_ASSERT(ldap_state);
863 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
864 return LDAP_NO_MEMORY;
867 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
869 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
872 rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
875 if (rc == LDAP_SERVER_DOWN) {
876 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
877 ldapsam_close(ldap_state);
884 static int ldapsam_delete(struct ldapsam_privates *ldap_state, char *dn)
886 int rc = LDAP_SERVER_DOWN;
890 SMB_ASSERT(ldap_state);
892 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
893 return LDAP_NO_MEMORY;
896 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
898 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
901 rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
904 if (rc == LDAP_SERVER_DOWN) {
905 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
906 ldapsam_close(ldap_state);
913 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
914 static int ldapsam_extended_operation(struct ldapsam_privates *ldap_state, LDAP_CONST char *reqoid, struct berval *reqdata, LDAPControl **serverctrls, LDAPControl **clientctrls, char **retoidp, struct berval **retdatap)
916 int rc = LDAP_SERVER_DOWN;
922 while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
924 if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
927 rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata, serverctrls, clientctrls, retoidp, retdatap);
930 if (rc == LDAP_SERVER_DOWN) {
931 DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
932 ldapsam_close(ldap_state);
939 /*******************************************************************
940 run the search by name.
941 ******************************************************************/
942 static int ldapsam_search_suffix (struct ldapsam_privates *ldap_state, const char *filter,
943 char **search_attr, LDAPMessage ** result)
945 int scope = LDAP_SCOPE_SUBTREE;
948 DEBUG(2, ("ldapsam_search_suffix: searching for:[%s]\n", filter));
950 rc = ldapsam_search(ldap_state, lp_ldap_suffix(), scope, filter, search_attr, 0, result);
952 if (rc != LDAP_SUCCESS) {
953 char *ld_error = NULL;
954 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
956 DEBUG(0,("ldapsam_search_suffix: Problem during the LDAP search: %s (%s)\n",
957 ld_error?ld_error:"(unknown)", ldap_err2string (rc)));
958 DEBUG(3,("ldapsam_search_suffix: Query was: %s, %s\n", lp_ldap_suffix(),
966 /*******************************************************************
967 generate the LDAP search filter for the objectclass based on the
968 version of the schema we are using
969 ******************************************************************/
971 static const char* get_objclass_filter( int schema_ver )
973 static fstring objclass_filter;
977 case SCHEMAVER_SAMBAACCOUNT:
978 snprintf( objclass_filter, sizeof(objclass_filter)-1, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT );
980 case SCHEMAVER_SAMBASAMACCOUNT:
981 snprintf( objclass_filter, sizeof(objclass_filter)-1, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
984 DEBUG(0,("ldapsam_search_suffix_by_name(): Invalid schema version specified!\n"));
988 return objclass_filter;
991 /*******************************************************************
992 run the search by name.
993 ******************************************************************/
994 static int ldapsam_search_suffix_by_name (struct ldapsam_privates *ldap_state, const char *user,
995 LDAPMessage ** result, char **attr)
998 char *escape_user = escape_ldap_string_alloc(user);
1001 return LDAP_NO_MEMORY;
1005 * in the filter expression, replace %u with the real name
1006 * so in ldap filter, %u MUST exist :-)
1008 snprintf(filter, sizeof(filter)-1, "(&%s%s)", lp_ldap_filter(),
1009 get_objclass_filter(ldap_state->schema_ver));
1012 * have to use this here because $ is filtered out
1017 all_string_sub(filter, "%u", escape_user, sizeof(pstring));
1018 SAFE_FREE(escape_user);
1020 return ldapsam_search_suffix(ldap_state, filter, attr, result);
1023 /*******************************************************************
1024 run the search by rid.
1025 ******************************************************************/
1026 static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
1027 uint32 rid, LDAPMessage ** result,
1033 /* check if the user rid exists, if not, try searching on the uid */
1035 snprintf(filter, sizeof(filter)-1, "(&(rid=%i)%s)", rid,
1036 get_objclass_filter(ldap_state->schema_ver));
1038 rc = ldapsam_search_suffix(ldap_state, filter, attr, result);
1043 /*******************************************************************
1044 run the search by SID.
1045 ******************************************************************/
1046 static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
1047 const DOM_SID *sid, LDAPMessage ** result,
1054 /* check if the user rid exsists, if not, try searching on the uid */
1056 snprintf(filter, sizeof(filter)-1, "(&(%s=%s)%s)",
1057 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
1058 sid_to_string(sid_string, sid),
1059 get_objclass_filter(ldap_state->schema_ver));
1061 rc = ldapsam_search_suffix(ldap_state, filter, attr, result);
1066 /*******************************************************************
1067 search an attribute and return the first value found.
1068 ******************************************************************/
1069 static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
1070 const char *attribute, pstring value)
1079 if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
1080 DEBUG (10, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute));
1085 if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, sizeof(pstring)) == (size_t)-1)
1087 DEBUG(1, ("get_single_attribute: string conversion of [%s] = [%s] failed!\n",
1088 attribute, values[0]));
1089 ldap_value_free(values);
1093 ldap_value_free(values);
1094 #ifdef DEBUG_PASSWORDS
1095 DEBUG (100, ("get_single_attribute: [%s] = [%s]\n", attribute, value));
1100 /************************************************************************
1101 Routine to manage the LDAPMod structure array
1102 manage memory used by the array, by each struct, and values
1104 ************************************************************************/
1105 static void make_a_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
1113 /* sanity checks on the mod values */
1115 if (attribute == NULL || *attribute == '\0')
1117 #if 0 /* commented out after discussion with abartlet. Do not reenable.
1118 left here so other so re-add similar code --jerry */
1119 if (value == NULL || *value == '\0')
1125 mods = (LDAPMod **) malloc(sizeof(LDAPMod *));
1128 DEBUG(0, ("make_a_mod: out of memory!\n"));
1134 for (i = 0; mods[i] != NULL; ++i) {
1135 if (mods[i]->mod_op == modop && !strcasecmp(mods[i]->mod_type, attribute))
1139 if (mods[i] == NULL)
1141 mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *));
1144 DEBUG(0, ("make_a_mod: out of memory!\n"));
1147 mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
1148 if (mods[i] == NULL)
1150 DEBUG(0, ("make_a_mod: out of memory!\n"));
1153 mods[i]->mod_op = modop;
1154 mods[i]->mod_values = NULL;
1155 mods[i]->mod_type = strdup(attribute);
1161 char *utf8_value = NULL;
1164 if (mods[i]->mod_values != NULL) {
1165 for (; mods[i]->mod_values[j] != NULL; j++);
1167 mods[i]->mod_values = (char **)Realloc(mods[i]->mod_values,
1168 (j + 2) * sizeof (char *));
1170 if (mods[i]->mod_values == NULL) {
1171 DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
1175 if (push_utf8_allocate(&utf8_value, value) == (size_t)-1) {
1176 DEBUG (0, ("make_a_mod: String conversion failure!\n"));
1180 mods[i]->mod_values[j] = utf8_value;
1182 mods[i]->mod_values[j + 1] = NULL;
1187 /**********************************************************************
1188 Set attribute to newval in LDAP, regardless of what value the
1189 attribute had in LDAP before.
1190 *********************************************************************/
1191 static void make_ldap_mod(LDAP *ldap_struct, LDAPMessage *existing,
1193 const char *attribute, const char *newval)
1195 char **values = NULL;
1197 if (existing != NULL) {
1198 values = ldap_get_values(ldap_struct, existing, attribute);
1201 if ((values != NULL) && (values[0] != NULL) &&
1202 strcmp(values[0], newval) == 0) {
1204 /* Believe it or not, but LDAP will deny a delete and
1205 an add at the same time if the values are the
1208 ldap_value_free(values);
1212 /* Regardless of the real operation (add or modify)
1213 we add the new value here. We rely on deleting
1214 the old value, should it exist. */
1216 if ((newval != NULL) && (strlen(newval) > 0)) {
1217 make_a_mod(mods, LDAP_MOD_ADD, attribute, newval);
1220 if (values == NULL) {
1221 /* There has been no value before, so don't delete it.
1222 Here's a possible race: We might end up with
1223 duplicate attributes */
1227 /* By deleting exactly the value we found in the entry this
1228 should be race-free in the sense that the LDAP-Server will
1229 deny the complete operation if somebody changed the
1230 attribute behind our back. */
1232 make_a_mod(mods, LDAP_MOD_DELETE, attribute, values[0]);
1233 ldap_value_free(values);
1236 /*******************************************************************
1237 Delete complete object or objectclass and attrs from
1238 object found in search_result depending on lp_ldap_delete_dn
1239 ******************************************************************/
1240 static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
1241 LDAPMessage *result,
1242 const char *objectclass,
1247 LDAPMod **mods = NULL;
1249 BerElement *ptr = NULL;
1251 rc = ldap_count_entries(ldap_state->ldap_struct, result);
1254 DEBUG(0, ("Entry must exist exactly once!\n"));
1255 return NT_STATUS_UNSUCCESSFUL;
1258 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1259 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
1261 if (lp_ldap_delete_dn()) {
1262 NTSTATUS ret = NT_STATUS_OK;
1263 rc = ldapsam_delete(ldap_state, dn);
1265 if (rc != LDAP_SUCCESS) {
1266 DEBUG(0, ("Could not delete object %s\n", dn));
1267 ret = NT_STATUS_UNSUCCESSFUL;
1273 /* Ok, delete only the SAM attributes */
1275 for (name = ldap_first_attribute(ldap_state->ldap_struct, entry, &ptr);
1277 name = ldap_next_attribute(ldap_state->ldap_struct, entry, ptr))
1281 /* We are only allowed to delete the attributes that
1284 for (attrib = attrs; *attrib != NULL; attrib++)
1286 if (StrCaseCmp(*attrib, name) == 0) {
1287 DEBUG(10, ("deleting attribute %s\n", name));
1288 make_a_mod(&mods, LDAP_MOD_DELETE, name, NULL);
1299 make_a_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
1301 rc = ldapsam_modify(ldap_state, dn, mods);
1302 ldap_mods_free(mods, 1);
1304 if (rc != LDAP_SUCCESS) {
1305 char *ld_error = NULL;
1306 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1309 DEBUG(0, ("could not delete attributes for %s, error: %s (%s)\n",
1310 dn, ldap_err2string(rc), ld_error?ld_error:"unknown"));
1311 SAFE_FREE(ld_error);
1313 return NT_STATUS_UNSUCCESSFUL;
1317 return NT_STATUS_OK;
1320 /**********************************************************************
1321 Search for the domain info entry
1322 *********************************************************************/
1323 static int ldapsam_search_domain_info(struct ldapsam_privates *ldap_state,
1324 LDAPMessage ** result)
1330 snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))",
1332 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
1333 ldap_state->domain_name);
1335 DEBUG(2, ("Searching for:[%s]\n", filter));
1338 attr_list = get_attr_list( dominfo_attr_list );
1339 rc = ldapsam_search_suffix(ldap_state, filter, attr_list , result);
1340 free_attr_list( attr_list );
1342 if (rc != LDAP_SUCCESS) {
1343 DEBUG(2,("Problem during LDAPsearch: %s\n", ldap_err2string (rc)));
1344 DEBUG(2,("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1350 /**********************************************************************
1351 If this entry is is the 'allocated' range, extract the RID and return
1352 it, so we can find the 'next' rid to allocate.
1354 Do this, no matter what type of object holds the RID - be it a user,
1355 group or somthing else.
1356 *********************************************************************/
1357 static uint32 entry_to_rid(struct ldapsam_privates *ldap_state, LDAPMessage *entry, int rid_type)
1363 if (!get_single_attribute(ldap_state->ldap_struct, entry,
1364 LDAP_ATTRIBUTE_SID, sid_string))
1369 if (!string_to_sid(&dom_sid, sid_string)) {
1373 if (!sid_peek_check_rid(&dom_sid, get_global_sam_sid(), &rid)) {
1374 /* not our domain, so we don't care */
1380 if (rid >= ldap_state->low_allocated_user_rid &&
1381 rid <= ldap_state->high_allocated_user_rid) {
1385 case GROUP_RID_TYPE:
1386 if (rid >= ldap_state->low_allocated_group_rid &&
1387 rid <= ldap_state->high_allocated_group_rid) {
1396 /**********************************************************************
1397 Connect to LDAP server and find the next available 'allocated' RID.
1399 The search is done 'per type' as we allocate seperate pools for the
1400 EVEN and ODD (user and group) RIDs.
1402 This is only done once, so that we can fill out the sambaDomain.
1403 *********************************************************************/
1404 static uint32 search_next_allocated_rid(struct ldapsam_privates *ldap_state, int rid_type)
1407 LDAPMessage *result;
1413 char *sid_attr[] = {LDAP_ATTRIBUTE_SID, NULL};
1416 snprintf( filter, sizeof(filter)-1, "(%s=*)", LDAP_ATTRIBUTE_SID );
1418 DEBUG(2, ("search_top_allocated_rid: searching for:[%s]\n", filter));
1420 rc = ldapsam_search_suffix(ldap_state, filter, sid_attr, &result);
1422 if (rc != LDAP_SUCCESS) {
1423 DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc)));
1424 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1430 count = ldap_count_entries(ldap_state->ldap_struct, result);
1431 DEBUG(2, ("search_top_allocated_rid: %d entries in the base!\n", count));
1434 DEBUG(3, ("LDAP search returned no records, assuming no allocated RIDs present!: %s\n", ldap_err2string(rc)));
1435 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
1437 entry = ldap_first_entry(ldap_state->ldap_struct,result);
1439 top_rid = entry_to_rid(ldap_state, entry, rid_type);
1441 while ((entry = ldap_next_entry(ldap_state->ldap_struct, entry))) {
1443 rid = entry_to_rid(ldap_state, entry, rid_type);
1444 if (((rid & ~RID_TYPE_MASK) == rid_type) && (rid > top_rid)) {
1452 if (top_rid < ldap_state->low_allocated_user_rid) {
1453 return ldap_state->low_allocated_user_rid;
1456 case GROUP_RID_TYPE:
1457 if (top_rid < ldap_state->low_allocated_group_rid)
1458 return ldap_state->low_allocated_group_rid;
1462 next_rid = (top_rid & ~RID_TYPE_MASK) + rid_type + RID_MULTIPLIER;
1466 if (next_rid > ldap_state->high_allocated_user_rid) {
1470 case GROUP_RID_TYPE:
1471 if (next_rid > ldap_state->high_allocated_group_rid) {
1479 /**********************************************************************
1480 Add the sambaDomain to LDAP, so we don't have to search for this stuff
1481 again. This is a once-add operation for now.
1483 TODO: Add other attributes, and allow modification.
1484 *********************************************************************/
1485 static NTSTATUS add_new_domain_info(struct ldapsam_privates *ldap_state)
1489 LDAPMod **mods = NULL;
1492 LDAPMessage *result = NULL;
1497 uint32 next_allocated_user_rid;
1498 uint32 next_allocated_group_rid;
1500 next_allocated_user_rid = search_next_allocated_rid(ldap_state, USER_RID_TYPE);
1501 if (!next_allocated_user_rid) {
1502 return NT_STATUS_UNSUCCESSFUL;
1505 next_allocated_group_rid = search_next_allocated_rid(ldap_state, GROUP_RID_TYPE);
1506 if (!next_allocated_group_rid) {
1507 return NT_STATUS_UNSUCCESSFUL;
1510 slprintf (filter, sizeof (filter) - 1, "(&(%s=%s)(objectclass=%s))",
1511 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
1512 ldap_state->domain_name, LDAP_OBJ_DOMINFO);
1514 attr_list = get_attr_list( dominfo_attr_list );
1515 rc = ldapsam_search_suffix(ldap_state, filter, attr_list, &result);
1516 free_attr_list( attr_list );
1518 if (rc != LDAP_SUCCESS) {
1519 return NT_STATUS_UNSUCCESSFUL;
1522 num_result = ldap_count_entries(ldap_state->ldap_struct, result);
1524 if (num_result > 1) {
1525 DEBUG (0, ("More than domain with that name exists: bailing out!\n"));
1526 ldap_msgfree(result);
1527 return NT_STATUS_UNSUCCESSFUL;
1530 /* Check if we need to add an entry */
1531 DEBUG(3,("Adding new domain\n"));
1532 ldap_op = LDAP_MOD_ADD;
1533 asprintf (&dn, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
1534 ldap_state->domain_name, lp_ldap_suffix());
1536 /* Free original search */
1537 ldap_msgfree(result);
1540 return NT_STATUS_NO_MEMORY;
1542 /* make the changes - the entry *must* not already have samba attributes */
1543 make_a_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
1544 ldap_state->domain_name);
1546 sid_to_string(tmp, &ldap_state->domain_sid);
1547 make_a_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), tmp);
1549 snprintf(tmp, sizeof(tmp)-1, "%i", next_allocated_user_rid);
1550 make_a_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), tmp);
1552 snprintf(tmp, sizeof(tmp)-1, "%i", next_allocated_group_rid);
1553 make_a_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID), tmp);
1555 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
1560 rc = ldapsam_add(ldap_state, dn, mods);
1562 case LDAP_MOD_REPLACE:
1563 rc = ldapsam_modify(ldap_state, dn, mods);
1566 DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
1567 return NT_STATUS_INVALID_PARAMETER;
1570 if (rc!=LDAP_SUCCESS) {
1571 char *ld_error = NULL;
1572 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1575 ("failed to %s domain dn= %s with: %s\n\t%s\n",
1576 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
1577 dn, ldap_err2string(rc),
1578 ld_error?ld_error:"unknown"));
1579 SAFE_FREE(ld_error);
1581 ldap_mods_free(mods,1);
1582 return NT_STATUS_UNSUCCESSFUL;
1585 DEBUG(2,("added: domain = %s in the LDAP database\n", ldap_state->domain_name));
1586 ldap_mods_free(mods, 1);
1587 return NT_STATUS_OK;
1590 /**********************************************************************
1591 Even if the sambaAccount attribute in LDAP tells us that this RID is
1592 safe to use, always check before use.
1593 *********************************************************************/
1594 static BOOL sid_in_use(struct ldapsam_privates *ldap_state,
1595 const DOM_SID *sid, int *error)
1599 LDAPMessage *result = NULL;
1602 char *sid_attr[] = {LDAP_ATTRIBUTE_SID, NULL};
1604 slprintf(filter, sizeof(filter)-1, "(%s=%s)", LDAP_ATTRIBUTE_SID, sid_to_string(sid_string, sid));
1606 rc = ldapsam_search_suffix(ldap_state, filter, sid_attr, &result);
1608 if (rc != LDAP_SUCCESS) {
1609 char *ld_error = NULL;
1610 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
1611 DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n",
1612 sid_string, ld_error));
1613 SAFE_FREE(ld_error);
1619 if ((count = ldap_count_entries(ldap_state->ldap_struct, result)) > 0) {
1620 DEBUG(3, ("Sid %s already in use - trying next RID\n",
1622 ldap_msgfree(result);
1626 ldap_msgfree(result);
1628 /* good, sid is not in use */
1632 /**********************************************************************
1633 Set the new nextRid attribute, and return one we can use.
1635 This also checks that this RID is actually free - in case the admin
1636 manually stole it :-).
1637 *********************************************************************/
1638 static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *rid, int rid_type)
1640 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1642 LDAPMessage *result = NULL;
1643 LDAPMessage *entry = NULL;
1645 LDAPMod **mods = NULL;
1647 fstring old_rid_string;
1648 fstring next_rid_string;
1652 if ( ldap_state->schema_ver != SCHEMAVER_SAMBASAMACCOUNT ) {
1653 DEBUG(0, ("Allocated RIDs require the %s objectclass used by 'ldapsam'\n",
1654 LDAP_OBJ_SAMBASAMACCOUNT));
1655 return NT_STATUS_UNSUCCESSFUL;
1658 while (attempts < 10)
1661 if (ldapsam_search_domain_info(ldap_state, &result)) {
1665 if (ldap_count_entries(ldap_state->ldap_struct, result) < 1) {
1666 DEBUG(3, ("Got no domain info entries for domain %s\n",
1667 ldap_state->domain_name));
1668 ldap_msgfree(result);
1669 if (NT_STATUS_IS_OK(ret = add_new_domain_info(ldap_state))) {
1672 DEBUG(0, ("Adding domain info failed with %s\n", nt_errstr(ret)));
1677 if ((count = ldap_count_entries(ldap_state->ldap_struct, result)) > 1) {
1678 DEBUG(0, ("Got too many (%d) domain info entries for domain %s\n",
1679 count, ldap_state->domain_name));
1680 ldap_msgfree(result);
1684 entry = ldap_first_entry(ldap_state->ldap_struct, result);
1686 ldap_msgfree(result);
1690 if ((dn = ldap_get_dn(ldap_state->ldap_struct, entry)) == NULL) {
1691 DEBUG(0, ("Could not get domain info DN\n"));
1692 ldap_msgfree(result);
1696 /* yes, we keep 2 seperate counters, to avoid stomping on the two
1697 different sets of algorithmic RIDs */
1701 if (!get_single_attribute(ldap_state->ldap_struct,
1702 entry, "nextUserRid",
1705 ldap_msgfree(result);
1709 case GROUP_RID_TYPE:
1710 if (!get_single_attribute(ldap_state->ldap_struct,
1711 entry, "nextGroupRid",
1714 ldap_msgfree(result);
1720 /* This is the core of the whole routine. If we had
1721 scheme-style closures, there would be a *lot* less code
1723 *rid = (uint32)atol(old_rid_string);
1724 next_rid = *rid+RID_MULTIPLIER;
1726 slprintf(next_rid_string, sizeof(next_rid_string)-1, "%d", next_rid);
1730 if (next_rid > ldap_state->high_allocated_user_rid) {
1731 return NT_STATUS_UNSUCCESSFUL;
1734 /* Try to make the modification atomically by enforcing the
1735 old value in the delete mod. */
1736 make_ldap_mod(ldap_state->ldap_struct, entry, &mods,
1737 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
1741 case GROUP_RID_TYPE:
1742 if (next_rid > ldap_state->high_allocated_group_rid) {
1743 return NT_STATUS_UNSUCCESSFUL;
1746 /* Try to make the modification atomically by enforcing the
1747 old value in the delete mod. */
1748 make_ldap_mod(ldap_state->ldap_struct, entry, &mods,
1749 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
1754 if ((rc = ldap_modify_s(ldap_state->ldap_struct, dn, mods)) == LDAP_SUCCESS) {
1757 pstring domain_sid_string;
1760 if (!get_single_attribute(ldap_state->ldap_struct, result,
1761 get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID),
1764 ldap_mods_free(mods, 1);
1766 ldap_msgfree(result);
1770 if (!string_to_sid(&dom_sid, domain_sid_string)) {
1771 ldap_mods_free(mods, 1);
1773 ldap_msgfree(result);
1777 ldap_mods_free(mods, 1);
1780 ldap_msgfree(result);
1782 sid_copy(&sid, &dom_sid);
1783 sid_append_rid(&sid, *rid);
1785 /* check RID is not in use */
1786 if (sid_in_use(ldap_state, &sid, &error)) {
1793 return NT_STATUS_OK;
1796 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
1797 DEBUG(2, ("Failed to modify rid: %s\n", ld_error));
1798 SAFE_FREE(ld_error);
1800 ldap_mods_free(mods, 1);
1806 ldap_msgfree(result);
1810 /* Sleep for a random timeout */
1811 unsigned sleeptime = (sys_random()*sys_getpid()*attempts);
1819 DEBUG(0, ("Failed to set new RID\n"));
1823 /* New Interface is being implemented here */
1825 /**********************************************************************
1826 Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
1827 *********************************************************************/
1828 static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
1829 SAM_ACCOUNT * sampass,
1830 LDAPMessage * entry,
1838 if ((ldap_values = ldap_get_values (ldap_state->ldap_struct, entry, "objectClass")) == NULL) {
1839 DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
1843 for (values=ldap_values;*values;values++) {
1844 if (strcasecmp(*values, LDAP_OBJ_POSIXACCOUNT ) == 0) {
1849 if (!*values) { /*end of array, no posixAccount */
1850 DEBUG(10, ("user does not have %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
1851 ldap_value_free(ldap_values);
1854 ldap_value_free(ldap_values);
1856 if ( !get_single_attribute(ldap_state->ldap_struct, entry,
1857 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_UNIX_HOME), homedir) )
1862 if ( !get_single_attribute(ldap_state->ldap_struct, entry,
1863 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_GIDNUMBER), temp) )
1868 *gid = (gid_t)atol(temp);
1870 pdb_set_unix_homedir(sampass, homedir, PDB_SET);
1872 DEBUG(10, ("user has %s attributes\n", LDAP_OBJ_POSIXACCOUNT));
1878 /**********************************************************************
1879 Initialize SAM_ACCOUNT from an LDAP query
1880 (Based on init_sam_from_buffer in pdb_tdb.c)
1881 *********************************************************************/
1882 static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
1883 SAM_ACCOUNT * sampass,
1884 LDAPMessage * entry)
1890 pass_can_change_time,
1891 pass_must_change_time;
1904 uint8 smblmpwd[LM_HASH_LEN],
1905 smbntpwd[NT_HASH_LEN];
1906 uint16 acct_ctrl = 0,
1909 uint8 hours[MAX_HOURS_LEN];
1912 gid_t gid = getegid();
1915 * do a little initialization
1919 nt_username[0] = '\0';
1922 dir_drive[0] = '\0';
1923 logon_script[0] = '\0';
1924 profile_path[0] = '\0';
1925 acct_desc[0] = '\0';
1926 munged_dial[0] = '\0';
1927 workstations[0] = '\0';
1930 if (sampass == NULL || ldap_state == NULL || entry == NULL) {
1931 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
1935 if (ldap_state->ldap_struct == NULL) {
1936 DEBUG(0, ("init_sam_from_ldap: ldap_state->ldap_struct is NULL!\n"));
1940 if (!get_single_attribute(ldap_state->ldap_struct, entry, "uid", username)) {
1941 DEBUG(1, ("No uid attribute found for this user!\n"));
1945 DEBUG(2, ("Entry found for user: %s\n", username));
1947 pstrcpy(nt_username, username);
1949 pstrcpy(domain, ldap_state->domain_name);
1951 pdb_set_username(sampass, username, PDB_SET);
1953 pdb_set_domain(sampass, domain, PDB_DEFAULT);
1954 pdb_set_nt_username(sampass, nt_username, PDB_SET);
1956 /* deal with different attributes between the schema first */
1958 if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT )
1960 if (get_single_attribute(ldap_state->ldap_struct, entry,
1961 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), temp))
1963 pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
1966 if (!get_single_attribute(ldap_state->ldap_struct, entry,
1967 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_SID), temp))
1969 pdb_set_group_sid_from_string(sampass, temp, PDB_SET);
1973 pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
1980 if (get_single_attribute(ldap_state->ldap_struct, entry,
1981 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), temp))
1983 user_rid = (uint32)atol(temp);
1984 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
1987 if (!get_single_attribute(ldap_state->ldap_struct, entry,
1988 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_RID), temp))
1990 pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
1994 group_rid = (uint32)atol(temp);
1996 /* for some reason, we often have 0 as a primary group RID.
1997 Make sure that we treat this just as a 'default' value */
1999 if ( group_rid > 0 )
2000 pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
2002 pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
2006 if (pdb_get_init_flags(sampass,PDB_USERSID) == PDB_DEFAULT) {
2007 DEBUG(1, ("no %s or %s attribute found for this user %s\n",
2008 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
2009 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
2016 * If so configured, try and get the values from LDAP
2019 if (lp_ldap_trust_ids() && (get_unix_attributes(ldap_state, sampass, entry, &gid)))
2021 if (pdb_get_init_flags(sampass,PDB_GROUPSID) == PDB_DEFAULT)
2024 /* call the mapping code here */
2025 if(pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) {
2026 pdb_set_group_sid(sampass, &map.sid, PDB_SET);
2029 pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid), PDB_SET);
2034 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2035 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), temp))
2037 /* leave as default */
2039 pass_last_set_time = (time_t) atol(temp);
2040 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
2043 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2044 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp))
2046 /* leave as default */
2048 logon_time = (time_t) atol(temp);
2049 pdb_set_logon_time(sampass, logon_time, PDB_SET);
2052 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2053 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp))
2055 /* leave as default */
2057 logoff_time = (time_t) atol(temp);
2058 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
2061 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2062 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp))
2064 /* leave as default */
2066 kickoff_time = (time_t) atol(temp);
2067 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
2070 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2071 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp))
2073 /* leave as default */
2075 pass_can_change_time = (time_t) atol(temp);
2076 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
2079 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2080 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp))
2082 /* leave as default */
2084 pass_must_change_time = (time_t) atol(temp);
2085 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
2088 /* recommend that 'gecos' and 'displayName' should refer to the same
2089 * attribute OID. userFullName depreciated, only used by Samba
2090 * primary rules of LDAP: don't make a new attribute when one is already defined
2091 * that fits your needs; using cn then displayName rather than 'userFullName'
2094 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2095 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME), fullname))
2097 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2098 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_CN), fullname))
2100 /* leave as default */
2102 pdb_set_fullname(sampass, fullname, PDB_SET);
2105 pdb_set_fullname(sampass, fullname, PDB_SET);
2108 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2109 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), dir_drive))
2111 pdb_set_dir_drive(sampass, talloc_sub_specified(sampass->mem_ctx,
2117 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
2120 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2121 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), homedir))
2123 pdb_set_homedir(sampass, talloc_sub_specified(sampass->mem_ctx,
2129 pdb_set_homedir(sampass, homedir, PDB_SET);
2132 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2133 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), logon_script))
2135 pdb_set_logon_script(sampass, talloc_sub_specified(sampass->mem_ctx,
2141 pdb_set_logon_script(sampass, logon_script, PDB_SET);
2144 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2145 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), profile_path))
2147 pdb_set_profile_path(sampass, talloc_sub_specified(sampass->mem_ctx,
2153 pdb_set_profile_path(sampass, profile_path, PDB_SET);
2156 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2157 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC), acct_desc))
2159 /* leave as default */
2161 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
2164 if (!get_single_attribute(ldap_state->ldap_struct, entry,
2165 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), workstations))
2167 /* leave as default */;
2169 pdb_set_workstations(sampass, workstations, PDB_SET);
2172 /* FIXME: hours stuff should be cleaner */
2176 memset(hours, 0xff, hours_len);
2178 if (!get_single_attribute (ldap_state->ldap_struct, entry,
2179 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), temp))
2181 /* leave as default */
2183 pdb_gethexpwd(temp, smblmpwd);
2184 memset((char *)temp, '\0', strlen(temp)+1);
2185 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
2187 ZERO_STRUCT(smblmpwd);
2190 if (!get_single_attribute (ldap_state->ldap_struct, entry,
2191 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), temp))
2193 /* leave as default */
2195 pdb_gethexpwd(temp, smbntpwd);
2196 memset((char *)temp, '\0', strlen(temp)+1);
2197 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
2199 ZERO_STRUCT(smbntpwd);
2202 if (!get_single_attribute (ldap_state->ldap_struct, entry,
2203 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), temp))
2205 acct_ctrl |= ACB_NORMAL;
2207 acct_ctrl = pdb_decode_acct_ctrl(temp);
2210 acct_ctrl |= ACB_NORMAL;
2212 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
2215 pdb_set_hours_len(sampass, hours_len, PDB_SET);
2216 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
2218 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
2220 /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
2221 /* pdb_set_unknown_5(sampass, unknown5, PDB_SET); */
2222 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
2224 pdb_set_hours(sampass, hours, PDB_SET);
2229 /**********************************************************************
2230 Initialize SAM_ACCOUNT from an LDAP query
2231 (Based on init_buffer_from_sam in pdb_tdb.c)
2232 *********************************************************************/
2233 static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
2234 LDAPMessage *existing,
2235 LDAPMod *** mods, SAM_ACCOUNT * sampass,
2236 BOOL (*need_update)(const SAM_ACCOUNT *,
2242 if (mods == NULL || sampass == NULL) {
2243 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
2250 * took out adding "objectclass: sambaAccount"
2251 * do this on a per-mod basis
2253 if (need_update(sampass, PDB_USERNAME))
2254 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2255 "uid", pdb_get_username(sampass));
2257 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
2259 if (pdb_get_init_flags(sampass, PDB_USERSID) == PDB_DEFAULT) {
2260 if (ldap_state->permit_non_unix_accounts) {
2261 if (!NT_STATUS_IS_OK(ldapsam_next_rid(ldap_state, &rid, USER_RID_TYPE))) {
2262 DEBUG(0, ("NO user RID specified on account %s, and "
2263 "finding next available NUA RID failed, "
2265 pdb_get_username(sampass)));
2266 ldap_mods_free(*mods, 1);
2270 DEBUG(0, ("NO user RID specified on account %s, "
2271 "cannot store!\n", pdb_get_username(sampass)));
2272 ldap_mods_free(*mods, 1);
2276 /* now that we have figured out the RID, always store it, as
2277 the schema requires it (either as a SID or a RID) */
2279 if (!pdb_set_user_sid_from_rid(sampass, rid, PDB_CHANGED)) {
2280 DEBUG(0, ("Could not store RID back onto SAM_ACCOUNT for user %s!\n",
2281 pdb_get_username(sampass)));
2282 ldap_mods_free(*mods, 1);
2287 /* only update the RID if we actually need to */
2288 if (need_update(sampass, PDB_USERSID))
2291 fstring dom_sid_string;
2292 const DOM_SID *user_sid = pdb_get_user_sid(sampass);
2294 switch ( ldap_state->schema_ver )
2296 case SCHEMAVER_SAMBAACCOUNT:
2297 if (!sid_peek_check_rid(get_global_sam_sid(), user_sid, &rid)) {
2298 DEBUG(1, ("User's SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
2299 sid_to_string(sid_string, user_sid),
2300 sid_to_string(dom_sid_string, get_global_sam_sid())));
2303 slprintf(temp, sizeof(temp) - 1, "%i", rid);
2304 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2305 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
2309 case SCHEMAVER_SAMBASAMACCOUNT:
2310 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2311 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
2312 sid_to_string(sid_string, user_sid));
2316 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
2321 /* we don't need to store the primary group RID - so leaving it
2322 'free' to hang off the unix primary group makes life easier */
2324 if (need_update(sampass, PDB_GROUPSID))
2327 fstring dom_sid_string;
2328 const DOM_SID *group_sid = pdb_get_group_sid(sampass);
2330 switch ( ldap_state->schema_ver )
2332 case SCHEMAVER_SAMBAACCOUNT:
2333 if (!sid_peek_check_rid(get_global_sam_sid(), group_sid, &rid)) {
2334 DEBUG(1, ("User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
2335 sid_to_string(sid_string, group_sid),
2336 sid_to_string(dom_sid_string, get_global_sam_sid())));
2340 slprintf(temp, sizeof(temp) - 1, "%i", rid);
2341 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2342 get_userattr_key2string(ldap_state->schema_ver,
2343 LDAP_ATTR_PRIMARY_GROUP_RID), temp);
2346 case SCHEMAVER_SAMBASAMACCOUNT:
2347 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2348 get_userattr_key2string(ldap_state->schema_ver,
2349 LDAP_ATTR_PRIMARY_GROUP_SID), sid_to_string(sid_string, group_sid));
2353 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
2359 /* displayName, cn, and gecos should all be the same
2360 * most easily accomplished by giving them the same OID
2361 * gecos isn't set here b/c it should be handled by the
2363 * We change displayName only and fall back to cn if
2364 * it does not exist.
2367 if (need_update(sampass, PDB_FULLNAME))
2368 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2369 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME),
2370 pdb_get_fullname(sampass));
2372 if (need_update(sampass, PDB_ACCTDESC))
2373 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2374 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC),
2375 pdb_get_acct_desc(sampass));
2377 if (need_update(sampass, PDB_WORKSTATIONS))
2378 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2379 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS),
2380 pdb_get_workstations(sampass));
2382 if (need_update(sampass, PDB_SMBHOME))
2383 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2384 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH),
2385 pdb_get_homedir(sampass));
2387 if (need_update(sampass, PDB_DRIVE))
2388 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2389 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE),
2390 pdb_get_dir_drive(sampass));
2392 if (need_update(sampass, PDB_LOGONSCRIPT))
2393 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2394 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT),
2395 pdb_get_logon_script(sampass));
2397 if (need_update(sampass, PDB_PROFILE))
2398 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2399 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH),
2400 pdb_get_profile_path(sampass));
2402 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
2403 if (need_update(sampass, PDB_LOGONTIME))
2404 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2405 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
2407 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
2408 if (need_update(sampass, PDB_LOGOFFTIME))
2409 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2410 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
2412 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
2413 if (need_update(sampass, PDB_KICKOFFTIME))
2414 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2415 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
2417 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
2418 if (need_update(sampass, PDB_CANCHANGETIME))
2419 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2420 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
2422 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
2423 if (need_update(sampass, PDB_MUSTCHANGETIME))
2424 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2425 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp);
2427 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
2428 || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY))
2431 pdb_sethexpwd(temp, pdb_get_lanman_passwd(sampass),
2432 pdb_get_acct_ctrl(sampass));
2434 if (need_update(sampass, PDB_LMPASSWD))
2435 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2436 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
2439 pdb_sethexpwd (temp, pdb_get_nt_passwd(sampass),
2440 pdb_get_acct_ctrl(sampass));
2442 if (need_update(sampass, PDB_NTPASSWD))
2443 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2444 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
2447 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
2448 if (need_update(sampass, PDB_PASSLASTSET))
2449 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2450 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET),
2454 /* FIXME: Hours stuff goes in LDAP */
2456 if (need_update(sampass, PDB_ACCTCTRL))
2457 make_ldap_mod(ldap_state->ldap_struct, existing, mods,
2458 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO),
2459 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
2466 /**********************************************************************
2467 Connect to LDAP server for password enumeration
2468 *********************************************************************/
2469 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
2471 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2476 snprintf( filter, sizeof(filter)-1, "(&%s%s)", lp_ldap_filter(),
2477 get_objclass_filter(ldap_state->schema_ver));
2478 all_string_sub(filter, "%u", "*", sizeof(pstring));
2480 attr_list = get_userattr_list(ldap_state->schema_ver);
2481 rc = ldapsam_search_suffix(ldap_state, filter, attr_list, &ldap_state->result);
2482 free_attr_list( attr_list );
2484 if (rc != LDAP_SUCCESS) {
2485 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
2486 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
2487 ldap_msgfree(ldap_state->result);
2488 ldap_state->result = NULL;
2489 return NT_STATUS_UNSUCCESSFUL;
2492 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
2493 ldap_count_entries(ldap_state->ldap_struct,
2494 ldap_state->result)));
2496 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
2497 ldap_state->result);
2498 ldap_state->index = 0;
2500 return NT_STATUS_OK;
2503 /**********************************************************************
2504 End enumeration of the LDAP password list
2505 *********************************************************************/
2506 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
2508 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2509 if (ldap_state->result) {
2510 ldap_msgfree(ldap_state->result);
2511 ldap_state->result = NULL;
2515 /**********************************************************************
2516 Get the next entry in the LDAP password database
2517 *********************************************************************/
2518 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
2520 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2521 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2524 /* The rebind proc needs this *HACK*. We are not multithreaded, so
2525 this will work, but it's not nice. */
2526 static_ldap_state = ldap_state;
2529 if (!ldap_state->entry)
2532 ldap_state->index++;
2533 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
2535 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
2539 return NT_STATUS_OK;
2542 /**********************************************************************
2543 Get SAM_ACCOUNT entry from LDAP by username
2544 *********************************************************************/
2545 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
2547 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2548 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2549 LDAPMessage *result;
2555 attr_list = get_userattr_list( ldap_state->schema_ver );
2556 rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
2557 free_attr_list( attr_list );
2559 if ( rc != LDAP_SUCCESS )
2560 return NT_STATUS_NO_SUCH_USER;
2562 count = ldap_count_entries(ldap_state->ldap_struct, result);
2566 ("Unable to locate user [%s] count=%d\n", sname,
2568 return NT_STATUS_NO_SUCH_USER;
2569 } else if (count > 1) {
2571 ("Duplicate entries for this user [%s] Failing. count=%d\n", sname,
2573 return NT_STATUS_NO_SUCH_USER;
2576 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2578 if (!init_sam_from_ldap(ldap_state, user, entry)) {
2579 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
2580 ldap_msgfree(result);
2581 return NT_STATUS_NO_SUCH_USER;
2583 ldap_msgfree(result);
2586 ldap_msgfree(result);
2591 /**********************************************************************
2592 Get SAM_ACCOUNT entry from LDAP by SID
2593 *********************************************************************/
2594 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
2596 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2597 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2598 LDAPMessage *result;
2605 switch ( ldap_state->schema_ver )
2607 case SCHEMAVER_SAMBASAMACCOUNT:
2608 attr_list = get_userattr_list(ldap_state->schema_ver);
2609 rc = ldapsam_search_suffix_by_sid(ldap_state, sid, &result, attr_list);
2610 free_attr_list( attr_list );
2612 if ( rc != LDAP_SUCCESS )
2613 return NT_STATUS_NO_SUCH_USER;
2616 case SCHEMAVER_SAMBAACCOUNT:
2619 if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) {
2620 return NT_STATUS_NO_SUCH_USER;
2623 attr_list = get_userattr_list(ldap_state->schema_ver);
2624 rc = ldapsam_search_suffix_by_rid(ldap_state, rid, &result, attr_list );
2625 free_attr_list( attr_list );
2627 if ( rc != LDAP_SUCCESS )
2628 return NT_STATUS_NO_SUCH_USER;
2633 count = ldap_count_entries(ldap_state->ldap_struct, result);
2638 ("Unable to locate SID [%s] count=%d\n", sid_to_string(sid_string, sid),
2640 return NT_STATUS_NO_SUCH_USER;
2645 ("More than one user with SID [%s]. Failing. count=%d\n", sid_to_string(sid_string, sid),
2647 return NT_STATUS_NO_SUCH_USER;
2650 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2653 if (!init_sam_from_ldap(ldap_state, user, entry)) {
2654 DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
2655 ldap_msgfree(result);
2656 return NT_STATUS_NO_SUCH_USER;
2658 ldap_msgfree(result);
2661 ldap_msgfree(result);
2666 /********************************************************************
2667 Do the actual modification - also change a plaittext passord if
2669 **********************************************************************/
2671 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
2672 SAM_ACCOUNT *newpwd, char *dn,
2673 LDAPMod **mods, int ldap_op,
2674 BOOL (*need_update)(const SAM_ACCOUNT *,
2677 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2680 if (!my_methods || !newpwd || !dn) {
2681 return NT_STATUS_INVALID_PARAMETER;
2685 DEBUG(5,("mods is empty: nothing to modify\n"));
2686 /* may be password change below however */
2691 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_ACCOUNT);
2692 rc = ldapsam_add(ldap_state, dn, mods);
2694 case LDAP_MOD_REPLACE:
2695 rc = ldapsam_modify(ldap_state, dn ,mods);
2698 DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
2699 return NT_STATUS_INVALID_PARAMETER;
2702 if (rc!=LDAP_SUCCESS) {
2703 char *ld_error = NULL;
2704 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
2707 ("failed to %s user dn= %s with: %s\n\t%s\n",
2708 ldap_op == LDAP_MOD_ADD ? "add" : "modify",
2709 dn, ldap_err2string(rc),
2710 ld_error?ld_error:"unknown"));
2711 SAFE_FREE(ld_error);
2712 return NT_STATUS_UNSUCCESSFUL;
2716 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
2717 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) &&
2718 (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) &&
2719 need_update(newpwd, PDB_PLAINTEXT_PW) &&
2720 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
2724 struct berval *retdata;
2725 char *utf8_password;
2728 if (push_utf8_allocate(&utf8_password, pdb_get_plaintext_passwd(newpwd)) == (size_t)-1) {
2729 return NT_STATUS_NO_MEMORY;
2732 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
2733 return NT_STATUS_NO_MEMORY;
2736 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
2737 DEBUG(0,("ber_alloc_t returns NULL\n"));
2738 SAFE_FREE(utf8_password);
2739 return NT_STATUS_UNSUCCESSFUL;
2742 ber_printf (ber, "{");
2743 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID, utf8_dn);
2744 ber_printf (ber, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW, utf8_password);
2745 ber_printf (ber, "N}");
2747 if ((rc = ber_flatten (ber, &bv))<0) {
2748 DEBUG(0,("ber_flatten returns a value <0\n"));
2751 SAFE_FREE(utf8_password);
2752 return NT_STATUS_UNSUCCESSFUL;
2756 SAFE_FREE(utf8_password);
2759 if ((rc = ldapsam_extended_operation(ldap_state, LDAP_EXOP_X_MODIFY_PASSWD,
2760 bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) {
2761 DEBUG(0,("LDAP Password could not be changed for user %s: %s\n",
2762 pdb_get_username(newpwd),ldap_err2string(rc)));
2764 DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
2765 #ifdef DEBUG_PASSWORD
2766 DEBUG(100,("LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd)));
2768 ber_bvfree(retdata);
2769 ber_memfree(retoid);
2774 DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n"));
2775 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */
2776 return NT_STATUS_OK;
2779 /**********************************************************************
2780 Delete entry from LDAP for username
2781 *********************************************************************/
2782 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
2784 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2787 LDAPMessage *result;
2793 DEBUG(0, ("sam_acct was NULL!\n"));
2794 return NT_STATUS_INVALID_PARAMETER;
2797 sname = pdb_get_username(sam_acct);
2799 DEBUG (3, ("Deleting user %s from LDAP.\n", sname));
2801 attr_list= get_userattr_list( ldap_state->schema_ver );
2802 rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
2804 if (rc != LDAP_SUCCESS) {
2805 free_attr_list( attr_list );
2806 return NT_STATUS_NO_SUCH_USER;
2809 switch ( ldap_state->schema_ver )
2811 case SCHEMAVER_SAMBASAMACCOUNT:
2812 fstrcpy( objclass, LDAP_OBJ_SAMBASAMACCOUNT );
2815 case SCHEMAVER_SAMBAACCOUNT:
2816 fstrcpy( objclass, LDAP_OBJ_SAMBAACCOUNT );
2819 fstrcpy( objclass, "UNKNOWN" );
2820 DEBUG(0,("ldapsam_delete_sam_account: Unknown schema version specified!\n"));
2824 ret = ldapsam_delete_entry(ldap_state, result, objclass, attr_list );
2825 ldap_msgfree(result);
2826 free_attr_list( attr_list );
2831 /**********************************************************************
2832 Helper function to determine for update_sam_account whether
2833 we need LDAP modification.
2834 *********************************************************************/
2835 static BOOL element_is_changed(const SAM_ACCOUNT *sampass,
2836 enum pdb_elements element)
2838 return IS_SAM_CHANGED(sampass, element);
2841 /**********************************************************************
2843 *********************************************************************/
2844 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
2846 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2847 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2850 LDAPMessage *result;
2855 attr_list = get_userattr_list(ldap_state->schema_ver);
2856 rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
2857 free_attr_list( attr_list );
2858 if (rc != LDAP_SUCCESS)
2859 return NT_STATUS_UNSUCCESSFUL;
2861 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
2862 DEBUG(0, ("No user to modify!\n"));
2863 ldap_msgfree(result);
2864 return NT_STATUS_UNSUCCESSFUL;
2867 entry = ldap_first_entry(ldap_state->ldap_struct, result);
2868 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
2870 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
2871 element_is_changed)) {
2872 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
2873 ldap_msgfree(result);
2874 return NT_STATUS_UNSUCCESSFUL;
2877 ldap_msgfree(result);
2880 DEBUG(4,("mods is empty: nothing to update for user: %s\n",
2881 pdb_get_username(newpwd)));
2882 ldap_mods_free(mods, 1);
2883 return NT_STATUS_OK;
2886 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed);
2887 ldap_mods_free(mods,1);
2889 if (!NT_STATUS_IS_OK(ret)) {
2890 char *ld_error = NULL;
2891 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
2893 DEBUG(0,("failed to modify user with uid = %s, error: %s (%s)\n",
2894 pdb_get_username(newpwd), ld_error?ld_error:"(unknwon)", ldap_err2string(rc)));
2895 SAFE_FREE(ld_error);
2899 DEBUG(2, ("successfully modified uid = %s in the LDAP database\n",
2900 pdb_get_username(newpwd)));
2901 return NT_STATUS_OK;
2904 /**********************************************************************
2905 Helper function to determine for update_sam_account whether
2906 we need LDAP modification.
2907 *********************************************************************/
2908 static BOOL element_is_set_or_changed(const SAM_ACCOUNT *sampass,
2909 enum pdb_elements element)
2911 return (IS_SAM_SET(sampass, element) ||
2912 IS_SAM_CHANGED(sampass, element));
2915 /**********************************************************************
2916 Add SAM_ACCOUNT to LDAP
2917 *********************************************************************/
2919 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
2921 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2922 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2924 LDAPMessage *result = NULL;
2925 LDAPMessage *entry = NULL;
2927 LDAPMod **mods = NULL;
2932 const char *username = pdb_get_username(newpwd);
2935 if (!username || !*username) {
2936 DEBUG(0, ("Cannot add user without a username!\n"));
2937 return NT_STATUS_INVALID_PARAMETER;
2940 /* free this list after the second search or in case we exit on failure */
2942 attr_list = get_userattr_list(ldap_state->schema_ver);
2943 rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
2945 if (rc != LDAP_SUCCESS) {
2946 free_attr_list( attr_list );
2947 return NT_STATUS_UNSUCCESSFUL;
2950 if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
2951 DEBUG(0,("User '%s' already in the base, with samba attributes\n",
2953 ldap_msgfree(result);
2954 free_attr_list( attr_list );
2955 return NT_STATUS_UNSUCCESSFUL;
2957 ldap_msgfree(result);
2959 /* does the entry already exist but without a samba rttibutes?
2960 we don't really care what attributes are returned here */
2962 escape_user = escape_ldap_string_alloc( username );
2963 pstrcpy( filter, lp_ldap_filter() );
2964 all_string_sub( filter, "%u", escape_user, sizeof(filter) );
2965 SAFE_FREE( escape_user );
2967 rc = ldapsam_search_suffix(ldap_state, filter, attr_list, &result);
2968 free_attr_list( attr_list );
2970 if ( rc != LDAP_SUCCESS )
2971 return NT_STATUS_UNSUCCESSFUL;
2973 num_result = ldap_count_entries(ldap_state->ldap_struct, result);
2975 if (num_result > 1) {
2976 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
2977 ldap_msgfree(result);
2978 return NT_STATUS_UNSUCCESSFUL;
2981 /* Check if we need to update an existing entry */
2982 if (num_result == 1) {
2985 DEBUG(3,("User exists without samba attributes: adding them\n"));
2986 ldap_op = LDAP_MOD_REPLACE;
2987 entry = ldap_first_entry (ldap_state->ldap_struct, result);
2988 tmp = ldap_get_dn (ldap_state->ldap_struct, entry);
2989 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
2992 /* Check if we need to add an entry */
2993 DEBUG(3,("Adding new user\n"));
2994 ldap_op = LDAP_MOD_ADD;
2995 if (username[strlen(username)-1] == '$') {
2996 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_machine_suffix ());
2998 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", username, lp_ldap_user_suffix ());
3002 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
3003 element_is_set_or_changed)) {
3004 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
3005 ldap_msgfree(result);
3006 return NT_STATUS_UNSUCCESSFUL;
3009 ldap_msgfree(result);
3012 DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
3013 return NT_STATUS_UNSUCCESSFUL;
3015 switch ( ldap_state->schema_ver )
3017 case SCHEMAVER_SAMBAACCOUNT:
3018 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT);
3020 case SCHEMAVER_SAMBASAMACCOUNT:
3021 make_a_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
3024 DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
3028 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, element_is_set_or_changed);
3029 if (NT_STATUS_IS_ERR(ret)) {
3030 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
3031 pdb_get_username(newpwd),dn));
3032 ldap_mods_free(mods,1);
3036 DEBUG(2,("added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
3037 ldap_mods_free(mods, 1);
3039 return NT_STATUS_OK;
3042 /**********************************************************************
3044 *********************************************************************/
3046 static void free_private_data(void **vp)
3048 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
3050 ldapsam_close(*ldap_state);
3052 if ((*ldap_state)->bind_secret) {
3053 memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
3056 ldapsam_close(*ldap_state);
3058 SAFE_FREE((*ldap_state)->bind_dn);
3059 SAFE_FREE((*ldap_state)->bind_secret);
3063 /* No need to free any further, as it is talloc()ed */
3066 /**********************************************************************
3067 *********************************************************************/
3069 static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
3071 LDAPMessage ** result)
3073 int scope = LDAP_SCOPE_SUBTREE;
3077 DEBUG(2, ("ldapsam_search_one_group: searching for:[%s]\n", filter));
3080 attr_list = get_attr_list(groupmap_attr_list);
3081 rc = ldapsam_search(ldap_state, lp_ldap_suffix (), scope,
3082 filter, attr_list, 0, result);
3083 free_attr_list( attr_list );
3085 if (rc != LDAP_SUCCESS) {
3086 char *ld_error = NULL;
3087 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
3089 DEBUG(0, ("ldapsam_search_one_group: "
3090 "Problem during the LDAP search: LDAP error: %s (%s)",
3091 ld_error?ld_error:"(unknown)", ldap_err2string(rc)));
3092 DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
3093 lp_ldap_suffix(), filter));
3094 SAFE_FREE(ld_error);
3100 /**********************************************************************
3101 *********************************************************************/
3103 static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
3104 GROUP_MAP *map, LDAPMessage *entry)
3108 if (ldap_state == NULL || map == NULL || entry == NULL ||
3109 ldap_state->ldap_struct == NULL)
3111 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
3115 if (!get_single_attribute(ldap_state->ldap_struct, entry,
3116 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER), temp))
3118 DEBUG(0, ("Mandatory attribute %s not found\n",
3119 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER)));
3122 DEBUG(2, ("Entry found for group: %s\n", temp));
3124 map->gid = (gid_t)atol(temp);
3126 if (!get_single_attribute(ldap_state->ldap_struct, entry,
3127 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID), temp))
3129 DEBUG(0, ("Mandatory attribute %s not found\n",
3130 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID)));
3133 string_to_sid(&map->sid, temp);
3135 if (!get_single_attribute(ldap_state->ldap_struct, entry,
3136 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), temp))
3138 DEBUG(0, ("Mandatory attribute %s not found\n",
3139 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
3142 map->sid_name_use = (uint32)atol(temp);
3144 if ((map->sid_name_use < SID_NAME_USER) ||
3145 (map->sid_name_use > SID_NAME_UNKNOWN)) {
3146 DEBUG(0, ("Unknown Group type: %d\n", map->sid_name_use));
3150 if (!get_single_attribute(ldap_state->ldap_struct, entry,
3151 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), temp))
3154 if (!get_single_attribute(ldap_state->ldap_struct, entry,
3155 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_CN), temp))
3157 DEBUG(0, ("Attributes cn not found either "
3158 "for gidNumber(%i)\n",map->gid));
3162 fstrcpy(map->nt_name, temp);
3164 if (!get_single_attribute(ldap_state->ldap_struct, entry,
3165 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), temp))
3169 fstrcpy(map->comment, temp);
3171 map->systemaccount = 0;
3172 init_privilege(&map->priv_set);
3177 /**********************************************************************
3178 *********************************************************************/
3180 static BOOL init_ldap_from_group(LDAP *ldap_struct,
3181 LDAPMessage *existing,
3183 const GROUP_MAP *map)
3187 if (mods == NULL || map == NULL) {
3188 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
3194 sid_to_string(tmp, &map->sid);
3195 make_ldap_mod(ldap_struct, existing, mods,
3196 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID), tmp);
3197 snprintf(tmp, sizeof(tmp)-1, "%i", map->sid_name_use);
3198 make_ldap_mod(ldap_struct, existing, mods,
3199 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), tmp);
3201 make_ldap_mod(ldap_struct, existing, mods,
3202 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), map->nt_name);
3203 make_ldap_mod(ldap_struct, existing, mods,
3204 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), map->comment);
3209 /**********************************************************************
3210 *********************************************************************/
3212 static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
3216 struct ldapsam_privates *ldap_state =
3217 (struct ldapsam_privates *)methods->private_data;
3218 LDAPMessage *result;
3222 if (ldapsam_search_one_group(ldap_state, filter, &result)
3224 return NT_STATUS_NO_SUCH_GROUP;
3227 count = ldap_count_entries(ldap_state->ldap_struct, result);
3230 DEBUG(4, ("Did not find group for filter %s\n", filter));
3231 return NT_STATUS_NO_SUCH_GROUP;
3235 DEBUG(1, ("Duplicate entries for filter %s: count=%d\n",
3237 return NT_STATUS_NO_SUCH_GROUP;
3240 entry = ldap_first_entry(ldap_state->ldap_struct, result);
3243 ldap_msgfree(result);
3244 return NT_STATUS_UNSUCCESSFUL;
3247 if (!init_group_from_ldap(ldap_state, map, entry)) {
3248 DEBUG(1, ("init_group_from_ldap failed for group filter %s\n",
3250 ldap_msgfree(result);
3251 return NT_STATUS_NO_SUCH_GROUP;
3254 ldap_msgfree(result);
3255 return NT_STATUS_OK;
3258 /**********************************************************************
3259 *********************************************************************/
3261 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
3262 DOM_SID sid, BOOL with_priv)
3266 snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))",
3268 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
3269 sid_string_static(&sid));
3271 return ldapsam_getgroup(methods, filter, map);
3274 /**********************************************************************
3275 *********************************************************************/
3277 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
3278 gid_t gid, BOOL with_priv)
3282 snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%d))",
3284 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
3287 return ldapsam_getgroup(methods, filter, map);
3290 /**********************************************************************
3291 *********************************************************************/
3293 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
3294 char *name, BOOL with_priv)
3298 /* TODO: Escaping of name? */
3300 snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
3302 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), name,
3303 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN), name);
3305 return ldapsam_getgroup(methods, filter, map);
3308 /**********************************************************************
3309 *********************************************************************/
3311 static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
3313 LDAPMessage **result)
3317 snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%i))",
3318 LDAP_OBJ_POSIXGROUP,
3319 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
3322 return ldapsam_search_one_group(ldap_state, filter, result);
3325 /**********************************************************************
3326 *********************************************************************/
3328 static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
3331 struct ldapsam_privates *ldap_state =
3332 (struct ldapsam_privates *)methods->private_data;
3333 LDAPMessage *result = NULL;
3334 LDAPMod **mods = NULL;
3344 if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
3345 map->gid, False))) {
3346 DEBUG(0, ("Group %i already exists in LDAP\n", map->gid));
3347 return NT_STATUS_UNSUCCESSFUL;
3350 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
3351 if (rc != LDAP_SUCCESS) {
3352 return NT_STATUS_UNSUCCESSFUL;
3355 if (ldap_count_entries(ldap_state->ldap_struct, result) != 1) {
3356 DEBUG(2, ("Group %i must exist exactly once in LDAP\n",
3358 ldap_msgfree(result);
3359 return NT_STATUS_UNSUCCESSFUL;
3362 entry = ldap_first_entry(ldap_state->ldap_struct, result);
3363 tmp = ldap_get_dn(ldap_state->ldap_struct, entry);
3367 if (!init_ldap_from_group(ldap_state->ldap_struct,
3368 result, &mods, map)) {
3369 DEBUG(0, ("init_ldap_from_group failed!\n"));
3370 ldap_mods_free(mods, 1);
3371 ldap_msgfree(result);
3372 return NT_STATUS_UNSUCCESSFUL;
3375 ldap_msgfree(result);
3378 DEBUG(0, ("mods is empty\n"));
3379 return NT_STATUS_UNSUCCESSFUL;
3382 make_a_mod(&mods, LDAP_MOD_ADD, "objectClass",
3383 "sambaGroupMapping");
3385 rc = ldapsam_modify(ldap_state, dn, mods);
3386 ldap_mods_free(mods, 1);
3388 if (rc != LDAP_SUCCESS) {
3389 char *ld_error = NULL;
3390 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
3392 DEBUG(0, ("failed to add group %i error: %s (%s)\n", map->gid,
3393 ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
3394 SAFE_FREE(ld_error);
3395 return NT_STATUS_UNSUCCESSFUL;
3398 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
3399 return NT_STATUS_OK;
3402 /**********************************************************************
3403 *********************************************************************/
3405 static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
3408 struct ldapsam_privates *ldap_state =
3409 (struct ldapsam_privates *)methods->private_data;
3412 LDAPMessage *result;
3416 rc = ldapsam_search_one_group_by_gid(ldap_state, map->gid, &result);
3418 if (rc != LDAP_SUCCESS) {
3419 return NT_STATUS_UNSUCCESSFUL;
3422 if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
3423 DEBUG(0, ("No group to modify!\n"));
3424 ldap_msgfree(result);
3425 return NT_STATUS_UNSUCCESSFUL;
3428 entry = ldap_first_entry(ldap_state->ldap_struct, result);
3429 dn = ldap_get_dn(ldap_state->ldap_struct, entry);
3431 if (!init_ldap_from_group(ldap_state->ldap_struct,
3432 result, &mods, map)) {
3433 DEBUG(0, ("init_ldap_from_group failed\n"));
3434 ldap_msgfree(result);
3435 return NT_STATUS_UNSUCCESSFUL;
3438 ldap_msgfree(result);
3441 DEBUG(4, ("mods is empty: nothing to do\n"));
3442 return NT_STATUS_UNSUCCESSFUL;
3445 rc = ldapsam_modify(ldap_state, dn, mods);
3447 ldap_mods_free(mods, 1);
3449 if (rc != LDAP_SUCCESS) {
3450 char *ld_error = NULL;
3451 ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
3453 DEBUG(0, ("failed to modify group %i error: %s (%s)\n", map->gid,
3454 ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
3455 SAFE_FREE(ld_error);
3458 DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
3459 return NT_STATUS_OK;
3462 /**********************************************************************
3463 *********************************************************************/
3465 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
3468 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data;
3469 pstring sidstring, filter;
3470 LDAPMessage *result;
3475 sid_to_string(sidstring, &sid);
3477 snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))",
3478 LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID, sidstring);
3480 rc = ldapsam_search_one_group(ldap_state, filter, &result);
3482 if (rc != LDAP_SUCCESS) {
3483 return NT_STATUS_NO_SUCH_GROUP;
3486 attr_list = get_attr_list( groupmap_attr_list_to_delete );
3487 ret = ldapsam_delete_entry(ldap_state, result, LDAP_OBJ_GROUPMAP, attr_list);
3488 free_attr_list ( attr_list );
3490 ldap_msgfree(result);
3495 /**********************************************************************
3496 *********************************************************************/
3498 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update)
3500 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
3505 snprintf( filter, sizeof(filter)-1, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
3506 attr_list = get_attr_list( groupmap_attr_list );
3507 rc = ldapsam_search(ldap_state, lp_ldap_suffix(),
3508 LDAP_SCOPE_SUBTREE, filter,
3509 attr_list, 0, &ldap_state->result);
3510 free_attr_list( attr_list );
3512 if (rc != LDAP_SUCCESS) {
3513 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc)));
3514 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
3515 ldap_msgfree(ldap_state->result);
3516 ldap_state->result = NULL;
3517 return NT_STATUS_UNSUCCESSFUL;
3520 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
3521 ldap_count_entries(ldap_state->ldap_struct,
3522 ldap_state->result)));
3524 ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct, ldap_state->result);
3525 ldap_state->index = 0;
3527 return NT_STATUS_OK;
3530 /**********************************************************************
3531 *********************************************************************/
3533 static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
3535 ldapsam_endsampwent(my_methods);
3538 /**********************************************************************
3539 *********************************************************************/
3541 static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
3544 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
3545 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
3548 /* The rebind proc needs this *HACK*. We are not multithreaded, so
3549 this will work, but it's not nice. */
3550 static_ldap_state = ldap_state;
3553 if (!ldap_state->entry)
3556 ldap_state->index++;
3557 bret = init_group_from_ldap(ldap_state, map, ldap_state->entry);
3559 ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
3563 return NT_STATUS_OK;
3566 /**********************************************************************
3567 *********************************************************************/
3569 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
3570 enum SID_NAME_USE sid_name_use,
3571 GROUP_MAP **rmap, int *num_entries,
3572 BOOL unix_only, BOOL with_priv)
3582 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
3583 DEBUG(0, ("Unable to open passdb\n"));
3584 return NT_STATUS_ACCESS_DENIED;
3587 while (NT_STATUS_IS_OK(nt_status = ldapsam_getsamgrent(methods, &map))) {
3588 if (sid_name_use != SID_NAME_UNKNOWN &&
3589 sid_name_use != map.sid_name_use) {
3590 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
3593 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
3594 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name));
3598 mapt=(GROUP_MAP *)Realloc((*rmap), (entries+1)*sizeof(GROUP_MAP));
3600 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
3602 return NT_STATUS_UNSUCCESSFUL;
3607 mapt[entries] = map;
3612 ldapsam_endsamgrent(methods);
3614 *num_entries = entries;
3616 return NT_STATUS_OK;
3619 /**********************************************************************
3620 *********************************************************************/
3622 static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method,
3623 const char *location)
3626 struct ldapsam_privates *ldap_state;
3628 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
3632 (*pdb_method)->name = "ldapsam";
3634 (*pdb_method)->setsampwent = ldapsam_setsampwent;
3635 (*pdb_method)->endsampwent = ldapsam_endsampwent;
3636 (*pdb_method)->getsampwent = ldapsam_getsampwent;
3637 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
3638 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
3639 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
3640 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
3641 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
3643 (*pdb_method)->getgrsid = ldapsam_getgrsid;
3644 (*pdb_method)->getgrgid = ldapsam_getgrgid;
3645 (*pdb_method)->getgrnam = ldapsam_getgrnam;
3646 (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
3647 (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
3648 (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
3649 (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
3651 /* TODO: Setup private data and free */
3653 ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct ldapsam_privates));
3656 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
3657 return NT_STATUS_NO_MEMORY;
3661 ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
3663 ldap_state->uri = "ldap://localhost";
3666 ldap_state->domain_name = talloc_strdup(pdb_context->mem_ctx, get_global_sam_name());
3667 if (!ldap_state->domain_name) {
3668 return NT_STATUS_NO_MEMORY;
3671 sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
3673 (*pdb_method)->private_data = ldap_state;
3675 (*pdb_method)->free_private_data = free_private_data;
3677 return NT_STATUS_OK;
3680 /**********************************************************************
3681 *********************************************************************/
3683 static NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
3686 struct ldapsam_privates *ldap_state;
3688 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
3692 (*pdb_method)->name = "ldapsam_compat";
3694 ldap_state = (*pdb_method)->private_data;
3695 ldap_state->schema_ver = SCHEMAVER_SAMBAACCOUNT;
3698 ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
3700 #ifndef WITH_LDAP_SAMCONFIG
3701 ldap_state->uri = "ldap://localhost";
3703 int ldap_port = lp_ldap_port();
3705 /* remap default port if not using SSL (ie clear or TLS) */
3706 if ( (lp_ldap_ssl() != LDAP_SSL_ON) && (ldap_port == 636) ) {
3710 ldap_state->uri = talloc_asprintf(pdb_context->mem_ctx, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON ? "ldaps" : "ldap", lp_ldap_server(), ldap_port);
3711 if (!ldap_state->uri) {
3712 return NT_STATUS_NO_MEMORY;
3717 return NT_STATUS_OK;
3720 /**********************************************************************
3721 *********************************************************************/
3723 static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
3726 struct ldapsam_privates *ldap_state;
3727 uint32 low_idmap_uid, high_idmap_uid;
3728 uint32 low_idmap_gid, high_idmap_gid;
3730 if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
3734 (*pdb_method)->name = "ldapsam";
3736 ldap_state = (*pdb_method)->private_data;
3737 ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
3738 ldap_state->permit_non_unix_accounts = False;
3740 /* check for non-unix account ranges */
3742 if (lp_idmap_uid(&low_idmap_uid, &high_idmap_uid)
3743 && lp_idmap_gid(&low_idmap_gid, &high_idmap_gid))
3745 DEBUG(2, ("Enabling non-unix account ranges\n"));
3747 ldap_state->permit_non_unix_accounts = True;
3749 ldap_state->low_allocated_user_rid = fallback_pdb_uid_to_user_rid(low_idmap_uid);
3750 ldap_state->high_allocated_user_rid = fallback_pdb_uid_to_user_rid(high_idmap_uid);
3751 ldap_state->low_allocated_group_rid = pdb_gid_to_group_rid(low_idmap_gid);
3752 ldap_state->high_allocated_group_rid = pdb_gid_to_group_rid(high_idmap_gid);
3755 return NT_STATUS_OK;
3758 NTSTATUS pdb_ldap_init(void)
3761 if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam", pdb_init_ldapsam)))
3764 if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_compat", pdb_init_ldapsam_compat)))
3767 return NT_STATUS_OK;