2 Unix SMB/CIFS implementation.
3 LDAP protocol helper functions for SAMBA
4 Copyright (C) Jean François Micouleau 1998
5 Copyright (C) Gerald Carter 2001
6 Copyright (C) Shahms King 2001
7 Copyright (C) Andrew Bartlett 2002
8 Copyright (C) Stefan (metze) Metzmacher 2002
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #define DBGC_CLASS DBGC_PASSDB
33 * persistent connections: if using NSS LDAP, many connections are made
34 * however, using only one within Samba would be nice
36 * Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
38 * Other LDAP based login attributes: accountExpires, etc.
39 * (should be the domain of Samba proper, but the sam_password/SAM_ACCOUNT
40 * structures don't have fields for some of these attributes)
42 * SSL is done, but can't get the certificate based authentication to work
43 * against on my test platform (Linux 2.4, OpenLDAP 2.x)
46 /* NOTE: this will NOT work against an Active Directory server
47 * due to the fact that the two password fields cannot be retrieved
48 * from a server; recommend using security = domain in this situation
56 #define SAM_ACCOUNT struct sam_passwd
59 struct ldapsam_privates
{
67 /* retrive-once info */
70 BOOL permit_non_unix_accounts
;
80 static struct ldapsam_privates
*static_ldap_state
;
82 static uint32
ldapsam_get_next_available_nua_rid(struct ldapsam_privates
*ldap_state
);
84 /*******************************************************************
85 find the ldap password
86 ******************************************************************/
87 static BOOL
fetch_ldapsam_pw(char **dn
, char** pw
)
92 *dn
= smb_xstrdup(lp_ldap_admin_dn());
94 if (asprintf(&key
, "%s/%s", SECRETS_LDAP_BIND_PW
, *dn
) < 0) {
96 DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
99 *pw
=secrets_fetch(key
, &size
);
101 /* Upgrade 2.2 style entry */
103 char* old_style_key
= strdup(*dn
);
105 fstring old_style_pw
;
107 if (!old_style_key
) {
108 DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n"));
112 for (p
=old_style_key
; *p
; p
++)
113 if (*p
== ',') *p
= '/';
115 data
=secrets_fetch(old_style_key
, &size
);
116 if (!size
&& size
< sizeof(old_style_pw
)) {
117 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
118 SAFE_FREE(old_style_key
);
123 strncpy(old_style_pw
, data
, size
);
124 old_style_pw
[size
] = 0;
128 if (!secrets_store_ldap_pw(*dn
, old_style_pw
)) {
129 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
130 SAFE_FREE(old_style_key
);
134 if (!secrets_delete(old_style_key
)) {
135 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
138 SAFE_FREE(old_style_key
);
140 *pw
= smb_xstrdup(old_style_pw
);
146 static const char *attr
[] = {"uid", "pwdLastSet", "logonTime",
147 "logoffTime", "kickoffTime", "cn",
148 "pwdCanChange", "pwdMustChange",
149 "displayName", "homeDrive",
150 "smbHome", "scriptPath",
151 "profilePath", "description",
152 "userWorkstations", "rid",
153 "primaryGroupID", "lmPassword",
154 "ntPassword", "acctFlags",
155 "domain", "description", NULL
};
157 /*******************************************************************
158 open a connection to the ldap server.
159 ******************************************************************/
160 static BOOL
ldapsam_open_connection (struct ldapsam_privates
*ldap_state
, LDAP
** ldap_struct
)
165 if (geteuid() != 0) {
166 DEBUG(0, ("ldap_open_connection: cannot access LDAP when not root..\n"));
170 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
171 DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state
->uri
));
173 if (ldap_initialize(ldap_struct
, ldap_state
->uri
) != LDAP_SUCCESS
) {
174 DEBUG(0, ("ldap_initialize: %s\n", strerror(errno
)));
178 if (ldap_get_option(*ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
) == LDAP_OPT_SUCCESS
)
180 if (version
!= LDAP_VERSION3
)
182 version
= LDAP_VERSION3
;
183 ldap_set_option (*ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
189 /* Parse the string manually */
193 int tls
= LDAP_OPT_X_TLS_HARD
;
197 const char *p
= ldap_state
->uri
;
198 SMB_ASSERT(sizeof(protocol
)>10 && sizeof(host
)>254);
200 /* skip leading "URL:" (if any) */
201 if ( strncasecmp( p
, "URL:", 4 ) == 0 ) {
205 sscanf(p
, "%10[^:]://%254s[^:]:%d", protocol
, host
, &port
);
208 if (strequal(protocol
, "ldap")) {
210 } else if (strequal(protocol
, "ldaps")) {
213 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol
));
217 if ((*ldap_struct
= ldap_init(host
, port
)) == NULL
) {
218 DEBUG(0, ("ldap_init failed !\n"));
222 /* Connect to older servers using SSL and V2 rather than Start TLS */
223 if (ldap_get_option(*ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
) == LDAP_OPT_SUCCESS
)
225 if (version
!= LDAP_VERSION2
)
227 version
= LDAP_VERSION2
;
228 ldap_set_option (*ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
232 if (strequal(protocol
, "ldaps")) {
233 if (lp_ldap_ssl() == LDAP_SSL_START_TLS
) {
234 if (ldap_get_option (*ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
,
235 &version
) == LDAP_OPT_SUCCESS
)
237 if (version
< LDAP_VERSION3
)
239 version
= LDAP_VERSION3
;
240 ldap_set_option (*ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
,
244 if ((rc
= ldap_start_tls_s (*ldap_struct
, NULL
, NULL
)) != LDAP_SUCCESS
)
246 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
247 ldap_err2string(rc
)));
250 DEBUG (2, ("StartTLS issued: using a TLS connection\n"));
253 if (ldap_set_option (*ldap_struct
, LDAP_OPT_X_TLS
, &tls
) != LDAP_SUCCESS
)
255 DEBUG(0, ("Failed to setup a TLS session\n"));
260 * No special needs to setup options prior to the LDAP
261 * bind (which should be called next via ldap_connect_system()
267 DEBUG(2, ("ldap_open_connection: connection opened\n"));
272 /*******************************************************************
273 a rebind function for authenticated referrals
274 This version takes a void* that we can shove useful stuff in :-)
275 ******************************************************************/
276 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
278 static int rebindproc_with_state (LDAP
* ld
, char **whop
, char **credp
,
279 int *methodp
, int freeit
, void *arg
)
281 struct ldapsam_privates
*ldap_state
= arg
;
283 /** @TODO Should we be doing something to check what servers we rebind to?
284 Could we get a referral to a machine that we don't want to give our
285 username and password to? */
289 memset(*credp
, '\0', strlen(*credp
));
292 DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
293 ldap_state
->bind_dn
));
295 *whop
= strdup(ldap_state
->bind_dn
);
297 return LDAP_NO_MEMORY
;
299 *credp
= strdup(ldap_state
->bind_secret
);
302 return LDAP_NO_MEMORY
;
304 *methodp
= LDAP_AUTH_SIMPLE
;
308 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
310 /*******************************************************************
311 a rebind function for authenticated referrals
312 This version takes a void* that we can shove useful stuff in :-)
313 and actually does the connection.
314 ******************************************************************/
315 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
316 static int rebindproc_connect_with_state (LDAP
*ldap_struct
,
317 LDAP_CONST
char *url
,
319 ber_int_t msgid
, void *arg
)
321 struct ldapsam_privates
*ldap_state
= arg
;
323 DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
324 ldap_state
->bind_dn
));
326 /** @TODO Should we be doing something to check what servers we rebind to?
327 Could we get a referral to a machine that we don't want to give our
328 username and password to? */
330 rc
= ldap_simple_bind_s(ldap_struct
, ldap_state
->bind_dn
, ldap_state
->bind_secret
);
334 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
336 /*******************************************************************
337 Add a rebind function for authenticated referrals
338 ******************************************************************/
339 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
341 # if LDAP_SET_REBIND_PROC_ARGS == 2
342 static int rebindproc (LDAP
*ldap_struct
, char **whop
, char **credp
,
343 int *method
, int freeit
)
345 return rebindproc_with_state(ldap_struct
, whop
, credp
,
346 method
, freeit
, static_ldap_state
);
349 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
350 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
352 /*******************************************************************
353 a rebind function for authenticated referrals
354 this also does the connection, but no void*.
355 ******************************************************************/
356 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
357 # if LDAP_SET_REBIND_PROC_ARGS == 2
358 static int rebindproc_connect (LDAP
* ld
, LDAP_CONST
char *url
, int request
,
361 return rebindproc_connect_with_state(ld
, url
, (ber_tag_t
)request
, msgid
,
364 # endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
365 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
367 /*******************************************************************
368 connect to the ldap server under system privilege.
369 ******************************************************************/
370 static BOOL
ldapsam_connect_system(struct ldapsam_privates
*ldap_state
, LDAP
* ldap_struct
)
376 /* The rebind proc needs this *HACK*. We are not multithreaded, so
377 this will work, but it's not nice. */
378 static_ldap_state
= ldap_state
;
380 /* get the password */
381 if (!fetch_ldapsam_pw(&ldap_dn
, &ldap_secret
))
383 DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
387 ldap_state
->bind_dn
= ldap_dn
;
388 ldap_state
->bind_secret
= ldap_secret
;
390 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
391 (OpenLDAP) doesnt' seem to support it */
393 DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n",
396 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
397 # if LDAP_SET_REBIND_PROC_ARGS == 2
398 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect
);
400 # if LDAP_SET_REBIND_PROC_ARGS == 3
401 ldap_set_rebind_proc(ldap_struct
, &rebindproc_connect_with_state
, (void *)ldap_state
);
403 #else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
404 # if LDAP_SET_REBIND_PROC_ARGS == 2
405 ldap_set_rebind_proc(ldap_struct
, &rebindproc
);
407 # if LDAP_SET_REBIND_PROC_ARGS == 3
408 ldap_set_rebind_proc(ldap_struct
, &rebindproc_with_state
, (void *)ldap_state
);
410 #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
412 rc
= ldap_simple_bind_s(ldap_struct
, ldap_dn
, ldap_secret
);
414 if (rc
!= LDAP_SUCCESS
) {
415 DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc
)));
419 DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n"));
423 /*******************************************************************
424 run the search by name.
425 ******************************************************************/
426 static int ldapsam_search_one_user (struct ldapsam_privates
*ldap_state
, LDAP
* ldap_struct
, const char *filter
, LDAPMessage
** result
)
428 int scope
= LDAP_SCOPE_SUBTREE
;
431 DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter
));
433 rc
= ldap_search_s(ldap_struct
, lp_ldap_suffix (), scope
, filter
, (char **)attr
, 0, result
);
435 if (rc
!= LDAP_SUCCESS
) {
436 DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n",
437 ldap_err2string (rc
)));
438 DEBUG(3,("ldapsam_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(),
445 /*******************************************************************
446 run the search by name.
447 ******************************************************************/
448 static int ldapsam_search_one_user_by_name (struct ldapsam_privates
*ldap_state
, LDAP
* ldap_struct
, const char *user
,
449 LDAPMessage
** result
)
454 * in the filter expression, replace %u with the real name
455 * so in ldap filter, %u MUST exist :-)
457 pstrcpy(filter
, lp_ldap_filter());
460 * have to use this here because $ is filtered out
463 all_string_sub(filter
, "%u", user
, sizeof(pstring
));
465 return ldapsam_search_one_user(ldap_state
, ldap_struct
, filter
, result
);
468 /*******************************************************************
469 run the search by uid.
470 ******************************************************************/
471 static int ldapsam_search_one_user_by_uid(struct ldapsam_privates
*ldap_state
,
472 LDAP
* ldap_struct
, int uid
,
473 LDAPMessage
** result
)
478 /* Get the username from the system and look that up in the LDAP */
480 if ((user
= getpwuid_alloc(uid
)) == NULL
) {
481 DEBUG(3,("ldapsam_search_one_user_by_uid: Failed to locate uid [%d]\n", uid
));
482 return LDAP_NO_SUCH_OBJECT
;
485 pstrcpy(filter
, lp_ldap_filter());
487 all_string_sub(filter
, "%u", user
->pw_name
, sizeof(pstring
));
491 return ldapsam_search_one_user(ldap_state
, ldap_struct
, filter
, result
);
494 /*******************************************************************
495 run the search by rid.
496 ******************************************************************/
497 static int ldapsam_search_one_user_by_rid (struct ldapsam_privates
*ldap_state
,
498 LDAP
* ldap_struct
, uint32 rid
,
499 LDAPMessage
** result
)
504 /* check if the user rid exsists, if not, try searching on the uid */
506 snprintf(filter
, sizeof(filter
) - 1, "rid=%i", rid
);
507 rc
= ldapsam_search_one_user(ldap_state
, ldap_struct
, filter
, result
);
509 if (rc
!= LDAP_SUCCESS
)
510 rc
= ldapsam_search_one_user_by_uid(ldap_state
, ldap_struct
,
511 fallback_pdb_user_rid_to_uid(rid
),
517 /*******************************************************************
518 search an attribute and return the first value found.
519 ******************************************************************/
520 static BOOL
get_single_attribute (LDAP
* ldap_struct
, LDAPMessage
* entry
,
521 char *attribute
, pstring value
)
525 if ((values
= ldap_get_values (ldap_struct
, entry
, attribute
)) == NULL
) {
527 DEBUG (10, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute
));
532 pstrcpy(value
, values
[0]);
533 ldap_value_free(values
);
534 #ifdef DEBUG_PASSWORDS
535 DEBUG (100, ("get_single_attribute: [%s] = [%s]\n", attribute
, value
));
540 /************************************************************************
541 Routine to manage the LDAPMod structure array
542 manage memory used by the array, by each struct, and values
544 ************************************************************************/
545 static void make_a_mod (LDAPMod
*** modlist
, int modop
, const char *attribute
, const char *value
)
553 if (attribute
== NULL
|| *attribute
== '\0')
556 if (value
== NULL
|| *value
== '\0')
561 mods
= (LDAPMod
**) malloc(sizeof(LDAPMod
*));
564 DEBUG(0, ("make_a_mod: out of memory!\n"));
570 for (i
= 0; mods
[i
] != NULL
; ++i
) {
571 if (mods
[i
]->mod_op
== modop
&& !strcasecmp(mods
[i
]->mod_type
, attribute
))
577 mods
= (LDAPMod
**) Realloc (mods
, (i
+ 2) * sizeof (LDAPMod
*));
580 DEBUG(0, ("make_a_mod: out of memory!\n"));
583 mods
[i
] = (LDAPMod
*) malloc(sizeof(LDAPMod
));
586 DEBUG(0, ("make_a_mod: out of memory!\n"));
589 mods
[i
]->mod_op
= modop
;
590 mods
[i
]->mod_values
= NULL
;
591 mods
[i
]->mod_type
= strdup(attribute
);
598 if (mods
[i
]->mod_values
!= NULL
) {
599 for (; mods
[i
]->mod_values
[j
] != NULL
; j
++);
601 mods
[i
]->mod_values
= (char **)Realloc(mods
[i
]->mod_values
,
602 (j
+ 2) * sizeof (char *));
604 if (mods
[i
]->mod_values
== NULL
) {
605 DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
608 mods
[i
]->mod_values
[j
] = strdup(value
);
609 mods
[i
]->mod_values
[j
+ 1] = NULL
;
614 /* New Interface is being implemented here */
616 /**********************************************************************
617 Initialize SAM_ACCOUNT from an LDAP query
618 (Based on init_sam_from_buffer in pdb_tdb.c)
619 *********************************************************************/
620 static BOOL
init_sam_from_ldap (struct ldapsam_privates
*ldap_state
,
621 SAM_ACCOUNT
* sampass
,
622 LDAP
* ldap_struct
, LDAPMessage
* entry
)
628 pass_can_change_time
,
629 pass_must_change_time
;
649 uint8 hours
[MAX_HOURS_LEN
];
652 gid_t gid
= getegid();
656 * do a little initialization
660 nt_username
[0] = '\0';
664 logon_script
[0] = '\0';
665 profile_path
[0] = '\0';
667 munged_dial
[0] = '\0';
668 workstations
[0] = '\0';
671 if (sampass
== NULL
|| ldap_struct
== NULL
|| entry
== NULL
) {
672 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
676 get_single_attribute(ldap_struct
, entry
, "uid", username
);
677 DEBUG(2, ("Entry found for user: %s\n", username
));
679 pstrcpy(nt_username
, username
);
681 pstrcpy(domain
, lp_workgroup());
683 get_single_attribute(ldap_struct
, entry
, "rid", temp
);
684 user_rid
= (uint32
)atol(temp
);
686 pdb_set_user_sid_from_rid(sampass
, user_rid
);
688 if (!get_single_attribute(ldap_struct
, entry
, "primaryGroupID", temp
)) {
691 group_rid
= (uint32
)atol(temp
);
692 pdb_set_group_sid_from_rid(sampass
, group_rid
);
695 if ((ldap_state
->permit_non_unix_accounts
)
696 && (user_rid
>= ldap_state
->low_nua_rid
)
697 && (user_rid
<= ldap_state
->high_nua_rid
)) {
701 /* These values MAY be in LDAP, but they can also be retrieved through
702 * sys_getpw*() which is how we're doing it
705 pw
= getpwnam_alloc(username
);
707 DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\n", username
));
713 pdb_set_unix_homedir(sampass
, pw
->pw_dir
);
717 pdb_set_uid(sampass
, uid
);
718 pdb_set_gid(sampass
, gid
);
720 if (group_rid
== 0) {
722 /* call the mapping code here */
723 if(get_group_map_from_gid(gid
, &map
, MAPPING_WITHOUT_PRIV
)) {
724 pdb_set_group_sid(sampass
, &map
.sid
);
727 pdb_set_group_sid_from_rid(sampass
, pdb_gid_to_group_rid(gid
));
732 if (!get_single_attribute(ldap_struct
, entry
, "pwdLastSet", temp
)) {
733 /* leave as default */
735 pass_last_set_time
= (time_t) atol(temp
);
736 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
);
739 if (!get_single_attribute(ldap_struct
, entry
, "logonTime", temp
)) {
740 /* leave as default */
742 logon_time
= (time_t) atol(temp
);
743 pdb_set_logon_time(sampass
, logon_time
, True
);
746 if (!get_single_attribute(ldap_struct
, entry
, "logoffTime", temp
)) {
747 /* leave as default */
749 logoff_time
= (time_t) atol(temp
);
750 pdb_set_logoff_time(sampass
, logoff_time
, True
);
753 if (!get_single_attribute(ldap_struct
, entry
, "kickoffTime", temp
)) {
754 /* leave as default */
756 kickoff_time
= (time_t) atol(temp
);
757 pdb_set_kickoff_time(sampass
, kickoff_time
, True
);
760 if (!get_single_attribute(ldap_struct
, entry
, "pwdCanChange", temp
)) {
761 /* leave as default */
763 pass_can_change_time
= (time_t) atol(temp
);
764 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, True
);
767 if (!get_single_attribute(ldap_struct
, entry
, "pwdMustChange", temp
)) {
768 /* leave as default */
770 pass_must_change_time
= (time_t) atol(temp
);
771 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, True
);
774 /* recommend that 'gecos' and 'displayName' should refer to the same
775 * attribute OID. userFullName depreciated, only used by Samba
776 * primary rules of LDAP: don't make a new attribute when one is already defined
777 * that fits your needs; using cn then displayName rather than 'userFullName'
780 if (!get_single_attribute(ldap_struct
, entry
, "cn", fullname
)) {
781 if (!get_single_attribute(ldap_struct
, entry
, "displayName", fullname
)) {
782 /* leave as default */
784 pdb_set_fullname(sampass
, fullname
);
787 pdb_set_fullname(sampass
, fullname
);
790 if (!get_single_attribute(ldap_struct
, entry
, "homeDrive", dir_drive
)) {
791 pdb_set_dir_drive(sampass
, talloc_sub_specified(sampass
->mem_ctx
,
797 pdb_set_dir_drive(sampass
, dir_drive
, True
);
800 if (!get_single_attribute(ldap_struct
, entry
, "smbHome", homedir
)) {
801 pdb_set_homedir(sampass
, talloc_sub_specified(sampass
->mem_ctx
,
807 pdb_set_homedir(sampass
, homedir
, True
);
810 if (!get_single_attribute(ldap_struct
, entry
, "scriptPath", logon_script
)) {
811 pdb_set_logon_script(sampass
, talloc_sub_specified(sampass
->mem_ctx
,
817 pdb_set_logon_script(sampass
, logon_script
, True
);
820 if (!get_single_attribute(ldap_struct
, entry
, "profilePath", profile_path
)) {
821 pdb_set_profile_path(sampass
, talloc_sub_specified(sampass
->mem_ctx
,
827 pdb_set_profile_path(sampass
, profile_path
, True
);
830 if (!get_single_attribute(ldap_struct
, entry
, "description", acct_desc
)) {
831 /* leave as default */
833 pdb_set_acct_desc(sampass
, acct_desc
);
836 if (!get_single_attribute(ldap_struct
, entry
, "userWorkstations", workstations
)) {
837 /* leave as default */;
839 pdb_set_workstations(sampass
, workstations
);
842 /* FIXME: hours stuff should be cleaner */
846 memset(hours
, 0xff, hours_len
);
848 if (!get_single_attribute (ldap_struct
, entry
, "lmPassword", temp
)) {
849 /* leave as default */
851 pdb_gethexpwd(temp
, smblmpwd
);
852 memset((char *)temp
, '\0', strlen(temp
)+1);
853 if (!pdb_set_lanman_passwd(sampass
, smblmpwd
))
855 ZERO_STRUCT(smblmpwd
);
858 if (!get_single_attribute (ldap_struct
, entry
, "ntPassword", temp
)) {
859 /* leave as default */
861 pdb_gethexpwd(temp
, smbntpwd
);
862 memset((char *)temp
, '\0', strlen(temp
)+1);
863 if (!pdb_set_nt_passwd(sampass
, smbntpwd
))
865 ZERO_STRUCT(smbntpwd
);
868 if (!get_single_attribute (ldap_struct
, entry
, "acctFlags", temp
)) {
869 acct_ctrl
|= ACB_NORMAL
;
871 acct_ctrl
= pdb_decode_acct_ctrl(temp
);
874 acct_ctrl
|= ACB_NORMAL
;
876 pdb_set_acct_ctrl(sampass
, acct_ctrl
);
879 pdb_set_hours_len(sampass
, hours_len
);
880 pdb_set_logon_divs(sampass
, logon_divs
);
882 pdb_set_username(sampass
, username
);
884 pdb_set_domain(sampass
, domain
);
885 pdb_set_nt_username(sampass
, nt_username
);
887 pdb_set_munged_dial(sampass
, munged_dial
);
889 /* pdb_set_unknown_3(sampass, unknown3); */
890 /* pdb_set_unknown_5(sampass, unknown5); */
891 /* pdb_set_unknown_6(sampass, unknown6); */
893 pdb_set_hours(sampass
, hours
);
898 /**********************************************************************
899 Initialize SAM_ACCOUNT from an LDAP query
900 (Based on init_buffer_from_sam in pdb_tdb.c)
901 *********************************************************************/
902 static BOOL
init_ldap_from_sam (struct ldapsam_privates
*ldap_state
,
903 LDAPMod
*** mods
, int ldap_op
,
904 const SAM_ACCOUNT
* sampass
)
909 if (mods
== NULL
|| sampass
== NULL
) {
910 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
917 * took out adding "objectclass: sambaAccount"
918 * do this on a per-mod basis
921 make_a_mod(mods
, ldap_op
, "uid", pdb_get_username(sampass
));
922 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass
)));
924 if ( pdb_get_user_rid(sampass
) ) {
925 rid
= pdb_get_user_rid(sampass
);
926 } else if (IS_SAM_SET(sampass
, FLAG_SAM_UID
)) {
927 rid
= fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass
));
928 } else if (ldap_state
->permit_non_unix_accounts
) {
929 rid
= ldapsam_get_next_available_nua_rid(ldap_state
);
931 DEBUG(0, ("NO user RID specified on account %s, and findining next available NUA RID failed, cannot store!\n", pdb_get_username(sampass
)));
935 DEBUG(0, ("NO user RID specified on account %s, cannot store!\n", pdb_get_username(sampass
)));
939 slprintf(temp
, sizeof(temp
) - 1, "%i", rid
);
940 make_a_mod(mods
, ldap_op
, "rid", temp
);
942 if ( pdb_get_group_rid(sampass
) ) {
943 rid
= pdb_get_group_rid(sampass
);
944 } else if (IS_SAM_SET(sampass
, FLAG_SAM_GID
)) {
945 rid
= pdb_gid_to_group_rid(pdb_get_gid(sampass
));
946 } else if (ldap_state
->permit_non_unix_accounts
) {
947 rid
= DOMAIN_GROUP_RID_USERS
;
949 DEBUG(0, ("NO group RID specified on account %s, cannot store!\n", pdb_get_username(sampass
)));
953 slprintf(temp
, sizeof(temp
) - 1, "%i", rid
);
954 make_a_mod(mods
, ldap_op
, "primaryGroupID", temp
);
956 /* displayName, cn, and gecos should all be the same
957 * most easily accomplished by giving them the same OID
958 * gecos isn't set here b/c it should be handled by the
962 make_a_mod(mods
, ldap_op
, "displayName", pdb_get_fullname(sampass
));
963 make_a_mod(mods
, ldap_op
, "cn", pdb_get_fullname(sampass
));
964 make_a_mod(mods
, ldap_op
, "description", pdb_get_acct_desc(sampass
));
965 make_a_mod(mods
, ldap_op
, "userWorkstations", pdb_get_workstations(sampass
));
968 * Only updates fields which have been set (not defaults from smb.conf)
971 if (IS_SAM_SET(sampass
, FLAG_SAM_SMBHOME
))
972 make_a_mod(mods
, ldap_op
, "smbHome", pdb_get_homedir(sampass
));
974 if (IS_SAM_SET(sampass
, FLAG_SAM_DRIVE
))
975 make_a_mod(mods
, ldap_op
, "homeDrive", pdb_get_dir_drive(sampass
));
977 if (IS_SAM_SET(sampass
, FLAG_SAM_LOGONSCRIPT
))
978 make_a_mod(mods
, ldap_op
, "scriptPath", pdb_get_logon_script(sampass
));
980 if (IS_SAM_SET(sampass
, FLAG_SAM_PROFILE
))
981 make_a_mod(mods
, ldap_op
, "profilePath", pdb_get_profile_path(sampass
));
983 if (IS_SAM_SET(sampass
, FLAG_SAM_LOGONTIME
)) {
984 slprintf(temp
, sizeof(temp
) - 1, "%li", pdb_get_logon_time(sampass
));
985 make_a_mod(mods
, ldap_op
, "logonTime", temp
);
988 if (IS_SAM_SET(sampass
, FLAG_SAM_LOGOFFTIME
)) {
989 slprintf(temp
, sizeof(temp
) - 1, "%li", pdb_get_logoff_time(sampass
));
990 make_a_mod(mods
, ldap_op
, "logoffTime", temp
);
993 if (IS_SAM_SET(sampass
, FLAG_SAM_KICKOFFTIME
)) {
994 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_kickoff_time(sampass
));
995 make_a_mod(mods
, ldap_op
, "kickoffTime", temp
);
999 if (IS_SAM_SET(sampass
, FLAG_SAM_CANCHANGETIME
)) {
1000 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_can_change_time(sampass
));
1001 make_a_mod(mods
, ldap_op
, "pwdCanChange", temp
);
1004 if (IS_SAM_SET(sampass
, FLAG_SAM_MUSTCHANGETIME
)) {
1005 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_must_change_time(sampass
));
1006 make_a_mod(mods
, ldap_op
, "pwdMustChange", temp
);
1009 if ((pdb_get_acct_ctrl(sampass
)&(ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
))||
1010 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY
)) {
1012 pdb_sethexpwd (temp
, pdb_get_lanman_passwd(sampass
), pdb_get_acct_ctrl(sampass
));
1013 make_a_mod (mods
, ldap_op
, "lmPassword", temp
);
1015 pdb_sethexpwd (temp
, pdb_get_nt_passwd(sampass
), pdb_get_acct_ctrl(sampass
));
1016 make_a_mod (mods
, ldap_op
, "ntPassword", temp
);
1018 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_last_set_time(sampass
));
1019 make_a_mod(mods
, ldap_op
, "pwdLastSet", temp
);
1023 /* FIXME: Hours stuff goes in LDAP */
1025 make_a_mod (mods
, ldap_op
, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass
),
1026 NEW_PW_FORMAT_SPACE_PADDED_LEN
));
1032 /**********************************************************************
1033 Connect to LDAP server and find the next available RID.
1034 *********************************************************************/
1035 static uint32
check_nua_rid_is_avail(struct ldapsam_privates
*ldap_state
, uint32 top_rid
, LDAP
*ldap_struct
)
1037 LDAPMessage
*result
;
1038 uint32 final_rid
= (top_rid
& (~USER_RID_TYPE
)) + RID_MULTIPLIER
;
1043 if (final_rid
< ldap_state
->low_nua_rid
|| final_rid
> ldap_state
->high_nua_rid
) {
1047 if (ldapsam_search_one_user_by_rid(ldap_state
, ldap_struct
, final_rid
, &result
) != LDAP_SUCCESS
) {
1048 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid
, final_rid
));
1049 ldap_msgfree(result
);
1053 if (ldap_count_entries(ldap_struct
, result
) != 0) {
1054 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid
, final_rid
));
1055 ldap_msgfree(result
);
1059 DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid
, final_rid
));
1060 ldap_msgfree(result
);
1064 /**********************************************************************
1065 Extract the RID from an LDAP entry
1066 *********************************************************************/
1067 static uint32
entry_to_user_rid(struct ldapsam_privates
*ldap_state
, LDAPMessage
*entry
, LDAP
*ldap_struct
) {
1069 SAM_ACCOUNT
*user
= NULL
;
1070 if (!NT_STATUS_IS_OK(pdb_init_sam(&user
))) {
1074 if (init_sam_from_ldap(ldap_state
, user
, ldap_struct
, entry
)) {
1075 rid
= pdb_get_user_rid(user
);
1079 pdb_free_sam(&user
);
1080 if (rid
>= ldap_state
->low_nua_rid
&& rid
<= ldap_state
->high_nua_rid
) {
1087 /**********************************************************************
1088 Connect to LDAP server and find the next available RID.
1089 *********************************************************************/
1090 static uint32
search_top_nua_rid(struct ldapsam_privates
*ldap_state
, LDAP
*ldap_struct
)
1094 LDAPMessage
*result
;
1096 char *final_filter
= NULL
;
1101 pstrcpy(filter
, lp_ldap_filter());
1102 all_string_sub(filter
, "%u", "*", sizeof(pstring
));
1105 asprintf(&final_filter
, "(&(%s)(&(rid>=%d)(rid<=%d)))", filter
, ldap_state
->low_nua_rid
, ldap_state
->high_nua_rid
);
1107 final_filter
= strdup(filter
);
1109 DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter
));
1111 rc
= ldap_search_s(ldap_struct
, lp_ldap_suffix(),
1112 LDAP_SCOPE_SUBTREE
, final_filter
, (char **)attr
, 0,
1115 if (rc
!= LDAP_SUCCESS
) {
1116 DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc
)));
1117 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter
));
1120 ldap_msgfree(result
);
1125 count
= ldap_count_entries(ldap_struct
, result
);
1126 DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count
));
1129 DEBUG(3, ("LDAP search returned no records, assuming no non-unix-accounts present!: %s\n", ldap_err2string(rc
)));
1130 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter
));
1132 ldap_msgfree(result
);
1134 return ldap_state
->low_nua_rid
;
1138 entry
= ldap_first_entry(ldap_struct
,result
);
1140 top_rid
= entry_to_user_rid(ldap_state
, entry
, ldap_struct
);
1142 while ((entry
= ldap_next_entry(ldap_struct
, entry
))) {
1144 rid
= entry_to_user_rid(ldap_state
, entry
, ldap_struct
);
1145 if (rid
> top_rid
) {
1150 ldap_msgfree(result
);
1152 if (top_rid
< ldap_state
->low_nua_rid
)
1153 top_rid
= ldap_state
->low_nua_rid
;
1158 /**********************************************************************
1159 Connect to LDAP server and find the next available RID.
1160 *********************************************************************/
1161 static uint32
ldapsam_get_next_available_nua_rid(struct ldapsam_privates
*ldap_state
) {
1163 uint32 next_nua_rid
;
1166 if (!ldapsam_open_connection(ldap_state
, &ldap_struct
)) {
1169 if (!ldapsam_connect_system(ldap_state
, ldap_struct
)) {
1170 ldap_unbind(ldap_struct
);
1174 top_nua_rid
= search_top_nua_rid(ldap_state
, ldap_struct
);
1176 next_nua_rid
= check_nua_rid_is_avail(ldap_state
,
1177 top_nua_rid
, ldap_struct
);
1179 ldap_unbind(ldap_struct
);
1180 return next_nua_rid
;
1183 /**********************************************************************
1184 Connect to LDAP server for password enumeration
1185 *********************************************************************/
1186 static NTSTATUS
ldapsam_setsampwent(struct pdb_methods
*my_methods
, BOOL update
)
1188 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1189 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1193 if (!ldapsam_open_connection(ldap_state
, &ldap_state
->ldap_struct
)) {
1196 if (!ldapsam_connect_system(ldap_state
, ldap_state
->ldap_struct
)) {
1197 ldap_unbind(ldap_state
->ldap_struct
);
1201 pstrcpy(filter
, lp_ldap_filter());
1202 all_string_sub(filter
, "%u", "*", sizeof(pstring
));
1204 rc
= ldap_search_s(ldap_state
->ldap_struct
, lp_ldap_suffix(),
1205 LDAP_SCOPE_SUBTREE
, filter
, (char **)attr
, 0,
1206 &ldap_state
->result
);
1208 if (rc
!= LDAP_SUCCESS
) {
1209 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc
)));
1210 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter
));
1211 ldap_msgfree(ldap_state
->result
);
1212 ldap_unbind(ldap_state
->ldap_struct
);
1213 ldap_state
->ldap_struct
= NULL
;
1214 ldap_state
->result
= NULL
;
1218 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
1219 ldap_count_entries(ldap_state
->ldap_struct
,
1220 ldap_state
->result
)));
1222 ldap_state
->entry
= ldap_first_entry(ldap_state
->ldap_struct
,
1223 ldap_state
->result
);
1224 ldap_state
->index
= 0;
1226 return NT_STATUS_OK
;
1229 /**********************************************************************
1230 End enumeration of the LDAP password list
1231 *********************************************************************/
1232 static void ldapsam_endsampwent(struct pdb_methods
*my_methods
)
1234 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1235 if (ldap_state
->ldap_struct
&& ldap_state
->result
) {
1236 ldap_msgfree(ldap_state
->result
);
1237 ldap_unbind(ldap_state
->ldap_struct
);
1238 ldap_state
->ldap_struct
= NULL
;
1239 ldap_state
->result
= NULL
;
1243 /**********************************************************************
1244 Get the next entry in the LDAP password database
1245 *********************************************************************/
1246 static NTSTATUS
ldapsam_getsampwent(struct pdb_methods
*my_methods
, SAM_ACCOUNT
*user
)
1248 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1249 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1252 /* The rebind proc needs this *HACK*. We are not multithreaded, so
1253 this will work, but it's not nice. */
1254 static_ldap_state
= ldap_state
;
1257 if (!ldap_state
->entry
)
1260 ldap_state
->index
++;
1261 bret
= init_sam_from_ldap(ldap_state
, user
, ldap_state
->ldap_struct
,
1264 ldap_state
->entry
= ldap_next_entry(ldap_state
->ldap_struct
,
1268 return NT_STATUS_OK
;
1271 /**********************************************************************
1272 Get SAM_ACCOUNT entry from LDAP by username
1273 *********************************************************************/
1274 static NTSTATUS
ldapsam_getsampwnam(struct pdb_methods
*my_methods
, SAM_ACCOUNT
*user
, const char *sname
)
1276 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1277 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1279 LDAPMessage
*result
;
1282 if (!ldapsam_open_connection(ldap_state
, &ldap_struct
))
1284 if (!ldapsam_connect_system(ldap_state
, ldap_struct
)) {
1285 ldap_unbind(ldap_struct
);
1288 if (ldapsam_search_one_user_by_name(ldap_state
, ldap_struct
, sname
, &result
) != LDAP_SUCCESS
) {
1289 ldap_unbind(ldap_struct
);
1292 if (ldap_count_entries(ldap_struct
, result
) < 1) {
1294 ("We don't find this user [%s] count=%d\n", sname
,
1295 ldap_count_entries(ldap_struct
, result
)));
1296 ldap_unbind(ldap_struct
);
1299 entry
= ldap_first_entry(ldap_struct
, result
);
1301 if (!init_sam_from_ldap(ldap_state
, user
, ldap_struct
, entry
)) {
1302 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname
));
1303 ldap_msgfree(result
);
1304 ldap_unbind(ldap_struct
);
1307 ldap_msgfree(result
);
1308 ldap_unbind(ldap_struct
);
1311 ldap_msgfree(result
);
1312 ldap_unbind(ldap_struct
);
1317 /**********************************************************************
1318 Get SAM_ACCOUNT entry from LDAP by rid
1319 *********************************************************************/
1320 static NTSTATUS
ldapsam_getsampwrid(struct pdb_methods
*my_methods
, SAM_ACCOUNT
*user
, uint32 rid
)
1322 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1323 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1325 LDAPMessage
*result
;
1328 if (!ldapsam_open_connection(ldap_state
, &ldap_struct
))
1331 if (!ldapsam_connect_system(ldap_state
, ldap_struct
)) {
1332 ldap_unbind(ldap_struct
);
1335 if (ldapsam_search_one_user_by_rid(ldap_state
, ldap_struct
, rid
, &result
) != LDAP_SUCCESS
) {
1336 ldap_unbind(ldap_struct
);
1340 if (ldap_count_entries(ldap_struct
, result
) < 1) {
1342 ("We don't find this rid [%i] count=%d\n", rid
,
1343 ldap_count_entries(ldap_struct
, result
)));
1344 ldap_unbind(ldap_struct
);
1348 entry
= ldap_first_entry(ldap_struct
, result
);
1350 if (!init_sam_from_ldap(ldap_state
, user
, ldap_struct
, entry
)) {
1351 DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
1352 ldap_msgfree(result
);
1353 ldap_unbind(ldap_struct
);
1356 ldap_msgfree(result
);
1357 ldap_unbind(ldap_struct
);
1360 ldap_msgfree(result
);
1361 ldap_unbind(ldap_struct
);
1366 static NTSTATUS
ldapsam_getsampwsid(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* user
, const DOM_SID
*sid
)
1369 if (!sid_peek_check_rid(get_global_sam_sid(), sid
, &rid
))
1370 return NT_STATUS_UNSUCCESSFUL
;
1371 return ldapsam_getsampwrid(my_methods
, user
, rid
);
1374 static NTSTATUS
ldapsam_modify_entry(LDAP
*ldap_struct
,SAM_ACCOUNT
*newpwd
,char *dn
,LDAPMod
**mods
,int ldap_op
)
1376 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1383 make_a_mod(&mods
, LDAP_MOD_ADD
, "objectclass", "account");
1384 if((rc
= ldap_add_s(ldap_struct
,dn
,mods
))!=LDAP_SUCCESS
) {
1386 ldap_get_option(ldap_struct
, LDAP_OPT_ERROR_STRING
,
1389 ("failed to add user with uid = %s with: %s\n\t%s\n",
1390 pdb_get_username(newpwd
), ldap_err2string(rc
),
1396 case LDAP_MOD_REPLACE
:
1397 if((rc
= ldap_modify_s(ldap_struct
,dn
,mods
))!=LDAP_SUCCESS
) {
1399 ldap_get_option(ldap_struct
, LDAP_OPT_ERROR_STRING
,
1402 ("failed to modify user with uid = %s with: %s\n\t%s\n",
1403 pdb_get_username(newpwd
), ldap_err2string(rc
),
1410 DEBUG(0,("Wrong LDAP operation type: %d!\n",ldap_op
));
1414 #ifdef LDAP_EXOP_X_MODIFY_PASSWD
1415 if (!(pdb_get_acct_ctrl(newpwd
)&(ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
))&&
1416 (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_OFF
)&&
1417 (pdb_get_plaintext_passwd(newpwd
)!=NULL
)) {
1421 struct berval
*retdata
;
1423 if (ldap_get_option(ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
) == LDAP_OPT_SUCCESS
) {
1424 if (version
!= LDAP_VERSION3
) {
1425 version
= LDAP_VERSION3
;
1426 ldap_set_option (ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
1430 if ((ber
= ber_alloc_t(LBER_USE_DER
))==NULL
) {
1431 DEBUG(0,("ber_alloc_t returns NULL\n"));
1434 ber_printf (ber
, "{");
1435 ber_printf (ber
, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_ID
,dn
);
1436 ber_printf (ber
, "ts", LDAP_TAG_EXOP_X_MODIFY_PASSWD_NEW
, pdb_get_plaintext_passwd(newpwd
));
1437 ber_printf (ber
, "N}");
1439 if ((rc
= ber_flatten (ber
, &bv
))<0) {
1440 DEBUG(0,("ber_flatten returns a value <0\n"));
1446 if ((rc
= ldap_extended_operation_s(ldap_struct
, LDAP_EXOP_X_MODIFY_PASSWD
,
1447 bv
, NULL
, NULL
, &retoid
, &retdata
))!=LDAP_SUCCESS
) {
1448 DEBUG(0,("LDAP Password could not be changed for user %s: %s\n",
1449 pdb_get_username(newpwd
),ldap_err2string(rc
)));
1451 DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd
)));
1453 ber_bvfree(retdata
);
1454 ber_memfree(retoid
);
1459 DEBUG(10,("LDAP PASSWORD SYNC is not supported!\n"));
1460 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */
1461 return NT_STATUS_OK
;
1464 /**********************************************************************
1465 Delete entry from LDAP for username
1466 *********************************************************************/
1467 static NTSTATUS
ldapsam_delete_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* sam_acct
)
1469 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1470 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1476 LDAPMessage
*result
;
1479 DEBUG(0, ("sam_acct was NULL!\n"));
1483 sname
= pdb_get_username(sam_acct
);
1485 if (!ldapsam_open_connection(ldap_state
, &ldap_struct
))
1488 DEBUG (3, ("Deleting user %s from LDAP.\n", sname
));
1490 if (!ldapsam_connect_system(ldap_state
, ldap_struct
)) {
1491 ldap_unbind (ldap_struct
);
1492 DEBUG(0, ("Failed to delete user %s from LDAP.\n", sname
));
1496 rc
= ldapsam_search_one_user_by_name(ldap_state
, ldap_struct
, sname
, &result
);
1497 if (ldap_count_entries (ldap_struct
, result
) == 0) {
1498 DEBUG (0, ("User doesn't exit!\n"));
1499 ldap_msgfree (result
);
1500 ldap_unbind (ldap_struct
);
1504 entry
= ldap_first_entry (ldap_struct
, result
);
1505 dn
= ldap_get_dn (ldap_struct
, entry
);
1506 ldap_msgfree(result
);
1508 rc
= ldap_delete_s (ldap_struct
, dn
);
1511 if (rc
!= LDAP_SUCCESS
) {
1513 ldap_get_option (ldap_struct
, LDAP_OPT_ERROR_STRING
, &ld_error
);
1514 DEBUG (0,("failed to delete user with uid = %s with: %s\n\t%s\n",
1515 sname
, ldap_err2string (rc
), ld_error
));
1517 ldap_unbind (ldap_struct
);
1521 DEBUG (2,("successfully deleted uid = %s from the LDAP database\n", sname
));
1522 ldap_unbind (ldap_struct
);
1523 return NT_STATUS_OK
;
1526 /**********************************************************************
1528 *********************************************************************/
1529 static NTSTATUS
ldapsam_update_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* newpwd
)
1531 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1532 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1536 LDAPMessage
*result
;
1540 if (!ldapsam_open_connection(ldap_state
, &ldap_struct
)) /* open a connection to the server */
1543 if (!ldapsam_connect_system(ldap_state
, ldap_struct
)) { /* connect as system account */
1544 ldap_unbind(ldap_struct
);
1548 rc
= ldapsam_search_one_user_by_name(ldap_state
, ldap_struct
,
1549 pdb_get_username(newpwd
), &result
);
1551 if (ldap_count_entries(ldap_struct
, result
) == 0) {
1552 DEBUG(0, ("No user to modify!\n"));
1553 ldap_msgfree(result
);
1554 ldap_unbind(ldap_struct
);
1558 if (!init_ldap_from_sam(ldap_state
, &mods
, LDAP_MOD_REPLACE
, newpwd
)) {
1559 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1560 ldap_msgfree(result
);
1561 ldap_unbind(ldap_struct
);
1565 entry
= ldap_first_entry(ldap_struct
, result
);
1566 dn
= ldap_get_dn(ldap_struct
, entry
);
1567 ldap_msgfree(result
);
1569 if (NT_STATUS_IS_ERR(ldapsam_modify_entry(ldap_struct
,newpwd
,dn
,mods
,LDAP_MOD_REPLACE
))) {
1570 DEBUG(0,("failed to modify user with uid = %s\n",
1571 pdb_get_username(newpwd
)));
1572 ldap_mods_free(mods
,1);
1573 ldap_unbind(ldap_struct
);
1579 ("successfully modified uid = %s in the LDAP database\n",
1580 pdb_get_username(newpwd
)));
1581 ldap_mods_free(mods
, 1);
1582 ldap_unbind(ldap_struct
);
1583 return NT_STATUS_OK
;
1586 /**********************************************************************
1587 Add SAM_ACCOUNT to LDAP
1588 *********************************************************************/
1589 static NTSTATUS
ldapsam_add_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* newpwd
)
1591 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1592 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1595 LDAP
*ldap_struct
= NULL
;
1596 LDAPMessage
*result
= NULL
;
1598 LDAPMod
**mods
= NULL
;
1602 const char *username
= pdb_get_username(newpwd
);
1603 if (!username
|| !*username
) {
1604 DEBUG(0, ("Cannot add user without a username!\n"));
1608 if (!ldapsam_open_connection(ldap_state
, &ldap_struct
)) /* open a connection to the server */
1611 if (!ldapsam_connect_system(ldap_state
, ldap_struct
)) { /* connect as system account */
1612 ldap_unbind(ldap_struct
);
1616 rc
= ldapsam_search_one_user_by_name (ldap_state
, ldap_struct
, username
, &result
);
1618 if (ldap_count_entries(ldap_struct
, result
) != 0) {
1619 DEBUG(0,("User already in the base, with samba properties\n"));
1620 ldap_msgfree(result
);
1621 ldap_unbind(ldap_struct
);
1624 ldap_msgfree(result
);
1626 slprintf (filter
, sizeof (filter
) - 1, "uid=%s", username
);
1627 rc
= ldapsam_search_one_user(ldap_state
, ldap_struct
, filter
, &result
);
1628 num_result
= ldap_count_entries(ldap_struct
, result
);
1630 if (num_result
> 1) {
1631 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
1632 ldap_msgfree(result
);
1636 /* Check if we need to update an existing entry */
1637 if (num_result
== 1) {
1641 DEBUG(3,("User exists without samba properties: adding them\n"));
1642 ldap_op
= LDAP_MOD_REPLACE
;
1643 entry
= ldap_first_entry (ldap_struct
, result
);
1644 tmp
= ldap_get_dn (ldap_struct
, entry
);
1645 slprintf (dn
, sizeof (dn
) - 1, "%s", tmp
);
1648 /* Check if we need to add an entry */
1649 DEBUG(3,("Adding new user\n"));
1650 ldap_op
= LDAP_MOD_ADD
;
1651 if (username
[strlen(username
)-1] == '$') {
1652 slprintf (dn
, sizeof (dn
) - 1, "uid=%s,%s", username
, lp_ldap_machine_suffix ());
1654 slprintf (dn
, sizeof (dn
) - 1, "uid=%s,%s", username
, lp_ldap_user_suffix ());
1658 ldap_msgfree(result
);
1660 if (!init_ldap_from_sam(ldap_state
, &mods
, ldap_op
, newpwd
)) {
1661 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
1662 ldap_mods_free(mods
, 1);
1663 ldap_unbind(ldap_struct
);
1666 make_a_mod(&mods
, LDAP_MOD_ADD
, "objectclass", "sambaAccount");
1668 if (NT_STATUS_IS_ERR(ldapsam_modify_entry(ldap_struct
,newpwd
,dn
,mods
,ldap_op
))) {
1669 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
1670 pdb_get_username(newpwd
),dn
));
1671 ldap_mods_free(mods
,1);
1672 ldap_unbind(ldap_struct
);
1676 DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd
)));
1677 ldap_mods_free(mods
, 1);
1678 ldap_unbind(ldap_struct
);
1679 return NT_STATUS_OK
;
1682 static void free_private_data(void **vp
)
1684 struct ldapsam_privates
**ldap_state
= (struct ldapsam_privates
**)vp
;
1686 if ((*ldap_state
)->ldap_struct
) {
1687 ldap_unbind((*ldap_state
)->ldap_struct
);
1690 if ((*ldap_state
)->bind_secret
) {
1691 memset((*ldap_state
)->bind_secret
, '\0', strlen((*ldap_state
)->bind_secret
));
1694 SAFE_FREE((*ldap_state
)->bind_dn
);
1695 SAFE_FREE((*ldap_state
)->bind_secret
);
1699 /* No need to free any further, as it is talloc()ed */
1702 NTSTATUS
pdb_init_ldapsam(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
1705 struct ldapsam_privates
*ldap_state
;
1707 if (!NT_STATUS_IS_OK(nt_status
= make_pdb_methods(pdb_context
->mem_ctx
, pdb_method
))) {
1711 (*pdb_method
)->name
= "ldapsam";
1713 (*pdb_method
)->setsampwent
= ldapsam_setsampwent
;
1714 (*pdb_method
)->endsampwent
= ldapsam_endsampwent
;
1715 (*pdb_method
)->getsampwent
= ldapsam_getsampwent
;
1716 (*pdb_method
)->getsampwnam
= ldapsam_getsampwnam
;
1717 (*pdb_method
)->getsampwsid
= ldapsam_getsampwsid
;
1718 (*pdb_method
)->add_sam_account
= ldapsam_add_sam_account
;
1719 (*pdb_method
)->update_sam_account
= ldapsam_update_sam_account
;
1720 (*pdb_method
)->delete_sam_account
= ldapsam_delete_sam_account
;
1722 /* TODO: Setup private data and free */
1724 ldap_state
= talloc_zero(pdb_context
->mem_ctx
, sizeof(struct ldapsam_privates
));
1727 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
1728 return NT_STATUS_NO_MEMORY
;
1732 ldap_state
->uri
= talloc_strdup(pdb_context
->mem_ctx
, location
);
1734 ldap_state
->uri
= "ldap://localhost";
1737 (*pdb_method
)->private_data
= ldap_state
;
1739 (*pdb_method
)->free_private_data
= free_private_data
;
1741 return NT_STATUS_OK
;
1744 NTSTATUS
pdb_init_ldapsam_nua(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
1747 struct ldapsam_privates
*ldap_state
;
1748 uint32 low_nua_uid
, high_nua_uid
;
1750 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_ldapsam(pdb_context
, pdb_method
, location
))) {
1754 (*pdb_method
)->name
= "ldapsam_nua";
1756 ldap_state
= (*pdb_method
)->private_data
;
1758 ldap_state
->permit_non_unix_accounts
= True
;
1760 if (!lp_non_unix_account_range(&low_nua_uid
, &high_nua_uid
)) {
1761 DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n"));
1762 return NT_STATUS_UNSUCCESSFUL
;
1765 ldap_state
->low_nua_rid
=fallback_pdb_uid_to_user_rid(low_nua_uid
);
1767 ldap_state
->high_nua_rid
=fallback_pdb_uid_to_user_rid(high_nua_uid
);
1769 return NT_STATUS_OK
;
1775 NTSTATUS
pdb_init_ldapsam(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
1777 DEBUG(0, ("ldap not detected at configure time, ldapsam not availalble!\n"));
1778 return NT_STATUS_UNSUCCESSFUL
;
1781 NTSTATUS
pdb_init_ldapsam_nua(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
1783 DEBUG(0, ("ldap not dectected at configure time, ldapsam_nua not available!\n"));
1784 return NT_STATUS_UNSUCCESSFUL
;