2 Unix SMB/CIFS implementation.
3 LDAP protocol helper functions for SAMBA
4 Copyright (C) Jean François Micouleau 1998
5 Copyright (C) Gerald Carter 2001-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
;
482 * do a little initialization
486 nt_username
[0] = '\0';
490 logon_script
[0] = '\0';
491 profile_path
[0] = '\0';
493 munged_dial
[0] = '\0';
494 workstations
[0] = '\0';
497 if (sampass
== NULL
|| ldap_state
== NULL
|| entry
== NULL
) {
498 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
502 if (ldap_state
->smbldap_state
->ldap_struct
== NULL
) {
503 DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->ldap_struct is NULL!\n"));
507 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
, "uid", username
)) {
508 DEBUG(1, ("init_sam_from_ldap: No uid attribute found for this user!\n"));
512 DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username
));
514 pstrcpy(nt_username
, username
);
516 pstrcpy(domain
, ldap_state
->domain_name
);
518 pdb_set_username(sampass
, username
, PDB_SET
);
520 pdb_set_domain(sampass
, domain
, PDB_DEFAULT
);
521 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
523 /* deal with different attributes between the schema first */
525 if ( ldap_state
->schema_ver
== SCHEMAVER_SAMBASAMACCOUNT
) {
526 if (smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
527 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
), temp
)) {
528 pdb_set_user_sid_from_string(sampass
, temp
, PDB_SET
);
531 if (smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
532 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PRIMARY_GROUP_SID
), temp
)) {
533 pdb_set_group_sid_from_string(sampass
, temp
, PDB_SET
);
535 pdb_set_group_sid_from_rid(sampass
, DOMAIN_GROUP_RID_USERS
, PDB_DEFAULT
);
538 if (smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
539 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_RID
), temp
)) {
540 user_rid
= (uint32
)atol(temp
);
541 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
544 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
545 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PRIMARY_GROUP_RID
), temp
)) {
546 pdb_set_group_sid_from_rid(sampass
, DOMAIN_GROUP_RID_USERS
, PDB_DEFAULT
);
550 group_rid
= (uint32
)atol(temp
);
552 /* for some reason, we often have 0 as a primary group RID.
553 Make sure that we treat this just as a 'default' value */
556 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
558 pdb_set_group_sid_from_rid(sampass
, DOMAIN_GROUP_RID_USERS
, PDB_DEFAULT
);
562 if (pdb_get_init_flags(sampass
,PDB_USERSID
) == PDB_DEFAULT
) {
563 DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n",
564 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
565 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_RID
),
570 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
571 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_LAST_SET
), temp
)) {
572 /* leave as default */
574 pass_last_set_time
= (time_t) atol(temp
);
575 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
578 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
579 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_TIME
), temp
)) {
580 /* leave as default */
582 logon_time
= (time_t) atol(temp
);
583 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
586 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
587 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGOFF_TIME
), temp
)) {
588 /* leave as default */
590 logoff_time
= (time_t) atol(temp
);
591 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
594 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
595 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_KICKOFF_TIME
), temp
)) {
596 /* leave as default */
598 kickoff_time
= (time_t) atol(temp
);
599 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
602 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
603 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_CAN_CHANGE
), temp
)) {
604 /* leave as default */
606 pass_can_change_time
= (time_t) atol(temp
);
607 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
610 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
611 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_MUST_CHANGE
), temp
)) {
612 /* leave as default */
614 pass_must_change_time
= (time_t) atol(temp
);
615 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
618 /* recommend that 'gecos' and 'displayName' should refer to the same
619 * attribute OID. userFullName depreciated, only used by Samba
620 * primary rules of LDAP: don't make a new attribute when one is already defined
621 * that fits your needs; using cn then displayName rather than 'userFullName'
624 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
625 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DISPLAY_NAME
), fullname
)) {
626 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
627 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_CN
), fullname
)) {
628 /* leave as default */
630 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
633 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
636 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
637 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_DRIVE
), dir_drive
))
639 pdb_set_dir_drive( sampass
, lp_logon_drive(), PDB_DEFAULT
);
641 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
644 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
645 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_PATH
), homedir
))
647 pdb_set_homedir( sampass
,
648 talloc_sub_basic(sampass
->mem_ctx
, username
, lp_logon_home()),
651 pstrcpy( tmpstring
, homedir
);
652 standard_sub_basic( username
, tmpstring
, sizeof(tmpstring
) );
653 pdb_set_homedir(sampass
, tmpstring
, PDB_SET
);
656 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
657 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_SCRIPT
), logon_script
))
659 pdb_set_logon_script( sampass
,
660 talloc_sub_basic(sampass
->mem_ctx
, username
, lp_logon_script()),
663 pstrcpy( tmpstring
, logon_script
);
664 standard_sub_basic( username
, tmpstring
, sizeof(tmpstring
) );
665 pdb_set_logon_script(sampass
, tmpstring
, PDB_SET
);
668 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
669 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PROFILE_PATH
), profile_path
))
671 pdb_set_profile_path( sampass
,
672 talloc_sub_basic( sampass
->mem_ctx
, username
, lp_logon_path()),
675 pstrcpy( tmpstring
, profile_path
);
676 standard_sub_basic( username
, tmpstring
, sizeof(tmpstring
) );
677 pdb_set_profile_path(sampass
, tmpstring
, PDB_SET
);
680 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
681 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DESC
), acct_desc
))
683 /* leave as default */
685 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
688 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
689 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_WKS
), workstations
)) {
690 /* leave as default */;
692 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
695 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
696 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_MUNGED_DIAL
), munged_dial
, sizeof(munged_dial
))) {
697 /* leave as default */;
699 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
702 /* FIXME: hours stuff should be cleaner */
706 memset(hours
, 0xff, hours_len
);
708 if (!smbldap_get_single_pstring (ldap_state
->smbldap_state
->ldap_struct
, entry
,
709 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LMPW
), temp
)) {
710 /* leave as default */
712 pdb_gethexpwd(temp
, smblmpwd
);
713 memset((char *)temp
, '\0', strlen(temp
)+1);
714 if (!pdb_set_lanman_passwd(sampass
, smblmpwd
, PDB_SET
))
716 ZERO_STRUCT(smblmpwd
);
719 if (!smbldap_get_single_pstring (ldap_state
->smbldap_state
->ldap_struct
, entry
,
720 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_NTPW
), temp
)) {
721 /* leave as default */
723 pdb_gethexpwd(temp
, smbntpwd
);
724 memset((char *)temp
, '\0', strlen(temp
)+1);
725 if (!pdb_set_nt_passwd(sampass
, smbntpwd
, PDB_SET
))
727 ZERO_STRUCT(smbntpwd
);
730 account_policy_get(AP_PASSWORD_HISTORY
, &pwHistLen
);
732 uint8
*pwhist
= NULL
;
735 /* We can only store (sizeof(pstring)-1)/64 password history entries. */
736 pwHistLen
= MIN(pwHistLen
, ((sizeof(temp
)-1)/64));
738 if ((pwhist
= SMB_MALLOC(pwHistLen
* PW_HISTORY_ENTRY_LEN
)) == NULL
){
739 DEBUG(0, ("init_sam_from_ldap: malloc failed!\n"));
742 memset(pwhist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
744 if (!smbldap_get_single_pstring (ldap_state
->smbldap_state
->ldap_struct
, entry
,
745 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_HISTORY
), temp
)) {
746 /* leave as default - zeros */
748 BOOL hex_failed
= False
;
749 for (i
= 0; i
< pwHistLen
; i
++){
750 /* Get the 16 byte salt. */
751 if (!pdb_gethexpwd(&temp
[i
*64], &pwhist
[i
*PW_HISTORY_ENTRY_LEN
])) {
755 /* Get the 16 byte MD5 hash of salt+passwd. */
756 if (!pdb_gethexpwd(&temp
[(i
*64)+32],
757 &pwhist
[(i
*PW_HISTORY_ENTRY_LEN
)+PW_HISTORY_SALT_LEN
])) {
763 DEBUG(0,("init_sam_from_ldap: Failed to get password history for user %s\n",
765 memset(pwhist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
768 if (!pdb_set_pw_history(sampass
, pwhist
, pwHistLen
, PDB_SET
)){
775 if (!smbldap_get_single_pstring (ldap_state
->smbldap_state
->ldap_struct
, entry
,
776 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_ACB_INFO
), temp
)) {
777 acct_ctrl
|= ACB_NORMAL
;
779 acct_ctrl
= pdb_decode_acct_ctrl(temp
);
782 acct_ctrl
|= ACB_NORMAL
;
784 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
787 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
788 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
790 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
791 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_BAD_PASSWORD_COUNT
), temp
)) {
792 /* leave as default */
794 bad_password_count
= (uint32
) atol(temp
);
795 pdb_set_bad_password_count(sampass
, bad_password_count
, PDB_SET
);
798 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
799 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_BAD_PASSWORD_TIME
), temp
)) {
800 /* leave as default */
802 bad_password_time
= (time_t) atol(temp
);
803 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
807 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
808 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_COUNT
), temp
)) {
809 /* leave as default */
811 logon_count
= (uint32
) atol(temp
);
812 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
815 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
817 if(!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
818 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_HOURS
), temp
)) {
819 /* leave as default */
821 pdb_gethexhours(temp
, hours
);
822 memset((char *)temp
, '\0', strlen(temp
) +1);
823 pdb_set_hours(sampass
, hours
, PDB_SET
);
827 /* check the timestamp of the cache vs ldap entry */
828 if (!(ldap_entry_time
= ldapsam_get_entry_timestamp(ldap_state
,
832 /* see if we have newer updates */
833 if (!(cache_entry
= login_cache_read(sampass
))) {
834 DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n",
835 (unsigned int)pdb_get_bad_password_count(sampass
),
836 (unsigned int)pdb_get_bad_password_time(sampass
)));
840 DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n",
841 (unsigned int)ldap_entry_time
, (unsigned int)cache_entry
->entry_timestamp
,
842 (unsigned int)cache_entry
->bad_password_time
));
844 if (ldap_entry_time
> cache_entry
->entry_timestamp
) {
845 /* cache is older than directory , so
846 we need to delete the entry but allow the
847 fields to be written out */
848 login_cache_delentry(sampass
);
851 pdb_set_acct_ctrl(sampass
,
852 pdb_get_acct_ctrl(sampass
) |
853 (cache_entry
->acct_ctrl
& ACB_AUTOLOCK
),
855 pdb_set_bad_password_count(sampass
,
856 cache_entry
->bad_password_count
,
858 pdb_set_bad_password_time(sampass
,
859 cache_entry
->bad_password_time
,
863 SAFE_FREE(cache_entry
);
867 /**********************************************************************
868 Initialize the ldap db from a SAM_ACCOUNT. Called on update.
869 (Based on init_buffer_from_sam in pdb_tdb.c)
870 *********************************************************************/
872 static BOOL
init_ldap_from_sam (struct ldapsam_privates
*ldap_state
,
873 LDAPMessage
*existing
,
874 LDAPMod
*** mods
, SAM_ACCOUNT
* sampass
,
875 BOOL (*need_update
)(const SAM_ACCOUNT
*,
881 if (mods
== NULL
|| sampass
== NULL
) {
882 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
889 * took out adding "objectclass: sambaAccount"
890 * do this on a per-mod basis
892 if (need_update(sampass
, PDB_USERNAME
))
893 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
894 "uid", pdb_get_username(sampass
));
896 DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass
)));
898 /* only update the RID if we actually need to */
899 if (need_update(sampass
, PDB_USERSID
)) {
901 fstring dom_sid_string
;
902 const DOM_SID
*user_sid
= pdb_get_user_sid(sampass
);
904 switch ( ldap_state
->schema_ver
) {
905 case SCHEMAVER_SAMBAACCOUNT
:
906 if (!sid_peek_check_rid(&ldap_state
->domain_sid
, user_sid
, &rid
)) {
907 DEBUG(1, ("init_ldap_from_sam: User's SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
908 sid_to_string(sid_string
, user_sid
),
909 sid_to_string(dom_sid_string
, &ldap_state
->domain_sid
)));
912 slprintf(temp
, sizeof(temp
) - 1, "%i", rid
);
913 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
914 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_RID
),
918 case SCHEMAVER_SAMBASAMACCOUNT
:
919 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
920 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
921 sid_to_string(sid_string
, user_sid
));
925 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
930 /* we don't need to store the primary group RID - so leaving it
931 'free' to hang off the unix primary group makes life easier */
933 if (need_update(sampass
, PDB_GROUPSID
)) {
935 fstring dom_sid_string
;
936 const DOM_SID
*group_sid
= pdb_get_group_sid(sampass
);
938 switch ( ldap_state
->schema_ver
) {
939 case SCHEMAVER_SAMBAACCOUNT
:
940 if (!sid_peek_check_rid(&ldap_state
->domain_sid
, group_sid
, &rid
)) {
941 DEBUG(1, ("init_ldap_from_sam: User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
942 sid_to_string(sid_string
, group_sid
),
943 sid_to_string(dom_sid_string
, &ldap_state
->domain_sid
)));
947 slprintf(temp
, sizeof(temp
) - 1, "%i", rid
);
948 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
949 get_userattr_key2string(ldap_state
->schema_ver
,
950 LDAP_ATTR_PRIMARY_GROUP_RID
), temp
);
953 case SCHEMAVER_SAMBASAMACCOUNT
:
954 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
955 get_userattr_key2string(ldap_state
->schema_ver
,
956 LDAP_ATTR_PRIMARY_GROUP_SID
), sid_to_string(sid_string
, group_sid
));
960 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
966 /* displayName, cn, and gecos should all be the same
967 * most easily accomplished by giving them the same OID
968 * gecos isn't set here b/c it should be handled by the
970 * We change displayName only and fall back to cn if
974 if (need_update(sampass
, PDB_FULLNAME
))
975 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
976 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DISPLAY_NAME
),
977 pdb_get_fullname(sampass
));
979 if (need_update(sampass
, PDB_ACCTDESC
))
980 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
981 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DESC
),
982 pdb_get_acct_desc(sampass
));
984 if (need_update(sampass
, PDB_WORKSTATIONS
))
985 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
986 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_WKS
),
987 pdb_get_workstations(sampass
));
989 if (need_update(sampass
, PDB_MUNGEDDIAL
))
990 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
991 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_MUNGED_DIAL
),
992 pdb_get_munged_dial(sampass
));
994 if (need_update(sampass
, PDB_SMBHOME
))
995 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
996 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_PATH
),
997 pdb_get_homedir(sampass
));
999 if (need_update(sampass
, PDB_DRIVE
))
1000 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1001 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_DRIVE
),
1002 pdb_get_dir_drive(sampass
));
1004 if (need_update(sampass
, PDB_LOGONSCRIPT
))
1005 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1006 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_SCRIPT
),
1007 pdb_get_logon_script(sampass
));
1009 if (need_update(sampass
, PDB_PROFILE
))
1010 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1011 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PROFILE_PATH
),
1012 pdb_get_profile_path(sampass
));
1014 slprintf(temp
, sizeof(temp
) - 1, "%li", pdb_get_logon_time(sampass
));
1015 if (need_update(sampass
, PDB_LOGONTIME
))
1016 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1017 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_TIME
), temp
);
1019 slprintf(temp
, sizeof(temp
) - 1, "%li", pdb_get_logoff_time(sampass
));
1020 if (need_update(sampass
, PDB_LOGOFFTIME
))
1021 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1022 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGOFF_TIME
), temp
);
1024 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_kickoff_time(sampass
));
1025 if (need_update(sampass
, PDB_KICKOFFTIME
))
1026 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1027 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_KICKOFF_TIME
), temp
);
1029 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_can_change_time(sampass
));
1030 if (need_update(sampass
, PDB_CANCHANGETIME
))
1031 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1032 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_CAN_CHANGE
), temp
);
1034 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_must_change_time(sampass
));
1035 if (need_update(sampass
, PDB_MUSTCHANGETIME
))
1036 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1037 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_MUST_CHANGE
), temp
);
1040 if ((pdb_get_acct_ctrl(sampass
)&(ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
))
1041 || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY
)) {
1043 if (need_update(sampass
, PDB_LMPASSWD
)) {
1044 const uchar
*lm_pw
= pdb_get_lanman_passwd(sampass
);
1046 pdb_sethexpwd(temp
, lm_pw
,
1047 pdb_get_acct_ctrl(sampass
));
1048 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1049 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LMPW
),
1052 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1053 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LMPW
),
1057 if (need_update(sampass
, PDB_NTPASSWD
)) {
1058 const uchar
*nt_pw
= pdb_get_nt_passwd(sampass
);
1060 pdb_sethexpwd(temp
, nt_pw
,
1061 pdb_get_acct_ctrl(sampass
));
1062 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1063 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_NTPW
),
1066 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1067 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_NTPW
),
1072 if (need_update(sampass
, PDB_PWHISTORY
)) {
1074 account_policy_get(AP_PASSWORD_HISTORY
, &pwHistLen
);
1075 if (pwHistLen
== 0) {
1076 /* Remove any password history from the LDAP store. */
1077 memset(temp
, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
1080 int i
, currHistLen
= 0;
1081 const uint8
*pwhist
= pdb_get_pw_history(sampass
, &currHistLen
);
1082 if (pwhist
!= NULL
) {
1083 /* We can only store (sizeof(pstring)-1)/64 password history entries. */
1084 pwHistLen
= MIN(pwHistLen
, ((sizeof(temp
)-1)/64));
1085 for (i
=0; i
< pwHistLen
&& i
< currHistLen
; i
++) {
1086 /* Store the salt. */
1087 pdb_sethexpwd(&temp
[i
*64], &pwhist
[i
*PW_HISTORY_ENTRY_LEN
], 0);
1088 /* Followed by the md5 hash of salt + md4 hash */
1089 pdb_sethexpwd(&temp
[(i
*64)+32],
1090 &pwhist
[(i
*PW_HISTORY_ENTRY_LEN
)+PW_HISTORY_SALT_LEN
], 0);
1091 DEBUG(100, ("temp=%s\n", temp
));
1095 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1096 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_HISTORY
),
1100 if (need_update(sampass
, PDB_PASSLASTSET
)) {
1101 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_last_set_time(sampass
));
1102 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1103 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_LAST_SET
),
1108 if (need_update(sampass
, PDB_HOURS
)) {
1109 const char *hours
= pdb_get_hours(sampass
);
1111 pdb_sethexhours(temp
, hours
);
1112 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
,
1115 get_userattr_key2string(ldap_state
->schema_ver
,
1116 LDAP_ATTR_LOGON_HOURS
),
1121 if (need_update(sampass
, PDB_ACCTCTRL
))
1122 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
1123 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_ACB_INFO
),
1124 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass
), NEW_PW_FORMAT_SPACE_PADDED_LEN
));
1126 /* password lockout cache:
1127 - If we are now autolocking or clearing, we write to ldap
1128 - If we are clearing, we delete the cache entry
1129 - If the count is > 0, we update the cache
1131 This even means when autolocking, we cache, just in case the
1132 update doesn't work, and we have to cache the autolock flag */
1134 if (need_update(sampass
, PDB_BAD_PASSWORD_COUNT
)) /* &&
1135 need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ {
1136 uint16 badcount
= pdb_get_bad_password_count(sampass
);
1137 time_t badtime
= pdb_get_bad_password_time(sampass
);
1139 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT
, &pol
);
1141 DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
1142 (unsigned int)pol
, (unsigned int)badcount
, (unsigned int)badtime
));
1144 if ((badcount
>= pol
) || (badcount
== 0)) {
1145 DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n",
1146 (unsigned int)badcount
, (unsigned int)badtime
));
1147 slprintf (temp
, sizeof (temp
) - 1, "%li", (long)badcount
);
1149 ldap_state
->smbldap_state
->ldap_struct
,
1151 get_userattr_key2string(
1152 ldap_state
->schema_ver
,
1153 LDAP_ATTR_BAD_PASSWORD_COUNT
),
1156 slprintf (temp
, sizeof (temp
) - 1, "%li", badtime
);
1158 ldap_state
->smbldap_state
->ldap_struct
,
1160 get_userattr_key2string(
1161 ldap_state
->schema_ver
,
1162 LDAP_ATTR_BAD_PASSWORD_TIME
),
1165 if (badcount
== 0) {
1166 DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass
)));
1167 login_cache_delentry(sampass
);
1169 LOGIN_CACHE cache_entry
;
1171 cache_entry
.entry_timestamp
= time(NULL
);
1172 cache_entry
.acct_ctrl
= pdb_get_acct_ctrl(sampass
);
1173 cache_entry
.bad_password_count
= badcount
;
1174 cache_entry
.bad_password_time
= badtime
;
1176 DEBUG(7, ("Updating bad password count and time in login cache\n"));
1177 login_cache_write(sampass
, cache_entry
);
1184 /**********************************************************************
1185 Connect to LDAP server for password enumeration.
1186 *********************************************************************/
1188 static NTSTATUS
ldapsam_setsampwent(struct pdb_methods
*my_methods
, BOOL update
, uint16 acb_mask
)
1190 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1192 pstring filter
, suffix
;
1194 BOOL machine_mask
= False
, user_mask
= False
;
1196 pstr_sprintf( filter
, "(&%s%s)", lp_ldap_filter(),
1197 get_objclass_filter(ldap_state
->schema_ver
));
1198 all_string_sub(filter
, "%u", "*", sizeof(pstring
));
1200 machine_mask
= ((acb_mask
!= 0) && (acb_mask
& (ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
)));
1201 user_mask
= ((acb_mask
!= 0) && (acb_mask
& ACB_NORMAL
));
1204 pstrcpy(suffix
, lp_ldap_machine_suffix());
1205 } else if (user_mask
) {
1206 pstrcpy(suffix
, lp_ldap_user_suffix());
1208 pstrcpy(suffix
, lp_ldap_suffix());
1211 DEBUG(10,("ldapsam_setsampwent: LDAP Query for acb_mask 0x%x will use suffix %s\n",
1214 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1215 rc
= smbldap_search(ldap_state
->smbldap_state
, suffix
, LDAP_SCOPE_SUBTREE
, filter
,
1216 attr_list
, 0, &ldap_state
->result
);
1217 free_attr_list( attr_list
);
1219 if (rc
!= LDAP_SUCCESS
) {
1220 DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc
)));
1221 DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", suffix
, filter
));
1222 ldap_msgfree(ldap_state
->result
);
1223 ldap_state
->result
= NULL
;
1224 return NT_STATUS_UNSUCCESSFUL
;
1227 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base %s\n",
1228 ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
,
1229 ldap_state
->result
), suffix
));
1231 ldap_state
->entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
,
1232 ldap_state
->result
);
1233 ldap_state
->index
= 0;
1235 return NT_STATUS_OK
;
1238 /**********************************************************************
1239 End enumeration of the LDAP password list.
1240 *********************************************************************/
1242 static void ldapsam_endsampwent(struct pdb_methods
*my_methods
)
1244 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1245 if (ldap_state
->result
) {
1246 ldap_msgfree(ldap_state
->result
);
1247 ldap_state
->result
= NULL
;
1251 /**********************************************************************
1252 Get the next entry in the LDAP password database.
1253 *********************************************************************/
1255 static NTSTATUS
ldapsam_getsampwent(struct pdb_methods
*my_methods
, SAM_ACCOUNT
*user
)
1257 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1258 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1262 if (!ldap_state
->entry
)
1265 ldap_state
->index
++;
1266 bret
= init_sam_from_ldap(ldap_state
, user
, ldap_state
->entry
);
1268 ldap_state
->entry
= ldap_next_entry(ldap_state
->smbldap_state
->ldap_struct
,
1272 return NT_STATUS_OK
;
1275 static void append_attr(char ***attr_list
, const char *new_attr
)
1279 if (new_attr
== NULL
) {
1283 for (i
=0; (*attr_list
)[i
] != NULL
; i
++) {
1287 (*attr_list
) = SMB_REALLOC_ARRAY((*attr_list
), char *, i
+2);
1288 SMB_ASSERT((*attr_list
) != NULL
);
1289 (*attr_list
)[i
] = SMB_STRDUP(new_attr
);
1290 (*attr_list
)[i
+1] = NULL
;
1293 /**********************************************************************
1294 Get SAM_ACCOUNT entry from LDAP by username.
1295 *********************************************************************/
1297 static NTSTATUS
ldapsam_getsampwnam(struct pdb_methods
*my_methods
, SAM_ACCOUNT
*user
, const char *sname
)
1299 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1300 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1301 LDAPMessage
*result
= NULL
;
1302 LDAPMessage
*entry
= NULL
;
1307 attr_list
= get_userattr_list( ldap_state
->schema_ver
);
1308 append_attr(&attr_list
, get_userattr_key2string(ldap_state
->schema_ver
,LDAP_ATTR_MOD_TIMESTAMP
));
1309 rc
= ldapsam_search_suffix_by_name(ldap_state
, sname
, &result
, attr_list
);
1310 free_attr_list( attr_list
);
1312 if ( rc
!= LDAP_SUCCESS
)
1313 return NT_STATUS_NO_SUCH_USER
;
1315 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1318 DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname
, count
));
1319 ldap_msgfree(result
);
1320 return NT_STATUS_NO_SUCH_USER
;
1321 } else if (count
> 1) {
1322 DEBUG(1, ("ldapsam_getsampwnam: Duplicate entries for this user [%s] Failing. count=%d\n", sname
, count
));
1323 ldap_msgfree(result
);
1324 return NT_STATUS_NO_SUCH_USER
;
1327 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1329 if (!init_sam_from_ldap(ldap_state
, user
, entry
)) {
1330 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname
));
1331 ldap_msgfree(result
);
1332 return NT_STATUS_NO_SUCH_USER
;
1334 pdb_set_backend_private_data(user
, result
,
1335 private_data_free_fn
,
1336 my_methods
, PDB_CHANGED
);
1339 ldap_msgfree(result
);
1344 static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates
*ldap_state
,
1345 const DOM_SID
*sid
, LDAPMessage
**result
)
1351 switch ( ldap_state
->schema_ver
) {
1352 case SCHEMAVER_SAMBASAMACCOUNT
:
1353 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1354 append_attr(&attr_list
, get_userattr_key2string(ldap_state
->schema_ver
,LDAP_ATTR_MOD_TIMESTAMP
));
1355 rc
= ldapsam_search_suffix_by_sid(ldap_state
, sid
, result
, attr_list
);
1356 free_attr_list( attr_list
);
1358 if ( rc
!= LDAP_SUCCESS
)
1362 case SCHEMAVER_SAMBAACCOUNT
:
1363 if (!sid_peek_check_rid(&ldap_state
->domain_sid
, sid
, &rid
)) {
1367 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1368 rc
= ldapsam_search_suffix_by_rid(ldap_state
, rid
, result
, attr_list
);
1369 free_attr_list( attr_list
);
1371 if ( rc
!= LDAP_SUCCESS
)
1378 /**********************************************************************
1379 Get SAM_ACCOUNT entry from LDAP by SID.
1380 *********************************************************************/
1382 static NTSTATUS
ldapsam_getsampwsid(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* user
, const DOM_SID
*sid
)
1384 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1385 LDAPMessage
*result
= NULL
;
1386 LDAPMessage
*entry
= NULL
;
1391 rc
= ldapsam_get_ldap_user_by_sid(ldap_state
,
1393 if (rc
!= LDAP_SUCCESS
)
1394 return NT_STATUS_NO_SUCH_USER
;
1396 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1399 DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] count=%d\n", sid_to_string(sid_string
, sid
),
1401 ldap_msgfree(result
);
1402 return NT_STATUS_NO_SUCH_USER
;
1403 } else if (count
> 1) {
1404 DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID [%s]. Failing. count=%d\n", sid_to_string(sid_string
, sid
),
1406 ldap_msgfree(result
);
1407 return NT_STATUS_NO_SUCH_USER
;
1410 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1412 ldap_msgfree(result
);
1413 return NT_STATUS_NO_SUCH_USER
;
1416 if (!init_sam_from_ldap(ldap_state
, user
, entry
)) {
1417 DEBUG(1,("ldapsam_getsampwsid: init_sam_from_ldap failed!\n"));
1418 ldap_msgfree(result
);
1419 return NT_STATUS_NO_SUCH_USER
;
1422 pdb_set_backend_private_data(user
, result
,
1423 private_data_free_fn
,
1424 my_methods
, PDB_CHANGED
);
1425 return NT_STATUS_OK
;
1428 static BOOL
ldapsam_can_pwchange_exop(struct smbldap_state
*ldap_state
)
1430 return smbldap_has_extension(ldap_state
, LDAP_EXOP_MODIFY_PASSWD
);
1433 /********************************************************************
1434 Do the actual modification - also change a plaintext passord if
1436 **********************************************************************/
1438 static NTSTATUS
ldapsam_modify_entry(struct pdb_methods
*my_methods
,
1439 SAM_ACCOUNT
*newpwd
, char *dn
,
1440 LDAPMod
**mods
, int ldap_op
,
1441 BOOL (*need_update
)(const SAM_ACCOUNT
*, enum pdb_elements
))
1443 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1446 if (!my_methods
|| !newpwd
|| !dn
) {
1447 return NT_STATUS_INVALID_PARAMETER
;
1451 DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
1452 /* may be password change below however */
1456 smbldap_set_mod(&mods
, LDAP_MOD_ADD
,
1459 rc
= smbldap_add(ldap_state
->smbldap_state
,
1462 case LDAP_MOD_REPLACE
:
1463 rc
= smbldap_modify(ldap_state
->smbldap_state
,
1467 DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n",
1469 return NT_STATUS_INVALID_PARAMETER
;
1472 if (rc
!=LDAP_SUCCESS
) {
1473 char *ld_error
= NULL
;
1474 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1476 DEBUG(1, ("ldapsam_modify_entry: Failed to %s user dn= %s with: %s\n\t%s\n",
1477 ldap_op
== LDAP_MOD_ADD
? "add" : "modify",
1478 dn
, ldap_err2string(rc
),
1479 ld_error
?ld_error
:"unknown"));
1480 SAFE_FREE(ld_error
);
1481 return NT_STATUS_UNSUCCESSFUL
;
1485 if (!(pdb_get_acct_ctrl(newpwd
)&(ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
)) &&
1486 (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF
) &&
1487 need_update(newpwd
, PDB_PLAINTEXT_PW
) &&
1488 (pdb_get_plaintext_passwd(newpwd
)!=NULL
)) {
1492 struct berval
*retdata
;
1493 char *utf8_password
;
1496 if (!ldapsam_can_pwchange_exop(ldap_state
->smbldap_state
)) {
1497 DEBUG(2, ("ldap password change requested, but LDAP "
1498 "server does not support it -- ignoring\n"));
1499 return NT_STATUS_OK
;
1502 if (push_utf8_allocate(&utf8_password
, pdb_get_plaintext_passwd(newpwd
)) == (size_t)-1) {
1503 return NT_STATUS_NO_MEMORY
;
1506 if (push_utf8_allocate(&utf8_dn
, dn
) == (size_t)-1) {
1507 return NT_STATUS_NO_MEMORY
;
1510 if ((ber
= ber_alloc_t(LBER_USE_DER
))==NULL
) {
1511 DEBUG(0,("ber_alloc_t returns NULL\n"));
1512 SAFE_FREE(utf8_password
);
1513 return NT_STATUS_UNSUCCESSFUL
;
1516 ber_printf (ber
, "{");
1517 ber_printf (ber
, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID
, utf8_dn
);
1518 ber_printf (ber
, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW
, utf8_password
);
1519 ber_printf (ber
, "N}");
1521 if ((rc
= ber_flatten (ber
, &bv
))<0) {
1522 DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
1525 SAFE_FREE(utf8_password
);
1526 return NT_STATUS_UNSUCCESSFUL
;
1530 SAFE_FREE(utf8_password
);
1533 if ((rc
= smbldap_extended_operation(ldap_state
->smbldap_state
,
1534 LDAP_EXOP_MODIFY_PASSWD
,
1535 bv
, NULL
, NULL
, &retoid
,
1536 &retdata
)) != LDAP_SUCCESS
) {
1537 char *ld_error
= NULL
;
1539 if (rc
== LDAP_OBJECT_CLASS_VIOLATION
) {
1540 DEBUG(3, ("Could not set userPassword "
1541 "attribute due to an objectClass "
1542 "violation -- ignoring\n"));
1544 return NT_STATUS_OK
;
1547 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1549 DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n",
1550 pdb_get_username(newpwd
), ldap_err2string(rc
), ld_error
?ld_error
:"unknown"));
1551 SAFE_FREE(ld_error
);
1553 return NT_STATUS_UNSUCCESSFUL
;
1555 DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd
)));
1556 #ifdef DEBUG_PASSWORD
1557 DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd
)));
1559 ber_bvfree(retdata
);
1560 ber_memfree(retoid
);
1564 return NT_STATUS_OK
;
1567 /**********************************************************************
1568 Delete entry from LDAP for username.
1569 *********************************************************************/
1571 static NTSTATUS
ldapsam_delete_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* sam_acct
)
1573 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1576 LDAPMessage
*result
= NULL
;
1582 DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n"));
1583 return NT_STATUS_INVALID_PARAMETER
;
1586 sname
= pdb_get_username(sam_acct
);
1588 DEBUG (3, ("ldapsam_delete_sam_account: Deleting user %s from LDAP.\n", sname
));
1590 attr_list
= get_userattr_delete_list( ldap_state
->schema_ver
);
1591 rc
= ldapsam_search_suffix_by_name(ldap_state
, sname
, &result
, attr_list
);
1593 if (rc
!= LDAP_SUCCESS
) {
1594 free_attr_list( attr_list
);
1595 return NT_STATUS_NO_SUCH_USER
;
1598 switch ( ldap_state
->schema_ver
) {
1599 case SCHEMAVER_SAMBASAMACCOUNT
:
1600 fstrcpy( objclass
, LDAP_OBJ_SAMBASAMACCOUNT
);
1603 case SCHEMAVER_SAMBAACCOUNT
:
1604 fstrcpy( objclass
, LDAP_OBJ_SAMBAACCOUNT
);
1607 fstrcpy( objclass
, "UNKNOWN" );
1608 DEBUG(0,("ldapsam_delete_sam_account: Unknown schema version specified!\n"));
1612 ret
= ldapsam_delete_entry(ldap_state
, result
, objclass
, attr_list
);
1613 ldap_msgfree(result
);
1614 free_attr_list( attr_list
);
1619 /**********************************************************************
1620 Helper function to determine for update_sam_account whether
1621 we need LDAP modification.
1622 *********************************************************************/
1624 static BOOL
element_is_changed(const SAM_ACCOUNT
*sampass
,
1625 enum pdb_elements element
)
1627 return IS_SAM_CHANGED(sampass
, element
);
1630 /**********************************************************************
1632 *********************************************************************/
1634 static NTSTATUS
ldapsam_update_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* newpwd
)
1636 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1637 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1640 LDAPMessage
*result
= NULL
;
1641 LDAPMessage
*entry
= NULL
;
1642 LDAPMod
**mods
= NULL
;
1645 result
= pdb_get_backend_private_data(newpwd
, my_methods
);
1647 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1648 rc
= ldapsam_search_suffix_by_name(ldap_state
, pdb_get_username(newpwd
), &result
, attr_list
);
1649 free_attr_list( attr_list
);
1650 if (rc
!= LDAP_SUCCESS
) {
1651 return NT_STATUS_UNSUCCESSFUL
;
1653 pdb_set_backend_private_data(newpwd
, result
, private_data_free_fn
, my_methods
, PDB_CHANGED
);
1656 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) == 0) {
1657 DEBUG(0, ("ldapsam_update_sam_account: No user to modify!\n"));
1658 return NT_STATUS_UNSUCCESSFUL
;
1661 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1662 dn
= smbldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
1664 return NT_STATUS_UNSUCCESSFUL
;
1667 DEBUG(4, ("ldapsam_update_sam_account: user %s to be modified has dn: %s\n", pdb_get_username(newpwd
), dn
));
1669 if (!init_ldap_from_sam(ldap_state
, entry
, &mods
, newpwd
,
1670 element_is_changed
)) {
1671 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1674 ldap_mods_free(mods
,True
);
1675 return NT_STATUS_UNSUCCESSFUL
;
1679 DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
1680 pdb_get_username(newpwd
)));
1682 return NT_STATUS_OK
;
1685 ret
= ldapsam_modify_entry(my_methods
,newpwd
,dn
,mods
,LDAP_MOD_REPLACE
, element_is_changed
);
1686 ldap_mods_free(mods
,True
);
1689 if (!NT_STATUS_IS_OK(ret
)) {
1690 char *ld_error
= NULL
;
1691 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1693 DEBUG(0,("ldapsam_update_sam_account: failed to modify user with uid = %s, error: %s (%s)\n",
1694 pdb_get_username(newpwd
), ld_error
?ld_error
:"(unknwon)", ldap_err2string(rc
)));
1695 SAFE_FREE(ld_error
);
1699 DEBUG(2, ("ldapsam_update_sam_account: successfully modified uid = %s in the LDAP database\n",
1700 pdb_get_username(newpwd
)));
1701 return NT_STATUS_OK
;
1704 /**********************************************************************
1705 Helper function to determine for update_sam_account whether
1706 we need LDAP modification.
1707 *********************************************************************/
1709 static BOOL
element_is_set_or_changed(const SAM_ACCOUNT
*sampass
,
1710 enum pdb_elements element
)
1712 return (IS_SAM_SET(sampass
, element
) ||
1713 IS_SAM_CHANGED(sampass
, element
));
1716 /**********************************************************************
1717 Add SAM_ACCOUNT to LDAP.
1718 *********************************************************************/
1720 static NTSTATUS
ldapsam_add_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* newpwd
)
1722 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1723 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1725 LDAPMessage
*result
= NULL
;
1726 LDAPMessage
*entry
= NULL
;
1728 LDAPMod
**mods
= NULL
;
1729 int ldap_op
= LDAP_MOD_REPLACE
;
1733 const char *username
= pdb_get_username(newpwd
);
1734 const DOM_SID
*sid
= pdb_get_user_sid(newpwd
);
1738 if (!username
|| !*username
) {
1739 DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
1740 return NT_STATUS_INVALID_PARAMETER
;
1743 /* free this list after the second search or in case we exit on failure */
1744 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1746 rc
= ldapsam_search_suffix_by_name (ldap_state
, username
, &result
, attr_list
);
1748 if (rc
!= LDAP_SUCCESS
) {
1749 free_attr_list( attr_list
);
1750 return NT_STATUS_UNSUCCESSFUL
;
1753 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) != 0) {
1754 DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n",
1756 ldap_msgfree(result
);
1757 free_attr_list( attr_list
);
1758 return NT_STATUS_UNSUCCESSFUL
;
1760 ldap_msgfree(result
);
1763 if (element_is_set_or_changed(newpwd
, PDB_USERSID
)) {
1764 rc
= ldapsam_get_ldap_user_by_sid(ldap_state
,
1766 if (rc
== LDAP_SUCCESS
) {
1767 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) != 0) {
1768 DEBUG(0,("ldapsam_add_sam_account: SID '%s' already in the base, with samba attributes\n",
1769 sid_to_string(sid_string
, sid
)));
1770 free_attr_list( attr_list
);
1771 ldap_msgfree(result
);
1772 return NT_STATUS_UNSUCCESSFUL
;
1774 ldap_msgfree(result
);
1778 /* does the entry already exist but without a samba attributes?
1779 we need to return the samba attributes here */
1781 escape_user
= escape_ldap_string_alloc( username
);
1782 pstrcpy( filter
, lp_ldap_filter() );
1783 all_string_sub( filter
, "%u", escape_user
, sizeof(filter
) );
1784 SAFE_FREE( escape_user
);
1786 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
,
1787 filter
, attr_list
, &result
);
1788 if ( rc
!= LDAP_SUCCESS
) {
1789 free_attr_list( attr_list
);
1790 return NT_STATUS_UNSUCCESSFUL
;
1793 num_result
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1795 if (num_result
> 1) {
1796 DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
1797 free_attr_list( attr_list
);
1798 ldap_msgfree(result
);
1799 return NT_STATUS_UNSUCCESSFUL
;
1802 /* Check if we need to update an existing entry */
1803 if (num_result
== 1) {
1806 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
1807 ldap_op
= LDAP_MOD_REPLACE
;
1808 entry
= ldap_first_entry (ldap_state
->smbldap_state
->ldap_struct
, result
);
1809 tmp
= smbldap_get_dn (ldap_state
->smbldap_state
->ldap_struct
, entry
);
1811 free_attr_list( attr_list
);
1812 ldap_msgfree(result
);
1813 return NT_STATUS_UNSUCCESSFUL
;
1815 slprintf (dn
, sizeof (dn
) - 1, "%s", tmp
);
1818 } else if (ldap_state
->schema_ver
== SCHEMAVER_SAMBASAMACCOUNT
) {
1820 /* There might be a SID for this account already - say an idmap entry */
1822 pstr_sprintf(filter
, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
1823 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
1824 sid_to_string(sid_string
, sid
),
1825 LDAP_OBJ_IDMAP_ENTRY
,
1826 LDAP_OBJ_SID_ENTRY
);
1828 /* free old result before doing a new search */
1829 if (result
!= NULL
) {
1830 ldap_msgfree(result
);
1833 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
,
1834 filter
, attr_list
, &result
);
1836 if ( rc
!= LDAP_SUCCESS
) {
1837 free_attr_list( attr_list
);
1838 return NT_STATUS_UNSUCCESSFUL
;
1841 num_result
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1843 if (num_result
> 1) {
1844 DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
1845 free_attr_list( attr_list
);
1846 ldap_msgfree(result
);
1847 return NT_STATUS_UNSUCCESSFUL
;
1850 /* Check if we need to update an existing entry */
1851 if (num_result
== 1) {
1854 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
1855 ldap_op
= LDAP_MOD_REPLACE
;
1856 entry
= ldap_first_entry (ldap_state
->smbldap_state
->ldap_struct
, result
);
1857 tmp
= smbldap_get_dn (ldap_state
->smbldap_state
->ldap_struct
, entry
);
1859 free_attr_list( attr_list
);
1860 ldap_msgfree(result
);
1861 return NT_STATUS_UNSUCCESSFUL
;
1863 slprintf (dn
, sizeof (dn
) - 1, "%s", tmp
);
1868 free_attr_list( attr_list
);
1870 if (num_result
== 0) {
1871 /* Check if we need to add an entry */
1872 DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
1873 ldap_op
= LDAP_MOD_ADD
;
1874 if (username
[strlen(username
)-1] == '$') {
1875 slprintf (dn
, sizeof (dn
) - 1, "uid=%s,%s", username
, lp_ldap_machine_suffix ());
1877 slprintf (dn
, sizeof (dn
) - 1, "uid=%s,%s", username
, lp_ldap_user_suffix ());
1881 if (!init_ldap_from_sam(ldap_state
, entry
, &mods
, newpwd
,
1882 element_is_set_or_changed
)) {
1883 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
1884 ldap_msgfree(result
);
1886 ldap_mods_free(mods
,True
);
1887 return NT_STATUS_UNSUCCESSFUL
;
1890 ldap_msgfree(result
);
1893 DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd
)));
1894 return NT_STATUS_UNSUCCESSFUL
;
1896 switch ( ldap_state
->schema_ver
) {
1897 case SCHEMAVER_SAMBAACCOUNT
:
1898 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectclass", LDAP_OBJ_SAMBAACCOUNT
);
1900 case SCHEMAVER_SAMBASAMACCOUNT
:
1901 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT
);
1904 DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
1908 ret
= ldapsam_modify_entry(my_methods
,newpwd
,dn
,mods
,ldap_op
, element_is_set_or_changed
);
1909 if (!NT_STATUS_IS_OK(ret
)) {
1910 DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
1911 pdb_get_username(newpwd
),dn
));
1912 ldap_mods_free(mods
, True
);
1916 DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd
)));
1917 ldap_mods_free(mods
, True
);
1919 return NT_STATUS_OK
;
1922 /**********************************************************************
1923 *********************************************************************/
1925 static int ldapsam_search_one_group (struct ldapsam_privates
*ldap_state
,
1927 LDAPMessage
** result
)
1929 int scope
= LDAP_SCOPE_SUBTREE
;
1933 attr_list
= get_attr_list(groupmap_attr_list
);
1934 rc
= smbldap_search(ldap_state
->smbldap_state
,
1935 lp_ldap_group_suffix (), scope
,
1936 filter
, attr_list
, 0, result
);
1937 free_attr_list( attr_list
);
1939 if (rc
!= LDAP_SUCCESS
) {
1940 char *ld_error
= NULL
;
1941 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1943 DEBUG(0, ("ldapsam_search_one_group: "
1944 "Problem during the LDAP search: LDAP error: %s (%s)\n",
1945 ld_error
?ld_error
:"(unknown)", ldap_err2string(rc
)));
1946 DEBUGADD(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
1947 lp_ldap_group_suffix(), filter
));
1948 SAFE_FREE(ld_error
);
1954 /**********************************************************************
1955 *********************************************************************/
1957 static BOOL
init_group_from_ldap(struct ldapsam_privates
*ldap_state
,
1958 GROUP_MAP
*map
, LDAPMessage
*entry
)
1962 if (ldap_state
== NULL
|| map
== NULL
|| entry
== NULL
||
1963 ldap_state
->smbldap_state
->ldap_struct
== NULL
) {
1964 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
1968 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1969 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
), temp
)) {
1970 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
1971 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
)));
1974 DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp
));
1976 map
->gid
= (gid_t
)atol(temp
);
1978 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1979 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_SID
), temp
)) {
1980 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
1981 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_SID
)));
1985 if (!string_to_sid(&map
->sid
, temp
)) {
1986 DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp
));
1990 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1991 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_TYPE
), temp
)) {
1992 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
1993 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_TYPE
)));
1996 map
->sid_name_use
= (enum SID_NAME_USE
)atol(temp
);
1998 if ((map
->sid_name_use
< SID_NAME_USER
) ||
1999 (map
->sid_name_use
> SID_NAME_UNKNOWN
)) {
2000 DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map
->sid_name_use
));
2004 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
2005 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DISPLAY_NAME
), temp
)) {
2007 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
2008 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_CN
), temp
))
2010 DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
2011 for gidNumber(%lu)\n",(unsigned long)map
->gid
));
2015 fstrcpy(map
->nt_name
, temp
);
2017 if (!smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
2018 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DESC
), temp
)) {
2021 fstrcpy(map
->comment
, temp
);
2026 /**********************************************************************
2027 *********************************************************************/
2029 static BOOL
init_ldap_from_group(LDAP
*ldap_struct
,
2030 LDAPMessage
*existing
,
2032 const GROUP_MAP
*map
)
2036 if (mods
== NULL
|| map
== NULL
) {
2037 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
2043 sid_to_string(tmp
, &map
->sid
);
2045 smbldap_make_mod(ldap_struct
, existing
, mods
,
2046 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GROUP_SID
), tmp
);
2047 pstr_sprintf(tmp
, "%i", map
->sid_name_use
);
2048 smbldap_make_mod(ldap_struct
, existing
, mods
,
2049 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GROUP_TYPE
), tmp
);
2051 smbldap_make_mod(ldap_struct
, existing
, mods
,
2052 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DISPLAY_NAME
), map
->nt_name
);
2053 smbldap_make_mod(ldap_struct
, existing
, mods
,
2054 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DESC
), map
->comment
);
2059 /**********************************************************************
2060 *********************************************************************/
2062 static NTSTATUS
ldapsam_getgroup(struct pdb_methods
*methods
,
2066 struct ldapsam_privates
*ldap_state
=
2067 (struct ldapsam_privates
*)methods
->private_data
;
2068 LDAPMessage
*result
= NULL
;
2069 LDAPMessage
*entry
= NULL
;
2072 if (ldapsam_search_one_group(ldap_state
, filter
, &result
)
2074 return NT_STATUS_NO_SUCH_GROUP
;
2077 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
2080 DEBUG(4, ("ldapsam_getgroup: Did not find group\n"));
2081 ldap_msgfree(result
);
2082 return NT_STATUS_NO_SUCH_GROUP
;
2086 DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: count=%d\n",
2088 ldap_msgfree(result
);
2089 return NT_STATUS_NO_SUCH_GROUP
;
2092 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
2095 ldap_msgfree(result
);
2096 return NT_STATUS_UNSUCCESSFUL
;
2099 if (!init_group_from_ldap(ldap_state
, map
, entry
)) {
2100 DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for group filter %s\n",
2102 ldap_msgfree(result
);
2103 return NT_STATUS_NO_SUCH_GROUP
;
2106 ldap_msgfree(result
);
2107 return NT_STATUS_OK
;
2110 /**********************************************************************
2111 *********************************************************************/
2113 static NTSTATUS
ldapsam_getgrsid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
2118 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%s))",
2120 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GROUP_SID
),
2121 sid_string_static(&sid
));
2123 return ldapsam_getgroup(methods
, filter
, map
);
2126 /**********************************************************************
2127 *********************************************************************/
2129 static NTSTATUS
ldapsam_getgrgid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
2134 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%lu))",
2136 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
),
2137 (unsigned long)gid
);
2139 return ldapsam_getgroup(methods
, filter
, map
);
2142 /**********************************************************************
2143 *********************************************************************/
2145 static NTSTATUS
ldapsam_getgrnam(struct pdb_methods
*methods
, GROUP_MAP
*map
,
2149 char *escape_name
= escape_ldap_string_alloc(name
);
2152 return NT_STATUS_NO_MEMORY
;
2155 pstr_sprintf(filter
, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
2157 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_DISPLAY_NAME
), escape_name
,
2158 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_CN
), escape_name
);
2160 SAFE_FREE(escape_name
);
2162 return ldapsam_getgroup(methods
, filter
, map
);
2165 static NTSTATUS
ldapsam_enum_group_memberships(struct pdb_methods
*methods
,
2166 const char *username
,
2168 DOM_SID
**sids
, gid_t
**gids
,
2171 struct ldapsam_privates
*ldap_state
=
2172 (struct ldapsam_privates
*)methods
->private_data
;
2173 struct smbldap_state
*conn
= ldap_state
->smbldap_state
;
2175 char *attrs
[] = { "gidNumber", "sambaSID", NULL
};
2178 LDAPMessage
*msg
= NULL
;
2180 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2181 int num_sids
, num_gids
;
2182 extern DOM_SID global_sid_NULL
;
2184 if (!lp_parm_bool(-1, "ldapsam", "trusted", False
))
2185 return pdb_default_enum_group_memberships(methods
, username
,
2192 escape_name
= escape_ldap_string_alloc(username
);
2194 if (escape_name
== NULL
)
2195 return NT_STATUS_NO_MEMORY
;
2197 pstr_sprintf(filter
, "(&(objectClass=posixGroup)"
2198 "(|(memberUid=%s)(gidNumber=%d)))",
2199 username
, primary_gid
);
2201 rc
= smbldap_search(conn
, lp_ldap_group_suffix(),
2202 LDAP_SCOPE_SUBTREE
, filter
, attrs
, 0, &msg
);
2204 if (rc
!= LDAP_SUCCESS
)
2213 /* We need to add the primary group as the first gid/sid */
2215 add_gid_to_array_unique(primary_gid
, gids
, &num_gids
);
2217 /* This sid will be replaced later */
2219 add_sid_to_array_unique(&global_sid_NULL
, sids
, &num_sids
);
2221 for (entry
= ldap_first_entry(conn
->ldap_struct
, msg
);
2223 entry
= ldap_next_entry(conn
->ldap_struct
, entry
))
2230 if (!smbldap_get_single_attribute(conn
->ldap_struct
,
2232 str
, sizeof(str
)-1))
2235 if (!string_to_sid(&sid
, str
))
2238 if (!smbldap_get_single_attribute(conn
->ldap_struct
,
2240 str
, sizeof(str
)-1))
2243 gid
= strtoul(str
, &end
, 10);
2245 if (PTR_DIFF(end
, str
) != strlen(str
))
2248 if (gid
== primary_gid
) {
2249 sid_copy(&(*sids
)[0], &sid
);
2251 add_gid_to_array_unique(gid
, gids
, &num_gids
);
2252 add_sid_to_array_unique(&sid
, sids
, &num_sids
);
2256 if (sid_compare(&global_sid_NULL
, &(*sids
)[0]) == 0) {
2257 DEBUG(3, ("primary group of [%s] not found\n", username
));
2261 *num_groups
= num_sids
;
2263 result
= NT_STATUS_OK
;
2267 SAFE_FREE(escape_name
);
2274 /**********************************************************************
2275 *********************************************************************/
2277 static int ldapsam_search_one_group_by_gid(struct ldapsam_privates
*ldap_state
,
2279 LDAPMessage
**result
)
2283 pstr_sprintf(filter
, "(&(|(objectClass=%s)(objectclass=%s))(%s=%lu))",
2284 LDAP_OBJ_POSIXGROUP
, LDAP_OBJ_IDMAP_ENTRY
,
2285 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
),
2286 (unsigned long)gid
);
2288 return ldapsam_search_one_group(ldap_state
, filter
, result
);
2291 /**********************************************************************
2292 *********************************************************************/
2294 static NTSTATUS
ldapsam_add_group_mapping_entry(struct pdb_methods
*methods
,
2297 struct ldapsam_privates
*ldap_state
=
2298 (struct ldapsam_privates
*)methods
->private_data
;
2299 LDAPMessage
*result
= NULL
;
2300 LDAPMod
**mods
= NULL
;
2311 if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods
, &dummy
,
2313 DEBUG(0, ("ldapsam_add_group_mapping_entry: Group %ld already exists in LDAP\n", (unsigned long)map
->gid
));
2314 return NT_STATUS_UNSUCCESSFUL
;
2317 rc
= ldapsam_search_one_group_by_gid(ldap_state
, map
->gid
, &result
);
2318 if (rc
!= LDAP_SUCCESS
) {
2319 ldap_msgfree(result
);
2320 return NT_STATUS_UNSUCCESSFUL
;
2323 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
2326 /* There's no posixGroup account, let's try to find an
2327 * appropriate idmap entry for aliases */
2333 ldap_msgfree(result
);
2335 pstrcpy( suffix
, lp_ldap_idmap_suffix() );
2336 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%u))",
2337 LDAP_OBJ_IDMAP_ENTRY
, LDAP_ATTRIBUTE_GIDNUMBER
,
2340 attr_list
= get_attr_list( sidmap_attr_list
);
2341 rc
= smbldap_search(ldap_state
->smbldap_state
, suffix
,
2342 LDAP_SCOPE_SUBTREE
, filter
, attr_list
,
2345 free_attr_list(attr_list
);
2347 if (rc
!= LDAP_SUCCESS
) {
2348 DEBUG(3,("Failure looking up entry (%s)\n",
2349 ldap_err2string(rc
) ));
2350 ldap_msgfree(result
);
2351 return NT_STATUS_UNSUCCESSFUL
;
2355 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
2357 ldap_msgfree(result
);
2358 return NT_STATUS_UNSUCCESSFUL
;
2362 DEBUG(2, ("ldapsam_add_group_mapping_entry: Group %lu must exist exactly once in LDAP\n",
2363 (unsigned long)map
->gid
));
2364 ldap_msgfree(result
);
2365 return NT_STATUS_UNSUCCESSFUL
;
2368 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
2369 tmp
= smbldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
2371 ldap_msgfree(result
);
2372 return NT_STATUS_UNSUCCESSFUL
;
2377 if (!init_ldap_from_group(ldap_state
->smbldap_state
->ldap_struct
,
2378 result
, &mods
, map
)) {
2379 DEBUG(0, ("ldapsam_add_group_mapping_entry: init_ldap_from_group failed!\n"));
2380 ldap_mods_free(mods
, True
);
2381 ldap_msgfree(result
);
2382 return NT_STATUS_UNSUCCESSFUL
;
2385 ldap_msgfree(result
);
2388 DEBUG(0, ("ldapsam_add_group_mapping_entry: mods is empty\n"));
2389 return NT_STATUS_UNSUCCESSFUL
;
2392 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_GROUPMAP
);
2394 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
2395 ldap_mods_free(mods
, True
);
2397 if (rc
!= LDAP_SUCCESS
) {
2398 char *ld_error
= NULL
;
2399 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
2401 DEBUG(0, ("ldapsam_add_group_mapping_entry: failed to add group %lu error: %s (%s)\n", (unsigned long)map
->gid
,
2402 ld_error
? ld_error
: "(unknown)", ldap_err2string(rc
)));
2403 SAFE_FREE(ld_error
);
2404 return NT_STATUS_UNSUCCESSFUL
;
2407 DEBUG(2, ("ldapsam_add_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map
->gid
));
2408 return NT_STATUS_OK
;
2411 /**********************************************************************
2412 *********************************************************************/
2414 static NTSTATUS
ldapsam_update_group_mapping_entry(struct pdb_methods
*methods
,
2417 struct ldapsam_privates
*ldap_state
=
2418 (struct ldapsam_privates
*)methods
->private_data
;
2421 LDAPMessage
*result
= NULL
;
2422 LDAPMessage
*entry
= NULL
;
2423 LDAPMod
**mods
= NULL
;
2425 rc
= ldapsam_search_one_group_by_gid(ldap_state
, map
->gid
, &result
);
2427 if (rc
!= LDAP_SUCCESS
) {
2428 return NT_STATUS_UNSUCCESSFUL
;
2431 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) == 0) {
2432 DEBUG(0, ("ldapsam_update_group_mapping_entry: No group to modify!\n"));
2433 ldap_msgfree(result
);
2434 return NT_STATUS_UNSUCCESSFUL
;
2437 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
2439 if (!init_ldap_from_group(ldap_state
->smbldap_state
->ldap_struct
,
2440 result
, &mods
, map
)) {
2441 DEBUG(0, ("ldapsam_update_group_mapping_entry: init_ldap_from_group failed\n"));
2442 ldap_msgfree(result
);
2444 ldap_mods_free(mods
,True
);
2445 return NT_STATUS_UNSUCCESSFUL
;
2449 DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: nothing to do\n"));
2450 ldap_msgfree(result
);
2451 return NT_STATUS_OK
;
2454 dn
= smbldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
2456 ldap_msgfree(result
);
2457 return NT_STATUS_UNSUCCESSFUL
;
2459 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
2462 ldap_mods_free(mods
, True
);
2463 ldap_msgfree(result
);
2465 if (rc
!= LDAP_SUCCESS
) {
2466 char *ld_error
= NULL
;
2467 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
2469 DEBUG(0, ("ldapsam_update_group_mapping_entry: failed to modify group %lu error: %s (%s)\n", (unsigned long)map
->gid
,
2470 ld_error
? ld_error
: "(unknown)", ldap_err2string(rc
)));
2471 SAFE_FREE(ld_error
);
2472 return NT_STATUS_UNSUCCESSFUL
;
2475 DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified group %lu in LDAP\n", (unsigned long)map
->gid
));
2476 return NT_STATUS_OK
;
2479 /**********************************************************************
2480 *********************************************************************/
2482 static NTSTATUS
ldapsam_delete_group_mapping_entry(struct pdb_methods
*methods
,
2485 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)methods
->private_data
;
2486 pstring sidstring
, filter
;
2487 LDAPMessage
*result
= NULL
;
2492 sid_to_string(sidstring
, &sid
);
2494 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%s))",
2495 LDAP_OBJ_GROUPMAP
, LDAP_ATTRIBUTE_SID
, sidstring
);
2497 rc
= ldapsam_search_one_group(ldap_state
, filter
, &result
);
2499 if (rc
!= LDAP_SUCCESS
) {
2500 return NT_STATUS_NO_SUCH_GROUP
;
2503 attr_list
= get_attr_list( groupmap_attr_list_to_delete
);
2504 ret
= ldapsam_delete_entry(ldap_state
, result
, LDAP_OBJ_GROUPMAP
, attr_list
);
2505 free_attr_list ( attr_list
);
2507 ldap_msgfree(result
);
2512 /**********************************************************************
2513 *********************************************************************/
2515 static NTSTATUS
ldapsam_setsamgrent(struct pdb_methods
*my_methods
, BOOL update
)
2517 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
2522 pstr_sprintf( filter
, "(objectclass=%s)", LDAP_OBJ_GROUPMAP
);
2523 attr_list
= get_attr_list( groupmap_attr_list
);
2524 rc
= smbldap_search(ldap_state
->smbldap_state
, lp_ldap_group_suffix(),
2525 LDAP_SCOPE_SUBTREE
, filter
,
2526 attr_list
, 0, &ldap_state
->result
);
2527 free_attr_list( attr_list
);
2529 if (rc
!= LDAP_SUCCESS
) {
2530 DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n", ldap_err2string(rc
)));
2531 DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n", lp_ldap_group_suffix(), filter
));
2532 ldap_msgfree(ldap_state
->result
);
2533 ldap_state
->result
= NULL
;
2534 return NT_STATUS_UNSUCCESSFUL
;
2537 DEBUG(2, ("ldapsam_setsamgrent: %d entries in the base!\n",
2538 ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
,
2539 ldap_state
->result
)));
2541 ldap_state
->entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, ldap_state
->result
);
2542 ldap_state
->index
= 0;
2544 return NT_STATUS_OK
;
2547 /**********************************************************************
2548 *********************************************************************/
2550 static void ldapsam_endsamgrent(struct pdb_methods
*my_methods
)
2552 ldapsam_endsampwent(my_methods
);
2555 /**********************************************************************
2556 *********************************************************************/
2558 static NTSTATUS
ldapsam_getsamgrent(struct pdb_methods
*my_methods
,
2561 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
2562 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
2566 if (!ldap_state
->entry
)
2569 ldap_state
->index
++;
2570 bret
= init_group_from_ldap(ldap_state
, map
, ldap_state
->entry
);
2572 ldap_state
->entry
= ldap_next_entry(ldap_state
->smbldap_state
->ldap_struct
,
2576 return NT_STATUS_OK
;
2579 /**********************************************************************
2580 *********************************************************************/
2582 static NTSTATUS
ldapsam_enum_group_mapping(struct pdb_methods
*methods
,
2583 enum SID_NAME_USE sid_name_use
,
2584 GROUP_MAP
**rmap
, int *num_entries
,
2594 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods
, False
))) {
2595 DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open passdb\n"));
2596 return NT_STATUS_ACCESS_DENIED
;
2599 while (NT_STATUS_IS_OK(ldapsam_getsamgrent(methods
, &map
))) {
2600 if (sid_name_use
!= SID_NAME_UNKNOWN
&&
2601 sid_name_use
!= map
.sid_name_use
) {
2602 DEBUG(11,("ldapsam_enum_group_mapping: group %s is not of the requested type\n", map
.nt_name
));
2605 if (unix_only
==ENUM_ONLY_MAPPED
&& map
.gid
==-1) {
2606 DEBUG(11,("ldapsam_enum_group_mapping: group %s is non mapped\n", map
.nt_name
));
2610 mapt
=SMB_REALLOC_ARRAY((*rmap
), GROUP_MAP
, entries
+1);
2612 DEBUG(0,("ldapsam_enum_group_mapping: Unable to enlarge group map!\n"));
2614 return NT_STATUS_UNSUCCESSFUL
;
2619 mapt
[entries
] = map
;
2624 ldapsam_endsamgrent(methods
);
2626 *num_entries
= entries
;
2628 return NT_STATUS_OK
;
2631 static NTSTATUS
ldapsam_modify_aliasmem(struct pdb_methods
*methods
,
2632 const DOM_SID
*alias
,
2633 const DOM_SID
*member
,
2636 struct ldapsam_privates
*ldap_state
=
2637 (struct ldapsam_privates
*)methods
->private_data
;
2639 LDAPMessage
*result
= NULL
;
2640 LDAPMessage
*entry
= NULL
;
2642 LDAPMod
**mods
= NULL
;
2647 pstr_sprintf(filter
, "(&(|(objectClass=%s)(objectclass=%s))(%s=%s))",
2648 LDAP_OBJ_GROUPMAP
, LDAP_OBJ_IDMAP_ENTRY
,
2649 get_attr_key2string(groupmap_attr_list
,
2650 LDAP_ATTR_GROUP_SID
),
2651 sid_string_static(alias
));
2653 if (ldapsam_search_one_group(ldap_state
, filter
,
2654 &result
) != LDAP_SUCCESS
)
2655 return NT_STATUS_NO_SUCH_ALIAS
;
2657 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
,
2661 DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
2662 ldap_msgfree(result
);
2663 return NT_STATUS_NO_SUCH_ALIAS
;
2667 DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for filter %s: "
2668 "count=%d\n", filter
, count
));
2669 ldap_msgfree(result
);
2670 return NT_STATUS_NO_SUCH_ALIAS
;
2673 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
,
2677 ldap_msgfree(result
);
2678 return NT_STATUS_UNSUCCESSFUL
;
2681 dn
= smbldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
2683 ldap_msgfree(result
);
2684 return NT_STATUS_UNSUCCESSFUL
;
2687 smbldap_set_mod(&mods
, modop
,
2688 get_attr_key2string(groupmap_attr_list
,
2689 LDAP_ATTR_SID_LIST
),
2690 sid_string_static(member
));
2692 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
2694 ldap_mods_free(mods
, True
);
2695 ldap_msgfree(result
);
2697 if (rc
!= LDAP_SUCCESS
) {
2698 char *ld_error
= NULL
;
2699 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
,
2700 LDAP_OPT_ERROR_STRING
,&ld_error
);
2702 DEBUG(0, ("ldapsam_modify_aliasmem: Could not modify alias "
2703 "for %s, error: %s (%s)\n", dn
, ldap_err2string(rc
),
2704 ld_error
?ld_error
:"unknown"));
2705 SAFE_FREE(ld_error
);
2707 return NT_STATUS_UNSUCCESSFUL
;
2712 return NT_STATUS_OK
;
2715 static NTSTATUS
ldapsam_add_aliasmem(struct pdb_methods
*methods
,
2716 const DOM_SID
*alias
,
2717 const DOM_SID
*member
)
2719 return ldapsam_modify_aliasmem(methods
, alias
, member
, LDAP_MOD_ADD
);
2722 static NTSTATUS
ldapsam_del_aliasmem(struct pdb_methods
*methods
,
2723 const DOM_SID
*alias
,
2724 const DOM_SID
*member
)
2726 return ldapsam_modify_aliasmem(methods
, alias
, member
,
2730 static NTSTATUS
ldapsam_enum_aliasmem(struct pdb_methods
*methods
,
2731 const DOM_SID
*alias
, DOM_SID
**members
,
2734 struct ldapsam_privates
*ldap_state
=
2735 (struct ldapsam_privates
*)methods
->private_data
;
2736 LDAPMessage
*result
= NULL
;
2737 LDAPMessage
*entry
= NULL
;
2746 pstr_sprintf(filter
, "(&(|(objectClass=%s)(objectclass=%s))(%s=%s))",
2747 LDAP_OBJ_GROUPMAP
, LDAP_OBJ_IDMAP_ENTRY
,
2748 get_attr_key2string(groupmap_attr_list
,
2749 LDAP_ATTR_GROUP_SID
),
2750 sid_string_static(alias
));
2752 if (ldapsam_search_one_group(ldap_state
, filter
,
2753 &result
) != LDAP_SUCCESS
)
2754 return NT_STATUS_NO_SUCH_ALIAS
;
2756 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
,
2760 DEBUG(4, ("ldapsam_enum_aliasmem: Did not find alias\n"));
2761 ldap_msgfree(result
);
2762 return NT_STATUS_NO_SUCH_ALIAS
;
2766 DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for filter %s: "
2767 "count=%d\n", filter
, count
));
2768 ldap_msgfree(result
);
2769 return NT_STATUS_NO_SUCH_ALIAS
;
2772 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
,
2776 ldap_msgfree(result
);
2777 return NT_STATUS_UNSUCCESSFUL
;
2780 values
= ldap_get_values(ldap_state
->smbldap_state
->ldap_struct
,
2782 get_attr_key2string(groupmap_attr_list
,
2783 LDAP_ATTR_SID_LIST
));
2785 if (values
== NULL
) {
2786 ldap_msgfree(result
);
2787 return NT_STATUS_OK
;
2790 count
= ldap_count_values(values
);
2792 for (i
=0; i
<count
; i
++) {
2795 if (!string_to_sid(&member
, values
[i
]))
2798 add_sid_to_array(&member
, members
, num_members
);
2801 ldap_value_free(values
);
2802 ldap_msgfree(result
);
2804 return NT_STATUS_OK
;
2807 static NTSTATUS
ldapsam_alias_memberships(struct pdb_methods
*methods
,
2808 const DOM_SID
*members
,
2810 DOM_SID
**aliases
, int *num_aliases
)
2812 struct ldapsam_privates
*ldap_state
=
2813 (struct ldapsam_privates
*)methods
->private_data
;
2816 char *attrs
[] = { LDAP_ATTRIBUTE_SID
, NULL
};
2818 LDAPMessage
*result
= NULL
;
2819 LDAPMessage
*entry
= NULL
;
2823 TALLOC_CTX
*mem_ctx
;
2825 mem_ctx
= talloc_init("ldapsam_alias_memberships");
2827 if (mem_ctx
== NULL
)
2828 return NT_STATUS_NO_MEMORY
;
2830 /* This query could be further optimized by adding a
2831 (&(sambaSID=<domain-sid>*)) so that only those aliases that are
2832 asked for in the getuseraliases are returned. */
2834 filter
= talloc_asprintf(mem_ctx
,
2835 "(&(|(objectclass=%s)(objectclass=%s))(|",
2836 LDAP_OBJ_GROUPMAP
, LDAP_OBJ_IDMAP_ENTRY
);
2838 for (i
=0; i
<num_members
; i
++)
2839 filter
= talloc_asprintf(mem_ctx
, "%s(sambaSIDList=%s)",
2841 sid_string_static(&members
[i
]));
2843 filter
= talloc_asprintf(mem_ctx
, "%s))", filter
);
2845 rc
= smbldap_search(ldap_state
->smbldap_state
, lp_ldap_group_suffix(),
2846 LDAP_SCOPE_SUBTREE
, filter
, attrs
, 0, &result
);
2848 talloc_destroy(mem_ctx
);
2850 if (rc
!= LDAP_SUCCESS
)
2851 return NT_STATUS_UNSUCCESSFUL
;
2856 ldap_struct
= ldap_state
->smbldap_state
->ldap_struct
;
2858 for (entry
= ldap_first_entry(ldap_struct
, result
);
2860 entry
= ldap_next_entry(ldap_struct
, entry
))
2865 if (!smbldap_get_single_attribute(ldap_struct
, entry
,
2871 if (!string_to_sid(&sid
, sid_str
))
2874 add_sid_to_array_unique(&sid
, aliases
, num_aliases
);
2877 ldap_msgfree(result
);
2878 return NT_STATUS_OK
;
2881 /**********************************************************************
2883 *********************************************************************/
2885 static void free_private_data(void **vp
)
2887 struct ldapsam_privates
**ldap_state
= (struct ldapsam_privates
**)vp
;
2889 smbldap_free_struct(&(*ldap_state
)->smbldap_state
);
2891 if ((*ldap_state
)->result
!= NULL
) {
2892 ldap_msgfree((*ldap_state
)->result
);
2893 (*ldap_state
)->result
= NULL
;
2898 /* No need to free any further, as it is talloc()ed */
2901 /**********************************************************************
2902 Intitalise the parts of the pdb_context that are common to all pdb_ldap modes
2903 *********************************************************************/
2905 static NTSTATUS
pdb_init_ldapsam_common(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
,
2906 const char *location
)
2909 struct ldapsam_privates
*ldap_state
;
2911 if (!NT_STATUS_IS_OK(nt_status
= make_pdb_methods(pdb_context
->mem_ctx
, pdb_method
))) {
2915 (*pdb_method
)->name
= "ldapsam";
2917 (*pdb_method
)->setsampwent
= ldapsam_setsampwent
;
2918 (*pdb_method
)->endsampwent
= ldapsam_endsampwent
;
2919 (*pdb_method
)->getsampwent
= ldapsam_getsampwent
;
2920 (*pdb_method
)->getsampwnam
= ldapsam_getsampwnam
;
2921 (*pdb_method
)->getsampwsid
= ldapsam_getsampwsid
;
2922 (*pdb_method
)->add_sam_account
= ldapsam_add_sam_account
;
2923 (*pdb_method
)->update_sam_account
= ldapsam_update_sam_account
;
2924 (*pdb_method
)->delete_sam_account
= ldapsam_delete_sam_account
;
2926 (*pdb_method
)->getgrsid
= ldapsam_getgrsid
;
2927 (*pdb_method
)->getgrgid
= ldapsam_getgrgid
;
2928 (*pdb_method
)->getgrnam
= ldapsam_getgrnam
;
2929 (*pdb_method
)->add_group_mapping_entry
= ldapsam_add_group_mapping_entry
;
2930 (*pdb_method
)->update_group_mapping_entry
= ldapsam_update_group_mapping_entry
;
2931 (*pdb_method
)->delete_group_mapping_entry
= ldapsam_delete_group_mapping_entry
;
2932 (*pdb_method
)->enum_group_mapping
= ldapsam_enum_group_mapping
;
2933 (*pdb_method
)->enum_group_memberships
= ldapsam_enum_group_memberships
;
2935 /* TODO: Setup private data and free */
2937 ldap_state
= TALLOC_ZERO_P(pdb_context
->mem_ctx
, struct ldapsam_privates
);
2939 DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
2940 return NT_STATUS_NO_MEMORY
;
2943 if (!NT_STATUS_IS_OK(nt_status
=
2944 smbldap_init(pdb_context
->mem_ctx
, location
,
2945 &ldap_state
->smbldap_state
)));
2947 ldap_state
->domain_name
= talloc_strdup(pdb_context
->mem_ctx
, get_global_sam_name());
2948 if (!ldap_state
->domain_name
) {
2949 return NT_STATUS_NO_MEMORY
;
2952 (*pdb_method
)->private_data
= ldap_state
;
2954 (*pdb_method
)->free_private_data
= free_private_data
;
2956 return NT_STATUS_OK
;
2959 /**********************************************************************
2960 Initialise the 'compat' mode for pdb_ldap
2961 *********************************************************************/
2963 static NTSTATUS
pdb_init_ldapsam_compat(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
2966 struct ldapsam_privates
*ldap_state
;
2968 #ifdef WITH_LDAP_SAMCONFIG
2970 int ldap_port
= lp_ldap_port();
2972 /* remap default port if not using SSL (ie clear or TLS) */
2973 if ( (lp_ldap_ssl() != LDAP_SSL_ON
) && (ldap_port
== 636) ) {
2977 location
= talloc_asprintf(pdb_context
->mem_ctx
, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON
? "ldaps" : "ldap", lp_ldap_server(), ldap_port
);
2979 return NT_STATUS_NO_MEMORY
;
2984 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_ldapsam_common(pdb_context
, pdb_method
, location
))) {
2988 (*pdb_method
)->name
= "ldapsam_compat";
2990 ldap_state
= (*pdb_method
)->private_data
;
2991 ldap_state
->schema_ver
= SCHEMAVER_SAMBAACCOUNT
;
2993 sid_copy(&ldap_state
->domain_sid
, get_global_sam_sid());
2995 return NT_STATUS_OK
;
2998 /**********************************************************************
2999 Initialise the normal mode for pdb_ldap
3000 *********************************************************************/
3002 static NTSTATUS
pdb_init_ldapsam(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
3005 struct ldapsam_privates
*ldap_state
;
3006 uint32 alg_rid_base
;
3007 pstring alg_rid_base_string
;
3008 LDAPMessage
*result
= NULL
;
3009 LDAPMessage
*entry
= NULL
;
3010 DOM_SID ldap_domain_sid
;
3011 DOM_SID secrets_domain_sid
;
3012 pstring domain_sid_string
;
3014 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_ldapsam_common(pdb_context
, pdb_method
, location
))) {
3018 (*pdb_method
)->name
= "ldapsam";
3020 (*pdb_method
)->add_aliasmem
= ldapsam_add_aliasmem
;
3021 (*pdb_method
)->del_aliasmem
= ldapsam_del_aliasmem
;
3022 (*pdb_method
)->enum_aliasmem
= ldapsam_enum_aliasmem
;
3023 (*pdb_method
)->enum_alias_memberships
= ldapsam_alias_memberships
;
3025 ldap_state
= (*pdb_method
)->private_data
;
3026 ldap_state
->schema_ver
= SCHEMAVER_SAMBASAMACCOUNT
;
3028 /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
3030 nt_status
= smbldap_search_domain_info(ldap_state
->smbldap_state
, &result
,
3031 ldap_state
->domain_name
, True
);
3033 if ( !NT_STATUS_IS_OK(nt_status
) ) {
3034 DEBUG(2, ("pdb_init_ldapsam: WARNING: Could not get domain info, nor add one to the domain\n"));
3035 DEBUGADD(2, ("pdb_init_ldapsam: Continuing on regardless, will be unable to allocate new users/groups, \
3036 and will risk BDCs having inconsistant SIDs\n"));
3037 sid_copy(&ldap_state
->domain_sid
, get_global_sam_sid());
3038 return NT_STATUS_OK
;
3041 /* Given that the above might fail, everything below this must be optional */
3043 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
3045 DEBUG(0, ("pdb_init_ldapsam: Could not get domain info entry\n"));
3046 ldap_msgfree(result
);
3047 return NT_STATUS_UNSUCCESSFUL
;
3050 if (smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
3051 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
3052 domain_sid_string
)) {
3054 if (!string_to_sid(&ldap_domain_sid
, domain_sid_string
)) {
3055 DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be read as a valid SID\n", domain_sid_string
));
3056 return NT_STATUS_INVALID_PARAMETER
;
3058 found_sid
= secrets_fetch_domain_sid(ldap_state
->domain_name
, &secrets_domain_sid
);
3059 if (!found_sid
|| !sid_equal(&secrets_domain_sid
, &ldap_domain_sid
)) {
3060 fstring new_sid_str
, old_sid_str
;
3061 DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain %s based on pdb_ldap results %s -> %s\n",
3062 ldap_state
->domain_name
,
3063 sid_to_string(old_sid_str
, &secrets_domain_sid
),
3064 sid_to_string(new_sid_str
, &ldap_domain_sid
)));
3066 /* reset secrets.tdb sid */
3067 secrets_store_domain_sid(ldap_state
->domain_name
, &ldap_domain_sid
);
3068 DEBUG(1, ("New global sam SID: %s\n", sid_to_string(new_sid_str
, get_global_sam_sid())));
3070 sid_copy(&ldap_state
->domain_sid
, &ldap_domain_sid
);
3073 if (smbldap_get_single_pstring(ldap_state
->smbldap_state
->ldap_struct
, entry
,
3074 get_attr_key2string( dominfo_attr_list
, LDAP_ATTR_ALGORITHMIC_RID_BASE
),
3075 alg_rid_base_string
)) {
3076 alg_rid_base
= (uint32
)atol(alg_rid_base_string
);
3077 if (alg_rid_base
!= algorithmic_rid_base()) {
3078 DEBUG(0, ("The value of 'algorithmic RID base' has changed since the LDAP\n"
3079 "database was initialised. Aborting. \n"));
3080 ldap_msgfree(result
);
3081 return NT_STATUS_UNSUCCESSFUL
;
3084 ldap_msgfree(result
);
3086 return NT_STATUS_OK
;
3089 NTSTATUS
pdb_ldap_init(void)
3092 if (!NT_STATUS_IS_OK(nt_status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ldapsam", pdb_init_ldapsam
)))
3095 if (!NT_STATUS_IS_OK(nt_status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ldapsam_compat", pdb_init_ldapsam_compat
)))
3098 return NT_STATUS_OK
;