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-2003
8 Copyright (C) Stefan (metze) Metzmacher 2002-2003
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
55 * Work around versions of the LDAP client libs that don't have the OIDs
56 * defined, or have them defined under the old name.
57 * This functionality is really a factor of the server, not the client
61 #if defined(LDAP_EXOP_X_MODIFY_PASSWD) && !defined(LDAP_EXOP_MODIFY_PASSWD)
62 #define LDAP_EXOP_MODIFY_PASSWD LDAP_EXOP_X_MODIFY_PASSWD
63 #elif !defined(LDAP_EXOP_MODIFY_PASSWD)
64 #define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1"
67 #if defined(LDAP_EXOP_X_MODIFY_PASSWD_ID) && !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
68 #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID LDAP_EXOP_X_MODIFY_PASSWD_ID
69 #elif !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
70 #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U)
73 #if defined(LDAP_EXOP_X_MODIFY_PASSWD_NEW) && !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
74 #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW LDAP_EXOP_X_MODIFY_PASSWD_NEW
75 #elif !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
76 #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U)
81 #define SAM_ACCOUNT struct sam_passwd
86 struct ldapsam_privates
{
87 struct smbldap_state
*smbldap_state
;
94 const char *domain_name
;
97 /* configuration items */
101 /**********************************************************************
102 Free a LDAPMessage (one is stored on the SAM_ACCOUNT).
103 **********************************************************************/
105 static void private_data_free_fn(void **result
)
107 ldap_msgfree(*result
);
111 /**********************************************************************
112 Get the attribute name given a user schame version.
113 **********************************************************************/
115 static const char* get_userattr_key2string( int schema_ver
, int key
)
117 switch ( schema_ver
) {
118 case SCHEMAVER_SAMBAACCOUNT
:
119 return get_attr_key2string( attrib_map_v22
, key
);
121 case SCHEMAVER_SAMBASAMACCOUNT
:
122 return get_attr_key2string( attrib_map_v30
, key
);
125 DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
131 /**********************************************************************
132 Return the list of attribute names given a user schema version.
133 **********************************************************************/
135 static char** get_userattr_list( int schema_ver
)
137 switch ( schema_ver
) {
138 case SCHEMAVER_SAMBAACCOUNT
:
139 return get_attr_list( attrib_map_v22
);
141 case SCHEMAVER_SAMBASAMACCOUNT
:
142 return get_attr_list( attrib_map_v30
);
144 DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
151 /**************************************************************************
152 Return the list of attribute names to delete given a user schema version.
153 **************************************************************************/
155 static char** get_userattr_delete_list( int schema_ver
)
157 switch ( schema_ver
) {
158 case SCHEMAVER_SAMBAACCOUNT
:
159 return get_attr_list( attrib_map_to_delete_v22
);
161 case SCHEMAVER_SAMBASAMACCOUNT
:
162 return get_attr_list( attrib_map_to_delete_v30
);
164 DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n"));
172 /*******************************************************************
173 Generate the LDAP search filter for the objectclass based on the
174 version of the schema we are using.
175 ******************************************************************/
177 static const char* get_objclass_filter( int schema_ver
)
179 static fstring objclass_filter
;
181 switch( schema_ver
) {
182 case SCHEMAVER_SAMBAACCOUNT
:
183 fstr_sprintf( objclass_filter
, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT
);
185 case SCHEMAVER_SAMBASAMACCOUNT
:
186 fstr_sprintf( objclass_filter
, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT
);
189 DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));
193 return objclass_filter
;
196 /*******************************************************************
197 Run the search by name.
198 ******************************************************************/
200 static int ldapsam_search_suffix_by_name (struct ldapsam_privates
*ldap_state
,
202 LDAPMessage
** result
, char **attr
)
205 char *escape_user
= escape_ldap_string_alloc(user
);
208 return LDAP_NO_MEMORY
;
212 * in the filter expression, replace %u with the real name
213 * so in ldap filter, %u MUST exist :-)
215 pstr_sprintf(filter
, "(&%s%s)", lp_ldap_filter(),
216 get_objclass_filter(ldap_state
->schema_ver
));
219 * have to use this here because $ is filtered out
224 all_string_sub(filter
, "%u", escape_user
, sizeof(pstring
));
225 SAFE_FREE(escape_user
);
227 return smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, attr
, result
);
230 /*******************************************************************
231 Run the search by rid.
232 ******************************************************************/
234 static int ldapsam_search_suffix_by_rid (struct ldapsam_privates
*ldap_state
,
235 uint32 rid
, LDAPMessage
** result
,
241 pstr_sprintf(filter
, "(&(rid=%i)%s)", rid
,
242 get_objclass_filter(ldap_state
->schema_ver
));
244 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, attr
, result
);
249 /*******************************************************************
250 Run the search by SID.
251 ******************************************************************/
253 static int ldapsam_search_suffix_by_sid (struct ldapsam_privates
*ldap_state
,
254 const DOM_SID
*sid
, LDAPMessage
** result
,
261 pstr_sprintf(filter
, "(&(%s=%s)%s)",
262 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
263 sid_to_string(sid_string
, sid
),
264 get_objclass_filter(ldap_state
->schema_ver
));
266 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, attr
, result
);
271 /*******************************************************************
272 Delete complete object or objectclass and attrs from
273 object found in search_result depending on lp_ldap_delete_dn
274 ******************************************************************/
276 static NTSTATUS
ldapsam_delete_entry(struct ldapsam_privates
*ldap_state
,
278 const char *objectclass
,
282 LDAPMessage
*entry
= NULL
;
283 LDAPMod
**mods
= NULL
;
285 BerElement
*ptr
= NULL
;
287 rc
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
290 DEBUG(0, ("ldapsam_delete_entry: Entry must exist exactly once!\n"));
291 return NT_STATUS_UNSUCCESSFUL
;
294 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
295 dn
= smbldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
297 return NT_STATUS_UNSUCCESSFUL
;
300 if (lp_ldap_delete_dn()) {
301 NTSTATUS ret
= NT_STATUS_OK
;
302 rc
= smbldap_delete(ldap_state
->smbldap_state
, dn
);
304 if (rc
!= LDAP_SUCCESS
) {
305 DEBUG(0, ("ldapsam_delete_entry: Could not delete object %s\n", dn
));
306 ret
= NT_STATUS_UNSUCCESSFUL
;
312 /* Ok, delete only the SAM attributes */
314 for (name
= ldap_first_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
, &ptr
);
316 name
= ldap_next_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
, ptr
)) {
319 /* We are only allowed to delete the attributes that
322 for (attrib
= attrs
; *attrib
!= NULL
; attrib
++) {
323 /* Don't delete LDAP_ATTR_MOD_TIMESTAMP attribute. */
324 if (strequal(*attrib
, get_userattr_key2string(ldap_state
->schema_ver
,
325 LDAP_ATTR_MOD_TIMESTAMP
))) {
328 if (strequal(*attrib
, name
)) {
329 DEBUG(10, ("ldapsam_delete_entry: deleting "
330 "attribute %s\n", name
));
331 smbldap_set_mod(&mods
, LDAP_MOD_DELETE
, name
,
343 smbldap_set_mod(&mods
, LDAP_MOD_DELETE
, "objectClass", objectclass
);
345 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
346 ldap_mods_free(mods
, True
);
348 if (rc
!= LDAP_SUCCESS
) {
349 char *ld_error
= NULL
;
350 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
353 DEBUG(0, ("ldapsam_delete_entry: Could not delete attributes for %s, error: %s (%s)\n",
354 dn
, ldap_err2string(rc
), ld_error
?ld_error
:"unknown"));
357 return NT_STATUS_UNSUCCESSFUL
;
364 /* New Interface is being implemented here */
366 #if 0 /* JERRY - not uesed anymore */
368 /**********************************************************************
369 Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
370 *********************************************************************/
371 static BOOL
get_unix_attributes (struct ldapsam_privates
*ldap_state
,
372 SAM_ACCOUNT
* sampass
,
381 if ((ldap_values
= ldap_get_values (ldap_state
->smbldap_state
->ldap_struct
, entry
, "objectClass")) == NULL
) {
382 DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
386 for (values
=ldap_values
;*values
;values
++) {
387 if (strequal(*values
, LDAP_OBJ_POSIXACCOUNT
)) {
392 if (!*values
) { /*end of array, no posixAccount */
393 DEBUG(10, ("user does not have %s attributes\n", LDAP_OBJ_POSIXACCOUNT
));
394 ldap_value_free(ldap_values
);
397 ldap_value_free(ldap_values
);
399 if ( !smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
400 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_UNIX_HOME
), homedir
) )
405 if ( !smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
406 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_GIDNUMBER
), temp
) )
411 *gid
= (gid_t
)atol(temp
);
413 pdb_set_unix_homedir(sampass
, homedir
, PDB_SET
);
415 DEBUG(10, ("user has %s attributes\n", LDAP_OBJ_POSIXACCOUNT
));
422 static time_t ldapsam_get_entry_timestamp(
423 struct ldapsam_privates
*ldap_state
,
429 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
430 get_userattr_key2string(ldap_state
->schema_ver
,LDAP_ATTR_MOD_TIMESTAMP
),
434 strptime(temp
, "%Y%m%d%H%M%SZ", &tm
);
439 /**********************************************************************
440 Initialize SAM_ACCOUNT from an LDAP query.
441 (Based on init_sam_from_buffer in pdb_tdb.c)
442 *********************************************************************/
444 static BOOL
init_sam_from_ldap (struct ldapsam_privates
*ldap_state
,
445 SAM_ACCOUNT
* sampass
,
452 pass_can_change_time
,
453 pass_must_change_time
,
466 char munged_dial
[2048];
468 uint8 smblmpwd
[LM_HASH_LEN
],
469 smbntpwd
[NT_HASH_LEN
];
470 uint16 acct_ctrl
= 0,
472 uint16 bad_password_count
= 0,
475 uint8 hours
[MAX_HOURS_LEN
];
477 LOGIN_CACHE
*cache_entry
= NULL
;
481 * do a little initialization
485 nt_username
[0] = '\0';
489 logon_script
[0] = '\0';
490 profile_path
[0] = '\0';
492 munged_dial
[0] = '\0';
493 workstations
[0] = '\0';
496 if (sampass
== NULL
|| ldap_state
== NULL
|| entry
== NULL
) {
497 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
501 if (ldap_state
->smbldap_state
->ldap_struct
== NULL
) {
502 DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->ldap_struct is NULL!\n"));
506 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
, "uid", username
)) {
507 DEBUG(1, ("init_sam_from_ldap: No uid attribute found for this user!\n"));
511 DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username
));
513 pstrcpy(nt_username
, username
);
515 pstrcpy(domain
, ldap_state
->domain_name
);
517 pdb_set_username(sampass
, username
, PDB_SET
);
519 pdb_set_domain(sampass
, domain
, PDB_DEFAULT
);
520 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
522 /* deal with different attributes between the schema first */
524 if ( ldap_state
->schema_ver
== SCHEMAVER_SAMBASAMACCOUNT
) {
525 if (smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
526 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
), temp
)) {
527 pdb_set_user_sid_from_string(sampass
, temp
, PDB_SET
);
530 if (smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
531 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PRIMARY_GROUP_SID
), temp
)) {
532 pdb_set_group_sid_from_string(sampass
, temp
, PDB_SET
);
534 pdb_set_group_sid_from_rid(sampass
, DOMAIN_GROUP_RID_USERS
, PDB_DEFAULT
);
537 if (smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
538 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_RID
), temp
)) {
539 user_rid
= (uint32
)atol(temp
);
540 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
543 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
544 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PRIMARY_GROUP_RID
), temp
)) {
545 pdb_set_group_sid_from_rid(sampass
, DOMAIN_GROUP_RID_USERS
, PDB_DEFAULT
);
549 group_rid
= (uint32
)atol(temp
);
551 /* for some reason, we often have 0 as a primary group RID.
552 Make sure that we treat this just as a 'default' value */
555 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
557 pdb_set_group_sid_from_rid(sampass
, DOMAIN_GROUP_RID_USERS
, PDB_DEFAULT
);
561 if (pdb_get_init_flags(sampass
,PDB_USERSID
) == PDB_DEFAULT
) {
562 DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n",
563 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
564 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_RID
),
569 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
570 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_LAST_SET
), temp
)) {
571 /* leave as default */
573 pass_last_set_time
= (time_t) atol(temp
);
574 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
577 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
578 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_TIME
), temp
)) {
579 /* leave as default */
581 logon_time
= (time_t) atol(temp
);
582 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
585 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
586 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGOFF_TIME
), temp
)) {
587 /* leave as default */
589 logoff_time
= (time_t) atol(temp
);
590 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
593 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
594 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_KICKOFF_TIME
), temp
)) {
595 /* leave as default */
597 kickoff_time
= (time_t) atol(temp
);
598 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
601 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
602 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_CAN_CHANGE
), temp
)) {
603 /* leave as default */
605 pass_can_change_time
= (time_t) atol(temp
);
606 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
609 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
610 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_MUST_CHANGE
), temp
)) {
611 /* leave as default */
613 pass_must_change_time
= (time_t) atol(temp
);
614 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
617 /* recommend that 'gecos' and 'displayName' should refer to the same
618 * attribute OID. userFullName depreciated, only used by Samba
619 * primary rules of LDAP: don't make a new attribute when one is already defined
620 * that fits your needs; using cn then displayName rather than 'userFullName'
623 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
624 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DISPLAY_NAME
), fullname
)) {
625 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
626 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_CN
), fullname
)) {
627 /* leave as default */
629 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
632 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
635 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
636 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_DRIVE
), dir_drive
))
638 pdb_set_dir_drive( sampass
,
639 talloc_sub_basic(sampass
->mem_ctx
, username
, lp_logon_drive()),
642 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
645 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
646 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_PATH
), homedir
))
648 pdb_set_homedir( sampass
,
649 talloc_sub_basic(sampass
->mem_ctx
, username
, lp_logon_home()),
652 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
655 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
656 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_SCRIPT
), logon_script
))
658 pdb_set_logon_script( sampass
,
659 talloc_sub_basic(sampass
->mem_ctx
, username
, lp_logon_script()),
662 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
665 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
666 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PROFILE_PATH
), profile_path
))
668 pdb_set_profile_path( sampass
,
669 talloc_sub_basic( sampass
->mem_ctx
, username
, lp_logon_path()),
672 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
675 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
676 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DESC
), acct_desc
))
678 /* leave as default */
680 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
683 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
684 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_WKS
), workstations
)) {
685 /* leave as default */;
687 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
690 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
691 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_MUNGED_DIAL
), munged_dial
, sizeof(munged_dial
))) {
692 /* leave as default */;
694 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
697 /* FIXME: hours stuff should be cleaner */
701 memset(hours
, 0xff, hours_len
);
703 if (!smbldap_get_single_pstring (ldap_state
->smbldap_state
->ldap_struct
, entry
,
704 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LMPW
), temp
)) {
705 /* leave as default */
707 pdb_gethexpwd(temp
, smblmpwd
);
708 memset((char *)temp
, '\0', strlen(temp
)+1);
709 if (!pdb_set_lanman_passwd(sampass
, smblmpwd
, PDB_SET
))
711 ZERO_STRUCT(smblmpwd
);
714 if (!smbldap_get_single_pstring (ldap_state
->smbldap_state
->ldap_struct
, entry
,
715 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_NTPW
), temp
)) {
716 /* leave as default */
718 pdb_gethexpwd(temp
, smbntpwd
);
719 memset((char *)temp
, '\0', strlen(temp
)+1);
720 if (!pdb_set_nt_passwd(sampass
, smbntpwd
, PDB_SET
))
722 ZERO_STRUCT(smbntpwd
);
725 account_policy_get(AP_PASSWORD_HISTORY
, &pwHistLen
);
727 uint8
*pwhist
= NULL
;
730 /* We can only store (sizeof(pstring)-1)/64 password history entries. */
731 pwHistLen
= MIN(pwHistLen
, ((sizeof(temp
)-1)/64));
733 if ((pwhist
= SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
)) == NULL
){
734 DEBUG(0, ("init_sam_from_ldap: malloc failed!\n"));
737 memset(pwhist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
739 if (!smbldap_get_single_pstring (ldap_state
->smbldap_state
->ldap_struct
, entry
,
740 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_HISTORY
), temp
)) {
741 /* leave as default - zeros */
743 BOOL hex_failed
= False
;
744 for (i
= 0; i
< pwHistLen
; i
++){
745 /* Get the 16 byte salt. */
746 if (!pdb_gethexpwd(&temp
[i
*64], &pwhist
[i
*PW_HISTORY_ENTRY_LEN
])) {
750 /* Get the 16 byte MD5 hash of salt+passwd. */
751 if (!pdb_gethexpwd(&temp
[(i
*64)+32],
752 &pwhist
[(i
*PW_HISTORY_ENTRY_LEN
)+PW_HISTORY_SALT_LEN
])) {
758 DEBUG(0,("init_sam_from_ldap: Failed to get password history for user %s\n",
760 memset(pwhist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
763 if (!pdb_set_pw_history(sampass
, pwhist
, pwHistLen
, PDB_SET
)){
770 if (!smbldap_get_single_pstring (ldap_state
->smbldap_state
->ldap_struct
, entry
,
771 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_ACB_INFO
), temp
)) {
772 acct_ctrl
|= ACB_NORMAL
;
774 acct_ctrl
= pdb_decode_acct_ctrl(temp
);
777 acct_ctrl
|= ACB_NORMAL
;
779 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
782 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
783 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
785 /* pdb_set_munged_dial(sampass, munged_dial, PDB_SET); */
787 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
788 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_BAD_PASSWORD_COUNT
), temp
)) {
789 /* leave as default */
791 bad_password_count
= (uint32
) atol(temp
);
792 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
795 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
796 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_BAD_PASSWORD_TIME
), temp
)) {
797 /* leave as default */
799 bad_password_time
= (time_t) atol(temp
);
800 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
804 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
805 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_COUNT
), temp
)) {
806 /* leave as default */
808 logon_count
= (uint32
) atol(temp
);
809 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
812 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
814 if(!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
815 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_HOURS
), temp
)) {
816 /* leave as default */
818 pdb_gethexhours(temp
, hours
);
819 memset((char *)temp
, '\0', strlen(temp
) +1);
820 pdb_set_hours(sampass
, hours
, PDB_SET
);
824 /* check the timestamp of the cache vs ldap entry */
825 if (!(ldap_entry_time
= ldapsam_get_entry_timestamp(ldap_state
,
829 /* see if we have newer updates */
830 if (!(cache_entry
= login_cache_read(sampass
))) {
831 DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n",
832 (unsigned int)pdb_get_bad_password_count(sampass
),
833 (unsigned int)pdb_get_bad_password_time(sampass
)));
837 DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n",
838 (unsigned int)ldap_entry_time
, (unsigned int)cache_entry
->entry_timestamp
,
839 (unsigned int)cache_entry
->bad_password_time
));
841 if (ldap_entry_time
> cache_entry
->entry_timestamp
) {
842 /* cache is older than directory , so
843 we need to delete the entry but allow the
844 fields to be written out */
845 login_cache_delentry(sampass
);
848 pdb_set_acct_ctrl(sampass
,
849 pdb_get_acct_ctrl(sampass
) |
850 (cache_entry
->acct_ctrl
& ACB_AUTOLOCK
),
852 pdb_set_bad_password_count(sampass
,
853 cache_entry
->bad_password_count
,
855 pdb_set_bad_password_time(sampass
,
856 cache_entry
->bad_password_time
,
860 SAFE_FREE(cache_entry
);
864 /**********************************************************************
865 Initialize the ldap db from a SAM_ACCOUNT. Called on update.
866 (Based on init_buffer_from_sam in pdb_tdb.c)
867 *********************************************************************/
869 static BOOL
init_ldap_from_sam (struct ldapsam_privates
*ldap_state
,
870 LDAPMessage
*existing
,
871 LDAPMod
*** mods
, SAM_ACCOUNT
* sampass
,
872 BOOL (*need_update
)(const SAM_ACCOUNT
*,
878 if (mods
== NULL
|| sampass
== NULL
) {
879 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
886 * took out adding "objectclass: sambaAccount"
887 * do this on a per-mod basis
889 if (need_update(sampass
, PDB_USERNAME
))
890 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
891 "uid", pdb_get_username(sampass
));
893 DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass
)));
895 /* only update the RID if we actually need to */
896 if (need_update(sampass
, PDB_USERSID
)) {
898 fstring dom_sid_string
;
899 const DOM_SID
*user_sid
= pdb_get_user_sid(sampass
);
901 switch ( ldap_state
->schema_ver
) {
902 case SCHEMAVER_SAMBAACCOUNT
:
903 if (!sid_peek_check_rid(&ldap_state
->domain_sid
, user_sid
, &rid
)) {
904 DEBUG(1, ("init_ldap_from_sam: User's SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
905 sid_to_string(sid_string
, user_sid
),
906 sid_to_string(dom_sid_string
, &ldap_state
->domain_sid
)));
909 slprintf(temp
, sizeof(temp
) - 1, "%i", rid
);
910 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
911 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_RID
),
915 case SCHEMAVER_SAMBASAMACCOUNT
:
916 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
917 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
918 sid_to_string(sid_string
, user_sid
));
922 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
927 /* we don't need to store the primary group RID - so leaving it
928 'free' to hang off the unix primary group makes life easier */
930 if (need_update(sampass
, PDB_GROUPSID
)) {
932 fstring dom_sid_string
;
933 const DOM_SID
*group_sid
= pdb_get_group_sid(sampass
);
935 switch ( ldap_state
->schema_ver
) {
936 case SCHEMAVER_SAMBAACCOUNT
:
937 if (!sid_peek_check_rid(&ldap_state
->domain_sid
, group_sid
, &rid
)) {
938 DEBUG(1, ("init_ldap_from_sam: User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
939 sid_to_string(sid_string
, group_sid
),
940 sid_to_string(dom_sid_string
, &ldap_state
->domain_sid
)));
944 slprintf(temp
, sizeof(temp
) - 1, "%i", rid
);
945 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
946 get_userattr_key2string(ldap_state
->schema_ver
,
947 LDAP_ATTR_PRIMARY_GROUP_RID
), temp
);
950 case SCHEMAVER_SAMBASAMACCOUNT
:
951 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
952 get_userattr_key2string(ldap_state
->schema_ver
,
953 LDAP_ATTR_PRIMARY_GROUP_SID
), sid_to_string(sid_string
, group_sid
));
957 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
963 /* displayName, cn, and gecos should all be the same
964 * most easily accomplished by giving them the same OID
965 * gecos isn't set here b/c it should be handled by the
967 * We change displayName only and fall back to cn if
971 if (need_update(sampass
, PDB_FULLNAME
))
972 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
973 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DISPLAY_NAME
),
974 pdb_get_fullname(sampass
));
976 if (need_update(sampass
, PDB_ACCTDESC
))
977 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
978 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DESC
),
979 pdb_get_acct_desc(sampass
));
981 if (need_update(sampass
, PDB_WORKSTATIONS
))
982 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
983 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_WKS
),
984 pdb_get_workstations(sampass
));
986 if (need_update(sampass
, PDB_MUNGEDDIAL
))
987 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
988 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_MUNGED_DIAL
),
989 pdb_get_munged_dial(sampass
));
991 if (need_update(sampass
, PDB_SMBHOME
))
992 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
993 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_PATH
),
994 pdb_get_homedir(sampass
));
996 if (need_update(sampass
, PDB_DRIVE
))
997 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
998 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_DRIVE
),
999 pdb_get_dir_drive(sampass
));
1001 if (need_update(sampass
, PDB_LOGONSCRIPT
))
1002 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1003 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_SCRIPT
),
1004 pdb_get_logon_script(sampass
));
1006 if (need_update(sampass
, PDB_PROFILE
))
1007 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1008 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PROFILE_PATH
),
1009 pdb_get_profile_path(sampass
));
1011 slprintf(temp
, sizeof(temp
) - 1, "%li", pdb_get_logon_time(sampass
));
1012 if (need_update(sampass
, PDB_LOGONTIME
))
1013 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1014 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_TIME
), temp
);
1016 slprintf(temp
, sizeof(temp
) - 1, "%li", pdb_get_logoff_time(sampass
));
1017 if (need_update(sampass
, PDB_LOGOFFTIME
))
1018 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1019 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGOFF_TIME
), temp
);
1021 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_kickoff_time(sampass
));
1022 if (need_update(sampass
, PDB_KICKOFFTIME
))
1023 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1024 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_KICKOFF_TIME
), temp
);
1026 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_can_change_time(sampass
));
1027 if (need_update(sampass
, PDB_CANCHANGETIME
))
1028 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1029 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_CAN_CHANGE
), temp
);
1031 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_must_change_time(sampass
));
1032 if (need_update(sampass
, PDB_MUSTCHANGETIME
))
1033 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1034 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_MUST_CHANGE
), temp
);
1037 if ((pdb_get_acct_ctrl(sampass
)&(ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
))
1038 || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY
)) {
1040 if (need_update(sampass
, PDB_LMPASSWD
)) {
1041 const uchar
*lm_pw
= pdb_get_lanman_passwd(sampass
);
1043 pdb_sethexpwd(temp
, lm_pw
,
1044 pdb_get_acct_ctrl(sampass
));
1045 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1046 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LMPW
),
1049 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1050 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LMPW
),
1054 if (need_update(sampass
, PDB_NTPASSWD
)) {
1055 const uchar
*nt_pw
= pdb_get_nt_passwd(sampass
);
1057 pdb_sethexpwd(temp
, nt_pw
,
1058 pdb_get_acct_ctrl(sampass
));
1059 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1060 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_NTPW
),
1063 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1064 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_NTPW
),
1069 if (need_update(sampass
, PDB_PWHISTORY
)) {
1071 account_policy_get(AP_PASSWORD_HISTORY
, &pwHistLen
);
1072 if (pwHistLen
== 0) {
1073 /* Remove any password history from the LDAP store. */
1074 memset(temp
, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
1077 int i
, currHistLen
= 0;
1078 const uint8
*pwhist
= pdb_get_pw_history(sampass
, &currHistLen
);
1079 if (pwhist
!= NULL
) {
1080 /* We can only store (sizeof(pstring)-1)/64 password history entries. */
1081 pwHistLen
= MIN(pwHistLen
, ((sizeof(temp
)-1)/64));
1082 for (i
=0; i
< pwHistLen
&& i
< currHistLen
; i
++) {
1083 /* Store the salt. */
1084 pdb_sethexpwd(&temp
[i
*64], &pwhist
[i
*PW_HISTORY_ENTRY_LEN
], 0);
1085 /* Followed by the md5 hash of salt + md4 hash */
1086 pdb_sethexpwd(&temp
[(i
*64)+32],
1087 &pwhist
[(i
*PW_HISTORY_ENTRY_LEN
)+PW_HISTORY_SALT_LEN
], 0);
1088 DEBUG(100, ("temp=%s\n", temp
));
1092 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1093 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_HISTORY
),
1097 if (need_update(sampass
, PDB_PASSLASTSET
)) {
1098 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_last_set_time(sampass
));
1099 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1100 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_LAST_SET
),
1105 if (need_update(sampass
, PDB_HOURS
)) {
1106 const char *hours
= pdb_get_hours(sampass
);
1108 pdb_sethexhours(temp
, hours
);
1109 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
,
1112 get_userattr_key2string(ldap_state
->schema_ver
,
1113 LDAP_ATTR_LOGON_HOURS
),
1118 if (need_update(sampass
, PDB_ACCTCTRL
))
1119 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1120 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_ACB_INFO
),
1121 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass
), NEW_PW_FORMAT_SPACE_PADDED_LEN
));
1123 /* password lockout cache:
1124 - If we are now autolocking or clearing, we write to ldap
1125 - If we are clearing, we delete the cache entry
1126 - If the count is > 0, we update the cache
1128 This even means when autolocking, we cache, just in case the
1129 update doesn't work, and we have to cache the autolock flag */
1131 if (need_update(sampass
, PDB_BAD_PASSWORD_COUNT
)) /* &&
1132 need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ {
1133 uint16 badcount
= pdb_get_bad_password_count(sampass
);
1134 time_t badtime
= pdb_get_bad_password_time(sampass
);
1136 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT
, &pol
);
1138 DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
1139 (unsigned int)pol
, (unsigned int)badcount
, (unsigned int)badtime
));
1141 if ((badcount
>= pol
) || (badcount
== 0)) {
1142 DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n",
1143 (unsigned int)badcount
, (unsigned int)badtime
));
1144 slprintf (temp
, sizeof (temp
) - 1, "%li", (long)badcount
);
1146 ldap_state
->smbldap_state
->ldap_struct
,
1148 get_userattr_key2string(
1149 ldap_state
->schema_ver
,
1150 LDAP_ATTR_BAD_PASSWORD_COUNT
),
1153 slprintf (temp
, sizeof (temp
) - 1, "%li", badtime
);
1155 ldap_state
->smbldap_state
->ldap_struct
,
1157 get_userattr_key2string(
1158 ldap_state
->schema_ver
,
1159 LDAP_ATTR_BAD_PASSWORD_TIME
),
1162 if (badcount
== 0) {
1163 DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass
)));
1164 login_cache_delentry(sampass
);
1166 LOGIN_CACHE cache_entry
;
1168 cache_entry
.entry_timestamp
= time(NULL
);
1169 cache_entry
.acct_ctrl
= pdb_get_acct_ctrl(sampass
);
1170 cache_entry
.bad_password_count
= badcount
;
1171 cache_entry
.bad_password_time
= badtime
;
1173 DEBUG(7, ("Updating bad password count and time in login cache\n"));
1174 login_cache_write(sampass
, cache_entry
);
1181 /**********************************************************************
1182 Connect to LDAP server for password enumeration.
1183 *********************************************************************/
1185 static NTSTATUS
ldapsam_setsampwent(struct pdb_methods
*my_methods
, BOOL update
)
1187 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1192 pstr_sprintf( filter
, "(&%s%s)", lp_ldap_filter(),
1193 get_objclass_filter(ldap_state
->schema_ver
));
1194 all_string_sub(filter
, "%u", "*", sizeof(pstring
));
1196 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1197 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
,
1198 attr_list
, &ldap_state
->result
);
1199 free_attr_list( attr_list
);
1201 if (rc
!= LDAP_SUCCESS
) {
1202 DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc
)));
1203 DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", lp_ldap_suffix(), filter
));
1204 ldap_msgfree(ldap_state
->result
);
1205 ldap_state
->result
= NULL
;
1206 return NT_STATUS_UNSUCCESSFUL
;
1209 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
1210 ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
,
1211 ldap_state
->result
)));
1213 ldap_state
->entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
,
1214 ldap_state
->result
);
1215 ldap_state
->index
= 0;
1217 return NT_STATUS_OK
;
1220 /**********************************************************************
1221 End enumeration of the LDAP password list.
1222 *********************************************************************/
1224 static void ldapsam_endsampwent(struct pdb_methods
*my_methods
)
1226 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1227 if (ldap_state
->result
) {
1228 ldap_msgfree(ldap_state
->result
);
1229 ldap_state
->result
= NULL
;
1233 /**********************************************************************
1234 Get the next entry in the LDAP password database.
1235 *********************************************************************/
1237 static NTSTATUS
ldapsam_getsampwent(struct pdb_methods
*my_methods
, SAM_ACCOUNT
*user
)
1239 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1240 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1244 if (!ldap_state
->entry
)
1247 ldap_state
->index
++;
1248 bret
= init_sam_from_ldap(ldap_state
, user
, ldap_state
->entry
);
1250 ldap_state
->entry
= ldap_next_entry(ldap_state
->smbldap_state
->ldap_struct
,
1254 return NT_STATUS_OK
;
1257 static void append_attr(char ***attr_list
, const char *new_attr
)
1261 if (new_attr
== NULL
) {
1265 for (i
=0; (*attr_list
)[i
] != NULL
; i
++) {
1269 (*attr_list
) = SMB_REALLOC_ARRAY((*attr_list
), char *, i
+2);
1270 SMB_ASSERT((*attr_list
) != NULL
);
1271 (*attr_list
)[i
] = SMB_STRDUP(new_attr
);
1272 (*attr_list
)[i
+1] = NULL
;
1275 /**********************************************************************
1276 Get SAM_ACCOUNT entry from LDAP by username.
1277 *********************************************************************/
1279 static NTSTATUS
ldapsam_getsampwnam(struct pdb_methods
*my_methods
, SAM_ACCOUNT
*user
, const char *sname
)
1281 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1282 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1283 LDAPMessage
*result
= NULL
;
1284 LDAPMessage
*entry
= NULL
;
1289 attr_list
= get_userattr_list( ldap_state
->schema_ver
);
1290 append_attr(&attr_list
, get_userattr_key2string(ldap_state
->schema_ver
,LDAP_ATTR_MOD_TIMESTAMP
));
1291 rc
= ldapsam_search_suffix_by_name(ldap_state
, sname
, &result
, attr_list
);
1292 free_attr_list( attr_list
);
1294 if ( rc
!= LDAP_SUCCESS
)
1295 return NT_STATUS_NO_SUCH_USER
;
1297 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1300 DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname
, count
));
1301 ldap_msgfree(result
);
1302 return NT_STATUS_NO_SUCH_USER
;
1303 } else if (count
> 1) {
1304 DEBUG(1, ("ldapsam_getsampwnam: Duplicate entries for this user [%s] Failing. count=%d\n", sname
, count
));
1305 ldap_msgfree(result
);
1306 return NT_STATUS_NO_SUCH_USER
;
1309 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1311 if (!init_sam_from_ldap(ldap_state
, user
, entry
)) {
1312 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname
));
1313 ldap_msgfree(result
);
1314 return NT_STATUS_NO_SUCH_USER
;
1316 pdb_set_backend_private_data(user
, result
,
1317 private_data_free_fn
,
1318 my_methods
, PDB_CHANGED
);
1321 ldap_msgfree(result
);
1326 static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates
*ldap_state
,
1327 const DOM_SID
*sid
, LDAPMessage
**result
)
1333 switch ( ldap_state
->schema_ver
) {
1334 case SCHEMAVER_SAMBASAMACCOUNT
:
1335 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1336 append_attr(&attr_list
, get_userattr_key2string(ldap_state
->schema_ver
,LDAP_ATTR_MOD_TIMESTAMP
));
1337 rc
= ldapsam_search_suffix_by_sid(ldap_state
, sid
, result
, attr_list
);
1338 free_attr_list( attr_list
);
1340 if ( rc
!= LDAP_SUCCESS
)
1344 case SCHEMAVER_SAMBAACCOUNT
:
1345 if (!sid_peek_check_rid(&ldap_state
->domain_sid
, sid
, &rid
)) {
1349 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1350 rc
= ldapsam_search_suffix_by_rid(ldap_state
, rid
, result
, attr_list
);
1351 free_attr_list( attr_list
);
1353 if ( rc
!= LDAP_SUCCESS
)
1360 /**********************************************************************
1361 Get SAM_ACCOUNT entry from LDAP by SID.
1362 *********************************************************************/
1364 static NTSTATUS
ldapsam_getsampwsid(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* user
, const DOM_SID
*sid
)
1366 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1367 LDAPMessage
*result
= NULL
;
1368 LDAPMessage
*entry
= NULL
;
1373 rc
= ldapsam_get_ldap_user_by_sid(ldap_state
,
1375 if (rc
!= LDAP_SUCCESS
)
1376 return NT_STATUS_NO_SUCH_USER
;
1378 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1381 DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] count=%d\n", sid_to_string(sid_string
, sid
),
1383 ldap_msgfree(result
);
1384 return NT_STATUS_NO_SUCH_USER
;
1385 } else if (count
> 1) {
1386 DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID [%s]. Failing. count=%d\n", sid_to_string(sid_string
, sid
),
1388 ldap_msgfree(result
);
1389 return NT_STATUS_NO_SUCH_USER
;
1392 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1394 ldap_msgfree(result
);
1395 return NT_STATUS_NO_SUCH_USER
;
1398 if (!init_sam_from_ldap(ldap_state
, user
, entry
)) {
1399 DEBUG(1,("ldapsam_getsampwsid: init_sam_from_ldap failed!\n"));
1400 ldap_msgfree(result
);
1401 return NT_STATUS_NO_SUCH_USER
;
1404 pdb_set_backend_private_data(user
, result
,
1405 private_data_free_fn
,
1406 my_methods
, PDB_CHANGED
);
1407 return NT_STATUS_OK
;
1410 static BOOL
ldapsam_can_pwchange_exop(struct smbldap_state
*ldap_state
)
1412 LDAPMessage
*msg
= NULL
;
1413 LDAPMessage
*entry
= NULL
;
1414 char **values
= NULL
;
1415 char *attrs
[] = { "supportedExtension", NULL
};
1416 int rc
, num_result
, num_values
, i
;
1417 BOOL result
= False
;
1419 rc
= smbldap_search(ldap_state
, "", LDAP_SCOPE_BASE
, "(objectclass=*)",
1422 if (rc
!= LDAP_SUCCESS
) {
1423 DEBUG(3, ("Could not search rootDSE\n"));
1427 num_result
= ldap_count_entries(ldap_state
->ldap_struct
, msg
);
1429 if (num_result
!= 1) {
1430 DEBUG(3, ("Expected one rootDSE, got %d\n", num_result
));
1434 entry
= ldap_first_entry(ldap_state
->ldap_struct
, msg
);
1436 if (entry
== NULL
) {
1437 DEBUG(3, ("Could not retrieve rootDSE\n"));
1441 values
= ldap_get_values(ldap_state
->ldap_struct
, entry
,
1442 "supportedExtension");
1444 if (values
== NULL
) {
1445 DEBUG(9, ("LDAP Server does not support any extensions\n"));
1449 num_values
= ldap_count_values(values
);
1451 if (num_values
== 0) {
1452 DEBUG(9, ("LDAP Server does not support any extensions\n"));
1456 for (i
=0; i
<num_values
; i
++) {
1457 if (strcmp(values
[i
], LDAP_EXOP_MODIFY_PASSWD
) == 0)
1463 ldap_value_free(values
);
1470 /********************************************************************
1471 Do the actual modification - also change a plaintext passord if
1473 **********************************************************************/
1475 static NTSTATUS
ldapsam_modify_entry(struct pdb_methods
*my_methods
,
1476 SAM_ACCOUNT
*newpwd
, char *dn
,
1477 LDAPMod
**mods
, int ldap_op
,
1478 BOOL (*need_update
)(const SAM_ACCOUNT
*, enum pdb_elements
))
1480 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1483 if (!my_methods
|| !newpwd
|| !dn
) {
1484 return NT_STATUS_INVALID_PARAMETER
;
1488 DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
1489 /* may be password change below however */
1493 smbldap_set_mod(&mods
, LDAP_MOD_ADD
,
1496 rc
= smbldap_add(ldap_state
->smbldap_state
,
1499 case LDAP_MOD_REPLACE
:
1500 rc
= smbldap_modify(ldap_state
->smbldap_state
,
1504 DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n",
1506 return NT_STATUS_INVALID_PARAMETER
;
1509 if (rc
!=LDAP_SUCCESS
) {
1510 char *ld_error
= NULL
;
1511 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1513 DEBUG(1, ("ldapsam_modify_entry: Failed to %s user dn= %s with: %s\n\t%s\n",
1514 ldap_op
== LDAP_MOD_ADD
? "add" : "modify",
1515 dn
, ldap_err2string(rc
),
1516 ld_error
?ld_error
:"unknown"));
1517 SAFE_FREE(ld_error
);
1518 return NT_STATUS_UNSUCCESSFUL
;
1522 if (!(pdb_get_acct_ctrl(newpwd
)&(ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
)) &&
1523 (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF
) &&
1524 need_update(newpwd
, PDB_PLAINTEXT_PW
) &&
1525 (pdb_get_plaintext_passwd(newpwd
)!=NULL
)) {
1529 struct berval
*retdata
;
1530 char *utf8_password
;
1533 if (!ldapsam_can_pwchange_exop(ldap_state
->smbldap_state
)) {
1534 DEBUG(2, ("ldap password change requested, but LDAP "
1535 "server does not support it -- ignoring\n"));
1536 return NT_STATUS_OK
;
1539 if (push_utf8_allocate(&utf8_password
, pdb_get_plaintext_passwd(newpwd
)) == (size_t)-1) {
1540 return NT_STATUS_NO_MEMORY
;
1543 if (push_utf8_allocate(&utf8_dn
, dn
) == (size_t)-1) {
1544 return NT_STATUS_NO_MEMORY
;
1547 if ((ber
= ber_alloc_t(LBER_USE_DER
))==NULL
) {
1548 DEBUG(0,("ber_alloc_t returns NULL\n"));
1549 SAFE_FREE(utf8_password
);
1550 return NT_STATUS_UNSUCCESSFUL
;
1553 ber_printf (ber
, "{");
1554 ber_printf (ber
, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID
, utf8_dn
);
1555 ber_printf (ber
, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW
, utf8_password
);
1556 ber_printf (ber
, "N}");
1558 if ((rc
= ber_flatten (ber
, &bv
))<0) {
1559 DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
1562 SAFE_FREE(utf8_password
);
1563 return NT_STATUS_UNSUCCESSFUL
;
1567 SAFE_FREE(utf8_password
);
1570 if ((rc
= smbldap_extended_operation(ldap_state
->smbldap_state
,
1571 LDAP_EXOP_MODIFY_PASSWD
,
1572 bv
, NULL
, NULL
, &retoid
,
1573 &retdata
)) != LDAP_SUCCESS
) {
1574 char *ld_error
= NULL
;
1576 if (rc
== LDAP_OBJECT_CLASS_VIOLATION
) {
1577 DEBUG(3, ("Could not set userPassword "
1578 "attribute due to an objectClass "
1579 "violation -- ignoring\n"));
1581 return NT_STATUS_OK
;
1584 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1586 DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n",
1587 pdb_get_username(newpwd
), ldap_err2string(rc
), ld_error
?ld_error
:"unknown"));
1588 SAFE_FREE(ld_error
);
1590 return NT_STATUS_UNSUCCESSFUL
;
1592 DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd
)));
1593 #ifdef DEBUG_PASSWORD
1594 DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd
)));
1596 ber_bvfree(retdata
);
1597 ber_memfree(retoid
);
1601 return NT_STATUS_OK
;
1604 /**********************************************************************
1605 Delete entry from LDAP for username.
1606 *********************************************************************/
1608 static NTSTATUS
ldapsam_delete_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* sam_acct
)
1610 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1613 LDAPMessage
*result
= NULL
;
1619 DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n"));
1620 return NT_STATUS_INVALID_PARAMETER
;
1623 sname
= pdb_get_username(sam_acct
);
1625 DEBUG (3, ("ldapsam_delete_sam_account: Deleting user %s from LDAP.\n", sname
));
1627 attr_list
= get_userattr_delete_list( ldap_state
->schema_ver
);
1628 rc
= ldapsam_search_suffix_by_name(ldap_state
, sname
, &result
, attr_list
);
1630 if (rc
!= LDAP_SUCCESS
) {
1631 free_attr_list( attr_list
);
1632 return NT_STATUS_NO_SUCH_USER
;
1635 switch ( ldap_state
->schema_ver
) {
1636 case SCHEMAVER_SAMBASAMACCOUNT
:
1637 fstrcpy( objclass
, LDAP_OBJ_SAMBASAMACCOUNT
);
1640 case SCHEMAVER_SAMBAACCOUNT
:
1641 fstrcpy( objclass
, LDAP_OBJ_SAMBAACCOUNT
);
1644 fstrcpy( objclass
, "UNKNOWN" );
1645 DEBUG(0,("ldapsam_delete_sam_account: Unknown schema version specified!\n"));
1649 ret
= ldapsam_delete_entry(ldap_state
, result
, objclass
, attr_list
);
1650 ldap_msgfree(result
);
1651 free_attr_list( attr_list
);
1656 /**********************************************************************
1657 Helper function to determine for update_sam_account whether
1658 we need LDAP modification.
1659 *********************************************************************/
1661 static BOOL
element_is_changed(const SAM_ACCOUNT
*sampass
,
1662 enum pdb_elements element
)
1664 return IS_SAM_CHANGED(sampass
, element
);
1667 /**********************************************************************
1669 *********************************************************************/
1671 static NTSTATUS
ldapsam_update_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* newpwd
)
1673 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1674 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1677 LDAPMessage
*result
= NULL
;
1678 LDAPMessage
*entry
= NULL
;
1679 LDAPMod
**mods
= NULL
;
1682 result
= pdb_get_backend_private_data(newpwd
, my_methods
);
1684 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1685 rc
= ldapsam_search_suffix_by_name(ldap_state
, pdb_get_username(newpwd
), &result
, attr_list
);
1686 free_attr_list( attr_list
);
1687 if (rc
!= LDAP_SUCCESS
) {
1688 return NT_STATUS_UNSUCCESSFUL
;
1690 pdb_set_backend_private_data(newpwd
, result
, private_data_free_fn
, my_methods
, PDB_CHANGED
);
1693 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) == 0) {
1694 DEBUG(0, ("ldapsam_update_sam_account: No user to modify!\n"));
1695 return NT_STATUS_UNSUCCESSFUL
;
1698 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1699 dn
= smbldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
1701 return NT_STATUS_UNSUCCESSFUL
;
1704 DEBUG(4, ("ldapsam_update_sam_account: user %s to be modified has dn: %s\n", pdb_get_username(newpwd
), dn
));
1706 if (!init_ldap_from_sam(ldap_state
, entry
, &mods
, newpwd
,
1707 element_is_changed
)) {
1708 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1711 ldap_mods_free(mods
,True
);
1712 return NT_STATUS_UNSUCCESSFUL
;
1716 DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
1717 pdb_get_username(newpwd
)));
1719 return NT_STATUS_OK
;
1722 ret
= ldapsam_modify_entry(my_methods
,newpwd
,dn
,mods
,LDAP_MOD_REPLACE
, element_is_changed
);
1723 ldap_mods_free(mods
,True
);
1726 if (!NT_STATUS_IS_OK(ret
)) {
1727 char *ld_error
= NULL
;
1728 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1730 DEBUG(0,("ldapsam_update_sam_account: failed to modify user with uid = %s, error: %s (%s)\n",
1731 pdb_get_username(newpwd
), ld_error
?ld_error
:"(unknwon)", ldap_err2string(rc
)));
1732 SAFE_FREE(ld_error
);
1736 DEBUG(2, ("ldapsam_update_sam_account: successfully modified uid = %s in the LDAP database\n",
1737 pdb_get_username(newpwd
)));
1738 return NT_STATUS_OK
;
1741 /**********************************************************************
1742 Helper function to determine for update_sam_account whether
1743 we need LDAP modification.
1744 *********************************************************************/
1746 static BOOL
element_is_set_or_changed(const SAM_ACCOUNT
*sampass
,
1747 enum pdb_elements element
)
1749 return (IS_SAM_SET(sampass
, element
) ||
1750 IS_SAM_CHANGED(sampass
, element
));
1753 /**********************************************************************
1754 Add SAM_ACCOUNT to LDAP.
1755 *********************************************************************/
1757 static NTSTATUS
ldapsam_add_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* newpwd
)
1759 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1760 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1762 LDAPMessage
*result
= NULL
;
1763 LDAPMessage
*entry
= NULL
;
1765 LDAPMod
**mods
= NULL
;
1766 int ldap_op
= LDAP_MOD_REPLACE
;
1770 const char *username
= pdb_get_username(newpwd
);
1771 const DOM_SID
*sid
= pdb_get_user_sid(newpwd
);
1775 if (!username
|| !*username
) {
1776 DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
1777 return NT_STATUS_INVALID_PARAMETER
;
1780 /* free this list after the second search or in case we exit on failure */
1781 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1783 rc
= ldapsam_search_suffix_by_name (ldap_state
, username
, &result
, attr_list
);
1785 if (rc
!= LDAP_SUCCESS
) {
1786 free_attr_list( attr_list
);
1787 return NT_STATUS_UNSUCCESSFUL
;
1790 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) != 0) {
1791 DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n",
1793 ldap_msgfree(result
);
1794 free_attr_list( attr_list
);
1795 return NT_STATUS_UNSUCCESSFUL
;
1797 ldap_msgfree(result
);
1800 if (element_is_set_or_changed(newpwd
, PDB_USERSID
)) {
1801 rc
= ldapsam_get_ldap_user_by_sid(ldap_state
,
1803 if (rc
== LDAP_SUCCESS
) {
1804 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) != 0) {
1805 DEBUG(0,("ldapsam_add_sam_account: SID '%s' already in the base, with samba attributes\n",
1806 sid_to_string(sid_string
, sid
)));
1807 free_attr_list( attr_list
);
1808 ldap_msgfree(result
);
1809 return NT_STATUS_UNSUCCESSFUL
;
1811 ldap_msgfree(result
);
1815 /* does the entry already exist but without a samba attributes?
1816 we need to return the samba attributes here */
1818 escape_user
= escape_ldap_string_alloc( username
);
1819 pstrcpy( filter
, lp_ldap_filter() );
1820 all_string_sub( filter
, "%u", escape_user
, sizeof(filter
) );
1821 SAFE_FREE( escape_user
);
1823 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
,
1824 filter
, attr_list
, &result
);
1825 if ( rc
!= LDAP_SUCCESS
) {
1826 free_attr_list( attr_list
);
1827 return NT_STATUS_UNSUCCESSFUL
;
1830 num_result
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1832 if (num_result
> 1) {
1833 DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
1834 free_attr_list( attr_list
);
1835 ldap_msgfree(result
);
1836 return NT_STATUS_UNSUCCESSFUL
;
1839 /* Check if we need to update an existing entry */
1840 if (num_result
== 1) {
1843 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
1844 ldap_op
= LDAP_MOD_REPLACE
;
1845 entry
= ldap_first_entry (ldap_state
->smbldap_state
->ldap_struct
, result
);
1846 tmp
= smbldap_get_dn (ldap_state
->smbldap_state
->ldap_struct
, entry
);
1848 free_attr_list( attr_list
);
1849 ldap_msgfree(result
);
1850 return NT_STATUS_UNSUCCESSFUL
;
1852 slprintf (dn
, sizeof (dn
) - 1, "%s", tmp
);
1855 } else if (ldap_state
->schema_ver
== SCHEMAVER_SAMBASAMACCOUNT
) {
1857 /* There might be a SID for this account already - say an idmap entry */
1859 pstr_sprintf(filter
, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
1860 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
1861 sid_to_string(sid_string
, sid
),
1862 LDAP_OBJ_IDMAP_ENTRY
,
1863 LDAP_OBJ_SID_ENTRY
);
1865 /* free old result before doing a new search */
1866 if (result
!= NULL
) {
1867 ldap_msgfree(result
);
1870 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
,
1871 filter
, attr_list
, &result
);
1873 if ( rc
!= LDAP_SUCCESS
) {
1874 free_attr_list( attr_list
);
1875 return NT_STATUS_UNSUCCESSFUL
;
1878 num_result
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1880 if (num_result
> 1) {
1881 DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
1882 free_attr_list( attr_list
);
1883 ldap_msgfree(result
);
1884 return NT_STATUS_UNSUCCESSFUL
;
1887 /* Check if we need to update an existing entry */
1888 if (num_result
== 1) {
1891 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
1892 ldap_op
= LDAP_MOD_REPLACE
;
1893 entry
= ldap_first_entry (ldap_state
->smbldap_state
->ldap_struct
, result
);
1894 tmp
= smbldap_get_dn (ldap_state
->smbldap_state
->ldap_struct
, entry
);
1896 free_attr_list( attr_list
);
1897 ldap_msgfree(result
);
1898 return NT_STATUS_UNSUCCESSFUL
;
1900 slprintf (dn
, sizeof (dn
) - 1, "%s", tmp
);
1905 free_attr_list( attr_list
);
1907 if (num_result
== 0) {
1908 /* Check if we need to add an entry */
1909 DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
1910 ldap_op
= LDAP_MOD_ADD
;
1911 if (username
[strlen(username
)-1] == '$') {
1912 slprintf (dn
, sizeof (dn
) - 1, "uid=%s,%s", username
, lp_ldap_machine_suffix ());
1914 slprintf (dn
, sizeof (dn
) - 1, "uid=%s,%s", username
, lp_ldap_user_suffix ());
1918 if (!init_ldap_from_sam(ldap_state
, entry
, &mods
, newpwd
,
1919 element_is_set_or_changed
)) {
1920 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
1921 ldap_msgfree(result
);
1923 ldap_mods_free(mods
,True
);
1924 return NT_STATUS_UNSUCCESSFUL
;
1927 ldap_msgfree(result
);
1930 DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd
)));
1931 return NT_STATUS_UNSUCCESSFUL
;
1933 switch ( ldap_state
->schema_ver
) {
1934 case SCHEMAVER_SAMBAACCOUNT
:
1935 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectclass", LDAP_OBJ_SAMBAACCOUNT
);
1937 case SCHEMAVER_SAMBASAMACCOUNT
:
1938 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT
);
1941 DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
1945 ret
= ldapsam_modify_entry(my_methods
,newpwd
,dn
,mods
,ldap_op
, element_is_set_or_changed
);
1946 if (!NT_STATUS_IS_OK(ret
)) {
1947 DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
1948 pdb_get_username(newpwd
),dn
));
1949 ldap_mods_free(mods
, True
);
1953 DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd
)));
1954 ldap_mods_free(mods
, True
);
1956 return NT_STATUS_OK
;
1959 /**********************************************************************
1960 *********************************************************************/
1962 static int ldapsam_search_one_group (struct ldapsam_privates
*ldap_state
,
1964 LDAPMessage
** result
)
1966 int scope
= LDAP_SCOPE_SUBTREE
;
1970 attr_list
= get_attr_list(groupmap_attr_list
);
1971 rc
= smbldap_search(ldap_state
->smbldap_state
,
1972 lp_ldap_group_suffix (), scope
,
1973 filter
, attr_list
, 0, result
);
1974 free_attr_list( attr_list
);
1976 if (rc
!= LDAP_SUCCESS
) {
1977 char *ld_error
= NULL
;
1978 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1980 DEBUG(0, ("ldapsam_search_one_group: "
1981 "Problem during the LDAP search: LDAP error: %s (%s)\n",
1982 ld_error
?ld_error
:"(unknown)", ldap_err2string(rc
)));
1983 DEBUGADD(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
1984 lp_ldap_group_suffix(), filter
));
1985 SAFE_FREE(ld_error
);
1991 /**********************************************************************
1992 *********************************************************************/
1994 static BOOL
init_group_from_ldap(struct ldapsam_privates
*ldap_state
,
1995 GROUP_MAP
*map
, LDAPMessage
*entry
)
1999 if (ldap_state
== NULL
|| map
== NULL
|| entry
== NULL
||
2000 ldap_state
->smbldap_state
->ldap_struct
== NULL
) {
2001 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
2005 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
2006 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
), temp
)) {
2007 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2008 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
)));
2011 DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp
));
2013 map
->gid
= (gid_t
)atol(temp
);
2015 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
2016 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_SID
), temp
)) {
2017 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2018 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_SID
)));
2022 if (!string_to_sid(&map
->sid
, temp
)) {
2023 DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp
));
2027 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
2028 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_TYPE
), temp
)) {
2029 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2030 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_TYPE
)));
2033 map
->sid_name_use
= (enum SID_NAME_USE
)atol(temp
);
2035 if ((map
->sid_name_use
< SID_NAME_USER
) ||
2036 (map
->sid_name_use
> SID_NAME_UNKNOWN
)) {
2037 DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map
->sid_name_use
));
2041 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
2042 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DISPLAY_NAME
), temp
)) {
2044 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
2045 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_CN
), temp
))
2047 DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
2048 for gidNumber(%lu)\n",(unsigned long)map
->gid
));
2052 fstrcpy(map
->nt_name
, temp
);
2054 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
2055 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DESC
), temp
)) {
2058 fstrcpy(map
->comment
, temp
);
2063 /**********************************************************************
2064 *********************************************************************/
2066 static BOOL
init_ldap_from_group(LDAP
*ldap_struct
,
2067 LDAPMessage
*existing
,
2069 const GROUP_MAP
*map
)
2073 if (mods
== NULL
|| map
== NULL
) {
2074 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
2080 sid_to_string(tmp
, &map
->sid
);
2082 smbldap_make_mod(ldap_struct
, existing
, mods
,
2083 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GROUP_SID
), tmp
);
2084 pstr_sprintf(tmp
, "%i", map
->sid_name_use
);
2085 smbldap_make_mod(ldap_struct
, existing
, mods
,
2086 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GROUP_TYPE
), tmp
);
2088 smbldap_make_mod(ldap_struct
, existing
, mods
,
2089 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DISPLAY_NAME
), map
->nt_name
);
2090 smbldap_make_mod(ldap_struct
, existing
, mods
,
2091 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DESC
), map
->comment
);
2096 /**********************************************************************
2097 *********************************************************************/
2099 static NTSTATUS
ldapsam_getgroup(struct pdb_methods
*methods
,
2103 struct ldapsam_privates
*ldap_state
=
2104 (struct ldapsam_privates
*)methods
->private_data
;
2105 LDAPMessage
*result
= NULL
;
2106 LDAPMessage
*entry
= NULL
;
2109 if (ldapsam_search_one_group(ldap_state
, filter
, &result
)
2111 return NT_STATUS_NO_SUCH_GROUP
;
2114 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
2117 DEBUG(4, ("ldapsam_getgroup: Did not find group\n"));
2118 ldap_msgfree(result
);
2119 return NT_STATUS_NO_SUCH_GROUP
;
2123 DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: count=%d\n",
2125 ldap_msgfree(result
);
2126 return NT_STATUS_NO_SUCH_GROUP
;
2129 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
2132 ldap_msgfree(result
);
2133 return NT_STATUS_UNSUCCESSFUL
;
2136 if (!init_group_from_ldap(ldap_state
, map
, entry
)) {
2137 DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for group filter %s\n",
2139 ldap_msgfree(result
);
2140 return NT_STATUS_NO_SUCH_GROUP
;
2143 ldap_msgfree(result
);
2144 return NT_STATUS_OK
;
2147 /**********************************************************************
2148 *********************************************************************/
2150 static NTSTATUS
ldapsam_getgrsid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
2155 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%s))",
2157 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GROUP_SID
),
2158 sid_string_static(&sid
));
2160 return ldapsam_getgroup(methods
, filter
, map
);
2163 /**********************************************************************
2164 *********************************************************************/
2166 static NTSTATUS
ldapsam_getgrgid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
2171 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%lu))",
2173 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
),
2174 (unsigned long)gid
);
2176 return ldapsam_getgroup(methods
, filter
, map
);
2179 /**********************************************************************
2180 *********************************************************************/
2182 static NTSTATUS
ldapsam_getgrnam(struct pdb_methods
*methods
, GROUP_MAP
*map
,
2186 char *escape_name
= escape_ldap_string_alloc(name
);
2189 return NT_STATUS_NO_MEMORY
;
2192 pstr_sprintf(filter
, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
2194 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_DISPLAY_NAME
), escape_name
,
2195 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_CN
), escape_name
);
2197 SAFE_FREE(escape_name
);
2199 return ldapsam_getgroup(methods
, filter
, map
);
2202 static NTSTATUS
ldapsam_enum_group_memberships(struct pdb_methods
*methods
,
2203 const char *username
,
2205 DOM_SID
**sids
, gid_t
**gids
,
2208 struct ldapsam_privates
*ldap_state
=
2209 (struct ldapsam_privates
*)methods
->private_data
;
2210 struct smbldap_state
*conn
= ldap_state
->smbldap_state
;
2212 char *attrs
[] = { "gidNumber", "sambaSID", NULL
};
2215 LDAPMessage
*msg
= NULL
;
2217 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2218 int num_sids
, num_gids
;
2219 extern DOM_SID global_sid_NULL
;
2221 if (!lp_parm_bool(-1, "ldapsam", "trusted", False
))
2222 return pdb_default_enum_group_memberships(methods
, username
,
2229 escape_name
= escape_ldap_string_alloc(username
);
2231 if (escape_name
== NULL
)
2232 return NT_STATUS_NO_MEMORY
;
2234 pstr_sprintf(filter
, "(&(objectClass=posixGroup)"
2235 "(|(memberUid=%s)(gidNumber=%d)))",
2236 username
, primary_gid
);
2238 rc
= smbldap_search(conn
, lp_ldap_group_suffix(),
2239 LDAP_SCOPE_SUBTREE
, filter
, attrs
, 0, &msg
);
2241 if (rc
!= LDAP_SUCCESS
)
2250 /* We need to add the primary group as the first gid/sid */
2252 add_gid_to_array_unique(primary_gid
, gids
, &num_gids
);
2254 /* This sid will be replaced later */
2256 add_sid_to_array_unique(&global_sid_NULL
, sids
, &num_sids
);
2258 for (entry
= ldap_first_entry(conn
->ldap_struct
, msg
);
2260 entry
= ldap_next_entry(conn
->ldap_struct
, entry
))
2267 if (!smbldap_get_single_attribute(conn
->ldap_struct
,
2269 str
, sizeof(str
)-1))
2272 if (!string_to_sid(&sid
, str
))
2275 if (!smbldap_get_single_attribute(conn
->ldap_struct
,
2277 str
, sizeof(str
)-1))
2280 gid
= strtoul(str
, &end
, 10);
2282 if (PTR_DIFF(end
, str
) != strlen(str
))
2285 if (gid
== primary_gid
) {
2286 sid_copy(&(*sids
)[0], &sid
);
2288 add_gid_to_array_unique(gid
, gids
, &num_gids
);
2289 add_sid_to_array_unique(&sid
, sids
, &num_sids
);
2293 if (sid_compare(&global_sid_NULL
, &(*sids
)[0]) == 0) {
2294 DEBUG(3, ("primary group not found\n"));
2298 *num_groups
= num_sids
;
2300 result
= NT_STATUS_OK
;
2304 SAFE_FREE(escape_name
);
2311 /**********************************************************************
2312 *********************************************************************/
2314 static int ldapsam_search_one_group_by_gid(struct ldapsam_privates
*ldap_state
,
2316 LDAPMessage
**result
)
2320 pstr_sprintf(filter
, "(&(|(objectClass=%s)(objectclass=%s))(%s=%lu))",
2321 LDAP_OBJ_POSIXGROUP
, LDAP_OBJ_IDMAP_ENTRY
,
2322 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
),
2323 (unsigned long)gid
);
2325 return ldapsam_search_one_group(ldap_state
, filter
, result
);
2328 /**********************************************************************
2329 *********************************************************************/
2331 static NTSTATUS
ldapsam_add_group_mapping_entry(struct pdb_methods
*methods
,
2334 struct ldapsam_privates
*ldap_state
=
2335 (struct ldapsam_privates
*)methods
->private_data
;
2336 LDAPMessage
*result
= NULL
;
2337 LDAPMod
**mods
= NULL
;
2348 if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods
, &dummy
,
2350 DEBUG(0, ("ldapsam_add_group_mapping_entry: Group %ld already exists in LDAP\n", (unsigned long)map
->gid
));
2351 return NT_STATUS_UNSUCCESSFUL
;
2354 rc
= ldapsam_search_one_group_by_gid(ldap_state
, map
->gid
, &result
);
2355 if (rc
!= LDAP_SUCCESS
) {
2356 ldap_msgfree(result
);
2357 return NT_STATUS_UNSUCCESSFUL
;
2360 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
2363 /* There's no posixGroup account, let's try to find an
2364 * appropriate idmap entry for aliases */
2370 ldap_msgfree(result
);
2372 pstrcpy( suffix
, lp_ldap_idmap_suffix() );
2373 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%u))",
2374 LDAP_OBJ_IDMAP_ENTRY
, LDAP_ATTRIBUTE_GIDNUMBER
,
2377 attr_list
= get_attr_list( sidmap_attr_list
);
2378 rc
= smbldap_search(ldap_state
->smbldap_state
, suffix
,
2379 LDAP_SCOPE_SUBTREE
, filter
, attr_list
,
2382 free_attr_list(attr_list
);
2384 if (rc
!= LDAP_SUCCESS
) {
2385 DEBUG(3,("Failure looking up entry (%s)\n",
2386 ldap_err2string(rc
) ));
2387 ldap_msgfree(result
);
2388 return NT_STATUS_UNSUCCESSFUL
;
2392 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
2394 ldap_msgfree(result
);
2395 return NT_STATUS_UNSUCCESSFUL
;
2399 DEBUG(2, ("ldapsam_add_group_mapping_entry: Group %lu must exist exactly once in LDAP\n",
2400 (unsigned long)map
->gid
));
2401 ldap_msgfree(result
);
2402 return NT_STATUS_UNSUCCESSFUL
;
2405 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
2406 tmp
= smbldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
2408 ldap_msgfree(result
);
2409 return NT_STATUS_UNSUCCESSFUL
;
2414 if (!init_ldap_from_group(ldap_state
->smbldap_state
->ldap_struct
,
2415 result
, &mods
, map
)) {
2416 DEBUG(0, ("ldapsam_add_group_mapping_entry: init_ldap_from_group failed!\n"));
2417 ldap_mods_free(mods
, True
);
2418 ldap_msgfree(result
);
2419 return NT_STATUS_UNSUCCESSFUL
;
2422 ldap_msgfree(result
);
2425 DEBUG(0, ("ldapsam_add_group_mapping_entry: mods is empty\n"));
2426 return NT_STATUS_UNSUCCESSFUL
;
2429 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_GROUPMAP
);
2431 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
2432 ldap_mods_free(mods
, True
);
2434 if (rc
!= LDAP_SUCCESS
) {
2435 char *ld_error
= NULL
;
2436 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
2438 DEBUG(0, ("ldapsam_add_group_mapping_entry: failed to add group %lu error: %s (%s)\n", (unsigned long)map
->gid
,
2439 ld_error
? ld_error
: "(unknown)", ldap_err2string(rc
)));
2440 SAFE_FREE(ld_error
);
2441 return NT_STATUS_UNSUCCESSFUL
;
2444 DEBUG(2, ("ldapsam_add_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map
->gid
));
2445 return NT_STATUS_OK
;
2448 /**********************************************************************
2449 *********************************************************************/
2451 static NTSTATUS
ldapsam_update_group_mapping_entry(struct pdb_methods
*methods
,
2454 struct ldapsam_privates
*ldap_state
=
2455 (struct ldapsam_privates
*)methods
->private_data
;
2458 LDAPMessage
*result
= NULL
;
2459 LDAPMessage
*entry
= NULL
;
2460 LDAPMod
**mods
= NULL
;
2462 rc
= ldapsam_search_one_group_by_gid(ldap_state
, map
->gid
, &result
);
2464 if (rc
!= LDAP_SUCCESS
) {
2465 return NT_STATUS_UNSUCCESSFUL
;
2468 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) == 0) {
2469 DEBUG(0, ("ldapsam_update_group_mapping_entry: No group to modify!\n"));
2470 ldap_msgfree(result
);
2471 return NT_STATUS_UNSUCCESSFUL
;
2474 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
2476 if (!init_ldap_from_group(ldap_state
->smbldap_state
->ldap_struct
,
2477 result
, &mods
, map
)) {
2478 DEBUG(0, ("ldapsam_update_group_mapping_entry: init_ldap_from_group failed\n"));
2479 ldap_msgfree(result
);
2481 ldap_mods_free(mods
,True
);
2482 return NT_STATUS_UNSUCCESSFUL
;
2486 DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: nothing to do\n"));
2487 ldap_msgfree(result
);
2488 return NT_STATUS_OK
;
2491 dn
= smbldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
2493 ldap_msgfree(result
);
2494 return NT_STATUS_UNSUCCESSFUL
;
2496 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
2499 ldap_mods_free(mods
, True
);
2500 ldap_msgfree(result
);
2502 if (rc
!= LDAP_SUCCESS
) {
2503 char *ld_error
= NULL
;
2504 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
2506 DEBUG(0, ("ldapsam_update_group_mapping_entry: failed to modify group %lu error: %s (%s)\n", (unsigned long)map
->gid
,
2507 ld_error
? ld_error
: "(unknown)", ldap_err2string(rc
)));
2508 SAFE_FREE(ld_error
);
2509 return NT_STATUS_UNSUCCESSFUL
;
2512 DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map
->gid
));
2513 return NT_STATUS_OK
;
2516 /**********************************************************************
2517 *********************************************************************/
2519 static NTSTATUS
ldapsam_delete_group_mapping_entry(struct pdb_methods
*methods
,
2522 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)methods
->private_data
;
2523 pstring sidstring
, filter
;
2524 LDAPMessage
*result
= NULL
;
2529 sid_to_string(sidstring
, &sid
);
2531 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%s))",
2532 LDAP_OBJ_GROUPMAP
, LDAP_ATTRIBUTE_SID
, sidstring
);
2534 rc
= ldapsam_search_one_group(ldap_state
, filter
, &result
);
2536 if (rc
!= LDAP_SUCCESS
) {
2537 return NT_STATUS_NO_SUCH_GROUP
;
2540 attr_list
= get_attr_list( groupmap_attr_list_to_delete
);
2541 ret
= ldapsam_delete_entry(ldap_state
, result
, LDAP_OBJ_GROUPMAP
, attr_list
);
2542 free_attr_list ( attr_list
);
2544 ldap_msgfree(result
);
2549 /**********************************************************************
2550 *********************************************************************/
2552 static NTSTATUS
ldapsam_setsamgrent(struct pdb_methods
*my_methods
, BOOL update
)
2554 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
2559 pstr_sprintf( filter
, "(objectclass=%s)", LDAP_OBJ_GROUPMAP
);
2560 attr_list
= get_attr_list( groupmap_attr_list
);
2561 rc
= smbldap_search(ldap_state
->smbldap_state
, lp_ldap_group_suffix(),
2562 LDAP_SCOPE_SUBTREE
, filter
,
2563 attr_list
, 0, &ldap_state
->result
);
2564 free_attr_list( attr_list
);
2566 if (rc
!= LDAP_SUCCESS
) {
2567 DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n", ldap_err2string(rc
)));
2568 DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n", lp_ldap_group_suffix(), filter
));
2569 ldap_msgfree(ldap_state
->result
);
2570 ldap_state
->result
= NULL
;
2571 return NT_STATUS_UNSUCCESSFUL
;
2574 DEBUG(2, ("ldapsam_setsamgrent: %d entries in the base!\n",
2575 ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
,
2576 ldap_state
->result
)));
2578 ldap_state
->entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, ldap_state
->result
);
2579 ldap_state
->index
= 0;
2581 return NT_STATUS_OK
;
2584 /**********************************************************************
2585 *********************************************************************/
2587 static void ldapsam_endsamgrent(struct pdb_methods
*my_methods
)
2589 ldapsam_endsampwent(my_methods
);
2592 /**********************************************************************
2593 *********************************************************************/
2595 static NTSTATUS
ldapsam_getsamgrent(struct pdb_methods
*my_methods
,
2598 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
2599 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
2603 if (!ldap_state
->entry
)
2606 ldap_state
->index
++;
2607 bret
= init_group_from_ldap(ldap_state
, map
, ldap_state
->entry
);
2609 ldap_state
->entry
= ldap_next_entry(ldap_state
->smbldap_state
->ldap_struct
,
2613 return NT_STATUS_OK
;
2616 /**********************************************************************
2617 *********************************************************************/
2619 static NTSTATUS
ldapsam_enum_group_mapping(struct pdb_methods
*methods
,
2620 enum SID_NAME_USE sid_name_use
,
2621 GROUP_MAP
**rmap
, int *num_entries
,
2631 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods
, False
))) {
2632 DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open passdb\n"));
2633 return NT_STATUS_ACCESS_DENIED
;
2636 while (NT_STATUS_IS_OK(ldapsam_getsamgrent(methods
, &map
))) {
2637 if (sid_name_use
!= SID_NAME_UNKNOWN
&&
2638 sid_name_use
!= map
.sid_name_use
) {
2639 DEBUG(11,("ldapsam_enum_group_mapping: group %s is not of the requested type\n", map
.nt_name
));
2642 if (unix_only
==ENUM_ONLY_MAPPED
&& map
.gid
==-1) {
2643 DEBUG(11,("ldapsam_enum_group_mapping: group %s is non mapped\n", map
.nt_name
));
2647 mapt
=SMB_REALLOC_ARRAY((*rmap
), GROUP_MAP
, entries
+1);
2649 DEBUG(0,("ldapsam_enum_group_mapping: Unable to enlarge group map!\n"));
2651 return NT_STATUS_UNSUCCESSFUL
;
2656 mapt
[entries
] = map
;
2661 ldapsam_endsamgrent(methods
);
2663 *num_entries
= entries
;
2665 return NT_STATUS_OK
;
2668 static NTSTATUS
ldapsam_modify_aliasmem(struct pdb_methods
*methods
,
2669 const DOM_SID
*alias
,
2670 const DOM_SID
*member
,
2673 struct ldapsam_privates
*ldap_state
=
2674 (struct ldapsam_privates
*)methods
->private_data
;
2676 LDAPMessage
*result
= NULL
;
2677 LDAPMessage
*entry
= NULL
;
2679 LDAPMod
**mods
= NULL
;
2684 pstr_sprintf(filter
, "(&(|(objectClass=%s)(objectclass=%s))(%s=%s))",
2685 LDAP_OBJ_GROUPMAP
, LDAP_OBJ_IDMAP_ENTRY
,
2686 get_attr_key2string(groupmap_attr_list
,
2687 LDAP_ATTR_GROUP_SID
),
2688 sid_string_static(alias
));
2690 if (ldapsam_search_one_group(ldap_state
, filter
,
2691 &result
) != LDAP_SUCCESS
)
2692 return NT_STATUS_NO_SUCH_ALIAS
;
2694 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
,
2698 DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
2699 ldap_msgfree(result
);
2700 return NT_STATUS_NO_SUCH_ALIAS
;
2704 DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for filter %s: "
2705 "count=%d\n", filter
, count
));
2706 ldap_msgfree(result
);
2707 return NT_STATUS_NO_SUCH_ALIAS
;
2710 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
,
2714 ldap_msgfree(result
);
2715 return NT_STATUS_UNSUCCESSFUL
;
2718 dn
= smbldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
2720 ldap_msgfree(result
);
2721 return NT_STATUS_UNSUCCESSFUL
;
2724 smbldap_set_mod(&mods
, modop
,
2725 get_attr_key2string(groupmap_attr_list
,
2726 LDAP_ATTR_SID_LIST
),
2727 sid_string_static(member
));
2729 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
2731 ldap_mods_free(mods
, True
);
2732 ldap_msgfree(result
);
2734 if (rc
!= LDAP_SUCCESS
) {
2735 char *ld_error
= NULL
;
2736 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
,
2737 LDAP_OPT_ERROR_STRING
,&ld_error
);
2739 DEBUG(0, ("ldapsam_modify_aliasmem: Could not modify alias "
2740 "for %s, error: %s (%s)\n", dn
, ldap_err2string(rc
),
2741 ld_error
?ld_error
:"unknown"));
2742 SAFE_FREE(ld_error
);
2744 return NT_STATUS_UNSUCCESSFUL
;
2749 return NT_STATUS_OK
;
2752 static NTSTATUS
ldapsam_add_aliasmem(struct pdb_methods
*methods
,
2753 const DOM_SID
*alias
,
2754 const DOM_SID
*member
)
2756 return ldapsam_modify_aliasmem(methods
, alias
, member
, LDAP_MOD_ADD
);
2759 static NTSTATUS
ldapsam_del_aliasmem(struct pdb_methods
*methods
,
2760 const DOM_SID
*alias
,
2761 const DOM_SID
*member
)
2763 return ldapsam_modify_aliasmem(methods
, alias
, member
,
2767 static NTSTATUS
ldapsam_enum_aliasmem(struct pdb_methods
*methods
,
2768 const DOM_SID
*alias
, DOM_SID
**members
,
2771 struct ldapsam_privates
*ldap_state
=
2772 (struct ldapsam_privates
*)methods
->private_data
;
2773 LDAPMessage
*result
= NULL
;
2774 LDAPMessage
*entry
= NULL
;
2783 pstr_sprintf(filter
, "(&(|(objectClass=%s)(objectclass=%s))(%s=%s))",
2784 LDAP_OBJ_GROUPMAP
, LDAP_OBJ_IDMAP_ENTRY
,
2785 get_attr_key2string(groupmap_attr_list
,
2786 LDAP_ATTR_GROUP_SID
),
2787 sid_string_static(alias
));
2789 if (ldapsam_search_one_group(ldap_state
, filter
,
2790 &result
) != LDAP_SUCCESS
)
2791 return NT_STATUS_NO_SUCH_ALIAS
;
2793 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
,
2797 DEBUG(4, ("ldapsam_enum_aliasmem: Did not find alias\n"));
2798 ldap_msgfree(result
);
2799 return NT_STATUS_NO_SUCH_ALIAS
;
2803 DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for filter %s: "
2804 "count=%d\n", filter
, count
));
2805 ldap_msgfree(result
);
2806 return NT_STATUS_NO_SUCH_ALIAS
;
2809 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
,
2813 ldap_msgfree(result
);
2814 return NT_STATUS_UNSUCCESSFUL
;
2817 values
= ldap_get_values(ldap_state
->smbldap_state
->ldap_struct
,
2819 get_attr_key2string(groupmap_attr_list
,
2820 LDAP_ATTR_SID_LIST
));
2822 if (values
== NULL
) {
2823 ldap_msgfree(result
);
2824 return NT_STATUS_OK
;
2827 count
= ldap_count_values(values
);
2829 for (i
=0; i
<count
; i
++) {
2832 if (!string_to_sid(&member
, values
[i
]))
2835 add_sid_to_array(&member
, members
, num_members
);
2838 ldap_value_free(values
);
2839 ldap_msgfree(result
);
2841 return NT_STATUS_OK
;
2844 static NTSTATUS
ldapsam_alias_memberships(struct pdb_methods
*methods
,
2845 const DOM_SID
*members
,
2847 DOM_SID
**aliases
, int *num_aliases
)
2849 struct ldapsam_privates
*ldap_state
=
2850 (struct ldapsam_privates
*)methods
->private_data
;
2853 char *attrs
[] = { LDAP_ATTRIBUTE_SID
, NULL
};
2855 LDAPMessage
*result
= NULL
;
2856 LDAPMessage
*entry
= NULL
;
2860 TALLOC_CTX
*mem_ctx
;
2862 mem_ctx
= talloc_init("ldapsam_alias_memberships");
2864 if (mem_ctx
== NULL
)
2865 return NT_STATUS_NO_MEMORY
;
2867 /* This query could be further optimized by adding a
2868 (&(sambaSID=<domain-sid>*)) so that only those aliases that are
2869 asked for in the getuseraliases are returned. */
2871 filter
= talloc_asprintf(mem_ctx
,
2872 "(&(|(objectclass=%s)(objectclass=%s))(|",
2873 LDAP_OBJ_GROUPMAP
, LDAP_OBJ_IDMAP_ENTRY
);
2875 for (i
=0; i
<num_members
; i
++)
2876 filter
= talloc_asprintf(mem_ctx
, "%s(sambaSIDList=%s)",
2878 sid_string_static(&members
[i
]));
2880 filter
= talloc_asprintf(mem_ctx
, "%s))", filter
);
2882 rc
= smbldap_search(ldap_state
->smbldap_state
, lp_ldap_group_suffix(),
2883 LDAP_SCOPE_SUBTREE
, filter
, attrs
, 0, &result
);
2885 talloc_destroy(mem_ctx
);
2887 if (rc
!= LDAP_SUCCESS
)
2888 return NT_STATUS_UNSUCCESSFUL
;
2893 ldap_struct
= ldap_state
->smbldap_state
->ldap_struct
;
2895 for (entry
= ldap_first_entry(ldap_struct
, result
);
2897 entry
= ldap_next_entry(ldap_struct
, entry
))
2902 if (!smbldap_get_single_attribute(ldap_struct
, entry
,
2908 if (!string_to_sid(&sid
, sid_str
))
2911 add_sid_to_array_unique(&sid
, aliases
, num_aliases
);
2914 ldap_msgfree(result
);
2915 return NT_STATUS_OK
;
2918 /**********************************************************************
2920 *********************************************************************/
2922 static void free_private_data(void **vp
)
2924 struct ldapsam_privates
**ldap_state
= (struct ldapsam_privates
**)vp
;
2926 smbldap_free_struct(&(*ldap_state
)->smbldap_state
);
2928 if ((*ldap_state
)->result
!= NULL
) {
2929 ldap_msgfree((*ldap_state
)->result
);
2930 (*ldap_state
)->result
= NULL
;
2935 /* No need to free any further, as it is talloc()ed */
2938 /**********************************************************************
2939 Intitalise the parts of the pdb_context that are common to all pdb_ldap modes
2940 *********************************************************************/
2942 static NTSTATUS
pdb_init_ldapsam_common(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
,
2943 const char *location
)
2946 struct ldapsam_privates
*ldap_state
;
2948 if (!NT_STATUS_IS_OK(nt_status
= make_pdb_methods(pdb_context
->mem_ctx
, pdb_method
))) {
2952 (*pdb_method
)->name
= "ldapsam";
2954 (*pdb_method
)->setsampwent
= ldapsam_setsampwent
;
2955 (*pdb_method
)->endsampwent
= ldapsam_endsampwent
;
2956 (*pdb_method
)->getsampwent
= ldapsam_getsampwent
;
2957 (*pdb_method
)->getsampwnam
= ldapsam_getsampwnam
;
2958 (*pdb_method
)->getsampwsid
= ldapsam_getsampwsid
;
2959 (*pdb_method
)->add_sam_account
= ldapsam_add_sam_account
;
2960 (*pdb_method
)->update_sam_account
= ldapsam_update_sam_account
;
2961 (*pdb_method
)->delete_sam_account
= ldapsam_delete_sam_account
;
2963 (*pdb_method
)->getgrsid
= ldapsam_getgrsid
;
2964 (*pdb_method
)->getgrgid
= ldapsam_getgrgid
;
2965 (*pdb_method
)->getgrnam
= ldapsam_getgrnam
;
2966 (*pdb_method
)->add_group_mapping_entry
= ldapsam_add_group_mapping_entry
;
2967 (*pdb_method
)->update_group_mapping_entry
= ldapsam_update_group_mapping_entry
;
2968 (*pdb_method
)->delete_group_mapping_entry
= ldapsam_delete_group_mapping_entry
;
2969 (*pdb_method
)->enum_group_mapping
= ldapsam_enum_group_mapping
;
2970 (*pdb_method
)->enum_group_memberships
= ldapsam_enum_group_memberships
;
2972 /* TODO: Setup private data and free */
2974 ldap_state
= TALLOC_ZERO_P(pdb_context
->mem_ctx
, struct ldapsam_privates
);
2976 DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
2977 return NT_STATUS_NO_MEMORY
;
2980 if (!NT_STATUS_IS_OK(nt_status
=
2981 smbldap_init(pdb_context
->mem_ctx
, location
,
2982 &ldap_state
->smbldap_state
)));
2984 ldap_state
->domain_name
= talloc_strdup(pdb_context
->mem_ctx
, get_global_sam_name());
2985 if (!ldap_state
->domain_name
) {
2986 return NT_STATUS_NO_MEMORY
;
2989 (*pdb_method
)->private_data
= ldap_state
;
2991 (*pdb_method
)->free_private_data
= free_private_data
;
2993 return NT_STATUS_OK
;
2996 /**********************************************************************
2997 Initialise the 'compat' mode for pdb_ldap
2998 *********************************************************************/
3000 static NTSTATUS
pdb_init_ldapsam_compat(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
3003 struct ldapsam_privates
*ldap_state
;
3005 #ifdef WITH_LDAP_SAMCONFIG
3007 int ldap_port
= lp_ldap_port();
3009 /* remap default port if not using SSL (ie clear or TLS) */
3010 if ( (lp_ldap_ssl() != LDAP_SSL_ON
) && (ldap_port
== 636) ) {
3014 location
= talloc_asprintf(pdb_context
->mem_ctx
, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON
? "ldaps" : "ldap", lp_ldap_server(), ldap_port
);
3016 return NT_STATUS_NO_MEMORY
;
3021 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_ldapsam_common(pdb_context
, pdb_method
, location
))) {
3025 (*pdb_method
)->name
= "ldapsam_compat";
3027 ldap_state
= (*pdb_method
)->private_data
;
3028 ldap_state
->schema_ver
= SCHEMAVER_SAMBAACCOUNT
;
3030 sid_copy(&ldap_state
->domain_sid
, get_global_sam_sid());
3032 return NT_STATUS_OK
;
3035 /**********************************************************************
3036 Initialise the normal mode for pdb_ldap
3037 *********************************************************************/
3039 static NTSTATUS
pdb_init_ldapsam(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
3042 struct ldapsam_privates
*ldap_state
;
3043 uint32 alg_rid_base
;
3044 pstring alg_rid_base_string
;
3045 LDAPMessage
*result
= NULL
;
3046 LDAPMessage
*entry
= NULL
;
3047 DOM_SID ldap_domain_sid
;
3048 DOM_SID secrets_domain_sid
;
3049 pstring domain_sid_string
;
3051 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_ldapsam_common(pdb_context
, pdb_method
, location
))) {
3055 (*pdb_method
)->name
= "ldapsam";
3057 (*pdb_method
)->add_aliasmem
= ldapsam_add_aliasmem
;
3058 (*pdb_method
)->del_aliasmem
= ldapsam_del_aliasmem
;
3059 (*pdb_method
)->enum_aliasmem
= ldapsam_enum_aliasmem
;
3060 (*pdb_method
)->enum_alias_memberships
= ldapsam_alias_memberships
;
3062 ldap_state
= (*pdb_method
)->private_data
;
3063 ldap_state
->schema_ver
= SCHEMAVER_SAMBASAMACCOUNT
;
3065 /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
3067 nt_status
= smbldap_search_domain_info(ldap_state
->smbldap_state
, &result
,
3068 ldap_state
->domain_name
, True
);
3070 if ( !NT_STATUS_IS_OK(nt_status
) ) {
3071 DEBUG(2, ("pdb_init_ldapsam: WARNING: Could not get domain info, nor add one to the domain\n"));
3072 DEBUGADD(2, ("pdb_init_ldapsam: Continuing on regardless, will be unable to allocate new users/groups, \
3073 and will risk BDCs having inconsistant SIDs\n"));
3074 sid_copy(&ldap_state
->domain_sid
, get_global_sam_sid());
3075 return NT_STATUS_OK
;
3078 /* Given that the above might fail, everything below this must be optional */
3080 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
3082 DEBUG(0, ("pdb_init_ldapsam: Could not get domain info entry\n"));
3083 ldap_msgfree(result
);
3084 return NT_STATUS_UNSUCCESSFUL
;
3087 if (smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
3088 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
3089 domain_sid_string
)) {
3091 if (!string_to_sid(&ldap_domain_sid
, domain_sid_string
)) {
3092 DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be read as a valid SID\n", domain_sid_string
));
3093 return NT_STATUS_INVALID_PARAMETER
;
3095 found_sid
= secrets_fetch_domain_sid(ldap_state
->domain_name
, &secrets_domain_sid
);
3096 if (!found_sid
|| !sid_equal(&secrets_domain_sid
, &ldap_domain_sid
)) {
3097 fstring new_sid_str
, old_sid_str
;
3098 DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain %s based on pdb_ldap results %s -> %s\n",
3099 ldap_state
->domain_name
,
3100 sid_to_string(old_sid_str
, &secrets_domain_sid
),
3101 sid_to_string(new_sid_str
, &ldap_domain_sid
)));
3103 /* reset secrets.tdb sid */
3104 secrets_store_domain_sid(ldap_state
->domain_name
, &ldap_domain_sid
);
3105 DEBUG(1, ("New global sam SID: %s\n", sid_to_string(new_sid_str
, get_global_sam_sid())));
3107 sid_copy(&ldap_state
->domain_sid
, &ldap_domain_sid
);
3110 if (smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
3111 get_attr_key2string( dominfo_attr_list
, LDAP_ATTR_ALGORITHMIC_RID_BASE
),
3112 alg_rid_base_string
)) {
3113 alg_rid_base
= (uint32
)atol(alg_rid_base_string
);
3114 if (alg_rid_base
!= algorithmic_rid_base()) {
3115 DEBUG(0, ("The value of 'algorithmic RID base' has changed since the LDAP\n"
3116 "database was initialised. Aborting. \n"));
3117 ldap_msgfree(result
);
3118 return NT_STATUS_UNSUCCESSFUL
;
3121 ldap_msgfree(result
);
3123 return NT_STATUS_OK
;
3126 NTSTATUS
pdb_ldap_init(void)
3129 if (!NT_STATUS_IS_OK(nt_status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ldapsam", pdb_init_ldapsam
)))
3132 if (!NT_STATUS_IS_OK(nt_status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ldapsam_compat", pdb_init_ldapsam_compat
)))
3135 return NT_STATUS_OK
;