2 Unix SMB/CIFS implementation.
3 LDAP protocol helper functions for SAMBA
4 Copyright (C) Gerald Carter 2001
5 Copyright (C) Shahms King 2001
6 Copyright (C) Jean François Micouleau 1998
7 Copyright (C) Andrew Bartlett 2002
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #define DBGC_CLASS DBGC_PASSDB
32 * persistent connections: if using NSS LDAP, many connections are made
33 * however, using only one within Samba would be nice
35 * Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
37 * Other LDAP based login attributes: accountExpires, etc.
38 * (should be the domain of Samba proper, but the sam_password/SAM_ACCOUNT
39 * structures don't have fields for some of these attributes)
41 * SSL is done, but can't get the certificate based authentication to work
42 * against on my test platform (Linux 2.4, OpenLDAP 2.x)
45 /* NOTE: this will NOT work against an Active Directory server
46 * due to the fact that the two password fields cannot be retrieved
47 * from a server; recommend using security = domain in this situation
55 #define SAM_ACCOUNT struct sam_passwd
58 struct ldapsam_privates
{
66 /* retrive-once info */
69 BOOL permit_non_unix_accounts
;
75 static uint32
ldapsam_get_next_available_nua_rid(struct ldapsam_privates
*ldap_state
);
77 /*******************************************************************
78 find the ldap password
79 ******************************************************************/
80 static BOOL
fetch_ldapsam_pw(char **dn
, char** pw
)
85 *dn
= smb_xstrdup(lp_ldap_admin_dn());
87 if (asprintf(&key
, "%s/%s", SECRETS_LDAP_BIND_PW
, *dn
) < 0) {
89 DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
92 *pw
=secrets_fetch(key
, &size
);
94 /* Upgrade 2.2 style entry */
96 char* old_style_key
= strdup(*dn
);
100 if (!old_style_key
) {
101 DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n"));
105 for (p
=old_style_key
; *p
; p
++)
106 if (*p
== ',') *p
= '/';
108 data
=secrets_fetch(old_style_key
, &size
);
109 if (!size
&& size
< sizeof(old_style_pw
)) {
110 DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
111 SAFE_FREE(old_style_key
);
116 strncpy(old_style_pw
, data
, size
);
117 old_style_pw
[size
] = 0;
121 if (!secrets_store_ldap_pw(*dn
, old_style_pw
)) {
122 DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
123 SAFE_FREE(old_style_key
);
127 if (!secrets_delete(old_style_key
)) {
128 DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
131 SAFE_FREE(old_style_key
);
133 *pw
= smb_xstrdup(old_style_pw
);
139 static const char *attr
[] = {"uid", "pwdLastSet", "logonTime",
140 "logoffTime", "kickoffTime", "cn",
141 "pwdCanChange", "pwdMustChange",
142 "displayName", "homeDrive",
143 "smbHome", "scriptPath",
144 "profilePath", "description",
145 "userWorkstations", "rid",
146 "primaryGroupID", "lmPassword",
147 "ntPassword", "acctFlags",
148 "domain", "description", NULL
};
150 /*******************************************************************
151 open a connection to the ldap server.
152 ******************************************************************/
153 static BOOL
ldapsam_open_connection (struct ldapsam_privates
*ldap_state
, LDAP
** ldap_struct
)
156 if (geteuid() != 0) {
157 DEBUG(0, ("ldap_open_connection: cannot access LDAP when not root..\n"));
161 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
162 DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state
->uri
));
164 if (ldap_initialize(ldap_struct
, ldap_state
->uri
) != LDAP_SUCCESS
) {
165 DEBUG(0, ("ldap_initialize: %s\n", strerror(errno
)));
170 /* Parse the string manually */
174 int tls
= LDAP_OPT_X_TLS_HARD
;
179 const char *p
= ldap_state
->uri
;
180 SMB_ASSERT(sizeof(protocol
)>10 && sizeof(host
)>254);
182 /* skip leading "URL:" (if any) */
183 if ( strncasecmp( p
, "URL:", 4 ) == 0 ) {
187 sscanf(p
, "%10[^:]://%254s[^:]:%d", protocol
, host
, &port
);
190 if (strequal(protocol
, "ldap")) {
192 } else if (strequal(protocol
, "ldaps")) {
195 DEBUG(0, ("unrecognised protocol (%s)!\n", protocol
));
199 if ((*ldap_struct
= ldap_init(host
, port
)) == NULL
) {
200 DEBUG(0, ("ldap_init failed !\n"));
204 /* Connect to older servers using SSL and V2 rather than Start TLS */
205 if (ldap_get_option(*ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
) == LDAP_OPT_SUCCESS
)
207 if (version
!= LDAP_VERSION2
)
209 version
= LDAP_VERSION2
;
210 ldap_set_option (*ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
, &version
);
214 if (strequal(protocol
, "ldaps")) {
215 if (lp_ldap_ssl() == LDAP_SSL_START_TLS
) {
216 if (ldap_get_option (*ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
,
217 &version
) == LDAP_OPT_SUCCESS
)
219 if (version
< LDAP_VERSION3
)
221 version
= LDAP_VERSION3
;
222 ldap_set_option (*ldap_struct
, LDAP_OPT_PROTOCOL_VERSION
,
226 if ((rc
= ldap_start_tls_s (*ldap_struct
, NULL
, NULL
)) != LDAP_SUCCESS
)
228 DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
229 ldap_err2string(rc
)));
232 DEBUG (2, ("StartTLS issued: using a TLS connection\n"));
235 if (ldap_set_option (*ldap_struct
, LDAP_OPT_X_TLS
, &tls
) != LDAP_SUCCESS
)
237 DEBUG(0, ("Failed to setup a TLS session\n"));
242 * No special needs to setup options prior to the LDAP
243 * bind (which should be called next via ldap_connect_system()
249 DEBUG(2, ("ldap_open_connection: connection opened\n"));
254 /*******************************************************************
255 Add a rebind function for authenticated referrals
256 ******************************************************************/
258 static int rebindproc (LDAP
*ldap_struct
, char **whop
, char **credp
,
259 int *method
, int freeit
)
265 /** @TODO Should we be doing something to check what servers we rebind to?
266 Could we get a referral to a machine that we don't want to give our
267 username and password to? */
272 if (!fetch_ldapsam_pw(&ldap_dn
, &ldap_secret
))
274 DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
275 return LDAP_OPERATIONS_ERROR
; /* No idea what to return */
278 DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
281 rc
= ldap_simple_bind_s(ldap_struct
, ldap_dn
, ldap_secret
);
284 SAFE_FREE(ldap_secret
);
291 /*******************************************************************
292 connect to the ldap server under system privilege.
293 ******************************************************************/
294 static BOOL
ldapsam_connect_system(struct ldapsam_privates
*ldap_state
, LDAP
* ldap_struct
)
300 /* get the password */
301 if (!fetch_ldapsam_pw(&ldap_dn
, &ldap_secret
))
303 DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
307 /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
308 (OpenLDAP) doesnt' seem to support it */
310 DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n",
313 #if LDAP_SET_REBIND_PROC_ARGS == 3
314 ldap_set_rebind_proc(ldap_struct
, (LDAP_REBIND_PROC
*)(&rebindproc
), NULL
);
315 #elif LDAP_SET_REBIND_PROC_ARGS == 2
316 ldap_set_rebind_proc(ldap_struct
, (LDAP_REBIND_PROC
*)(&rebindproc
));
320 rc
= ldap_simple_bind_s(ldap_struct
, ldap_dn
, ldap_secret
);
323 SAFE_FREE(ldap_secret
);
325 if (rc
!= LDAP_SUCCESS
)
327 DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc
)));
331 DEBUG(2, ("ldap_connect_system: succesful connection to the LDAP server\n"));
335 /*******************************************************************
336 run the search by name.
337 ******************************************************************/
338 static int ldapsam_search_one_user (struct ldapsam_privates
*ldap_state
, LDAP
* ldap_struct
, const char *filter
, LDAPMessage
** result
)
340 int scope
= LDAP_SCOPE_SUBTREE
;
343 DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter
));
345 rc
= ldap_search_s(ldap_struct
, lp_ldap_suffix (), scope
, filter
, attr
, 0, result
);
347 if (rc
!= LDAP_SUCCESS
) {
348 DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n",
349 ldap_err2string (rc
)));
350 DEBUG(3,("ldapsam_search_one_user: Query was: %s, %s\n", lp_ldap_suffix(),
357 /*******************************************************************
358 run the search by name.
359 ******************************************************************/
360 static int ldapsam_search_one_user_by_name (struct ldapsam_privates
*ldap_state
, LDAP
* ldap_struct
, const char *user
,
361 LDAPMessage
** result
)
366 * in the filter expression, replace %u with the real name
367 * so in ldap filter, %u MUST exist :-)
369 pstrcpy(filter
, lp_ldap_filter());
372 * have to use this here because $ is filtered out
375 all_string_sub(filter
, "%u", user
, sizeof(pstring
));
377 return ldapsam_search_one_user(ldap_state
, ldap_struct
, filter
, result
);
380 /*******************************************************************
381 run the search by uid.
382 ******************************************************************/
383 static int ldapsam_search_one_user_by_uid(struct ldapsam_privates
*ldap_state
,
384 LDAP
* ldap_struct
, int uid
,
385 LDAPMessage
** result
)
390 /* Get the username from the system and look that up in the LDAP */
392 if ((user
= getpwuid_alloc(uid
)) == NULL
) {
393 DEBUG(3,("ldapsam_search_one_user_by_uid: Failed to locate uid [%d]\n", uid
));
394 return LDAP_NO_SUCH_OBJECT
;
397 pstrcpy(filter
, lp_ldap_filter());
399 all_string_sub(filter
, "%u", user
->pw_name
, sizeof(pstring
));
403 return ldapsam_search_one_user(ldap_state
, ldap_struct
, filter
, result
);
406 /*******************************************************************
407 run the search by rid.
408 ******************************************************************/
409 static int ldapsam_search_one_user_by_rid (struct ldapsam_privates
*ldap_state
,
410 LDAP
* ldap_struct
, uint32 rid
,
411 LDAPMessage
** result
)
416 /* check if the user rid exsists, if not, try searching on the uid */
418 snprintf(filter
, sizeof(filter
) - 1, "rid=%i", rid
);
419 rc
= ldapsam_search_one_user(ldap_state
, ldap_struct
, filter
, result
);
421 if (rc
!= LDAP_SUCCESS
)
422 rc
= ldapsam_search_one_user_by_uid(ldap_state
, ldap_struct
,
423 fallback_pdb_user_rid_to_uid(rid
),
429 /*******************************************************************
430 search an attribute and return the first value found.
431 ******************************************************************/
432 static BOOL
get_single_attribute (LDAP
* ldap_struct
, LDAPMessage
* entry
,
433 char *attribute
, pstring value
)
437 if ((values
= ldap_get_values (ldap_struct
, entry
, attribute
)) == NULL
) {
439 DEBUG (10, ("get_single_attribute: [%s] = [<does not exist>]\n", attribute
));
444 pstrcpy(value
, values
[0]);
445 ldap_value_free(values
);
446 #ifdef DEBUG_PASSWORDS
447 DEBUG (100, ("get_single_attribute: [%s] = [%s]\n", attribute
, value
));
452 /************************************************************************
453 Routine to manage the LDAPMod structure array
454 manage memory used by the array, by each struct, and values
456 ************************************************************************/
457 static void make_a_mod (LDAPMod
*** modlist
, int modop
, const char *attribute
, const char *value
)
465 if (attribute
== NULL
|| *attribute
== '\0')
468 if (value
== NULL
|| *value
== '\0')
473 mods
= (LDAPMod
**) malloc(sizeof(LDAPMod
*));
476 DEBUG(0, ("make_a_mod: out of memory!\n"));
482 for (i
= 0; mods
[i
] != NULL
; ++i
) {
483 if (mods
[i
]->mod_op
== modop
&& !strcasecmp(mods
[i
]->mod_type
, attribute
))
489 mods
= (LDAPMod
**) Realloc (mods
, (i
+ 2) * sizeof (LDAPMod
*));
492 DEBUG(0, ("make_a_mod: out of memory!\n"));
495 mods
[i
] = (LDAPMod
*) malloc(sizeof(LDAPMod
));
498 DEBUG(0, ("make_a_mod: out of memory!\n"));
501 mods
[i
]->mod_op
= modop
;
502 mods
[i
]->mod_values
= NULL
;
503 mods
[i
]->mod_type
= strdup(attribute
);
510 if (mods
[i
]->mod_values
!= NULL
) {
511 for (; mods
[i
]->mod_values
[j
] != NULL
; j
++);
513 mods
[i
]->mod_values
= (char **)Realloc(mods
[i
]->mod_values
,
514 (j
+ 2) * sizeof (char *));
516 if (mods
[i
]->mod_values
== NULL
) {
517 DEBUG (0, ("make_a_mod: Memory allocation failure!\n"));
520 mods
[i
]->mod_values
[j
] = strdup(value
);
521 mods
[i
]->mod_values
[j
+ 1] = NULL
;
526 /* New Interface is being implemented here */
528 /**********************************************************************
529 Initialize SAM_ACCOUNT from an LDAP query
530 (Based on init_sam_from_buffer in pdb_tdb.c)
531 *********************************************************************/
532 static BOOL
init_sam_from_ldap (struct ldapsam_privates
*ldap_state
,
533 SAM_ACCOUNT
* sampass
,
534 LDAP
* ldap_struct
, LDAPMessage
* entry
)
540 pass_can_change_time
,
541 pass_must_change_time
;
561 uint8 hours
[MAX_HOURS_LEN
];
564 gid_t gid
= getegid();
568 * do a little initialization
572 nt_username
[0] = '\0';
576 logon_script
[0] = '\0';
577 profile_path
[0] = '\0';
579 munged_dial
[0] = '\0';
580 workstations
[0] = '\0';
583 if (sampass
== NULL
|| ldap_struct
== NULL
|| entry
== NULL
) {
584 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
588 get_single_attribute(ldap_struct
, entry
, "uid", username
);
589 DEBUG(2, ("Entry found for user: %s\n", username
));
591 pstrcpy(nt_username
, username
);
593 pstrcpy(domain
, lp_workgroup());
595 get_single_attribute(ldap_struct
, entry
, "rid", temp
);
596 user_rid
= (uint32
)atol(temp
);
598 pdb_set_user_sid_from_rid(sampass
, user_rid
);
600 if (!get_single_attribute(ldap_struct
, entry
, "primaryGroupID", temp
)) {
603 group_rid
= (uint32
)atol(temp
);
604 pdb_set_group_sid_from_rid(sampass
, group_rid
);
607 if ((ldap_state
->permit_non_unix_accounts
)
608 && (user_rid
>= ldap_state
->low_nua_rid
)
609 && (user_rid
<= ldap_state
->high_nua_rid
)) {
613 /* These values MAY be in LDAP, but they can also be retrieved through
614 * sys_getpw*() which is how we're doing it
617 pw
= getpwnam_alloc(username
);
619 DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\n", username
));
625 pdb_set_unix_homedir(sampass
, pw
->pw_dir
);
629 pdb_set_uid(sampass
, uid
);
630 pdb_set_gid(sampass
, gid
);
632 if (group_rid
== 0) {
634 /* call the mapping code here */
635 if(get_group_map_from_gid(gid
, &map
, MAPPING_WITHOUT_PRIV
)) {
636 pdb_set_group_sid(sampass
, &map
.sid
);
639 pdb_set_group_sid_from_rid(sampass
, pdb_gid_to_group_rid(gid
));
644 if (!get_single_attribute(ldap_struct
, entry
, "pwdLastSet", temp
)) {
645 /* leave as default */
647 pass_last_set_time
= (time_t) atol(temp
);
648 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
);
651 if (!get_single_attribute(ldap_struct
, entry
, "logonTime", temp
)) {
652 /* leave as default */
654 logon_time
= (time_t) atol(temp
);
655 pdb_set_logon_time(sampass
, logon_time
, True
);
658 if (!get_single_attribute(ldap_struct
, entry
, "logoffTime", temp
)) {
659 /* leave as default */
661 logoff_time
= (time_t) atol(temp
);
662 pdb_set_logoff_time(sampass
, logoff_time
, True
);
665 if (!get_single_attribute(ldap_struct
, entry
, "kickoffTime", temp
)) {
666 /* leave as default */
668 kickoff_time
= (time_t) atol(temp
);
669 pdb_set_kickoff_time(sampass
, kickoff_time
, True
);
672 if (!get_single_attribute(ldap_struct
, entry
, "pwdCanChange", temp
)) {
673 /* leave as default */
675 pass_can_change_time
= (time_t) atol(temp
);
676 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, True
);
679 if (!get_single_attribute(ldap_struct
, entry
, "pwdMustChange", temp
)) {
680 /* leave as default */
682 pass_must_change_time
= (time_t) atol(temp
);
683 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, True
);
686 /* recommend that 'gecos' and 'displayName' should refer to the same
687 * attribute OID. userFullName depreciated, only used by Samba
688 * primary rules of LDAP: don't make a new attribute when one is already defined
689 * that fits your needs; using cn then displayName rather than 'userFullName'
692 if (!get_single_attribute(ldap_struct
, entry
, "cn", fullname
)) {
693 if (!get_single_attribute(ldap_struct
, entry
, "displayName", fullname
)) {
694 /* leave as default */
696 pdb_set_fullname(sampass
, fullname
);
699 pdb_set_fullname(sampass
, fullname
);
702 if (!get_single_attribute(ldap_struct
, entry
, "homeDrive", dir_drive
)) {
703 pdb_set_dir_drive(sampass
, talloc_sub_specified(sampass
->mem_ctx
,
709 pdb_set_dir_drive(sampass
, dir_drive
, True
);
712 if (!get_single_attribute(ldap_struct
, entry
, "smbHome", homedir
)) {
713 pdb_set_homedir(sampass
, talloc_sub_specified(sampass
->mem_ctx
,
719 pdb_set_homedir(sampass
, homedir
, True
);
722 if (!get_single_attribute(ldap_struct
, entry
, "scriptPath", logon_script
)) {
723 pdb_set_logon_script(sampass
, talloc_sub_specified(sampass
->mem_ctx
,
729 pdb_set_logon_script(sampass
, logon_script
, True
);
732 if (!get_single_attribute(ldap_struct
, entry
, "profilePath", profile_path
)) {
733 pdb_set_profile_path(sampass
, talloc_sub_specified(sampass
->mem_ctx
,
739 pdb_set_profile_path(sampass
, profile_path
, True
);
742 if (!get_single_attribute(ldap_struct
, entry
, "description", acct_desc
)) {
743 /* leave as default */
745 pdb_set_acct_desc(sampass
, acct_desc
);
748 if (!get_single_attribute(ldap_struct
, entry
, "userWorkstations", workstations
)) {
749 /* leave as default */;
751 pdb_set_workstations(sampass
, workstations
);
754 /* FIXME: hours stuff should be cleaner */
758 memset(hours
, 0xff, hours_len
);
760 if (!get_single_attribute (ldap_struct
, entry
, "lmPassword", temp
)) {
761 /* leave as default */
763 pdb_gethexpwd(temp
, smblmpwd
);
764 memset((char *)temp
, '\0', sizeof(temp
));
765 if (!pdb_set_lanman_passwd(sampass
, smblmpwd
))
769 if (!get_single_attribute (ldap_struct
, entry
, "ntPassword", temp
)) {
770 /* leave as default */
772 pdb_gethexpwd(temp
, smbntpwd
);
773 memset((char *)temp
, '\0', sizeof(temp
));
774 if (!pdb_set_nt_passwd(sampass
, smbntpwd
))
778 if (!get_single_attribute (ldap_struct
, entry
, "acctFlags", temp
)) {
779 acct_ctrl
|= ACB_NORMAL
;
781 acct_ctrl
= pdb_decode_acct_ctrl(temp
);
784 acct_ctrl
|= ACB_NORMAL
;
786 pdb_set_acct_ctrl(sampass
, acct_ctrl
);
789 pdb_set_hours_len(sampass
, hours_len
);
790 pdb_set_logon_divs(sampass
, logon_divs
);
792 pdb_set_username(sampass
, username
);
794 pdb_set_domain(sampass
, domain
);
795 pdb_set_nt_username(sampass
, nt_username
);
797 pdb_set_munged_dial(sampass
, munged_dial
);
799 /* pdb_set_unknown_3(sampass, unknown3); */
800 /* pdb_set_unknown_5(sampass, unknown5); */
801 /* pdb_set_unknown_6(sampass, unknown6); */
803 pdb_set_hours(sampass
, hours
);
808 /**********************************************************************
809 Initialize SAM_ACCOUNT from an LDAP query
810 (Based on init_buffer_from_sam in pdb_tdb.c)
811 *********************************************************************/
812 static BOOL
init_ldap_from_sam (struct ldapsam_privates
*ldap_state
,
813 LDAPMod
*** mods
, int ldap_op
,
814 const SAM_ACCOUNT
* sampass
)
819 if (mods
== NULL
|| sampass
== NULL
) {
820 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
827 * took out adding "objectclass: sambaAccount"
828 * do this on a per-mod basis
831 make_a_mod(mods
, ldap_op
, "uid", pdb_get_username(sampass
));
832 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass
)));
834 if ( pdb_get_user_rid(sampass
) ) {
835 rid
= pdb_get_user_rid(sampass
);
836 } else if (IS_SAM_SET(sampass
, FLAG_SAM_UID
)) {
837 rid
= fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass
));
838 } else if (ldap_state
->permit_non_unix_accounts
) {
839 rid
= ldapsam_get_next_available_nua_rid(ldap_state
);
841 DEBUG(0, ("NO user RID specified on account %s, and findining next available NUA RID failed, cannot store!\n", pdb_get_username(sampass
)));
845 DEBUG(0, ("NO user RID specified on account %s, cannot store!\n", pdb_get_username(sampass
)));
849 slprintf(temp
, sizeof(temp
) - 1, "%i", rid
);
850 make_a_mod(mods
, ldap_op
, "rid", temp
);
852 if ( pdb_get_group_rid(sampass
) ) {
853 rid
= pdb_get_group_rid(sampass
);
854 } else if (IS_SAM_SET(sampass
, FLAG_SAM_GID
)) {
855 rid
= pdb_gid_to_group_rid(pdb_get_gid(sampass
));
856 } else if (ldap_state
->permit_non_unix_accounts
) {
857 rid
= DOMAIN_GROUP_RID_USERS
;
859 DEBUG(0, ("NO group RID specified on account %s, cannot store!\n", pdb_get_username(sampass
)));
863 slprintf(temp
, sizeof(temp
) - 1, "%i", rid
);
864 make_a_mod(mods
, ldap_op
, "primaryGroupID", temp
);
866 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_last_set_time(sampass
));
867 make_a_mod(mods
, ldap_op
, "pwdLastSet", temp
);
869 /* displayName, cn, and gecos should all be the same
870 * most easily accomplished by giving them the same OID
871 * gecos isn't set here b/c it should be handled by the
875 make_a_mod(mods
, ldap_op
, "displayName", pdb_get_fullname(sampass
));
876 make_a_mod(mods
, ldap_op
, "cn", pdb_get_fullname(sampass
));
877 make_a_mod(mods
, ldap_op
, "description", pdb_get_acct_desc(sampass
));
878 make_a_mod(mods
, ldap_op
, "userWorkstations", pdb_get_workstations(sampass
));
881 * Only updates fields which have been set (not defaults from smb.conf)
884 if (IS_SAM_SET(sampass
, FLAG_SAM_SMBHOME
))
885 make_a_mod(mods
, ldap_op
, "smbHome", pdb_get_homedir(sampass
));
887 if (IS_SAM_SET(sampass
, FLAG_SAM_DRIVE
))
888 make_a_mod(mods
, ldap_op
, "homeDrive", pdb_get_dir_drive(sampass
));
890 if (IS_SAM_SET(sampass
, FLAG_SAM_LOGONSCRIPT
))
891 make_a_mod(mods
, ldap_op
, "scriptPath", pdb_get_logon_script(sampass
));
893 if (IS_SAM_SET(sampass
, FLAG_SAM_PROFILE
))
894 make_a_mod(mods
, ldap_op
, "profilePath", pdb_get_profile_path(sampass
));
896 if (IS_SAM_SET(sampass
, FLAG_SAM_LOGONTIME
)) {
897 slprintf(temp
, sizeof(temp
) - 1, "%li", pdb_get_logon_time(sampass
));
898 make_a_mod(mods
, ldap_op
, "logonTime", temp
);
901 if (IS_SAM_SET(sampass
, FLAG_SAM_LOGOFFTIME
)) {
902 slprintf(temp
, sizeof(temp
) - 1, "%li", pdb_get_logoff_time(sampass
));
903 make_a_mod(mods
, ldap_op
, "logoffTime", temp
);
906 if (IS_SAM_SET(sampass
, FLAG_SAM_KICKOFFTIME
)) {
907 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_kickoff_time(sampass
));
908 make_a_mod(mods
, ldap_op
, "kickoffTime", temp
);
911 if (IS_SAM_SET(sampass
, FLAG_SAM_CANCHANGETIME
)) {
912 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_can_change_time(sampass
));
913 make_a_mod(mods
, ldap_op
, "pwdCanChange", temp
);
916 if (IS_SAM_SET(sampass
, FLAG_SAM_MUSTCHANGETIME
)) {
917 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_must_change_time(sampass
));
918 make_a_mod(mods
, ldap_op
, "pwdMustChange", temp
);
921 /* FIXME: Hours stuff goes in LDAP */
922 pdb_sethexpwd (temp
, pdb_get_lanman_passwd(sampass
), pdb_get_acct_ctrl(sampass
));
923 make_a_mod (mods
, ldap_op
, "lmPassword", temp
);
925 pdb_sethexpwd (temp
, pdb_get_nt_passwd(sampass
), pdb_get_acct_ctrl(sampass
));
926 make_a_mod (mods
, ldap_op
, "ntPassword", temp
);
928 make_a_mod (mods
, ldap_op
, "acctFlags", pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass
),
929 NEW_PW_FORMAT_SPACE_PADDED_LEN
));
935 /**********************************************************************
936 Connect to LDAP server and find the next available RID.
937 *********************************************************************/
938 static uint32
check_nua_rid_is_avail(struct ldapsam_privates
*ldap_state
, uint32 top_rid
, LDAP
*ldap_struct
)
941 uint32 final_rid
= (top_rid
& (~USER_RID_TYPE
)) + RID_MULTIPLIER
;
946 if (final_rid
< ldap_state
->low_nua_rid
|| final_rid
> ldap_state
->high_nua_rid
) {
950 if (ldapsam_search_one_user_by_rid(ldap_state
, ldap_struct
, final_rid
, &result
) != LDAP_SUCCESS
) {
951 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the confirmation search failed!\n", final_rid
, final_rid
));
953 ldap_msgfree(result
);
956 if (ldap_count_entries(ldap_struct
, result
) != 0)
958 DEBUG(0, ("Cannot allocate NUA RID %d (0x%x), as the RID is already in use!!\n", final_rid
, final_rid
));
960 ldap_msgfree(result
);
963 DEBUG(5, ("NUA RID %d (0x%x), declared valid\n", final_rid
, final_rid
));
967 /**********************************************************************
968 Extract the RID from an LDAP entry
969 *********************************************************************/
970 static uint32
entry_to_user_rid(struct ldapsam_privates
*ldap_state
, LDAPMessage
*entry
, LDAP
*ldap_struct
) {
972 SAM_ACCOUNT
*user
= NULL
;
973 if (!NT_STATUS_IS_OK(pdb_init_sam(&user
))) {
977 if (init_sam_from_ldap(ldap_state
, user
, ldap_struct
, entry
)) {
978 rid
= pdb_get_user_rid(user
);
983 if (rid
>= ldap_state
->low_nua_rid
&& rid
<= ldap_state
->high_nua_rid
) {
990 /**********************************************************************
991 Connect to LDAP server and find the next available RID.
992 *********************************************************************/
993 static uint32
search_top_nua_rid(struct ldapsam_privates
*ldap_state
, LDAP
*ldap_struct
)
999 char *final_filter
= NULL
;
1004 pstrcpy(filter
, lp_ldap_filter());
1005 all_string_sub(filter
, "%u", "*", sizeof(pstring
));
1008 asprintf(&final_filter
, "(&(%s)(&(rid>=%d)(rid<=%d)))", filter
, ldap_state
->low_nua_rid
, ldap_state
->high_nua_rid
);
1010 final_filter
= strdup(filter
);
1012 DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter
));
1014 rc
= ldap_search_s(ldap_struct
, lp_ldap_suffix(),
1015 LDAP_SCOPE_SUBTREE
, final_filter
, attr
, 0,
1018 if (rc
!= LDAP_SUCCESS
)
1021 DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc
)));
1022 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter
));
1025 ldap_msgfree(result
);
1030 count
= ldap_count_entries(ldap_struct
, result
);
1031 DEBUG(2, ("search_top_nua_rid: %d entries in the base!\n", count
));
1034 DEBUG(3, ("LDAP search returned no records, assuming no non-unix-accounts present!: %s\n", ldap_err2string(rc
)));
1035 DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), final_filter
));
1037 ldap_msgfree(result
);
1039 return ldap_state
->low_nua_rid
;
1043 entry
= ldap_first_entry(ldap_struct
,result
);
1045 top_rid
= entry_to_user_rid(ldap_state
, entry
, ldap_struct
);
1047 while ((entry
= ldap_next_entry(ldap_struct
, entry
))) {
1049 rid
= entry_to_user_rid(ldap_state
, entry
, ldap_struct
);
1050 if (rid
> top_rid
) {
1055 ldap_msgfree(result
);
1057 if (top_rid
< ldap_state
->low_nua_rid
)
1058 top_rid
= ldap_state
->low_nua_rid
;
1063 /**********************************************************************
1064 Connect to LDAP server and find the next available RID.
1065 *********************************************************************/
1066 static uint32
ldapsam_get_next_available_nua_rid(struct ldapsam_privates
*ldap_state
) {
1068 uint32 next_nua_rid
;
1071 if (!ldapsam_open_connection(ldap_state
, &ldap_struct
))
1075 if (!ldapsam_connect_system(ldap_state
, ldap_struct
))
1077 ldap_unbind(ldap_struct
);
1081 top_nua_rid
= search_top_nua_rid(ldap_state
, ldap_struct
);
1083 next_nua_rid
= check_nua_rid_is_avail(ldap_state
,
1084 top_nua_rid
, ldap_struct
);
1086 ldap_unbind(ldap_struct
);
1087 return next_nua_rid
;
1090 /**********************************************************************
1091 Connect to LDAP server for password enumeration
1092 *********************************************************************/
1093 static BOOL
ldapsam_setsampwent(struct pdb_methods
*my_methods
, BOOL update
)
1095 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1099 if (!ldapsam_open_connection(ldap_state
, &ldap_state
->ldap_struct
))
1103 if (!ldapsam_connect_system(ldap_state
, ldap_state
->ldap_struct
))
1105 ldap_unbind(ldap_state
->ldap_struct
);
1109 pstrcpy(filter
, lp_ldap_filter());
1110 all_string_sub(filter
, "%u", "*", sizeof(pstring
));
1112 rc
= ldap_search_s(ldap_state
->ldap_struct
, lp_ldap_suffix(),
1113 LDAP_SCOPE_SUBTREE
, filter
, attr
, 0,
1114 &ldap_state
->result
);
1116 if (rc
!= LDAP_SUCCESS
)
1118 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc
)));
1119 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter
));
1120 ldap_msgfree(ldap_state
->result
);
1121 ldap_unbind(ldap_state
->ldap_struct
);
1122 ldap_state
->ldap_struct
= NULL
;
1123 ldap_state
->result
= NULL
;
1127 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
1128 ldap_count_entries(ldap_state
->ldap_struct
,
1129 ldap_state
->result
)));
1131 ldap_state
->entry
= ldap_first_entry(ldap_state
->ldap_struct
,
1132 ldap_state
->result
);
1133 ldap_state
->index
= 0;
1138 /**********************************************************************
1139 End enumeration of the LDAP password list
1140 *********************************************************************/
1141 static void ldapsam_endsampwent(struct pdb_methods
*my_methods
)
1143 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1144 if (ldap_state
->ldap_struct
&& ldap_state
->result
)
1146 ldap_msgfree(ldap_state
->result
);
1147 ldap_unbind(ldap_state
->ldap_struct
);
1148 ldap_state
->ldap_struct
= NULL
;
1149 ldap_state
->result
= NULL
;
1153 /**********************************************************************
1154 Get the next entry in the LDAP password database
1155 *********************************************************************/
1156 static BOOL
ldapsam_getsampwent(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* user
)
1158 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1162 if (!ldap_state
->entry
)
1165 ldap_state
->index
++;
1166 ret
= init_sam_from_ldap(ldap_state
, user
, ldap_state
->ldap_struct
,
1169 ldap_state
->entry
= ldap_next_entry(ldap_state
->ldap_struct
,
1177 /**********************************************************************
1178 Get SAM_ACCOUNT entry from LDAP by username
1179 *********************************************************************/
1180 static BOOL
ldapsam_getsampwnam(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* user
, const char *sname
)
1182 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1184 LDAPMessage
*result
;
1187 if (!ldapsam_open_connection(ldap_state
, &ldap_struct
))
1189 if (!ldapsam_connect_system(ldap_state
, ldap_struct
))
1191 ldap_unbind(ldap_struct
);
1194 if (ldapsam_search_one_user_by_name(ldap_state
, ldap_struct
, sname
, &result
) != LDAP_SUCCESS
)
1196 ldap_unbind(ldap_struct
);
1199 if (ldap_count_entries(ldap_struct
, result
) < 1)
1202 ("We don't find this user [%s] count=%d\n", sname
,
1203 ldap_count_entries(ldap_struct
, result
)));
1204 ldap_unbind(ldap_struct
);
1207 entry
= ldap_first_entry(ldap_struct
, result
);
1210 if (!init_sam_from_ldap(ldap_state
, user
, ldap_struct
, entry
)) {
1211 DEBUG(0,("ldapsam_getsampwnam: init_sam_from_ldap failed!\n"));
1212 ldap_msgfree(result
);
1213 ldap_unbind(ldap_struct
);
1216 ldap_msgfree(result
);
1217 ldap_unbind(ldap_struct
);
1222 ldap_msgfree(result
);
1223 ldap_unbind(ldap_struct
);
1228 /**********************************************************************
1229 Get SAM_ACCOUNT entry from LDAP by rid
1230 *********************************************************************/
1231 static BOOL
ldapsam_getsampwrid(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* user
, uint32 rid
)
1233 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1235 LDAPMessage
*result
;
1238 if (!ldapsam_open_connection(ldap_state
, &ldap_struct
))
1241 if (!ldapsam_connect_system(ldap_state
, ldap_struct
))
1243 ldap_unbind(ldap_struct
);
1246 if (ldapsam_search_one_user_by_rid(ldap_state
, ldap_struct
, rid
, &result
) !=
1249 ldap_unbind(ldap_struct
);
1253 if (ldap_count_entries(ldap_struct
, result
) < 1)
1256 ("We don't find this rid [%i] count=%d\n", rid
,
1257 ldap_count_entries(ldap_struct
, result
)));
1258 ldap_unbind(ldap_struct
);
1262 entry
= ldap_first_entry(ldap_struct
, result
);
1265 if (!init_sam_from_ldap(ldap_state
, user
, ldap_struct
, entry
)) {
1266 DEBUG(0,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
1267 ldap_msgfree(result
);
1268 ldap_unbind(ldap_struct
);
1271 ldap_msgfree(result
);
1272 ldap_unbind(ldap_struct
);
1277 ldap_msgfree(result
);
1278 ldap_unbind(ldap_struct
);
1283 static BOOL
ldapsam_getsampwsid(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* user
, DOM_SID
*sid
)
1286 if (!sid_peek_check_rid(get_global_sam_sid(), sid
, &rid
))
1288 return ldapsam_getsampwrid(my_methods
, user
, rid
);
1291 /**********************************************************************
1292 Delete entry from LDAP for username
1293 *********************************************************************/
1294 static BOOL
ldapsam_delete_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* sam_acct
)
1296 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1302 LDAPMessage
*result
;
1305 DEBUG(0, ("sam_acct was NULL!\n"));
1309 sname
= pdb_get_username(sam_acct
);
1311 if (!ldapsam_open_connection(ldap_state
, &ldap_struct
))
1314 DEBUG (3, ("Deleting user %s from LDAP.\n", sname
));
1316 if (!ldapsam_connect_system(ldap_state
, ldap_struct
)) {
1317 ldap_unbind (ldap_struct
);
1318 DEBUG(0, ("Failed to delete user %s from LDAP.\n", sname
));
1322 rc
= ldapsam_search_one_user_by_name(ldap_state
, ldap_struct
, sname
, &result
);
1323 if (ldap_count_entries (ldap_struct
, result
) == 0) {
1324 DEBUG (0, ("User doesn't exit!\n"));
1325 ldap_msgfree (result
);
1326 ldap_unbind (ldap_struct
);
1330 entry
= ldap_first_entry (ldap_struct
, result
);
1331 dn
= ldap_get_dn (ldap_struct
, entry
);
1333 rc
= ldap_delete_s (ldap_struct
, dn
);
1336 if (rc
!= LDAP_SUCCESS
) {
1338 ldap_get_option (ldap_struct
, LDAP_OPT_ERROR_STRING
, &ld_error
);
1339 DEBUG (0,("failed to delete user with uid = %s with: %s\n\t%s\n",
1340 sname
, ldap_err2string (rc
), ld_error
));
1342 ldap_unbind (ldap_struct
);
1346 DEBUG (2,("successfully deleted uid = %s from the LDAP database\n", sname
));
1347 ldap_unbind (ldap_struct
);
1351 /**********************************************************************
1353 *********************************************************************/
1354 static BOOL
ldapsam_update_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* newpwd
)
1356 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1360 LDAPMessage
*result
;
1364 if (!ldapsam_open_connection(ldap_state
, &ldap_struct
)) /* open a connection to the server */
1367 if (!ldapsam_connect_system(ldap_state
, ldap_struct
)) /* connect as system account */
1369 ldap_unbind(ldap_struct
);
1373 rc
= ldapsam_search_one_user_by_name(ldap_state
, ldap_struct
,
1374 pdb_get_username(newpwd
), &result
);
1376 if (ldap_count_entries(ldap_struct
, result
) == 0)
1378 DEBUG(0, ("No user to modify!\n"));
1379 ldap_msgfree(result
);
1380 ldap_unbind(ldap_struct
);
1384 if (!init_ldap_from_sam(ldap_state
, &mods
, LDAP_MOD_REPLACE
, newpwd
)) {
1385 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1386 ldap_msgfree(result
);
1387 ldap_unbind(ldap_struct
);
1391 entry
= ldap_first_entry(ldap_struct
, result
);
1392 dn
= ldap_get_dn(ldap_struct
, entry
);
1394 rc
= ldap_modify_s(ldap_struct
, dn
, mods
);
1396 if (rc
!= 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
),
1406 ldap_unbind(ldap_struct
);
1411 ("successfully modified uid = %s in the LDAP database\n",
1412 pdb_get_username(newpwd
)));
1413 ldap_mods_free(mods
, 1);
1414 ldap_unbind(ldap_struct
);
1418 /**********************************************************************
1419 Add SAM_ACCOUNT to LDAP
1420 *********************************************************************/
1421 static BOOL
ldapsam_add_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* newpwd
)
1423 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1426 LDAP
*ldap_struct
= NULL
;
1427 LDAPMessage
*result
= NULL
;
1429 LDAPMod
**mods
= NULL
;
1433 const char *username
= pdb_get_username(newpwd
);
1434 if (!username
|| !*username
) {
1435 DEBUG(0, ("Cannot add user without a username!\n"));
1439 if (!ldapsam_open_connection(ldap_state
, &ldap_struct
)) /* open a connection to the server */
1444 if (!ldapsam_connect_system(ldap_state
, ldap_struct
)) /* connect as system account */
1446 ldap_unbind(ldap_struct
);
1450 rc
= ldapsam_search_one_user_by_name (ldap_state
, ldap_struct
, username
, &result
);
1452 if (ldap_count_entries(ldap_struct
, result
) != 0)
1454 DEBUG(0,("User already in the base, with samba properties\n"));
1455 ldap_msgfree(result
);
1456 ldap_unbind(ldap_struct
);
1459 ldap_msgfree(result
);
1461 slprintf (filter
, sizeof (filter
) - 1, "uid=%s", username
);
1462 rc
= ldapsam_search_one_user(ldap_state
, ldap_struct
, filter
, &result
);
1463 num_result
= ldap_count_entries(ldap_struct
, result
);
1465 if (num_result
> 1) {
1466 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
1467 ldap_msgfree(result
);
1471 /* Check if we need to update an existing entry */
1472 if (num_result
== 1) {
1476 DEBUG(3,("User exists without samba properties: adding them\n"));
1477 ldap_op
= LDAP_MOD_REPLACE
;
1478 entry
= ldap_first_entry (ldap_struct
, result
);
1479 tmp
= ldap_get_dn (ldap_struct
, entry
);
1480 slprintf (dn
, sizeof (dn
) - 1, "%s", tmp
);
1484 /* Check if we need to add an entry */
1485 DEBUG(3,("Adding new user\n"));
1486 ldap_op
= LDAP_MOD_ADD
;
1487 if (username
[strlen(username
)-1] == '$') {
1488 slprintf (dn
, sizeof (dn
) - 1, "uid=%s,%s", username
, lp_ldap_machine_suffix ());
1490 slprintf (dn
, sizeof (dn
) - 1, "uid=%s,%s", username
, lp_ldap_user_suffix ());
1494 ldap_msgfree(result
);
1496 if (!init_ldap_from_sam(ldap_state
, &mods
, ldap_op
, newpwd
)) {
1497 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
1498 ldap_mods_free(mods
, 1);
1499 ldap_unbind(ldap_struct
);
1502 make_a_mod(&mods
, LDAP_MOD_ADD
, "objectclass", "sambaAccount");
1504 if (ldap_op
== LDAP_MOD_REPLACE
) {
1505 rc
= ldap_modify_s(ldap_struct
, dn
, mods
);
1508 rc
= ldap_add_s(ldap_struct
, dn
, mods
);
1511 if (rc
!= LDAP_SUCCESS
)
1515 ldap_get_option (ldap_struct
, LDAP_OPT_ERROR_STRING
, &ld_error
);
1516 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s) with: %s\n\t%s\n",
1517 pdb_get_username(newpwd
), dn
, ldap_err2string (rc
), ld_error
));
1519 ldap_mods_free(mods
, 1);
1520 ldap_unbind(ldap_struct
);
1524 DEBUG(2,("added: uid = %s in the LDAP database\n", pdb_get_username(newpwd
)));
1525 ldap_mods_free(mods
, 1);
1526 ldap_unbind(ldap_struct
);
1530 static void free_private_data(void **vp
)
1532 struct ldapsam_privates
**ldap_state
= (struct ldapsam_privates
**)vp
;
1534 if ((*ldap_state
)->ldap_struct
) {
1535 ldap_unbind((*ldap_state
)->ldap_struct
);
1540 /* No need to free any further, as it is talloc()ed */
1543 NTSTATUS
pdb_init_ldapsam(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
1546 struct ldapsam_privates
*ldap_state
;
1548 if (!NT_STATUS_IS_OK(nt_status
= make_pdb_methods(pdb_context
->mem_ctx
, pdb_method
))) {
1552 (*pdb_method
)->name
= "ldapsam";
1554 (*pdb_method
)->setsampwent
= ldapsam_setsampwent
;
1555 (*pdb_method
)->endsampwent
= ldapsam_endsampwent
;
1556 (*pdb_method
)->getsampwent
= ldapsam_getsampwent
;
1557 (*pdb_method
)->getsampwnam
= ldapsam_getsampwnam
;
1558 (*pdb_method
)->getsampwsid
= ldapsam_getsampwsid
;
1559 (*pdb_method
)->add_sam_account
= ldapsam_add_sam_account
;
1560 (*pdb_method
)->update_sam_account
= ldapsam_update_sam_account
;
1561 (*pdb_method
)->delete_sam_account
= ldapsam_delete_sam_account
;
1563 /* TODO: Setup private data and free */
1565 ldap_state
= talloc_zero(pdb_context
->mem_ctx
, sizeof(struct ldapsam_privates
));
1568 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
1569 return NT_STATUS_NO_MEMORY
;
1573 ldap_state
->uri
= talloc_strdup(pdb_context
->mem_ctx
, location
);
1575 ldap_state
->uri
= "ldap://localhost";
1578 (*pdb_method
)->private_data
= ldap_state
;
1580 (*pdb_method
)->free_private_data
= free_private_data
;
1582 return NT_STATUS_OK
;
1585 NTSTATUS
pdb_init_ldapsam_nua(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
1588 struct ldapsam_privates
*ldap_state
;
1589 uint32 low_nua_uid
, high_nua_uid
;
1591 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_ldapsam(pdb_context
, pdb_method
, location
))) {
1595 (*pdb_method
)->name
= "ldapsam_nua";
1597 ldap_state
= (*pdb_method
)->private_data
;
1599 ldap_state
->permit_non_unix_accounts
= True
;
1601 if (!lp_non_unix_account_range(&low_nua_uid
, &high_nua_uid
)) {
1602 DEBUG(0, ("cannot use ldapsam_nua without 'non unix account range' in smb.conf!\n"));
1603 return NT_STATUS_UNSUCCESSFUL
;
1606 ldap_state
->low_nua_rid
=fallback_pdb_uid_to_user_rid(low_nua_uid
);
1608 ldap_state
->high_nua_rid
=fallback_pdb_uid_to_user_rid(high_nua_uid
);
1610 return NT_STATUS_OK
;
1616 NTSTATUS
pdb_init_ldapsam(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
1618 DEBUG(0, ("ldap not detected at configure time, ldapsam not availalble!\n"));
1619 return NT_STATUS_UNSUCCESSFUL
;
1622 NTSTATUS
pdb_init_ldapsam_nua(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
1624 DEBUG(0, ("ldap not dectected at configure time, ldapsam_nua not available!\n"));
1625 return NT_STATUS_UNSUCCESSFUL
;