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_memfree(*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 snprintf( objclass_filter
, sizeof(objclass_filter
)-1, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT
);
166 case SCHEMAVER_SAMBASAMACCOUNT
:
167 snprintf( objclass_filter
, sizeof(objclass_filter
)-1, "(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 snprintf(filter
, sizeof(filter
)-1, "(&%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 snprintf(filter
, sizeof(filter
)-1, "(&(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 snprintf(filter
, sizeof(filter
)-1, "(&(%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 snprintf( filter
, sizeof(filter
)-1, "(&%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 plaittext 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"));
1380 return NT_STATUS_UNSUCCESSFUL
;
1384 DEBUG(4,("mods is empty: nothing to update for user: %s\n",
1385 pdb_get_username(newpwd
)));
1386 ldap_mods_free(mods
, True
);
1387 return NT_STATUS_OK
;
1390 ret
= ldapsam_modify_entry(my_methods
,newpwd
,dn
,mods
,LDAP_MOD_REPLACE
, element_is_changed
);
1391 ldap_mods_free(mods
,True
);
1393 if (!NT_STATUS_IS_OK(ret
)) {
1394 char *ld_error
= NULL
;
1395 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1397 DEBUG(0,("failed to modify user with uid = %s, error: %s (%s)\n",
1398 pdb_get_username(newpwd
), ld_error
?ld_error
:"(unknwon)", ldap_err2string(rc
)));
1399 SAFE_FREE(ld_error
);
1403 DEBUG(2, ("successfully modified uid = %s in the LDAP database\n",
1404 pdb_get_username(newpwd
)));
1405 return NT_STATUS_OK
;
1408 /**********************************************************************
1409 Helper function to determine for update_sam_account whether
1410 we need LDAP modification.
1411 *********************************************************************/
1412 static BOOL
element_is_set_or_changed(const SAM_ACCOUNT
*sampass
,
1413 enum pdb_elements element
)
1415 return (IS_SAM_SET(sampass
, element
) ||
1416 IS_SAM_CHANGED(sampass
, element
));
1419 /**********************************************************************
1420 Add SAM_ACCOUNT to LDAP
1421 *********************************************************************/
1423 static NTSTATUS
ldapsam_add_sam_account(struct pdb_methods
*my_methods
, SAM_ACCOUNT
* newpwd
)
1425 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1426 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1428 LDAPMessage
*result
= NULL
;
1429 LDAPMessage
*entry
= NULL
;
1431 LDAPMod
**mods
= NULL
;
1436 const char *username
= pdb_get_username(newpwd
);
1437 const DOM_SID
*sid
= pdb_get_user_sid(newpwd
);
1441 if (!username
|| !*username
) {
1442 DEBUG(0, ("Cannot add user without a username!\n"));
1443 return NT_STATUS_INVALID_PARAMETER
;
1446 /* free this list after the second search or in case we exit on failure */
1447 attr_list
= get_userattr_list(ldap_state
->schema_ver
);
1449 rc
= ldapsam_search_suffix_by_name (ldap_state
, username
, &result
, attr_list
);
1451 if (rc
!= LDAP_SUCCESS
) {
1452 free_attr_list( attr_list
);
1453 return NT_STATUS_UNSUCCESSFUL
;
1456 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) != 0) {
1457 DEBUG(0,("User '%s' already in the base, with samba attributes\n",
1459 ldap_msgfree(result
);
1460 free_attr_list( attr_list
);
1461 return NT_STATUS_UNSUCCESSFUL
;
1463 ldap_msgfree(result
);
1466 if (element_is_set_or_changed(newpwd
, PDB_USERSID
)) {
1467 rc
= ldapsam_get_ldap_user_by_sid(ldap_state
,
1469 if (rc
== LDAP_SUCCESS
) {
1470 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) != 0) {
1471 DEBUG(0,("SID '%s' already in the base, with samba attributes\n",
1472 sid_to_string(sid_string
, sid
)));
1473 free_attr_list( attr_list
);
1474 return NT_STATUS_UNSUCCESSFUL
;
1476 ldap_msgfree(result
);
1480 /* does the entry already exist but without a samba attributes?
1481 we need to return the samba attributes here */
1483 escape_user
= escape_ldap_string_alloc( username
);
1484 pstrcpy( filter
, lp_ldap_filter() );
1485 all_string_sub( filter
, "%u", escape_user
, sizeof(filter
) );
1486 SAFE_FREE( escape_user
);
1488 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
,
1489 filter
, attr_list
, &result
);
1490 if ( rc
!= LDAP_SUCCESS
) {
1491 free_attr_list( attr_list
);
1492 return NT_STATUS_UNSUCCESSFUL
;
1495 num_result
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1497 if (num_result
> 1) {
1498 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
1499 free_attr_list( attr_list
);
1500 ldap_msgfree(result
);
1501 return NT_STATUS_UNSUCCESSFUL
;
1504 /* Check if we need to update an existing entry */
1505 if (num_result
== 1) {
1508 DEBUG(3,("User exists without samba attributes: adding them\n"));
1509 ldap_op
= LDAP_MOD_REPLACE
;
1510 entry
= ldap_first_entry (ldap_state
->smbldap_state
->ldap_struct
, result
);
1511 tmp
= ldap_get_dn (ldap_state
->smbldap_state
->ldap_struct
, entry
);
1512 slprintf (dn
, sizeof (dn
) - 1, "%s", tmp
);
1515 } else if (ldap_state
->schema_ver
== SCHEMAVER_SAMBASAMACCOUNT
) {
1517 /* There might be a SID for this account already - say an idmap entry */
1519 snprintf(filter
, sizeof(filter
)-1, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
1520 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
1521 sid_to_string(sid_string
, sid
),
1522 LDAP_OBJ_IDMAP_ENTRY
,
1523 LDAP_OBJ_SID_ENTRY
);
1525 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
,
1526 filter
, attr_list
, &result
);
1528 if ( rc
!= LDAP_SUCCESS
) {
1529 free_attr_list( attr_list
);
1530 return NT_STATUS_UNSUCCESSFUL
;
1533 num_result
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1535 if (num_result
> 1) {
1536 DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
1537 free_attr_list( attr_list
);
1538 ldap_msgfree(result
);
1539 return NT_STATUS_UNSUCCESSFUL
;
1542 /* Check if we need to update an existing entry */
1543 if (num_result
== 1) {
1546 DEBUG(3,("User exists without samba attributes: adding them\n"));
1547 ldap_op
= LDAP_MOD_REPLACE
;
1548 entry
= ldap_first_entry (ldap_state
->smbldap_state
->ldap_struct
, result
);
1549 tmp
= ldap_get_dn (ldap_state
->smbldap_state
->ldap_struct
, entry
);
1550 slprintf (dn
, sizeof (dn
) - 1, "%s", tmp
);
1555 free_attr_list( attr_list
);
1557 if (num_result
== 0) {
1558 /* Check if we need to add an entry */
1559 DEBUG(3,("Adding new user\n"));
1560 ldap_op
= LDAP_MOD_ADD
;
1561 if (username
[strlen(username
)-1] == '$') {
1562 slprintf (dn
, sizeof (dn
) - 1, "uid=%s,%s", username
, lp_ldap_machine_suffix ());
1564 slprintf (dn
, sizeof (dn
) - 1, "uid=%s,%s", username
, lp_ldap_user_suffix ());
1568 if (!init_ldap_from_sam(ldap_state
, entry
, &mods
, newpwd
,
1569 element_is_set_or_changed
)) {
1570 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
1571 ldap_msgfree(result
);
1572 return NT_STATUS_UNSUCCESSFUL
;
1575 ldap_msgfree(result
);
1578 DEBUG(0,("mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd
)));
1579 return NT_STATUS_UNSUCCESSFUL
;
1581 switch ( ldap_state
->schema_ver
)
1583 case SCHEMAVER_SAMBAACCOUNT
:
1584 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectclass", LDAP_OBJ_SAMBAACCOUNT
);
1586 case SCHEMAVER_SAMBASAMACCOUNT
:
1587 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT
);
1590 DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
1594 ret
= ldapsam_modify_entry(my_methods
,newpwd
,dn
,mods
,ldap_op
, element_is_set_or_changed
);
1595 if (!NT_STATUS_IS_OK(ret
)) {
1596 DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
1597 pdb_get_username(newpwd
),dn
));
1598 ldap_mods_free(mods
, True
);
1602 DEBUG(2,("added: uid == %s in the LDAP database\n", pdb_get_username(newpwd
)));
1603 ldap_mods_free(mods
, True
);
1605 return NT_STATUS_OK
;
1608 /**********************************************************************
1609 *********************************************************************/
1611 static int ldapsam_search_one_group (struct ldapsam_privates
*ldap_state
,
1613 LDAPMessage
** result
)
1615 int scope
= LDAP_SCOPE_SUBTREE
;
1619 DEBUG(2, ("ldapsam_search_one_group: searching for:[%s]\n", filter
));
1622 attr_list
= get_attr_list(groupmap_attr_list
);
1623 rc
= smbldap_search(ldap_state
->smbldap_state
,
1624 lp_ldap_group_suffix (), scope
,
1625 filter
, attr_list
, 0, result
);
1626 free_attr_list( attr_list
);
1628 if (rc
!= LDAP_SUCCESS
) {
1629 char *ld_error
= NULL
;
1630 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1632 DEBUG(0, ("ldapsam_search_one_group: "
1633 "Problem during the LDAP search: LDAP error: %s (%s)",
1634 ld_error
?ld_error
:"(unknown)", ldap_err2string(rc
)));
1635 DEBUG(3, ("ldapsam_search_one_group: Query was: %s, %s\n",
1636 lp_ldap_group_suffix(), filter
));
1637 SAFE_FREE(ld_error
);
1643 /**********************************************************************
1644 *********************************************************************/
1646 static BOOL
init_group_from_ldap(struct ldapsam_privates
*ldap_state
,
1647 GROUP_MAP
*map
, LDAPMessage
*entry
)
1651 if (ldap_state
== NULL
|| map
== NULL
|| entry
== NULL
||
1652 ldap_state
->smbldap_state
->ldap_struct
== NULL
)
1654 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
1658 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1659 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
), temp
))
1661 DEBUG(0, ("Mandatory attribute %s not found\n",
1662 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
)));
1665 DEBUG(2, ("Entry found for group: %s\n", temp
));
1667 map
->gid
= (gid_t
)atol(temp
);
1669 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1670 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_SID
), temp
))
1672 DEBUG(0, ("Mandatory attribute %s not found\n",
1673 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_SID
)));
1676 string_to_sid(&map
->sid
, temp
);
1678 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1679 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_TYPE
), temp
))
1681 DEBUG(0, ("Mandatory attribute %s not found\n",
1682 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_TYPE
)));
1685 map
->sid_name_use
= (uint32
)atol(temp
);
1687 if ((map
->sid_name_use
< SID_NAME_USER
) ||
1688 (map
->sid_name_use
> SID_NAME_UNKNOWN
)) {
1689 DEBUG(0, ("Unknown Group type: %d\n", map
->sid_name_use
));
1693 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1694 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DISPLAY_NAME
), temp
))
1697 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1698 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_CN
), temp
))
1700 DEBUG(0, ("Attributes cn not found either "
1701 "for gidNumber(%i)\n",map
->gid
));
1705 fstrcpy(map
->nt_name
, temp
);
1707 if (!smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
1708 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DESC
), temp
))
1712 fstrcpy(map
->comment
, temp
);
1717 /**********************************************************************
1718 *********************************************************************/
1720 static BOOL
init_ldap_from_group(LDAP
*ldap_struct
,
1721 LDAPMessage
*existing
,
1723 const GROUP_MAP
*map
)
1727 if (mods
== NULL
|| map
== NULL
) {
1728 DEBUG(0, ("init_ldap_from_group: NULL parameters found!\n"));
1734 sid_to_string(tmp
, &map
->sid
);
1735 smbldap_make_mod(ldap_struct
, existing
, mods
,
1736 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GROUP_SID
), tmp
);
1737 snprintf(tmp
, sizeof(tmp
)-1, "%i", map
->sid_name_use
);
1738 smbldap_make_mod(ldap_struct
, existing
, mods
,
1739 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GROUP_TYPE
), tmp
);
1741 smbldap_make_mod(ldap_struct
, existing
, mods
,
1742 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DISPLAY_NAME
), map
->nt_name
);
1743 smbldap_make_mod(ldap_struct
, existing
, mods
,
1744 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_DESC
), map
->comment
);
1749 /**********************************************************************
1750 *********************************************************************/
1752 static NTSTATUS
ldapsam_getgroup(struct pdb_methods
*methods
,
1756 struct ldapsam_privates
*ldap_state
=
1757 (struct ldapsam_privates
*)methods
->private_data
;
1758 LDAPMessage
*result
;
1762 if (ldapsam_search_one_group(ldap_state
, filter
, &result
)
1764 return NT_STATUS_NO_SUCH_GROUP
;
1767 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1770 DEBUG(4, ("Did not find group\n"));
1771 ldap_msgfree(result
);
1772 return NT_STATUS_NO_SUCH_GROUP
;
1776 DEBUG(1, ("Duplicate entries for filter %s: count=%d\n",
1778 ldap_msgfree(result
);
1779 return NT_STATUS_NO_SUCH_GROUP
;
1782 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1785 ldap_msgfree(result
);
1786 return NT_STATUS_UNSUCCESSFUL
;
1789 if (!init_group_from_ldap(ldap_state
, map
, entry
)) {
1790 DEBUG(1, ("init_group_from_ldap failed for group filter %s\n",
1792 ldap_msgfree(result
);
1793 return NT_STATUS_NO_SUCH_GROUP
;
1796 ldap_msgfree(result
);
1797 return NT_STATUS_OK
;
1800 /**********************************************************************
1801 *********************************************************************/
1803 static NTSTATUS
ldapsam_getgrsid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
1808 snprintf(filter
, sizeof(filter
)-1, "(&(objectClass=%s)(%s=%s))",
1810 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GROUP_SID
),
1811 sid_string_static(&sid
));
1813 return ldapsam_getgroup(methods
, filter
, map
);
1816 /**********************************************************************
1817 *********************************************************************/
1819 static NTSTATUS
ldapsam_getgrgid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
1824 snprintf(filter
, sizeof(filter
)-1, "(&(objectClass=%s)(%s=%d))",
1826 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
),
1829 return ldapsam_getgroup(methods
, filter
, map
);
1832 /**********************************************************************
1833 *********************************************************************/
1835 static NTSTATUS
ldapsam_getgrnam(struct pdb_methods
*methods
, GROUP_MAP
*map
,
1839 char *escape_name
= escape_ldap_string_alloc(name
);
1842 return NT_STATUS_NO_MEMORY
;
1845 snprintf(filter
, sizeof(filter
)-1, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
1847 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_DISPLAY_NAME
), escape_name
,
1848 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_CN
), escape_name
);
1850 SAFE_FREE(escape_name
);
1852 return ldapsam_getgroup(methods
, filter
, map
);
1855 /**********************************************************************
1856 *********************************************************************/
1858 static int ldapsam_search_one_group_by_gid(struct ldapsam_privates
*ldap_state
,
1860 LDAPMessage
**result
)
1864 snprintf(filter
, sizeof(filter
)-1, "(&(objectClass=%s)(%s=%i))",
1865 LDAP_OBJ_POSIXGROUP
,
1866 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
),
1869 return ldapsam_search_one_group(ldap_state
, filter
, result
);
1872 /**********************************************************************
1873 *********************************************************************/
1875 static NTSTATUS
ldapsam_add_group_mapping_entry(struct pdb_methods
*methods
,
1878 struct ldapsam_privates
*ldap_state
=
1879 (struct ldapsam_privates
*)methods
->private_data
;
1880 LDAPMessage
*result
= NULL
;
1881 LDAPMod
**mods
= NULL
;
1892 if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods
, &dummy
,
1894 DEBUG(0, ("Group %i already exists in LDAP\n", map
->gid
));
1895 return NT_STATUS_UNSUCCESSFUL
;
1898 rc
= ldapsam_search_one_group_by_gid(ldap_state
, map
->gid
, &result
);
1899 if (rc
!= LDAP_SUCCESS
) {
1900 return NT_STATUS_UNSUCCESSFUL
;
1903 count
= ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
);
1906 return NT_STATUS_UNSUCCESSFUL
;
1909 DEBUG(2, ("Group %i must exist exactly once in LDAP\n",
1911 ldap_msgfree(result
);
1912 return NT_STATUS_UNSUCCESSFUL
;
1915 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1916 tmp
= ldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
1920 if (!init_ldap_from_group(ldap_state
->smbldap_state
->ldap_struct
,
1921 result
, &mods
, map
)) {
1922 DEBUG(0, ("init_ldap_from_group failed!\n"));
1923 ldap_mods_free(mods
, True
);
1924 ldap_msgfree(result
);
1925 return NT_STATUS_UNSUCCESSFUL
;
1928 ldap_msgfree(result
);
1931 DEBUG(0, ("mods is empty\n"));
1932 return NT_STATUS_UNSUCCESSFUL
;
1935 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_GROUPMAP
);
1937 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
1938 ldap_mods_free(mods
, True
);
1940 if (rc
!= LDAP_SUCCESS
) {
1941 char *ld_error
= NULL
;
1942 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
1944 DEBUG(0, ("failed to add group %i error: %s (%s)\n", map
->gid
,
1945 ld_error
? ld_error
: "(unknown)", ldap_err2string(rc
)));
1946 SAFE_FREE(ld_error
);
1947 return NT_STATUS_UNSUCCESSFUL
;
1950 DEBUG(2, ("successfully modified group %i in LDAP\n", map
->gid
));
1951 return NT_STATUS_OK
;
1954 /**********************************************************************
1955 *********************************************************************/
1957 static NTSTATUS
ldapsam_update_group_mapping_entry(struct pdb_methods
*methods
,
1960 struct ldapsam_privates
*ldap_state
=
1961 (struct ldapsam_privates
*)methods
->private_data
;
1964 LDAPMessage
*result
;
1968 rc
= ldapsam_search_one_group_by_gid(ldap_state
, map
->gid
, &result
);
1970 if (rc
!= LDAP_SUCCESS
) {
1971 return NT_STATUS_UNSUCCESSFUL
;
1974 if (ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
, result
) == 0) {
1975 DEBUG(0, ("No group to modify!\n"));
1976 ldap_msgfree(result
);
1977 return NT_STATUS_UNSUCCESSFUL
;
1980 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
1981 dn
= ldap_get_dn(ldap_state
->smbldap_state
->ldap_struct
, entry
);
1983 if (!init_ldap_from_group(ldap_state
->smbldap_state
->ldap_struct
,
1984 result
, &mods
, map
)) {
1985 DEBUG(0, ("init_ldap_from_group failed\n"));
1986 ldap_msgfree(result
);
1987 return NT_STATUS_UNSUCCESSFUL
;
1990 ldap_msgfree(result
);
1993 DEBUG(4, ("mods is empty: nothing to do\n"));
1994 return NT_STATUS_UNSUCCESSFUL
;
1997 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
1999 ldap_mods_free(mods
, True
);
2001 if (rc
!= LDAP_SUCCESS
) {
2002 char *ld_error
= NULL
;
2003 ldap_get_option(ldap_state
->smbldap_state
->ldap_struct
, LDAP_OPT_ERROR_STRING
,
2005 DEBUG(0, ("failed to modify group %i error: %s (%s)\n", map
->gid
,
2006 ld_error
? ld_error
: "(unknown)", ldap_err2string(rc
)));
2007 SAFE_FREE(ld_error
);
2010 DEBUG(2, ("successfully modified group %i in LDAP\n", map
->gid
));
2011 return NT_STATUS_OK
;
2014 /**********************************************************************
2015 *********************************************************************/
2017 static NTSTATUS
ldapsam_delete_group_mapping_entry(struct pdb_methods
*methods
,
2020 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)methods
->private_data
;
2021 pstring sidstring
, filter
;
2022 LDAPMessage
*result
;
2027 sid_to_string(sidstring
, &sid
);
2029 snprintf(filter
, sizeof(filter
)-1, "(&(objectClass=%s)(%s=%s))",
2030 LDAP_OBJ_GROUPMAP
, LDAP_ATTRIBUTE_SID
, sidstring
);
2032 rc
= ldapsam_search_one_group(ldap_state
, filter
, &result
);
2034 if (rc
!= LDAP_SUCCESS
) {
2035 return NT_STATUS_NO_SUCH_GROUP
;
2038 attr_list
= get_attr_list( groupmap_attr_list_to_delete
);
2039 ret
= ldapsam_delete_entry(ldap_state
, result
, LDAP_OBJ_GROUPMAP
, attr_list
);
2040 free_attr_list ( attr_list
);
2042 ldap_msgfree(result
);
2047 /**********************************************************************
2048 *********************************************************************/
2050 static NTSTATUS
ldapsam_setsamgrent(struct pdb_methods
*my_methods
, BOOL update
)
2052 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
2057 snprintf( filter
, sizeof(filter
)-1, "(objectclass=%s)", LDAP_OBJ_GROUPMAP
);
2058 attr_list
= get_attr_list( groupmap_attr_list
);
2059 rc
= smbldap_search(ldap_state
->smbldap_state
, lp_ldap_group_suffix(),
2060 LDAP_SCOPE_SUBTREE
, filter
,
2061 attr_list
, 0, &ldap_state
->result
);
2062 free_attr_list( attr_list
);
2064 if (rc
!= LDAP_SUCCESS
) {
2065 DEBUG(0, ("LDAP search failed: %s\n", ldap_err2string(rc
)));
2066 DEBUG(3, ("Query was: %s, %s\n", lp_ldap_group_suffix(), filter
));
2067 ldap_msgfree(ldap_state
->result
);
2068 ldap_state
->result
= NULL
;
2069 return NT_STATUS_UNSUCCESSFUL
;
2072 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
2073 ldap_count_entries(ldap_state
->smbldap_state
->ldap_struct
,
2074 ldap_state
->result
)));
2076 ldap_state
->entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, ldap_state
->result
);
2077 ldap_state
->index
= 0;
2079 return NT_STATUS_OK
;
2082 /**********************************************************************
2083 *********************************************************************/
2085 static void ldapsam_endsamgrent(struct pdb_methods
*my_methods
)
2087 ldapsam_endsampwent(my_methods
);
2090 /**********************************************************************
2091 *********************************************************************/
2093 static NTSTATUS
ldapsam_getsamgrent(struct pdb_methods
*my_methods
,
2096 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
2097 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
2101 if (!ldap_state
->entry
)
2104 ldap_state
->index
++;
2105 bret
= init_group_from_ldap(ldap_state
, map
, ldap_state
->entry
);
2107 ldap_state
->entry
= ldap_next_entry(ldap_state
->smbldap_state
->ldap_struct
,
2111 return NT_STATUS_OK
;
2114 /**********************************************************************
2115 *********************************************************************/
2117 static NTSTATUS
ldapsam_enum_group_mapping(struct pdb_methods
*methods
,
2118 enum SID_NAME_USE sid_name_use
,
2119 GROUP_MAP
**rmap
, int *num_entries
,
2130 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods
, False
))) {
2131 DEBUG(0, ("Unable to open passdb\n"));
2132 return NT_STATUS_ACCESS_DENIED
;
2135 while (NT_STATUS_IS_OK(nt_status
= ldapsam_getsamgrent(methods
, &map
))) {
2136 if (sid_name_use
!= SID_NAME_UNKNOWN
&&
2137 sid_name_use
!= map
.sid_name_use
) {
2138 DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map
.nt_name
));
2141 if (unix_only
==ENUM_ONLY_MAPPED
&& map
.gid
==-1) {
2142 DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map
.nt_name
));
2146 mapt
=(GROUP_MAP
*)Realloc((*rmap
), (entries
+1)*sizeof(GROUP_MAP
));
2148 DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
2150 return NT_STATUS_UNSUCCESSFUL
;
2155 mapt
[entries
] = map
;
2160 ldapsam_endsamgrent(methods
);
2162 *num_entries
= entries
;
2164 return NT_STATUS_OK
;
2167 /**********************************************************************
2169 *********************************************************************/
2171 static void free_private_data(void **vp
)
2173 struct ldapsam_privates
**ldap_state
= (struct ldapsam_privates
**)vp
;
2175 smbldap_free_struct(&(*ldap_state
)->smbldap_state
);
2179 /* No need to free any further, as it is talloc()ed */
2182 /**********************************************************************
2183 Intitalise the parts of the pdb_context that are common to all pdb_ldap modes
2184 *********************************************************************/
2186 static NTSTATUS
pdb_init_ldapsam_common(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
,
2187 const char *location
)
2190 struct ldapsam_privates
*ldap_state
;
2192 if (!NT_STATUS_IS_OK(nt_status
= make_pdb_methods(pdb_context
->mem_ctx
, pdb_method
))) {
2196 (*pdb_method
)->name
= "ldapsam";
2198 (*pdb_method
)->setsampwent
= ldapsam_setsampwent
;
2199 (*pdb_method
)->endsampwent
= ldapsam_endsampwent
;
2200 (*pdb_method
)->getsampwent
= ldapsam_getsampwent
;
2201 (*pdb_method
)->getsampwnam
= ldapsam_getsampwnam
;
2202 (*pdb_method
)->getsampwsid
= ldapsam_getsampwsid
;
2203 (*pdb_method
)->add_sam_account
= ldapsam_add_sam_account
;
2204 (*pdb_method
)->update_sam_account
= ldapsam_update_sam_account
;
2205 (*pdb_method
)->delete_sam_account
= ldapsam_delete_sam_account
;
2207 (*pdb_method
)->getgrsid
= ldapsam_getgrsid
;
2208 (*pdb_method
)->getgrgid
= ldapsam_getgrgid
;
2209 (*pdb_method
)->getgrnam
= ldapsam_getgrnam
;
2210 (*pdb_method
)->add_group_mapping_entry
= ldapsam_add_group_mapping_entry
;
2211 (*pdb_method
)->update_group_mapping_entry
= ldapsam_update_group_mapping_entry
;
2212 (*pdb_method
)->delete_group_mapping_entry
= ldapsam_delete_group_mapping_entry
;
2213 (*pdb_method
)->enum_group_mapping
= ldapsam_enum_group_mapping
;
2215 /* TODO: Setup private data and free */
2217 ldap_state
= talloc_zero(pdb_context
->mem_ctx
, sizeof(*ldap_state
));
2219 DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
2220 return NT_STATUS_NO_MEMORY
;
2223 if (!NT_STATUS_IS_OK(nt_status
=
2224 smbldap_init(pdb_context
->mem_ctx
, location
,
2225 &ldap_state
->smbldap_state
)));
2227 ldap_state
->domain_name
= talloc_strdup(pdb_context
->mem_ctx
, get_global_sam_name());
2228 if (!ldap_state
->domain_name
) {
2229 return NT_STATUS_NO_MEMORY
;
2232 (*pdb_method
)->private_data
= ldap_state
;
2234 (*pdb_method
)->free_private_data
= free_private_data
;
2236 return NT_STATUS_OK
;
2239 /**********************************************************************
2240 Initialise the 'compat' mode for pdb_ldap
2241 *********************************************************************/
2243 static NTSTATUS
pdb_init_ldapsam_compat(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
2246 struct ldapsam_privates
*ldap_state
;
2248 #ifdef WITH_LDAP_SAMCONFIG
2250 int ldap_port
= lp_ldap_port();
2252 /* remap default port if not using SSL (ie clear or TLS) */
2253 if ( (lp_ldap_ssl() != LDAP_SSL_ON
) && (ldap_port
== 636) ) {
2257 location
= talloc_asprintf(pdb_context
->mem_ctx
, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON
? "ldaps" : "ldap", lp_ldap_server(), ldap_port
);
2259 return NT_STATUS_NO_MEMORY
;
2264 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_ldapsam_common(pdb_context
, pdb_method
, location
))) {
2268 (*pdb_method
)->name
= "ldapsam_compat";
2270 ldap_state
= (*pdb_method
)->private_data
;
2271 ldap_state
->schema_ver
= SCHEMAVER_SAMBAACCOUNT
;
2273 sid_copy(&ldap_state
->domain_sid
, get_global_sam_sid());
2275 return NT_STATUS_OK
;
2278 /**********************************************************************
2279 Initialise the normal mode for pdb_ldap
2280 *********************************************************************/
2282 static NTSTATUS
pdb_init_ldapsam(PDB_CONTEXT
*pdb_context
, PDB_METHODS
**pdb_method
, const char *location
)
2285 struct ldapsam_privates
*ldap_state
;
2286 uint32 alg_rid_base
;
2287 pstring alg_rid_base_string
;
2288 LDAPMessage
*result
= NULL
;
2289 LDAPMessage
*entry
= NULL
;
2290 DOM_SID ldap_domain_sid
;
2291 DOM_SID secrets_domain_sid
;
2292 pstring domain_sid_string
;
2294 if (!NT_STATUS_IS_OK(nt_status
= pdb_init_ldapsam_common(pdb_context
, pdb_method
, location
))) {
2298 (*pdb_method
)->name
= "ldapsam";
2300 ldap_state
= (*pdb_method
)->private_data
;
2301 ldap_state
->schema_ver
= SCHEMAVER_SAMBASAMACCOUNT
;
2303 /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
2305 nt_status
= smbldap_search_domain_info(ldap_state
->smbldap_state
, &result
,
2306 ldap_state
->domain_name
, True
);
2308 if ( !NT_STATUS_IS_OK(nt_status
) ) {
2309 DEBUG(2, ("WARNING: Could not get domain info, nor add one to the domain\n"));
2310 DEBUGADD(2, ("Continuing on regardless, will be unable to allocate new users/groups, "
2311 "and will risk BDCs having inconsistant SIDs\n"));
2312 sid_copy(&ldap_state
->domain_sid
, get_global_sam_sid());
2313 return NT_STATUS_OK
;
2316 /* Given that the above might fail, everything below this must be optional */
2318 entry
= ldap_first_entry(ldap_state
->smbldap_state
->ldap_struct
, result
);
2320 DEBUG(0, ("Could not get domain info entry\n"));
2321 ldap_msgfree(result
);
2322 return NT_STATUS_UNSUCCESSFUL
;
2325 if (smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
2326 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
2330 string_to_sid(&ldap_domain_sid
, domain_sid_string
);
2331 found_sid
= secrets_fetch_domain_sid(ldap_state
->domain_name
, &secrets_domain_sid
);
2332 if (!found_sid
|| !sid_equal(&secrets_domain_sid
, &ldap_domain_sid
)) {
2333 /* reset secrets.tdb sid */
2334 secrets_store_domain_sid(ldap_state
->domain_name
, &ldap_domain_sid
);
2336 sid_copy(&ldap_state
->domain_sid
, &ldap_domain_sid
);
2339 if (smbldap_get_single_attribute(ldap_state
->smbldap_state
->ldap_struct
, entry
,
2340 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_ALGORITHMIC_RID_BASE
),
2341 alg_rid_base_string
))
2343 alg_rid_base
= (uint32
)atol(alg_rid_base_string
);
2344 if (alg_rid_base
!= algorithmic_rid_base()) {
2345 DEBUG(0, ("The value of 'algorithmic RID base' has changed since the LDAP\n"
2346 "database was initialised. Aborting. \n"));
2347 ldap_msgfree(result
);
2348 return NT_STATUS_UNSUCCESSFUL
;
2351 ldap_msgfree(result
);
2353 return NT_STATUS_OK
;
2356 NTSTATUS
pdb_ldap_init(void)
2359 if (!NT_STATUS_IS_OK(nt_status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ldapsam", pdb_init_ldapsam
)))
2362 if (!NT_STATUS_IS_OK(nt_status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
, "ldapsam_compat", pdb_init_ldapsam_compat
)))
2365 return NT_STATUS_OK
;