2 Unix SMB/CIFS mplementation.
3 LDAP protocol helper functions for SAMBA
4 Copyright (C) Jean François Micouleau 1998
5 Copyright (C) Gerald Carter 2001-2003
6 Copyright (C) Shahms King 2001
7 Copyright (C) Andrew Bartlett 2002-2003
8 Copyright (C) Stefan (metze) Metzmacher 2002
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 "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
)
119 case SCHEMAVER_SAMBAACCOUNT
:
120 return get_attr_key2string( attrib_map_v22
, key
);
122 case SCHEMAVER_SAMBASAMACCOUNT
:
123 return get_attr_key2string( attrib_map_v30
, key
);
126 DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
132 /**********************************************************************
133 return the list of attribute names given a user schema version
134 **********************************************************************/
136 static char** get_userattr_list( int schema_ver
)
138 switch ( schema_ver
)
140 case SCHEMAVER_SAMBAACCOUNT
:
141 return get_attr_list( attrib_map_v22
);
143 case SCHEMAVER_SAMBASAMACCOUNT
:
144 return get_attr_list( attrib_map_v30
);
146 DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
152 /*******************************************************************
153 generate the LDAP search filter for the objectclass based on the
154 version of the schema we are using
155 ******************************************************************/
157 static const char* get_objclass_filter( int schema_ver
)
159 static fstring objclass_filter
;
163 case SCHEMAVER_SAMBAACCOUNT
:
164 fstr_sprintf( objclass_filter
, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT
);
166 case SCHEMAVER_SAMBASAMACCOUNT
:
167 fstr_sprintf( objclass_filter
, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT
);
170 DEBUG(0,("pdb_ldapsam: get_objclass_filter(): Invalid schema version specified!\n"));
174 return objclass_filter
;
177 /*******************************************************************
178 run the search by name.
179 ******************************************************************/
180 static int ldapsam_search_suffix_by_name (struct ldapsam_privates
*ldap_state
,
182 LDAPMessage
** result
, char **attr
)
185 char *escape_user
= escape_ldap_string_alloc(user
);
188 return LDAP_NO_MEMORY
;
192 * in the filter expression, replace %u with the real name
193 * so in ldap filter, %u MUST exist :-)
195 pstr_sprintf(filter
, "(&%s%s)", lp_ldap_filter(),
196 get_objclass_filter(ldap_state
->schema_ver
));
199 * have to use this here because $ is filtered out
204 all_string_sub(filter
, "%u", escape_user
, sizeof(pstring
));
205 SAFE_FREE(escape_user
);
207 return smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, attr
, result
);
210 /*******************************************************************
211 run the search by rid.
212 ******************************************************************/
213 static int ldapsam_search_suffix_by_rid (struct ldapsam_privates
*ldap_state
,
214 uint32 rid
, LDAPMessage
** result
,
220 pstr_sprintf(filter
, "(&(rid=%i)%s)", rid
,
221 get_objclass_filter(ldap_state
->schema_ver
));
223 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, attr
, result
);
228 /*******************************************************************
229 run the search by SID.
230 ******************************************************************/
231 static int ldapsam_search_suffix_by_sid (struct ldapsam_privates
*ldap_state
,
232 const DOM_SID
*sid
, LDAPMessage
** result
,
239 pstr_sprintf(filter
, "(&(%s=%s)%s)",
240 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
241 sid_to_string(sid_string
, sid
),
242 get_objclass_filter(ldap_state
->schema_ver
));
244 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, attr
, result
);
249 /*******************************************************************
250 Delete complete object or objectclass and attrs from
251 object found in search_result depending on lp_ldap_delete_dn
252 ******************************************************************/
253 static NTSTATUS
ldapsam_delete_entry(struct ldapsam_privates
*ldap_state
,
255 const char *objectclass
,
260 LDAPMod
**mods
= NULL
;
262 BerElement
*ptr
= NULL
;
264 rc
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
267 DEBUG(0, ("Entry must exist exactly once!\n"));
268 return NT_STATUS_UNSUCCESSFUL
;
271 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
272 dn
= ldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
274 if (lp_ldap_delete_dn()) {
275 NTSTATUS ret
= NT_STATUS_OK
;
276 rc
= smbldap_delete(ldap_state
->smbldap_state
, dn
);
278 if (rc
!= LDAP_SUCCESS
) {
279 DEBUG(0, ("Could not delete object %s\n", dn
));
280 ret
= NT_STATUS_UNSUCCESSFUL
;
286 /* Ok, delete only the SAM attributes */
288 for (name
= ldap_first_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
, &ptr
);
290 name
= ldap_next_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
, ptr
))
294 /* We are only allowed to delete the attributes that
297 for (attrib
= attrs
; *attrib
!= NULL
; attrib
++)
299 if (StrCaseCmp(*attrib
, name
) == 0) {
300 DEBUG(10, ("deleting attribute %s\n", name
));
301 smbldap_set_mod(&mods
, LDAP_MOD_DELETE
, name
, NULL
);
312 smbldap_set_mod(&mods
, LDAP_MOD_DELETE
, "objectClass", objectclass
);
314 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
315 ldap_mods_free(mods
, True
);
317 if (rc
!= LDAP_SUCCESS
) {
318 char *ld_error
= NULL
;
319 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
322 DEBUG(0, ("could not delete attributes for %s, error: %s (%s)\n",
323 dn
, ldap_err2string(rc
), ld_error
?ld_error
:"unknown"));
326 return NT_STATUS_UNSUCCESSFUL
;
334 /* New Interface is being implemented here */
336 /**********************************************************************
337 Initialize SAM_ACCOUNT from an LDAP query (unix attributes only)
338 *********************************************************************/
339 static BOOL
get_unix_attributes (struct ldapsam_privates
*ldap_state
,
340 SAM_ACCOUNT
* sampass
,
349 if ((ldap_values
= ldap_get_values (ldap_state
->smbldap_state
->ldap_struct
, entry
, "objectClass")) == NULL
) {
350 DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
354 for (values
=ldap_values
;*values
;values
++) {
355 if (strcasecmp(*values
, LDAP_OBJ_POSIXACCOUNT
) == 0) {
360 if (!*values
) { /*end of array, no posixAccount */
361 DEBUG(10, ("user does not have %s attributes\n", LDAP_OBJ_POSIXACCOUNT
));
362 ldap_value_free(ldap_values
);
365 ldap_value_free(ldap_values
);
367 if ( !smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
368 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_UNIX_HOME
), homedir
) )
373 if ( !smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
374 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_GIDNUMBER
), temp
) )
379 *gid
= (gid_t
)atol(temp
);
381 pdb_set_unix_homedir(sampass
, homedir
, PDB_SET
);
383 DEBUG(10, ("user has %s attributes\n", LDAP_OBJ_POSIXACCOUNT
));
389 /**********************************************************************
390 Initialize SAM_ACCOUNT from an LDAP query
391 (Based on init_sam_from_buffer in pdb_tdb.c)
392 *********************************************************************/
393 static BOOL
init_sam_from_ldap (struct ldapsam_privates
*ldap_state
,
394 SAM_ACCOUNT
* sampass
,
401 pass_can_change_time
,
402 pass_must_change_time
;
415 uint8 smblmpwd
[LM_HASH_LEN
],
416 smbntpwd
[NT_HASH_LEN
];
417 uint16 acct_ctrl
= 0,
420 uint8 hours
[MAX_HOURS_LEN
];
423 gid_t gid
= getegid();
426 * do a little initialization
430 nt_username
[0] = '\0';
434 logon_script
[0] = '\0';
435 profile_path
[0] = '\0';
437 munged_dial
[0] = '\0';
438 workstations
[0] = '\0';
441 if (sampass
== NULL
|| ldap_state
== NULL
|| entry
== NULL
) {
442 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
446 if (ldap_state
->smbldap_state
->ldap_struct
== NULL
) {
447 DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->ldap_struct is NULL!\n"));
451 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
, "uid", username
)) {
452 DEBUG(1, ("No uid attribute found for this user!\n"));
456 DEBUG(2, ("Entry found for user: %s\n", username
));
458 pstrcpy(nt_username
, username
);
460 pstrcpy(domain
, ldap_state
->domain_name
);
462 pdb_set_username(sampass
, username
, PDB_SET
);
464 pdb_set_domain(sampass
, domain
, PDB_DEFAULT
);
465 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
467 /* deal with different attributes between the schema first */
469 if ( ldap_state
->schema_ver
== SCHEMAVER_SAMBASAMACCOUNT
)
471 if (smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
472 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
), temp
))
474 pdb_set_user_sid_from_string(sampass
, temp
, PDB_SET
);
477 if (smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
478 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PRIMARY_GROUP_SID
), temp
))
480 pdb_set_group_sid_from_string(sampass
, temp
, PDB_SET
);
484 pdb_set_group_sid_from_rid(sampass
, DOMAIN_GROUP_RID_USERS
, PDB_DEFAULT
);
491 if (smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
492 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_RID
), temp
))
494 user_rid
= (uint32
)atol(temp
);
495 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
498 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
499 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PRIMARY_GROUP_RID
), temp
))
501 pdb_set_group_sid_from_rid(sampass
, DOMAIN_GROUP_RID_USERS
, PDB_DEFAULT
);
505 group_rid
= (uint32
)atol(temp
);
507 /* for some reason, we often have 0 as a primary group RID.
508 Make sure that we treat this just as a 'default' value */
511 pdb_set_group_sid_from_rid(sampass
, group_rid
, PDB_SET
);
513 pdb_set_group_sid_from_rid(sampass
, DOMAIN_GROUP_RID_USERS
, PDB_DEFAULT
);
517 if (pdb_get_init_flags(sampass
,PDB_USERSID
) == PDB_DEFAULT
) {
518 DEBUG(1, ("no %s or %s attribute found for this user %s\n",
519 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
520 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_RID
),
527 * If so configured, try and get the values from LDAP
530 if (lp_ldap_trust_ids() && (get_unix_attributes(ldap_state
, sampass
, entry
, &gid
)))
532 if (pdb_get_init_flags(sampass
,PDB_GROUPSID
) == PDB_DEFAULT
)
535 /* call the mapping code here */
536 if(pdb_getgrgid(&map
, gid
)) {
537 pdb_set_group_sid(sampass
, &map
.sid
, PDB_SET
);
540 pdb_set_group_sid_from_rid(sampass
, pdb_gid_to_group_rid(gid
), PDB_SET
);
545 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
546 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_LAST_SET
), temp
))
548 /* leave as default */
550 pass_last_set_time
= (time_t) atol(temp
);
551 pdb_set_pass_last_set_time(sampass
, pass_last_set_time
, PDB_SET
);
554 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
555 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_TIME
), temp
))
557 /* leave as default */
559 logon_time
= (time_t) atol(temp
);
560 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
563 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
564 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGOFF_TIME
), temp
))
566 /* leave as default */
568 logoff_time
= (time_t) atol(temp
);
569 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
572 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
573 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_KICKOFF_TIME
), temp
))
575 /* leave as default */
577 kickoff_time
= (time_t) atol(temp
);
578 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
581 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
582 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_CAN_CHANGE
), temp
))
584 /* leave as default */
586 pass_can_change_time
= (time_t) atol(temp
);
587 pdb_set_pass_can_change_time(sampass
, pass_can_change_time
, PDB_SET
);
590 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
591 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_MUST_CHANGE
), temp
))
593 /* leave as default */
595 pass_must_change_time
= (time_t) atol(temp
);
596 pdb_set_pass_must_change_time(sampass
, pass_must_change_time
, PDB_SET
);
599 /* recommend that 'gecos' and 'displayName' should refer to the same
600 * attribute OID. userFullName depreciated, only used by Samba
601 * primary rules of LDAP: don't make a new attribute when one is already defined
602 * that fits your needs; using cn then displayName rather than 'userFullName'
605 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
606 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DISPLAY_NAME
), fullname
))
608 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
609 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_CN
), fullname
))
611 /* leave as default */
613 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
616 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
619 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
620 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_DRIVE
), dir_drive
))
622 pdb_set_dir_drive(sampass
, talloc_sub_specified(sampass
->mem_ctx
,
628 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
631 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
632 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_PATH
), homedir
))
634 pdb_set_homedir(sampass
, talloc_sub_specified(sampass
->mem_ctx
,
640 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
643 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
644 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_SCRIPT
), logon_script
))
646 pdb_set_logon_script(sampass
, talloc_sub_specified(sampass
->mem_ctx
,
652 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
655 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
656 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PROFILE_PATH
), profile_path
))
658 pdb_set_profile_path(sampass
, talloc_sub_specified(sampass
->mem_ctx
,
664 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
667 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
668 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DESC
), acct_desc
))
670 /* leave as default */
672 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
675 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
676 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_WKS
), workstations
))
678 /* leave as default */;
680 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
683 /* FIXME: hours stuff should be cleaner */
687 memset(hours
, 0xff, hours_len
);
689 if (!smbldap_get_single_attribute (ldap_state
->smbldap_state
->ldap_struct
, entry
,
690 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LMPW
), temp
))
692 /* leave as default */
694 pdb_gethexpwd(temp
, smblmpwd
);
695 memset((char *)temp
, '\0', strlen(temp
)+1);
696 if (!pdb_set_lanman_passwd(sampass
, smblmpwd
, PDB_SET
))
698 ZERO_STRUCT(smblmpwd
);
701 if (!smbldap_get_single_attribute (ldap_state
->smbldap_state
->ldap_struct
, entry
,
702 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_NTPW
), temp
))
704 /* leave as default */
706 pdb_gethexpwd(temp
, smbntpwd
);
707 memset((char *)temp
, '\0', strlen(temp
)+1);
708 if (!pdb_set_nt_passwd(sampass
, smbntpwd
, PDB_SET
))
710 ZERO_STRUCT(smbntpwd
);
713 if (!smbldap_get_single_attribute (ldap_state
->smbldap_state
->ldap_struct
, entry
,
714 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_ACB_INFO
), temp
))
716 acct_ctrl
|= ACB_NORMAL
;
718 acct_ctrl
= pdb_decode_acct_ctrl(temp
);
721 acct_ctrl
|= ACB_NORMAL
;
723 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
726 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
727 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
729 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
731 /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
732 /* pdb_set_unknown_5(sampass, unknown5, PDB_SET); */
733 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
735 pdb_set_hours(sampass
, hours
, PDB_SET
);
740 /**********************************************************************
741 Initialize SAM_ACCOUNT from an LDAP query
742 (Based on init_buffer_from_sam in pdb_tdb.c)
743 *********************************************************************/
744 static BOOL
init_ldap_from_sam (struct ldapsam_privates
*ldap_state
,
745 LDAPMessage
*existing
,
746 LDAPMod
*** mods
, SAM_ACCOUNT
* sampass
,
747 BOOL (*need_update
)(const SAM_ACCOUNT
*,
753 if (mods
== NULL
|| sampass
== NULL
) {
754 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
761 * took out adding "objectclass: sambaAccount"
762 * do this on a per-mod basis
764 if (need_update(sampass
, PDB_USERNAME
))
765 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
766 "uid", pdb_get_username(sampass
));
768 DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass
)));
770 /* only update the RID if we actually need to */
771 if (need_update(sampass
, PDB_USERSID
))
774 fstring dom_sid_string
;
775 const DOM_SID
*user_sid
= pdb_get_user_sid(sampass
);
777 switch ( ldap_state
->schema_ver
)
779 case SCHEMAVER_SAMBAACCOUNT
:
780 if (!sid_peek_check_rid(&ldap_state
->domain_sid
, user_sid
, &rid
)) {
781 DEBUG(1, ("User's SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
782 sid_to_string(sid_string
, user_sid
),
783 sid_to_string(dom_sid_string
, &ldap_state
->domain_sid
)));
786 slprintf(temp
, sizeof(temp
) - 1, "%i", rid
);
787 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
788 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_RID
),
792 case SCHEMAVER_SAMBASAMACCOUNT
:
793 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
794 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
795 sid_to_string(sid_string
, user_sid
));
799 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
804 /* we don't need to store the primary group RID - so leaving it
805 'free' to hang off the unix primary group makes life easier */
807 if (need_update(sampass
, PDB_GROUPSID
))
810 fstring dom_sid_string
;
811 const DOM_SID
*group_sid
= pdb_get_group_sid(sampass
);
813 switch ( ldap_state
->schema_ver
)
815 case SCHEMAVER_SAMBAACCOUNT
:
816 if (!sid_peek_check_rid(&ldap_state
->domain_sid
, group_sid
, &rid
)) {
817 DEBUG(1, ("User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
818 sid_to_string(sid_string
, group_sid
),
819 sid_to_string(dom_sid_string
, &ldap_state
->domain_sid
)));
823 slprintf(temp
, sizeof(temp
) - 1, "%i", rid
);
824 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
825 get_userattr_key2string(ldap_state
->schema_ver
,
826 LDAP_ATTR_PRIMARY_GROUP_RID
), temp
);
829 case SCHEMAVER_SAMBASAMACCOUNT
:
830 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
831 get_userattr_key2string(ldap_state
->schema_ver
,
832 LDAP_ATTR_PRIMARY_GROUP_SID
), sid_to_string(sid_string
, group_sid
));
836 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
842 /* displayName, cn, and gecos should all be the same
843 * most easily accomplished by giving them the same OID
844 * gecos isn't set here b/c it should be handled by the
846 * We change displayName only and fall back to cn if
850 if (need_update(sampass
, PDB_FULLNAME
))
851 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
852 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DISPLAY_NAME
),
853 pdb_get_fullname(sampass
));
855 if (need_update(sampass
, PDB_ACCTDESC
))
856 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
857 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DESC
),
858 pdb_get_acct_desc(sampass
));
860 if (need_update(sampass
, PDB_WORKSTATIONS
))
861 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
862 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_WKS
),
863 pdb_get_workstations(sampass
));
865 if (need_update(sampass
, PDB_SMBHOME
))
866 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
867 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_PATH
),
868 pdb_get_homedir(sampass
));
870 if (need_update(sampass
, PDB_DRIVE
))
871 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
872 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_DRIVE
),
873 pdb_get_dir_drive(sampass
));
875 if (need_update(sampass
, PDB_LOGONSCRIPT
))
876 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
877 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_SCRIPT
),
878 pdb_get_logon_script(sampass
));
880 if (need_update(sampass
, PDB_PROFILE
))
881 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
882 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PROFILE_PATH
),
883 pdb_get_profile_path(sampass
));
885 slprintf(temp
, sizeof(temp
) - 1, "%li", pdb_get_logon_time(sampass
));
886 if (need_update(sampass
, PDB_LOGONTIME
))
887 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
888 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_TIME
), temp
);
890 slprintf(temp
, sizeof(temp
) - 1, "%li", pdb_get_logoff_time(sampass
));
891 if (need_update(sampass
, PDB_LOGOFFTIME
))
892 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
893 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGOFF_TIME
), temp
);
895 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_kickoff_time(sampass
));
896 if (need_update(sampass
, PDB_KICKOFFTIME
))
897 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
898 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_KICKOFF_TIME
), temp
);
900 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_can_change_time(sampass
));
901 if (need_update(sampass
, PDB_CANCHANGETIME
))
902 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
903 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_CAN_CHANGE
), temp
);
905 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_must_change_time(sampass
));
906 if (need_update(sampass
, PDB_MUSTCHANGETIME
))
907 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
908 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_MUST_CHANGE
), temp
);
910 if ((pdb_get_acct_ctrl(sampass
)&(ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
))
911 || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY
))
914 pdb_sethexpwd(temp
, pdb_get_lanman_passwd(sampass
),
915 pdb_get_acct_ctrl(sampass
));
917 if (need_update(sampass
, PDB_LMPASSWD
))
918 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
919 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LMPW
),
922 pdb_sethexpwd (temp
, pdb_get_nt_passwd(sampass
),
923 pdb_get_acct_ctrl(sampass
));
925 if (need_update(sampass
, PDB_NTPASSWD
))
926 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
927 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_NTPW
),
930 slprintf (temp
, sizeof (temp
) - 1, "%li", pdb_get_pass_last_set_time(sampass
));
931 if (need_update(sampass
, PDB_PASSLASTSET
))
932 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
933 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_LAST_SET
),
937 /* FIXME: Hours stuff goes in LDAP */
939 if (need_update(sampass
, PDB_ACCTCTRL
))
940 smbldap_make_mod(ldap_state
->smbldap_state
->ldap_struct
, existing
, mods
,
941 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_ACB_INFO
),
942 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass
), NEW_PW_FORMAT_SPACE_PADDED_LEN
));
949 /**********************************************************************
950 Connect to LDAP server for password enumeration
951 *********************************************************************/
952 static NTSTATUS
ldapsam_setsampwent(struct pdb_methods
*my_methods
, BOOL update
)
954 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
959 pstr_sprintf( filter
, "(&%s%s)", lp_ldap_filter(),
960 get_objclass_filter(ldap_state
->schema_ver
));
961 all_string_sub(filter
, "%u", "*", sizeof(pstring
));
963 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
964 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
,
965 attr_list
, &ldap_state
->result
);
966 free_attr_list( attr_list
);
968 if (rc
!= LDAP_SUCCESS
) {
969 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc
)));
970 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter
));
971 ldap_msgfree(ldap_state
->result
);
972 ldap_state
->result
= NULL
;
973 return NT_STATUS_UNSUCCESSFUL
;
976 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
977 ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
,
978 ldap_state
->result
)));
980 ldap_state
->entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
,
982 ldap_state
->index
= 0;
987 /**********************************************************************
988 End enumeration of the LDAP password list
989 *********************************************************************/
990 static void ldapsam_endsampwent(struct pdb_methods
*my_methods
)
992 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
993 if (ldap_state
->result
) {
994 ldap_msgfree(ldap_state
->result
);
995 ldap_state
->result
= NULL
;
999 /**********************************************************************
1000 Get the next entry in the LDAP password database
1001 *********************************************************************/
1002 static NTSTATUS
ldapsam_getsampwent(struct pdb_methods
*my_methods
, SAM_ACCOUNT
*user
)
1004 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1005 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1009 if (!ldap_state
->entry
)
1012 ldap_state
->index
++;
1013 bret
= init_sam_from_ldap(ldap_state
, user
, ldap_state
->entry
);
1015 ldap_state
->entry
= ldap_next_entry(ldap_state
->smbldap_state
->ldap_struct
,
1019 return NT_STATUS_OK
;
1022 /**********************************************************************
1023 Get SAM_ACCOUNT entry from LDAP by username
1024 *********************************************************************/
1025 static NTSTATUS
ldapsam_getsampwnam(struct pdb_methods
*my_methods
, SAM_ACCOUNT
*user
, const char *sname
)
1027 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1028 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1029 LDAPMessage
*result
;
1035 attr_list
= get_userattr_list( ldap_state
->schema_ver
);
1036 rc
= ldapsam_search_suffix_by_name(ldap_state
, sname
, &result
, attr_list
);
1037 free_attr_list( attr_list
);
1039 if ( rc
!= LDAP_SUCCESS
)
1040 return NT_STATUS_NO_SUCH_USER
;
1042 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1046 ("Unable to locate user [%s] count=%d\n", sname
,
1048 ldap_msgfree(result
);
1049 return NT_STATUS_NO_SUCH_USER
;
1050 } else if (count
> 1) {
1052 ("Duplicate entries for this user [%s] Failing. count=%d\n", sname
,
1054 ldap_msgfree(result
);
1055 return NT_STATUS_NO_SUCH_USER
;
1058 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1060 if (!init_sam_from_ldap(ldap_state
, user
, entry
)) {
1061 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname
));
1062 ldap_msgfree(result
);
1063 return NT_STATUS_NO_SUCH_USER
;
1065 pdb_set_backend_private_data(user
, result
,
1066 private_data_free_fn
,
1067 my_methods
, PDB_CHANGED
);
1070 ldap_msgfree(result
);
1075 static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates
*ldap_state
,
1076 const DOM_SID
*sid
, LDAPMessage
**result
)
1082 switch ( ldap_state
->schema_ver
)
1084 case SCHEMAVER_SAMBASAMACCOUNT
:
1085 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1086 rc
= ldapsam_search_suffix_by_sid(ldap_state
, sid
, result
, attr_list
);
1087 free_attr_list( attr_list
);
1089 if ( rc
!= LDAP_SUCCESS
)
1093 case SCHEMAVER_SAMBAACCOUNT
:
1094 if (!sid_peek_check_rid(&ldap_state
->domain_sid
, sid
, &rid
)) {
1098 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1099 rc
= ldapsam_search_suffix_by_rid(ldap_state
, rid
, result
, attr_list
);
1100 free_attr_list( attr_list
);
1102 if ( rc
!= LDAP_SUCCESS
)
1109 /**********************************************************************
1110 Get SAM_ACCOUNT entry from LDAP by SID
1111 *********************************************************************/
1112 static NTSTATUS
ldapsam_getsampwsid(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* user
, const DOM_SID
*sid
)
1114 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1115 LDAPMessage
*result
;
1121 rc
= ldapsam_get_ldap_user_by_sid(ldap_state
,
1123 if (rc
!= LDAP_SUCCESS
)
1124 return NT_STATUS_NO_SUCH_USER
;
1126 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1131 ("Unable to locate SID [%s] count=%d\n", sid_to_string(sid_string
, sid
),
1133 ldap_msgfree(result
);
1134 return NT_STATUS_NO_SUCH_USER
;
1139 ("More than one user with SID [%s]. Failing. count=%d\n", sid_to_string(sid_string
, sid
),
1141 ldap_msgfree(result
);
1142 return NT_STATUS_NO_SUCH_USER
;
1145 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1148 ldap_msgfree(result
);
1149 return NT_STATUS_NO_SUCH_USER
;
1152 if (!init_sam_from_ldap(ldap_state
, user
, entry
)) {
1153 DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
1154 ldap_msgfree(result
);
1155 return NT_STATUS_NO_SUCH_USER
;
1158 pdb_set_backend_private_data(user
, result
,
1159 private_data_free_fn
,
1160 my_methods
, PDB_CHANGED
);
1161 return NT_STATUS_OK
;
1164 /********************************************************************
1165 Do the actual modification - also change a plaintext passord if
1167 **********************************************************************/
1169 static NTSTATUS
ldapsam_modify_entry(struct pdb_methods
*my_methods
,
1170 SAM_ACCOUNT
*newpwd
, char *dn
,
1171 LDAPMod
**mods
, int ldap_op
,
1172 BOOL (*need_update
)(const SAM_ACCOUNT
*,
1175 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1178 if (!my_methods
|| !newpwd
|| !dn
) {
1179 return NT_STATUS_INVALID_PARAMETER
;
1183 DEBUG(5,("mods is empty: nothing to modify\n"));
1184 /* may be password change below however */
1189 smbldap_set_mod(&mods
, LDAP_MOD_ADD
,
1192 rc
= smbldap_add(ldap_state
->smbldap_state
,
1195 case LDAP_MOD_REPLACE
:
1196 rc
= smbldap_modify(ldap_state
->smbldap_state
,
1200 DEBUG(0,("Wrong LDAP operation type: %d!\n",
1202 return NT_STATUS_INVALID_PARAMETER
;
1205 if (rc
!=LDAP_SUCCESS
) {
1206 char *ld_error
= NULL
;
1207 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1210 ("failed to %s user dn= %s with: %s\n\t%s\n",
1211 ldap_op
== LDAP_MOD_ADD
? "add" : "modify",
1212 dn
, ldap_err2string(rc
),
1213 ld_error
?ld_error
:"unknown"));
1214 SAFE_FREE(ld_error
);
1215 return NT_STATUS_UNSUCCESSFUL
;
1219 if (!(pdb_get_acct_ctrl(newpwd
)&(ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
)) &&
1220 (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF
) &&
1221 need_update(newpwd
, PDB_PLAINTEXT_PW
) &&
1222 (pdb_get_plaintext_passwd(newpwd
)!=NULL
)) {
1226 struct berval
*retdata
;
1227 char *utf8_password
;
1230 if (push_utf8_allocate(&utf8_password
, pdb_get_plaintext_passwd(newpwd
)) == (size_t)-1) {
1231 return NT_STATUS_NO_MEMORY
;
1234 if (push_utf8_allocate(&utf8_dn
, dn
) == (size_t)-1) {
1235 return NT_STATUS_NO_MEMORY
;
1238 if ((ber
= ber_alloc_t(LBER_USE_DER
))==NULL
) {
1239 DEBUG(0,("ber_alloc_t returns NULL\n"));
1240 SAFE_FREE(utf8_password
);
1241 return NT_STATUS_UNSUCCESSFUL
;
1244 ber_printf (ber
, "{");
1245 ber_printf (ber
, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID
, utf8_dn
);
1246 ber_printf (ber
, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW
, utf8_password
);
1247 ber_printf (ber
, "N}");
1249 if ((rc
= ber_flatten (ber
, &bv
))<0) {
1250 DEBUG(0,("ber_flatten returns a value <0\n"));
1253 SAFE_FREE(utf8_password
);
1254 return NT_STATUS_UNSUCCESSFUL
;
1258 SAFE_FREE(utf8_password
);
1261 if ((rc
= smbldap_extended_operation(ldap_state
->smbldap_state
,
1262 LDAP_EXOP_MODIFY_PASSWD
,
1263 bv
, NULL
, NULL
, &retoid
,
1264 &retdata
)) != LDAP_SUCCESS
) {
1265 DEBUG(0,("LDAP Password could not be changed for user %s: %s\n",
1266 pdb_get_username(newpwd
),ldap_err2string(rc
)));
1268 DEBUG(3,("LDAP Password changed for user %s\n",pdb_get_username(newpwd
)));
1269 #ifdef DEBUG_PASSWORD
1270 DEBUG(100,("LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd
)));
1272 ber_bvfree(retdata
);
1273 ber_memfree(retoid
);
1277 return NT_STATUS_OK
;
1280 /**********************************************************************
1281 Delete entry from LDAP for username
1282 *********************************************************************/
1283 static NTSTATUS
ldapsam_delete_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* sam_acct
)
1285 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1288 LDAPMessage
*result
;
1294 DEBUG(0, ("sam_acct was NULL!\n"));
1295 return NT_STATUS_INVALID_PARAMETER
;
1298 sname
= pdb_get_username(sam_acct
);
1300 DEBUG (3, ("Deleting user %s from LDAP.\n", sname
));
1302 attr_list
= get_userattr_list( ldap_state
->schema_ver
);
1303 rc
= ldapsam_search_suffix_by_name(ldap_state
, sname
, &result
, attr_list
);
1305 if (rc
!= LDAP_SUCCESS
) {
1306 free_attr_list( attr_list
);
1307 return NT_STATUS_NO_SUCH_USER
;
1310 switch ( ldap_state
->schema_ver
)
1312 case SCHEMAVER_SAMBASAMACCOUNT
:
1313 fstrcpy( objclass
, LDAP_OBJ_SAMBASAMACCOUNT
);
1316 case SCHEMAVER_SAMBAACCOUNT
:
1317 fstrcpy( objclass
, LDAP_OBJ_SAMBAACCOUNT
);
1320 fstrcpy( objclass
, "UNKNOWN" );
1321 DEBUG(0,("ldapsam_delete_sam_account: Unknown schema version specified!\n"));
1325 ret
= ldapsam_delete_entry(ldap_state
, result
, objclass
, attr_list
);
1326 ldap_msgfree(result
);
1327 free_attr_list( attr_list
);
1332 /**********************************************************************
1333 Helper function to determine for update_sam_account whether
1334 we need LDAP modification.
1335 *********************************************************************/
1336 static BOOL
element_is_changed(const SAM_ACCOUNT
*sampass
,
1337 enum pdb_elements element
)
1339 return IS_SAM_CHANGED(sampass
, element
);
1342 /**********************************************************************
1344 *********************************************************************/
1345 static NTSTATUS
ldapsam_update_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* newpwd
)
1347 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1348 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1351 LDAPMessage
*result
;
1356 result
= pdb_get_backend_private_data(newpwd
, my_methods
);
1358 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1359 rc
= ldapsam_search_suffix_by_name(ldap_state
, pdb_get_username(newpwd
), &result
, attr_list
);
1360 free_attr_list( attr_list
);
1361 if (rc
!= LDAP_SUCCESS
) {
1362 return NT_STATUS_UNSUCCESSFUL
;
1364 pdb_set_backend_private_data(newpwd
, result
, private_data_free_fn
, my_methods
, PDB_CHANGED
);
1367 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) == 0) {
1368 DEBUG(0, ("No user to modify!\n"));
1369 return NT_STATUS_UNSUCCESSFUL
;
1372 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1373 dn
= ldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
1375 DEBUG(4, ("user %s to be modified has dn: %s\n", pdb_get_username(newpwd
), dn
));
1377 if (!init_ldap_from_sam(ldap_state
, entry
, &mods
, newpwd
,
1378 element_is_changed
)) {
1379 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1381 return NT_STATUS_UNSUCCESSFUL
;
1385 DEBUG(4,("mods is empty: nothing to update for user: %s\n",
1386 pdb_get_username(newpwd
)));
1387 ldap_mods_free(mods
, True
);
1389 return NT_STATUS_OK
;
1392 ret
= ldapsam_modify_entry(my_methods
,newpwd
,dn
,mods
,LDAP_MOD_REPLACE
, element_is_changed
);
1393 ldap_mods_free(mods
,True
);
1396 if (!NT_STATUS_IS_OK(ret
)) {
1397 char *ld_error
= NULL
;
1398 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1400 DEBUG(0,("failed to modify user with uid = %s, error: %s (%s)\n",
1401 pdb_get_username(newpwd
), ld_error
?ld_error
:"(unknwon)", ldap_err2string(rc
)));
1402 SAFE_FREE(ld_error
);
1406 DEBUG(2, ("successfully modified uid = %s in the LDAP database\n",
1407 pdb_get_username(newpwd
)));
1408 return NT_STATUS_OK
;
1411 /**********************************************************************
1412 Helper function to determine for update_sam_account whether
1413 we need LDAP modification.
1414 *********************************************************************/
1415 static BOOL
element_is_set_or_changed(const SAM_ACCOUNT
*sampass
,
1416 enum pdb_elements element
)
1418 return (IS_SAM_SET(sampass
, element
) ||
1419 IS_SAM_CHANGED(sampass
, element
));
1422 /**********************************************************************
1423 Add SAM_ACCOUNT to LDAP
1424 *********************************************************************/
1426 static NTSTATUS
ldapsam_add_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* newpwd
)
1428 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1429 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1431 LDAPMessage
*result
= NULL
;
1432 LDAPMessage
*entry
= NULL
;
1434 LDAPMod
**mods
= NULL
;
1439 const char *username
= pdb_get_username(newpwd
);
1440 const DOM_SID
*sid
= pdb_get_user_sid(newpwd
);
1444 if (!username
|| !*username
) {
1445 DEBUG(0, ("Cannot add user without a username!\n"));
1446 return NT_STATUS_INVALID_PARAMETER
;
1449 /* free this list after the second search or in case we exit on failure */
1450 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1452 rc
= ldapsam_search_suffix_by_name (ldap_state
, username
, &result
, attr_list
);
1454 if (rc
!= LDAP_SUCCESS
) {
1455 free_attr_list( attr_list
);
1456 return NT_STATUS_UNSUCCESSFUL
;
1459 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) != 0) {
1460 DEBUG(0,("User '%s' already in the base, with samba attributes\n",
1462 ldap_msgfree(result
);
1463 free_attr_list( attr_list
);
1464 return NT_STATUS_UNSUCCESSFUL
;
1466 ldap_msgfree(result
);
1469 if (element_is_set_or_changed(newpwd
, PDB_USERSID
)) {
1470 rc
= ldapsam_get_ldap_user_by_sid(ldap_state
,
1472 if (rc
== LDAP_SUCCESS
) {
1473 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) != 0) {
1474 DEBUG(0,("SID '%s' already in the base, with samba attributes\n",
1475 sid_to_string(sid_string
, sid
)));
1476 free_attr_list( attr_list
);
1477 return NT_STATUS_UNSUCCESSFUL
;
1479 ldap_msgfree(result
);
1483 /* does the entry already exist but without a samba attributes?
1484 we need to return the samba attributes here */
1486 escape_user
= escape_ldap_string_alloc( username
);
1487 pstrcpy( filter
, lp_ldap_filter() );
1488 all_string_sub( filter
, "%u", escape_user
, sizeof(filter
) );
1489 SAFE_FREE( escape_user
);
1491 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
,
1492 filter
, attr_list
, &result
);
1493 if ( rc
!= LDAP_SUCCESS
) {
1494 free_attr_list( attr_list
);
1495 return NT_STATUS_UNSUCCESSFUL
;
1498 num_result
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1500 if (num_result
> 1) {
1501 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
1502 free_attr_list( attr_list
);
1503 ldap_msgfree(result
);
1504 return NT_STATUS_UNSUCCESSFUL
;
1507 /* Check if we need to update an existing entry */
1508 if (num_result
== 1) {
1511 DEBUG(3,("User exists without samba attributes: adding them\n"));
1512 ldap_op
= LDAP_MOD_REPLACE
;
1513 entry
= ldap_first_entry (ldap_state
->smbldap_state
->ldap_struct
, result
);
1514 tmp
= ldap_get_dn (ldap_state
->smbldap_state
->ldap_struct
, entry
);
1515 slprintf (dn
, sizeof (dn
) - 1, "%s", tmp
);
1518 } else if (ldap_state
->schema_ver
== SCHEMAVER_SAMBASAMACCOUNT
) {
1520 /* There might be a SID for this account already - say an idmap entry */
1522 pstr_sprintf(filter
, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
1523 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
1524 sid_to_string(sid_string
, sid
),
1525 LDAP_OBJ_IDMAP_ENTRY
,
1526 LDAP_OBJ_SID_ENTRY
);
1528 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
,
1529 filter
, attr_list
, &result
);
1531 if ( rc
!= LDAP_SUCCESS
) {
1532 free_attr_list( attr_list
);
1533 return NT_STATUS_UNSUCCESSFUL
;
1536 num_result
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1538 if (num_result
> 1) {
1539 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
1540 free_attr_list( attr_list
);
1541 ldap_msgfree(result
);
1542 return NT_STATUS_UNSUCCESSFUL
;
1545 /* Check if we need to update an existing entry */
1546 if (num_result
== 1) {
1549 DEBUG(3,("User exists without samba attributes: adding them\n"));
1550 ldap_op
= LDAP_MOD_REPLACE
;
1551 entry
= ldap_first_entry (ldap_state
->smbldap_state
->ldap_struct
, result
);
1552 tmp
= ldap_get_dn (ldap_state
->smbldap_state
->ldap_struct
, entry
);
1553 slprintf (dn
, sizeof (dn
) - 1, "%s", tmp
);
1558 free_attr_list( attr_list
);
1560 if (num_result
== 0) {
1561 /* Check if we need to add an entry */
1562 DEBUG(3,("Adding new user\n"));
1563 ldap_op
= LDAP_MOD_ADD
;
1564 if (username
[strlen(username
)-1] == '$') {
1565 slprintf (dn
, sizeof (dn
) - 1, "uid=%s,%s", username
, lp_ldap_machine_suffix ());
1567 slprintf (dn
, sizeof (dn
) - 1, "uid=%s,%s", username
, lp_ldap_user_suffix ());
1571 if (!init_ldap_from_sam(ldap_state
, entry
, &mods
, newpwd
,
1572 element_is_set_or_changed
)) {
1573 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
1574 ldap_msgfree(result
);
1575 return NT_STATUS_UNSUCCESSFUL
;
1578 ldap_msgfree(result
);
1581 DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd
)));
1582 return NT_STATUS_UNSUCCESSFUL
;
1584 switch ( ldap_state
->schema_ver
)
1586 case SCHEMAVER_SAMBAACCOUNT
:
1587 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectclass", LDAP_OBJ_SAMBAACCOUNT
);
1589 case SCHEMAVER_SAMBASAMACCOUNT
:
1590 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT
);
1593 DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
1597 ret
= ldapsam_modify_entry(my_methods
,newpwd
,dn
,mods
,ldap_op
, element_is_set_or_changed
);
1598 if (!NT_STATUS_IS_OK(ret
)) {
1599 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
1600 pdb_get_username(newpwd
),dn
));
1601 ldap_mods_free(mods
, True
);
1605 DEBUG(2,("added: uid == %s in the LDAP database\n", pdb_get_username(newpwd
)));
1606 ldap_mods_free(mods
, True
);
1608 return NT_STATUS_OK
;
1611 /**********************************************************************
1612 *********************************************************************/
1614 static int ldapsam_search_one_group (struct ldapsam_privates
*ldap_state
,
1616 LDAPMessage
** result
)
1618 int scope
= LDAP_SCOPE_SUBTREE
;
1622 DEBUG(2, ("ldapsam_search_one_group: searching for:[%s]\n", filter
));
1625 attr_list
= get_attr_list(groupmap_attr_list
);
1626 rc
= smbldap_search(ldap_state
->smbldap_state
,
1627 lp_ldap_group_suffix (), scope
,
1628 filter
, attr_list
, 0, result
);
1629 free_attr_list( attr_list
);
1631 if (rc
!= LDAP_SUCCESS
) {
1632 char *ld_error
= NULL
;
1633 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1635 DEBUG(0, ("ldapsam_search_one_group: "
1636 "Problem during the LDAP search: LDAP error: %s (%s)",
1637 ld_error
?ld_error
:"(unknown)", ldap_err2string(rc
)));
1638 DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
1639 lp_ldap_group_suffix(), filter
));
1640 SAFE_FREE(ld_error
);
1646 /**********************************************************************
1647 *********************************************************************/
1649 static BOOL
init_group_from_ldap(struct ldapsam_privates
*ldap_state
,
1650 GROUP_MAP
*map
, LDAPMessage
*entry
)
1654 if (ldap_state
== NULL
|| map
== NULL
|| entry
== NULL
||
1655 ldap_state
->smbldap_state
->ldap_struct
== NULL
)
1657 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
1661 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1662 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
), temp
))
1664 DEBUG(0, ("Mandatory attribute %s not found\n",
1665 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
)));
1668 DEBUG(2, ("Entry found for group: %s\n", temp
));
1670 map
->gid
= (gid_t
)atol(temp
);
1672 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1673 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_SID
), temp
))
1675 DEBUG(0, ("Mandatory attribute %s not found\n",
1676 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_SID
)));
1679 string_to_sid(&map
->sid
, temp
);
1681 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1682 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_TYPE
), temp
))
1684 DEBUG(0, ("Mandatory attribute %s not found\n",
1685 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_TYPE
)));
1688 map
->sid_name_use
= (uint32
)atol(temp
);
1690 if ((map
->sid_name_use
< SID_NAME_USER
) ||
1691 (map
->sid_name_use
> SID_NAME_UNKNOWN
)) {
1692 DEBUG(0, ("Unknown Group type: %d\n", map
->sid_name_use
));
1696 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1697 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DISPLAY_NAME
), temp
))
1700 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1701 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_CN
), temp
))
1703 DEBUG(0, ("Attributes cn not found either "
1704 "for gidNumber(%lu)\n",(unsigned long)map
->gid
));
1708 fstrcpy(map
->nt_name
, temp
);
1710 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1711 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DESC
), temp
))
1715 fstrcpy(map
->comment
, temp
);
1720 /**********************************************************************
1721 *********************************************************************/
1723 static BOOL
init_ldap_from_group(LDAP
*ldap_struct
,
1724 LDAPMessage
*existing
,
1726 const GROUP_MAP
*map
)
1730 if (mods
== NULL
|| map
== NULL
) {
1731 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
1737 sid_to_string(tmp
, &map
->sid
);
1738 smbldap_make_mod(ldap_struct
, existing
, mods
,
1739 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GROUP_SID
), tmp
);
1740 pstr_sprintf(tmp
, "%i", map
->sid_name_use
);
1741 smbldap_make_mod(ldap_struct
, existing
, mods
,
1742 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GROUP_TYPE
), tmp
);
1744 smbldap_make_mod(ldap_struct
, existing
, mods
,
1745 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DISPLAY_NAME
), map
->nt_name
);
1746 smbldap_make_mod(ldap_struct
, existing
, mods
,
1747 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DESC
), map
->comment
);
1752 /**********************************************************************
1753 *********************************************************************/
1755 static NTSTATUS
ldapsam_getgroup(struct pdb_methods
*methods
,
1759 struct ldapsam_privates
*ldap_state
=
1760 (struct ldapsam_privates
*)methods
->private_data
;
1761 LDAPMessage
*result
;
1765 if (ldapsam_search_one_group(ldap_state
, filter
, &result
)
1767 return NT_STATUS_NO_SUCH_GROUP
;
1770 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1773 DEBUG(4, ("Did not find group\n"));
1774 ldap_msgfree(result
);
1775 return NT_STATUS_NO_SUCH_GROUP
;
1779 DEBUG(1, ("Duplicate entries for filter %s: count=%d\n",
1781 ldap_msgfree(result
);
1782 return NT_STATUS_NO_SUCH_GROUP
;
1785 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1788 ldap_msgfree(result
);
1789 return NT_STATUS_UNSUCCESSFUL
;
1792 if (!init_group_from_ldap(ldap_state
, map
, entry
)) {
1793 DEBUG(1, ("init_group_from_ldap failed for group filter %s\n",
1795 ldap_msgfree(result
);
1796 return NT_STATUS_NO_SUCH_GROUP
;
1799 ldap_msgfree(result
);
1800 return NT_STATUS_OK
;
1803 /**********************************************************************
1804 *********************************************************************/
1806 static NTSTATUS
ldapsam_getgrsid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
1811 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%s))",
1813 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GROUP_SID
),
1814 sid_string_static(&sid
));
1816 return ldapsam_getgroup(methods
, filter
, map
);
1819 /**********************************************************************
1820 *********************************************************************/
1822 static NTSTATUS
ldapsam_getgrgid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
1827 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%lu))",
1829 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
),
1830 (unsigned long)gid
);
1832 return ldapsam_getgroup(methods
, filter
, map
);
1835 /**********************************************************************
1836 *********************************************************************/
1838 static NTSTATUS
ldapsam_getgrnam(struct pdb_methods
*methods
, GROUP_MAP
*map
,
1842 char *escape_name
= escape_ldap_string_alloc(name
);
1845 return NT_STATUS_NO_MEMORY
;
1848 pstr_sprintf(filter
, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
1850 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_DISPLAY_NAME
), escape_name
,
1851 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_CN
), escape_name
);
1853 SAFE_FREE(escape_name
);
1855 return ldapsam_getgroup(methods
, filter
, map
);
1858 /**********************************************************************
1859 *********************************************************************/
1861 static int ldapsam_search_one_group_by_gid(struct ldapsam_privates
*ldap_state
,
1863 LDAPMessage
**result
)
1867 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%lu))",
1868 LDAP_OBJ_POSIXGROUP
,
1869 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
),
1870 (unsigned long)gid
);
1872 return ldapsam_search_one_group(ldap_state
, filter
, result
);
1875 /**********************************************************************
1876 *********************************************************************/
1878 static NTSTATUS
ldapsam_add_group_mapping_entry(struct pdb_methods
*methods
,
1881 struct ldapsam_privates
*ldap_state
=
1882 (struct ldapsam_privates
*)methods
->private_data
;
1883 LDAPMessage
*result
= NULL
;
1884 LDAPMod
**mods
= NULL
;
1895 if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods
, &dummy
,
1897 DEBUG(0, ("Group %ld already exists in LDAP\n", (unsigned long)map
->gid
));
1898 return NT_STATUS_UNSUCCESSFUL
;
1901 rc
= ldapsam_search_one_group_by_gid(ldap_state
, map
->gid
, &result
);
1902 if (rc
!= LDAP_SUCCESS
) {
1903 ldap_msgfree(result
);
1904 return NT_STATUS_UNSUCCESSFUL
;
1907 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1910 ldap_msgfree(result
);
1911 return NT_STATUS_UNSUCCESSFUL
;
1915 DEBUG(2, ("Group %lu must exist exactly once in LDAP\n",
1916 (unsigned long)map
->gid
));
1917 ldap_msgfree(result
);
1918 return NT_STATUS_UNSUCCESSFUL
;
1921 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1922 tmp
= ldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
1926 if (!init_ldap_from_group(ldap_state
->smbldap_state
->ldap_struct
,
1927 result
, &mods
, map
)) {
1928 DEBUG(0, ("init_ldap_from_group failed!\n"));
1929 ldap_mods_free(mods
, True
);
1930 ldap_msgfree(result
);
1931 return NT_STATUS_UNSUCCESSFUL
;
1934 ldap_msgfree(result
);
1937 DEBUG(0, ("mods is empty\n"));
1938 return NT_STATUS_UNSUCCESSFUL
;
1941 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_GROUPMAP
);
1943 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
1944 ldap_mods_free(mods
, True
);
1946 if (rc
!= LDAP_SUCCESS
) {
1947 char *ld_error
= NULL
;
1948 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1950 DEBUG(0, ("failed to add group %lu error: %s (%s)\n", (unsigned long)map
->gid
,
1951 ld_error
? ld_error
: "(unknown)", ldap_err2string(rc
)));
1952 SAFE_FREE(ld_error
);
1953 return NT_STATUS_UNSUCCESSFUL
;
1956 DEBUG(2, ("successfully modified group %lu in LDAP\n", (unsigned long)map
->gid
));
1957 return NT_STATUS_OK
;
1960 /**********************************************************************
1961 *********************************************************************/
1963 static NTSTATUS
ldapsam_update_group_mapping_entry(struct pdb_methods
*methods
,
1966 struct ldapsam_privates
*ldap_state
=
1967 (struct ldapsam_privates
*)methods
->private_data
;
1970 LDAPMessage
*result
;
1974 rc
= ldapsam_search_one_group_by_gid(ldap_state
, map
->gid
, &result
);
1976 if (rc
!= LDAP_SUCCESS
) {
1977 return NT_STATUS_UNSUCCESSFUL
;
1980 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) == 0) {
1981 DEBUG(0, ("No group to modify!\n"));
1982 ldap_msgfree(result
);
1983 return NT_STATUS_UNSUCCESSFUL
;
1986 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1987 dn
= ldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
1989 if (!init_ldap_from_group(ldap_state
->smbldap_state
->ldap_struct
,
1990 result
, &mods
, map
)) {
1991 DEBUG(0, ("init_ldap_from_group failed\n"));
1992 ldap_msgfree(result
);
1993 return NT_STATUS_UNSUCCESSFUL
;
1996 ldap_msgfree(result
);
1999 DEBUG(4, ("mods is empty: nothing to do\n"));
2000 return NT_STATUS_UNSUCCESSFUL
;
2003 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
2005 ldap_mods_free(mods
, True
);
2007 if (rc
!= LDAP_SUCCESS
) {
2008 char *ld_error
= NULL
;
2009 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
2011 DEBUG(0, ("failed to modify group %lu error: %s (%s)\n", (unsigned long)map
->gid
,
2012 ld_error
? ld_error
: "(unknown)", ldap_err2string(rc
)));
2013 SAFE_FREE(ld_error
);
2016 DEBUG(2, ("successfully modified group %lu in LDAP\n", (unsigned long)map
->gid
));
2017 return NT_STATUS_OK
;
2020 /**********************************************************************
2021 *********************************************************************/
2023 static NTSTATUS
ldapsam_delete_group_mapping_entry(struct pdb_methods
*methods
,
2026 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)methods
->private_data
;
2027 pstring sidstring
, filter
;
2028 LDAPMessage
*result
;
2033 sid_to_string(sidstring
, &sid
);
2035 pstr_sprintf(filter
, "(&(objectClass=%s)(%s=%s))",
2036 LDAP_OBJ_GROUPMAP
, LDAP_ATTRIBUTE_SID
, sidstring
);
2038 rc
= ldapsam_search_one_group(ldap_state
, filter
, &result
);
2040 if (rc
!= LDAP_SUCCESS
) {
2041 return NT_STATUS_NO_SUCH_GROUP
;
2044 attr_list
= get_attr_list( groupmap_attr_list_to_delete
);
2045 ret
= ldapsam_delete_entry(ldap_state
, result
, LDAP_OBJ_GROUPMAP
, attr_list
);
2046 free_attr_list ( attr_list
);
2048 ldap_msgfree(result
);
2053 /**********************************************************************
2054 *********************************************************************/
2056 static NTSTATUS
ldapsam_setsamgrent(struct pdb_methods
*my_methods
, BOOL update
)
2058 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
2063 pstr_sprintf( filter
, "(objectclass=%s)", LDAP_OBJ_GROUPMAP
);
2064 attr_list
= get_attr_list( groupmap_attr_list
);
2065 rc
= smbldap_search(ldap_state
->smbldap_state
, lp_ldap_group_suffix(),
2066 LDAP_SCOPE_SUBTREE
, filter
,
2067 attr_list
, 0, &ldap_state
->result
);
2068 free_attr_list( attr_list
);
2070 if (rc
!= LDAP_SUCCESS
) {
2071 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc
)));
2072 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_group_suffix(), filter
));
2073 ldap_msgfree(ldap_state
->result
);
2074 ldap_state
->result
= NULL
;
2075 return NT_STATUS_UNSUCCESSFUL
;
2078 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
2079 ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
,
2080 ldap_state
->result
)));
2082 ldap_state
->entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, ldap_state
->result
);
2083 ldap_state
->index
= 0;
2085 return NT_STATUS_OK
;
2088 /**********************************************************************
2089 *********************************************************************/
2091 static void ldapsam_endsamgrent(struct pdb_methods
*my_methods
)
2093 ldapsam_endsampwent(my_methods
);
2096 /**********************************************************************
2097 *********************************************************************/
2099 static NTSTATUS
ldapsam_getsamgrent(struct pdb_methods
*my_methods
,
2102 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
2103 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
2107 if (!ldap_state
->entry
)
2110 ldap_state
->index
++;
2111 bret
= init_group_from_ldap(ldap_state
, map
, ldap_state
->entry
);
2113 ldap_state
->entry
= ldap_next_entry(ldap_state
->smbldap_state
->ldap_struct
,
2117 return NT_STATUS_OK
;
2120 /**********************************************************************
2121 *********************************************************************/
2123 static NTSTATUS
ldapsam_enum_group_mapping(struct pdb_methods
*methods
,
2124 enum SID_NAME_USE sid_name_use
,
2125 GROUP_MAP
**rmap
, int *num_entries
,
2136 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods
, False
))) {
2137 DEBUG(0, ("Unable to open passdb\n"));
2138 return NT_STATUS_ACCESS_DENIED
;
2141 while (NT_STATUS_IS_OK(nt_status
= ldapsam_getsamgrent(methods
, &map
))) {
2142 if (sid_name_use
!= SID_NAME_UNKNOWN
&&
2143 sid_name_use
!= map
.sid_name_use
) {
2144 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map
.nt_name
));
2147 if (unix_only
==ENUM_ONLY_MAPPED
&& map
.gid
==-1) {
2148 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map
.nt_name
));
2152 mapt
=(GROUP_MAP
*)Realloc((*rmap
), (entries
+1)*sizeof(GROUP_MAP
));
2154 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
2156 return NT_STATUS_UNSUCCESSFUL
;
2161 mapt
[entries
] = map
;
2166 ldapsam_endsamgrent(methods
);
2168 *num_entries
= entries
;
2170 return NT_STATUS_OK
;
2173 /**********************************************************************
2175 *********************************************************************/
2177 static void free_private_data(void **vp
)
2179 struct ldapsam_privates
**ldap_state
= (struct ldapsam_privates
**)vp
;
2181 smbldap_free_struct(&(*ldap_state
)->smbldap_state
);
2185 /* No need to free any further, as it is talloc()ed */
2188 /**********************************************************************
2189 Intitalise the parts of the pdb_context that are common to all pdb_ldap modes
2190 *********************************************************************/
2192 static NTSTATUS
pdb_init_ldapsam_common(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
,
2193 const char *location
)
2196 struct ldapsam_privates
*ldap_state
;
2198 if (!NT_STATUS_IS_OK(nt_status
= make_pdb_methods(pdb_context
->mem_ctx
, pdb_method
))) {
2202 (*pdb_method
)->name
= "ldapsam";
2204 (*pdb_method
)->setsampwent
= ldapsam_setsampwent
;
2205 (*pdb_method
)->endsampwent
= ldapsam_endsampwent
;
2206 (*pdb_method
)->getsampwent
= ldapsam_getsampwent
;
2207 (*pdb_method
)->getsampwnam
= ldapsam_getsampwnam
;
2208 (*pdb_method
)->getsampwsid
= ldapsam_getsampwsid
;
2209 (*pdb_method
)->add_sam_account
= ldapsam_add_sam_account
;
2210 (*pdb_method
)->update_sam_account
= ldapsam_update_sam_account
;
2211 (*pdb_method
)->delete_sam_account
= ldapsam_delete_sam_account
;
2213 (*pdb_method
)->getgrsid
= ldapsam_getgrsid
;
2214 (*pdb_method
)->getgrgid
= ldapsam_getgrgid
;
2215 (*pdb_method
)->getgrnam
= ldapsam_getgrnam
;
2216 (*pdb_method
)->add_group_mapping_entry
= ldapsam_add_group_mapping_entry
;
2217 (*pdb_method
)->update_group_mapping_entry
= ldapsam_update_group_mapping_entry
;
2218 (*pdb_method
)->delete_group_mapping_entry
= ldapsam_delete_group_mapping_entry
;
2219 (*pdb_method
)->enum_group_mapping
= ldapsam_enum_group_mapping
;
2221 /* TODO: Setup private data and free */
2223 ldap_state
= talloc_zero(pdb_context
->mem_ctx
, sizeof(*ldap_state
));
2225 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
2226 return NT_STATUS_NO_MEMORY
;
2229 if (!NT_STATUS_IS_OK(nt_status
=
2230 smbldap_init(pdb_context
->mem_ctx
, location
,
2231 &ldap_state
->smbldap_state
)));
2233 ldap_state
->domain_name
= talloc_strdup(pdb_context
->mem_ctx
, get_global_sam_name());
2234 if (!ldap_state
->domain_name
) {
2235 return NT_STATUS_NO_MEMORY
;
2238 (*pdb_method
)->private_data
= ldap_state
;
2240 (*pdb_method
)->free_private_data
= free_private_data
;
2242 return NT_STATUS_OK
;
2245 /**********************************************************************
2246 Initialise the 'compat' mode for pdb_ldap
2247 *********************************************************************/
2249 static NTSTATUS
pdb_init_ldapsam_compat(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
2252 struct ldapsam_privates
*ldap_state
;
2254 #ifdef WITH_LDAP_SAMCONFIG
2256 int ldap_port
= lp_ldap_port();
2258 /* remap default port if not using SSL (ie clear or TLS) */
2259 if ( (lp_ldap_ssl() != LDAP_SSL_ON
) && (ldap_port
== 636) ) {
2263 location
= talloc_asprintf(pdb_context
->mem_ctx
, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON
? "ldaps" : "ldap", lp_ldap_server(), ldap_port
);
2265 return NT_STATUS_NO_MEMORY
;
2270 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_ldapsam_common(pdb_context
, pdb_method
, location
))) {
2274 (*pdb_method
)->name
= "ldapsam_compat";
2276 ldap_state
= (*pdb_method
)->private_data
;
2277 ldap_state
->schema_ver
= SCHEMAVER_SAMBAACCOUNT
;
2279 sid_copy(&ldap_state
->domain_sid
, get_global_sam_sid());
2281 return NT_STATUS_OK
;
2284 /**********************************************************************
2285 Initialise the normal mode for pdb_ldap
2286 *********************************************************************/
2288 static NTSTATUS
pdb_init_ldapsam(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
2291 struct ldapsam_privates
*ldap_state
;
2292 uint32 alg_rid_base
;
2293 pstring alg_rid_base_string
;
2294 LDAPMessage
*result
= NULL
;
2295 LDAPMessage
*entry
= NULL
;
2296 DOM_SID ldap_domain_sid
;
2297 DOM_SID secrets_domain_sid
;
2298 pstring domain_sid_string
;
2300 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_ldapsam_common(pdb_context
, pdb_method
, location
))) {
2304 (*pdb_method
)->name
= "ldapsam";
2306 ldap_state
= (*pdb_method
)->private_data
;
2307 ldap_state
->schema_ver
= SCHEMAVER_SAMBASAMACCOUNT
;
2309 /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
2311 nt_status
= smbldap_search_domain_info(ldap_state
->smbldap_state
, &result
,
2312 ldap_state
->domain_name
, True
);
2314 if ( !NT_STATUS_IS_OK(nt_status
) ) {
2315 DEBUG(2, ("WARNING: Could not get domain info, nor add one to the domain\n"));
2316 DEBUGADD(2, ("Continuing on regardless, will be unable to allocate new users/groups, "
2317 "and will risk BDCs having inconsistant SIDs\n"));
2318 sid_copy(&ldap_state
->domain_sid
, get_global_sam_sid());
2319 return NT_STATUS_OK
;
2322 /* Given that the above might fail, everything below this must be optional */
2324 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
2326 DEBUG(0, ("Could not get domain info entry\n"));
2327 ldap_msgfree(result
);
2328 return NT_STATUS_UNSUCCESSFUL
;
2331 if (smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
2332 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
2336 string_to_sid(&ldap_domain_sid
, domain_sid_string
);
2337 found_sid
= secrets_fetch_domain_sid(ldap_state
->domain_name
, &secrets_domain_sid
);
2338 if (!found_sid
|| !sid_equal(&secrets_domain_sid
, &ldap_domain_sid
)) {
2339 /* reset secrets.tdb sid */
2340 secrets_store_domain_sid(ldap_state
->domain_name
, &ldap_domain_sid
);
2342 sid_copy(&ldap_state
->domain_sid
, &ldap_domain_sid
);
2345 if (smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
2346 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_ALGORITHMIC_RID_BASE
),
2347 alg_rid_base_string
))
2349 alg_rid_base
= (uint32
)atol(alg_rid_base_string
);
2350 if (alg_rid_base
!= algorithmic_rid_base()) {
2351 DEBUG(0, ("The value of 'algorithmic RID base' has changed since the LDAP\n"
2352 "database was initialised. Aborting. \n"));
2353 ldap_msgfree(result
);
2354 return NT_STATUS_UNSUCCESSFUL
;
2357 ldap_msgfree(result
);
2359 return NT_STATUS_OK
;
2362 NTSTATUS
pdb_ldap_init(void)
2365 if (!NT_STATUS_IS_OK(nt_status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ldapsam", pdb_init_ldapsam
)))
2368 if (!NT_STATUS_IS_OK(nt_status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ldapsam_compat", pdb_init_ldapsam_compat
)))
2371 return NT_STATUS_OK
;