2 Unix SMB/CIFS implementation.
3 LDAP protocol helper functions for SAMBA
4 Copyright (C) Jean François Micouleau 1998
5 Copyright (C) Gerald Carter 2001-2003
6 Copyright (C) Shahms King 2001
7 Copyright (C) Andrew Bartlett 2002-2003
8 Copyright (C) Stefan (metze) Metzmacher 2002-2003
9 Copyright (C) Simo Sorce 2006
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
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/struct samu
34 * structures don't have fields for some of these attributes)
36 * SSL is done, but can't get the certificate based authentication to work
37 * against on my test platform (Linux 2.4, OpenLDAP 2.x)
40 /* NOTE: this will NOT work against an Active Directory server
41 * due to the fact that the two password fields cannot be retrieved
42 * from a server; recommend using security = domain in this situation
49 #define DBGC_CLASS DBGC_PASSDB
55 * Work around versions of the LDAP client libs that don't have the OIDs
56 * defined, or have them defined under the old name.
57 * This functionality is really a factor of the server, not the client
61 #if defined(LDAP_EXOP_X_MODIFY_PASSWD) && !defined(LDAP_EXOP_MODIFY_PASSWD)
62 #define LDAP_EXOP_MODIFY_PASSWD LDAP_EXOP_X_MODIFY_PASSWD
63 #elif !defined(LDAP_EXOP_MODIFY_PASSWD)
64 #define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1"
67 #if defined(LDAP_EXOP_X_MODIFY_PASSWD_ID) && !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
68 #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID LDAP_EXOP_X_MODIFY_PASSWD_ID
69 #elif !defined(LDAP_EXOP_MODIFY_PASSWD_ID)
70 #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U)
73 #if defined(LDAP_EXOP_X_MODIFY_PASSWD_NEW) && !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
74 #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW LDAP_EXOP_X_MODIFY_PASSWD_NEW
75 #elif !defined(LDAP_EXOP_MODIFY_PASSWD_NEW)
76 #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U)
82 /**********************************************************************
83 Simple helper function to make stuff better readable
84 **********************************************************************/
86 static LDAP *priv2ld(struct ldapsam_privates *priv)
88 return priv->smbldap_state->ldap_struct;
91 /**********************************************************************
92 Get the attribute name given a user schame version.
93 **********************************************************************/
95 static const char* get_userattr_key2string( int schema_ver, int key )
97 switch ( schema_ver ) {
98 case SCHEMAVER_SAMBAACCOUNT:
99 return get_attr_key2string( attrib_map_v22, key );
101 case SCHEMAVER_SAMBASAMACCOUNT:
102 return get_attr_key2string( attrib_map_v30, key );
105 DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
111 /**********************************************************************
112 Return the list of attribute names given a user schema version.
113 **********************************************************************/
115 const char** get_userattr_list( TALLOC_CTX *mem_ctx, int schema_ver )
117 switch ( schema_ver ) {
118 case SCHEMAVER_SAMBAACCOUNT:
119 return get_attr_list( mem_ctx, attrib_map_v22 );
121 case SCHEMAVER_SAMBASAMACCOUNT:
122 return get_attr_list( mem_ctx, attrib_map_v30 );
124 DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
131 /**************************************************************************
132 Return the list of attribute names to delete given a user schema version.
133 **************************************************************************/
135 static const char** get_userattr_delete_list( TALLOC_CTX *mem_ctx,
138 switch ( schema_ver ) {
139 case SCHEMAVER_SAMBAACCOUNT:
140 return get_attr_list( mem_ctx,
141 attrib_map_to_delete_v22 );
143 case SCHEMAVER_SAMBASAMACCOUNT:
144 return get_attr_list( mem_ctx,
145 attrib_map_to_delete_v30 );
147 DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n"));
155 /*******************************************************************
156 Generate the LDAP search filter for the objectclass based on the
157 version of the schema we are using.
158 ******************************************************************/
160 static const char* get_objclass_filter( int schema_ver )
162 fstring objclass_filter;
165 switch( schema_ver ) {
166 case SCHEMAVER_SAMBAACCOUNT:
167 fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT );
169 case SCHEMAVER_SAMBASAMACCOUNT:
170 fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
173 DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));
174 objclass_filter[0] = '\0';
178 result = talloc_strdup(talloc_tos(), objclass_filter);
179 SMB_ASSERT(result != NULL);
183 /*****************************************************************
184 Scan a sequence number off OpenLDAP's syncrepl contextCSN
185 ******************************************************************/
187 static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_num)
189 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
190 NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
191 LDAPMessage *msg = NULL;
192 LDAPMessage *entry = NULL;
194 char **values = NULL;
195 int rc, num_result, num_values, rid;
201 /* Unfortunatly there is no proper way to detect syncrepl-support in
202 * smbldap_connect_system(). The syncrepl OIDs are submitted for publication
203 * but do not show up in the root-DSE yet. Neither we can query the
204 * subschema-context for the syncProviderSubentry or syncConsumerSubentry
205 * objectclass. Currently we require lp_ldap_suffix() to show up as
206 * namingContext. - Guenther
209 if (!lp_parm_bool(-1, "ldapsam", "syncrepl_seqnum", False)) {
214 DEBUG(3,("ldapsam_get_seq_num: no sequence_number\n"));
218 if (!smbldap_has_naming_context(ldap_state->smbldap_state->ldap_struct, lp_ldap_suffix())) {
219 DEBUG(3,("ldapsam_get_seq_num: DIT not configured to hold %s "
220 "as top-level namingContext\n", lp_ldap_suffix()));
224 mem_ctx = talloc_init("ldapsam_get_seq_num");
227 return NT_STATUS_NO_MEMORY;
229 if ((attrs = TALLOC_ARRAY(mem_ctx, const char *, 2)) == NULL) {
230 ntstatus = NT_STATUS_NO_MEMORY;
234 /* if we got a syncrepl-rid (up to three digits long) we speak with a consumer */
235 rid = lp_parm_int(-1, "ldapsam", "syncrepl_rid", -1);
238 /* consumer syncreplCookie: */
239 /* csn=20050126161620Z#0000001#00#00000 */
240 attrs[0] = talloc_strdup(mem_ctx, "syncreplCookie");
242 pstr_sprintf( suffix, "cn=syncrepl%d,%s", rid, lp_ldap_suffix());
246 /* provider contextCSN */
247 /* 20050126161620Z#000009#00#000000 */
248 attrs[0] = talloc_strdup(mem_ctx, "contextCSN");
250 pstr_sprintf( suffix, "cn=ldapsync,%s", lp_ldap_suffix());
254 rc = smbldap_search(ldap_state->smbldap_state, suffix,
255 LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &msg);
257 if (rc != LDAP_SUCCESS) {
261 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg);
262 if (num_result != 1) {
263 DEBUG(3,("ldapsam_get_seq_num: Expected one entry, got %d\n", num_result));
267 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, msg);
269 DEBUG(3,("ldapsam_get_seq_num: Could not retrieve entry\n"));
273 values = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, attrs[0]);
274 if (values == NULL) {
275 DEBUG(3,("ldapsam_get_seq_num: no values\n"));
279 num_values = ldap_count_values(values);
280 if (num_values == 0) {
281 DEBUG(3,("ldapsam_get_seq_num: not a single value\n"));
286 if (!next_token(&p, tok, "#", sizeof(tok))) {
287 DEBUG(0,("ldapsam_get_seq_num: failed to parse sequence number\n"));
292 if (!strncmp(p, "csn=", strlen("csn=")))
295 DEBUG(10,("ldapsam_get_seq_num: got %s: %s\n", attrs[0], p));
297 *seq_num = generalized_to_unix_time(p);
299 /* very basic sanity check */
301 DEBUG(3,("ldapsam_get_seq_num: invalid sequence number: %d\n",
306 ntstatus = NT_STATUS_OK;
310 ldap_value_free(values);
314 talloc_destroy(mem_ctx);
319 /*******************************************************************
320 Run the search by name.
321 ******************************************************************/
323 int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
325 LDAPMessage ** result,
329 char *escape_user = escape_ldap_string_alloc(user);
332 return LDAP_NO_MEMORY;
336 * in the filter expression, replace %u with the real name
337 * so in ldap filter, %u MUST exist :-)
339 pstr_sprintf(filter, "(&%s%s)", "(uid=%u)",
340 get_objclass_filter(ldap_state->schema_ver));
343 * have to use this here because $ is filtered out
348 all_string_sub(filter, "%u", escape_user, sizeof(pstring));
349 SAFE_FREE(escape_user);
351 return smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
354 /*******************************************************************
355 Run the search by rid.
356 ******************************************************************/
358 static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
359 uint32 rid, LDAPMessage ** result,
365 pstr_sprintf(filter, "(&(rid=%i)%s)", rid,
366 get_objclass_filter(ldap_state->schema_ver));
368 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
373 /*******************************************************************
374 Run the search by SID.
375 ******************************************************************/
377 static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
378 const DOM_SID *sid, LDAPMessage ** result,
385 pstr_sprintf(filter, "(&(%s=%s)%s)",
386 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
387 sid_to_string(sid_string, sid),
388 get_objclass_filter(ldap_state->schema_ver));
390 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
395 /*******************************************************************
396 Delete complete object or objectclass and attrs from
397 object found in search_result depending on lp_ldap_delete_dn
398 ******************************************************************/
400 static int ldapsam_delete_entry(struct ldapsam_privates *priv,
403 const char *objectclass,
406 LDAPMod **mods = NULL;
409 BerElement *ptr = NULL;
411 dn = smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry);
413 return LDAP_NO_MEMORY;
416 if (lp_ldap_delete_dn()) {
417 return smbldap_delete(priv->smbldap_state, dn);
420 /* Ok, delete only the SAM attributes */
422 for (name = ldap_first_attribute(priv2ld(priv), entry, &ptr);
424 name = ldap_next_attribute(priv2ld(priv), entry, ptr)) {
427 /* We are only allowed to delete the attributes that
430 for (attrib = attrs; *attrib != NULL; attrib++) {
431 if (strequal(*attrib, name)) {
432 DEBUG(10, ("ldapsam_delete_entry: deleting "
433 "attribute %s\n", name));
434 smbldap_set_mod(&mods, LDAP_MOD_DELETE, name,
445 smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
446 talloc_autofree_ldapmod(mem_ctx, mods);
448 return smbldap_modify(priv->smbldap_state, dn, mods);
451 static time_t ldapsam_get_entry_timestamp( struct ldapsam_privates *ldap_state, LDAPMessage * entry)
456 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
457 get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP),
461 if ( !strptime(temp, "%Y%m%d%H%M%SZ", &tm)) {
462 DEBUG(2,("ldapsam_get_entry_timestamp: strptime failed on: %s\n",
470 /**********************************************************************
471 Initialize struct samu from an LDAP query.
472 (Based on init_sam_from_buffer in pdb_tdb.c)
473 *********************************************************************/
475 static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
476 struct samu * sampass,
483 pass_can_change_time,
484 pass_must_change_time,
497 char munged_dial[2048];
499 uint8 smblmpwd[LM_HASH_LEN],
500 smbntpwd[NT_HASH_LEN];
501 bool use_samba_attrs = True;
502 uint32 acct_ctrl = 0;
504 uint16 bad_password_count = 0,
507 uint8 hours[MAX_HOURS_LEN];
509 LOGIN_CACHE *cache_entry = NULL;
512 bool expand_explicit = lp_passdb_expand_explicit();
515 * do a little initialization
519 nt_username[0] = '\0';
523 logon_script[0] = '\0';
524 profile_path[0] = '\0';
526 munged_dial[0] = '\0';
527 workstations[0] = '\0';
530 if (sampass == NULL || ldap_state == NULL || entry == NULL) {
531 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
535 if (priv2ld(ldap_state) == NULL) {
536 DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->"
537 "ldap_struct is NULL!\n"));
541 if (!smbldap_get_single_pstring(priv2ld(ldap_state), entry, "uid",
543 DEBUG(1, ("init_sam_from_ldap: No uid attribute found for "
548 DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username));
550 pstrcpy(nt_username, username);
552 pstrcpy(domain, ldap_state->domain_name);
554 pdb_set_username(sampass, username, PDB_SET);
556 pdb_set_domain(sampass, domain, PDB_DEFAULT);
557 pdb_set_nt_username(sampass, nt_username, PDB_SET);
559 /* deal with different attributes between the schema first */
561 if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ) {
562 if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
563 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), temp)) {
564 pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
567 if (smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
568 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), temp)) {
569 user_rid = (uint32)atol(temp);
570 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
574 if (pdb_get_init_flags(sampass,PDB_USERSID) == PDB_DEFAULT) {
575 DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n",
576 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
577 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
582 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
583 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), temp)) {
584 /* leave as default */
586 pass_last_set_time = (time_t) atol(temp);
587 pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
590 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
591 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp)) {
592 /* leave as default */
594 logon_time = (time_t) atol(temp);
595 pdb_set_logon_time(sampass, logon_time, PDB_SET);
598 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
599 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp)) {
600 /* leave as default */
602 logoff_time = (time_t) atol(temp);
603 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
606 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
607 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp)) {
608 /* leave as default */
610 kickoff_time = (time_t) atol(temp);
611 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
614 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
615 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp)) {
616 /* leave as default */
618 pass_can_change_time = (time_t) atol(temp);
619 pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
622 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
623 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp)) {
624 /* leave as default */
626 pass_must_change_time = (time_t) atol(temp);
627 pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
630 /* recommend that 'gecos' and 'displayName' should refer to the same
631 * attribute OID. userFullName depreciated, only used by Samba
632 * primary rules of LDAP: don't make a new attribute when one is already defined
633 * that fits your needs; using cn then displayName rather than 'userFullName'
636 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
637 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME), fullname)) {
638 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
639 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_CN), fullname)) {
640 /* leave as default */
642 pdb_set_fullname(sampass, fullname, PDB_SET);
645 pdb_set_fullname(sampass, fullname, PDB_SET);
648 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
649 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), dir_drive))
651 pdb_set_dir_drive( sampass, lp_logon_drive(), PDB_DEFAULT );
653 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
656 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
657 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), homedir))
659 pdb_set_homedir( sampass,
660 talloc_sub_basic(sampass, username, domain,
664 pstrcpy( tmpstring, homedir );
665 if (expand_explicit) {
666 standard_sub_basic( username, domain, tmpstring,
669 pdb_set_homedir(sampass, tmpstring, PDB_SET);
672 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
673 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), logon_script))
675 pdb_set_logon_script( sampass,
676 talloc_sub_basic(sampass, username, domain,
680 pstrcpy( tmpstring, logon_script );
681 if (expand_explicit) {
682 standard_sub_basic( username, domain, tmpstring,
685 pdb_set_logon_script(sampass, tmpstring, PDB_SET);
688 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
689 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), profile_path))
691 pdb_set_profile_path( sampass,
692 talloc_sub_basic( sampass, username, domain,
696 pstrcpy( tmpstring, profile_path );
697 if (expand_explicit) {
698 standard_sub_basic( username, domain, tmpstring,
701 pdb_set_profile_path(sampass, tmpstring, PDB_SET);
704 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
705 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC), acct_desc))
707 /* leave as default */
709 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
712 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
713 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), workstations)) {
714 /* leave as default */;
716 pdb_set_workstations(sampass, workstations, PDB_SET);
719 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
720 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), munged_dial, sizeof(munged_dial))) {
721 /* leave as default */;
723 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
726 /* FIXME: hours stuff should be cleaner */
730 memset(hours, 0xff, hours_len);
732 if (ldap_state->is_nds_ldap) {
735 char clear_text_pw[512];
737 /* Make call to Novell eDirectory ldap extension to get clear text password.
738 NOTE: This will only work if we have an SSL connection to eDirectory. */
739 user_dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
740 if (user_dn != NULL) {
741 DEBUG(3, ("init_sam_from_ldap: smbldap_get_dn(%s) returned '%s'\n", username, user_dn));
743 pwd_len = sizeof(clear_text_pw);
744 if (pdb_nds_get_password(ldap_state->smbldap_state, user_dn, &pwd_len, clear_text_pw) == LDAP_SUCCESS) {
745 nt_lm_owf_gen(clear_text_pw, smbntpwd, smblmpwd);
746 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET)) {
750 ZERO_STRUCT(smblmpwd);
751 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET)) {
755 ZERO_STRUCT(smbntpwd);
756 use_samba_attrs = False;
762 DEBUG(0, ("init_sam_from_ldap: failed to get user_dn for '%s'\n", username));
766 if (use_samba_attrs) {
767 if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
768 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), temp)) {
769 /* leave as default */
771 pdb_gethexpwd(temp, smblmpwd);
772 memset((char *)temp, '\0', strlen(temp)+1);
773 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET))
775 ZERO_STRUCT(smblmpwd);
778 if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
779 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), temp)) {
780 /* leave as default */
782 pdb_gethexpwd(temp, smbntpwd);
783 memset((char *)temp, '\0', strlen(temp)+1);
784 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET))
786 ZERO_STRUCT(smbntpwd);
792 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
794 uint8 *pwhist = NULL;
796 char history_string[MAX_PW_HISTORY_LEN*64];
798 pwHistLen = MIN(pwHistLen, MAX_PW_HISTORY_LEN);
800 if ((pwhist = SMB_MALLOC_ARRAY(uint8, pwHistLen * PW_HISTORY_ENTRY_LEN)) == NULL){
801 DEBUG(0, ("init_sam_from_ldap: malloc failed!\n"));
804 memset(pwhist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
806 if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
807 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY),
808 history_string, sizeof(history_string))) {
809 /* leave as default - zeros */
811 bool hex_failed = False;
812 for (i = 0; i < pwHistLen; i++){
813 /* Get the 16 byte salt. */
814 if (!pdb_gethexpwd(&history_string[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN])) {
818 /* Get the 16 byte MD5 hash of salt+passwd. */
819 if (!pdb_gethexpwd(&history_string[(i*64)+32],
820 &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN])) {
826 DEBUG(0,("init_sam_from_ldap: Failed to get password history for user %s\n",
828 memset(pwhist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
831 if (!pdb_set_pw_history(sampass, pwhist, pwHistLen, PDB_SET)){
838 if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
839 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), temp)) {
840 acct_ctrl |= ACB_NORMAL;
842 acct_ctrl = pdb_decode_acct_ctrl(temp);
845 acct_ctrl |= ACB_NORMAL;
847 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
850 pdb_set_hours_len(sampass, hours_len, PDB_SET);
851 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
853 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
854 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_COUNT), temp)) {
855 /* leave as default */
857 bad_password_count = (uint32) atol(temp);
858 pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
861 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
862 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_TIME), temp)) {
863 /* leave as default */
865 bad_password_time = (time_t) atol(temp);
866 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
870 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
871 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_COUNT), temp)) {
872 /* leave as default */
874 logon_count = (uint32) atol(temp);
875 pdb_set_logon_count(sampass, logon_count, PDB_SET);
878 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
880 if(!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
881 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_HOURS), temp)) {
882 /* leave as default */
884 pdb_gethexhours(temp, hours);
885 memset((char *)temp, '\0', strlen(temp) +1);
886 pdb_set_hours(sampass, hours, PDB_SET);
890 if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
891 if (smbldap_get_single_pstring(priv2ld(ldap_state), entry,
892 "uidNumber", temp)) {
893 /* We've got a uid, feed the cache */
894 uid_t uid = strtoul(temp, NULL, 10);
895 store_uid_sid_cache(pdb_get_user_sid(sampass), uid);
899 /* check the timestamp of the cache vs ldap entry */
900 if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state,
904 /* see if we have newer updates */
905 if (!(cache_entry = login_cache_read(sampass))) {
906 DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n",
907 (unsigned int)pdb_get_bad_password_count(sampass),
908 (unsigned int)pdb_get_bad_password_time(sampass)));
912 DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n",
913 (unsigned int)ldap_entry_time, (unsigned int)cache_entry->entry_timestamp,
914 (unsigned int)cache_entry->bad_password_time));
916 if (ldap_entry_time > cache_entry->entry_timestamp) {
917 /* cache is older than directory , so
918 we need to delete the entry but allow the
919 fields to be written out */
920 login_cache_delentry(sampass);
923 pdb_set_acct_ctrl(sampass,
924 pdb_get_acct_ctrl(sampass) |
925 (cache_entry->acct_ctrl & ACB_AUTOLOCK),
927 pdb_set_bad_password_count(sampass,
928 cache_entry->bad_password_count,
930 pdb_set_bad_password_time(sampass,
931 cache_entry->bad_password_time,
935 SAFE_FREE(cache_entry);
939 /**********************************************************************
940 Initialize the ldap db from a struct samu. Called on update.
941 (Based on init_buffer_from_sam in pdb_tdb.c)
942 *********************************************************************/
944 static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
945 LDAPMessage *existing,
946 LDAPMod *** mods, struct samu * sampass,
947 bool (*need_update)(const struct samu *,
953 if (mods == NULL || sampass == NULL) {
954 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
961 * took out adding "objectclass: sambaAccount"
962 * do this on a per-mod basis
964 if (need_update(sampass, PDB_USERNAME)) {
965 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
966 "uid", pdb_get_username(sampass));
967 if (ldap_state->is_nds_ldap) {
968 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
969 "cn", pdb_get_username(sampass));
970 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
971 "sn", pdb_get_username(sampass));
975 DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass)));
977 /* only update the RID if we actually need to */
978 if (need_update(sampass, PDB_USERSID)) {
980 const DOM_SID *user_sid = pdb_get_user_sid(sampass);
982 switch ( ldap_state->schema_ver ) {
983 case SCHEMAVER_SAMBAACCOUNT:
984 if (!sid_peek_check_rid(&ldap_state->domain_sid, user_sid, &rid)) {
985 DEBUG(1, ("init_ldap_from_sam: User's SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
986 sid_string_static(user_sid),
987 sid_string_static(&ldap_state->domain_sid)));
990 slprintf(temp, sizeof(temp) - 1, "%i", rid);
991 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
992 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
996 case SCHEMAVER_SAMBASAMACCOUNT:
997 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
998 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
999 sid_to_string(sid_string, user_sid));
1003 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
1008 /* we don't need to store the primary group RID - so leaving it
1009 'free' to hang off the unix primary group makes life easier */
1011 if (need_update(sampass, PDB_GROUPSID)) {
1013 const DOM_SID *group_sid = pdb_get_group_sid(sampass);
1015 switch ( ldap_state->schema_ver ) {
1016 case SCHEMAVER_SAMBAACCOUNT:
1017 if (!sid_peek_check_rid(&ldap_state->domain_sid, group_sid, &rid)) {
1018 DEBUG(1, ("init_ldap_from_sam: User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
1019 sid_string_static(group_sid),
1020 sid_string_static(&ldap_state->domain_sid)));
1024 slprintf(temp, sizeof(temp) - 1, "%i", rid);
1025 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1026 get_userattr_key2string(ldap_state->schema_ver,
1027 LDAP_ATTR_PRIMARY_GROUP_RID), temp);
1030 case SCHEMAVER_SAMBASAMACCOUNT:
1031 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1032 get_userattr_key2string(ldap_state->schema_ver,
1033 LDAP_ATTR_PRIMARY_GROUP_SID), sid_to_string(sid_string, group_sid));
1037 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
1043 /* displayName, cn, and gecos should all be the same
1044 * most easily accomplished by giving them the same OID
1045 * gecos isn't set here b/c it should be handled by the
1047 * We change displayName only and fall back to cn if
1048 * it does not exist.
1051 if (need_update(sampass, PDB_FULLNAME))
1052 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1053 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME),
1054 pdb_get_fullname(sampass));
1056 if (need_update(sampass, PDB_ACCTDESC))
1057 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1058 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC),
1059 pdb_get_acct_desc(sampass));
1061 if (need_update(sampass, PDB_WORKSTATIONS))
1062 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1063 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS),
1064 pdb_get_workstations(sampass));
1066 if (need_update(sampass, PDB_MUNGEDDIAL))
1067 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1068 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL),
1069 pdb_get_munged_dial(sampass));
1071 if (need_update(sampass, PDB_SMBHOME))
1072 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1073 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH),
1074 pdb_get_homedir(sampass));
1076 if (need_update(sampass, PDB_DRIVE))
1077 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1078 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE),
1079 pdb_get_dir_drive(sampass));
1081 if (need_update(sampass, PDB_LOGONSCRIPT))
1082 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1083 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT),
1084 pdb_get_logon_script(sampass));
1086 if (need_update(sampass, PDB_PROFILE))
1087 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1088 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH),
1089 pdb_get_profile_path(sampass));
1091 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
1092 if (need_update(sampass, PDB_LOGONTIME))
1093 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1094 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
1096 slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
1097 if (need_update(sampass, PDB_LOGOFFTIME))
1098 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1099 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
1101 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
1102 if (need_update(sampass, PDB_KICKOFFTIME))
1103 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1104 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
1106 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time_noncalc(sampass));
1107 if (need_update(sampass, PDB_CANCHANGETIME))
1108 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1109 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
1111 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
1112 if (need_update(sampass, PDB_MUSTCHANGETIME))
1113 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1114 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp);
1117 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
1118 || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
1120 if (need_update(sampass, PDB_LMPASSWD)) {
1121 const uchar *lm_pw = pdb_get_lanman_passwd(sampass);
1123 pdb_sethexpwd(temp, lm_pw,
1124 pdb_get_acct_ctrl(sampass));
1125 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1126 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
1129 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1130 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
1134 if (need_update(sampass, PDB_NTPASSWD)) {
1135 const uchar *nt_pw = pdb_get_nt_passwd(sampass);
1137 pdb_sethexpwd(temp, nt_pw,
1138 pdb_get_acct_ctrl(sampass));
1139 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1140 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
1143 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1144 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
1149 if (need_update(sampass, PDB_PWHISTORY)) {
1150 uint32 pwHistLen = 0;
1151 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1152 if (pwHistLen == 0) {
1153 /* Remove any password history from the LDAP store. */
1154 memset(temp, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
1158 uint32 currHistLen = 0;
1159 const uint8 *pwhist = pdb_get_pw_history(sampass, &currHistLen);
1160 if (pwhist != NULL) {
1161 /* We can only store (sizeof(pstring)-1)/64 password history entries. */
1162 pwHistLen = MIN(pwHistLen, ((sizeof(temp)-1)/64));
1163 for (i=0; i< pwHistLen && i < currHistLen; i++) {
1164 /* Store the salt. */
1165 pdb_sethexpwd(&temp[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN], 0);
1166 /* Followed by the md5 hash of salt + md4 hash */
1167 pdb_sethexpwd(&temp[(i*64)+32],
1168 &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN], 0);
1169 DEBUG(100, ("temp=%s\n", temp));
1173 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1174 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY),
1178 if (need_update(sampass, PDB_PASSLASTSET)) {
1179 slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
1180 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1181 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET),
1186 if (need_update(sampass, PDB_HOURS)) {
1187 const uint8 *hours = pdb_get_hours(sampass);
1189 pdb_sethexhours(temp, hours);
1190 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct,
1193 get_userattr_key2string(ldap_state->schema_ver,
1194 LDAP_ATTR_LOGON_HOURS),
1199 if (need_update(sampass, PDB_ACCTCTRL))
1200 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1201 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO),
1202 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
1204 /* password lockout cache:
1205 - If we are now autolocking or clearing, we write to ldap
1206 - If we are clearing, we delete the cache entry
1207 - If the count is > 0, we update the cache
1209 This even means when autolocking, we cache, just in case the
1210 update doesn't work, and we have to cache the autolock flag */
1212 if (need_update(sampass, PDB_BAD_PASSWORD_COUNT)) /* &&
1213 need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ {
1214 uint16 badcount = pdb_get_bad_password_count(sampass);
1215 time_t badtime = pdb_get_bad_password_time(sampass);
1217 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &pol);
1219 DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
1220 (unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime));
1222 if ((badcount >= pol) || (badcount == 0)) {
1223 DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n",
1224 (unsigned int)badcount, (unsigned int)badtime));
1225 slprintf (temp, sizeof (temp) - 1, "%li", (long)badcount);
1227 ldap_state->smbldap_state->ldap_struct,
1229 get_userattr_key2string(
1230 ldap_state->schema_ver,
1231 LDAP_ATTR_BAD_PASSWORD_COUNT),
1234 slprintf (temp, sizeof (temp) - 1, "%li", badtime);
1236 ldap_state->smbldap_state->ldap_struct,
1238 get_userattr_key2string(
1239 ldap_state->schema_ver,
1240 LDAP_ATTR_BAD_PASSWORD_TIME),
1243 if (badcount == 0) {
1244 DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass)));
1245 login_cache_delentry(sampass);
1247 LOGIN_CACHE cache_entry;
1249 cache_entry.entry_timestamp = time(NULL);
1250 cache_entry.acct_ctrl = pdb_get_acct_ctrl(sampass);
1251 cache_entry.bad_password_count = badcount;
1252 cache_entry.bad_password_time = badtime;
1254 DEBUG(7, ("Updating bad password count and time in login cache\n"));
1255 login_cache_write(sampass, cache_entry);
1262 /**********************************************************************
1263 Connect to LDAP server for password enumeration.
1264 *********************************************************************/
1266 static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, bool update, uint32 acb_mask)
1268 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1270 pstring filter, suffix;
1271 const char **attr_list;
1272 bool machine_mask = False, user_mask = False;
1274 pstr_sprintf( filter, "(&%s%s)", "(uid=%u)",
1275 get_objclass_filter(ldap_state->schema_ver));
1276 all_string_sub(filter, "%u", "*", sizeof(pstring));
1278 machine_mask = ((acb_mask != 0) && (acb_mask & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)));
1279 user_mask = ((acb_mask != 0) && (acb_mask & ACB_NORMAL));
1282 pstrcpy(suffix, lp_ldap_machine_suffix());
1283 } else if (user_mask) {
1284 pstrcpy(suffix, lp_ldap_user_suffix());
1286 pstrcpy(suffix, lp_ldap_suffix());
1289 DEBUG(10,("ldapsam_setsampwent: LDAP Query for acb_mask 0x%x will use suffix %s\n",
1292 attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
1293 rc = smbldap_search(ldap_state->smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter,
1294 attr_list, 0, &ldap_state->result);
1295 TALLOC_FREE( attr_list );
1297 if (rc != LDAP_SUCCESS) {
1298 DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc)));
1299 DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", suffix, filter));
1300 ldap_msgfree(ldap_state->result);
1301 ldap_state->result = NULL;
1302 return NT_STATUS_UNSUCCESSFUL;
1305 DEBUG(2, ("ldapsam_setsampwent: %d entries in the base %s\n",
1306 ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
1307 ldap_state->result), suffix));
1309 ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
1310 ldap_state->result);
1311 ldap_state->index = 0;
1313 return NT_STATUS_OK;
1316 /**********************************************************************
1317 End enumeration of the LDAP password list.
1318 *********************************************************************/
1320 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1322 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1323 if (ldap_state->result) {
1324 ldap_msgfree(ldap_state->result);
1325 ldap_state->result = NULL;
1329 /**********************************************************************
1330 Get the next entry in the LDAP password database.
1331 *********************************************************************/
1333 static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods,
1336 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1337 struct ldapsam_privates *ldap_state =
1338 (struct ldapsam_privates *)my_methods->private_data;
1342 if (!ldap_state->entry)
1345 ldap_state->index++;
1346 bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
1348 ldap_state->entry = ldap_next_entry(priv2ld(ldap_state),
1352 return NT_STATUS_OK;
1355 static void append_attr(TALLOC_CTX *mem_ctx, const char ***attr_list,
1356 const char *new_attr)
1360 if (new_attr == NULL) {
1364 for (i=0; (*attr_list)[i] != NULL; i++) {
1368 (*attr_list) = TALLOC_REALLOC_ARRAY(mem_ctx, (*attr_list),
1370 SMB_ASSERT((*attr_list) != NULL);
1371 (*attr_list)[i] = talloc_strdup((*attr_list), new_attr);
1372 (*attr_list)[i+1] = NULL;
1375 /**********************************************************************
1376 Get struct samu entry from LDAP by username.
1377 *********************************************************************/
1379 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu *user, const char *sname)
1381 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1382 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1383 LDAPMessage *result = NULL;
1384 LDAPMessage *entry = NULL;
1386 const char ** attr_list;
1389 attr_list = get_userattr_list( user, ldap_state->schema_ver );
1390 append_attr(user, &attr_list,
1391 get_userattr_key2string(ldap_state->schema_ver,
1392 LDAP_ATTR_MOD_TIMESTAMP));
1393 append_attr(user, &attr_list, "uidNumber");
1394 rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result,
1396 TALLOC_FREE( attr_list );
1398 if ( rc != LDAP_SUCCESS )
1399 return NT_STATUS_NO_SUCH_USER;
1401 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1404 DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname, count));
1405 ldap_msgfree(result);
1406 return NT_STATUS_NO_SUCH_USER;
1407 } else if (count > 1) {
1408 DEBUG(1, ("ldapsam_getsampwnam: Duplicate entries for this user [%s] Failing. count=%d\n", sname, count));
1409 ldap_msgfree(result);
1410 return NT_STATUS_NO_SUCH_USER;
1413 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1415 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1416 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1417 ldap_msgfree(result);
1418 return NT_STATUS_NO_SUCH_USER;
1420 pdb_set_backend_private_data(user, result, NULL,
1421 my_methods, PDB_CHANGED);
1422 talloc_autofree_ldapmsg(user, result);
1425 ldap_msgfree(result);
1430 static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
1431 const DOM_SID *sid, LDAPMessage **result)
1434 const char ** attr_list;
1437 switch ( ldap_state->schema_ver ) {
1438 case SCHEMAVER_SAMBASAMACCOUNT: {
1439 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
1440 if (tmp_ctx == NULL) {
1441 return LDAP_NO_MEMORY;
1444 attr_list = get_userattr_list(tmp_ctx,
1445 ldap_state->schema_ver);
1446 append_attr(tmp_ctx, &attr_list,
1447 get_userattr_key2string(
1448 ldap_state->schema_ver,
1449 LDAP_ATTR_MOD_TIMESTAMP));
1450 append_attr(tmp_ctx, &attr_list, "uidNumber");
1451 rc = ldapsam_search_suffix_by_sid(ldap_state, sid,
1453 TALLOC_FREE(tmp_ctx);
1455 if ( rc != LDAP_SUCCESS )
1460 case SCHEMAVER_SAMBAACCOUNT:
1461 if (!sid_peek_check_rid(&ldap_state->domain_sid, sid, &rid)) {
1465 attr_list = get_userattr_list(NULL,
1466 ldap_state->schema_ver);
1467 rc = ldapsam_search_suffix_by_rid(ldap_state, rid, result, attr_list );
1468 TALLOC_FREE( attr_list );
1470 if ( rc != LDAP_SUCCESS )
1477 /**********************************************************************
1478 Get struct samu entry from LDAP by SID.
1479 *********************************************************************/
1481 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const DOM_SID *sid)
1483 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1484 LDAPMessage *result = NULL;
1485 LDAPMessage *entry = NULL;
1490 rc = ldapsam_get_ldap_user_by_sid(ldap_state,
1492 if (rc != LDAP_SUCCESS)
1493 return NT_STATUS_NO_SUCH_USER;
1495 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1498 DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] count=%d\n", sid_to_string(sid_string, sid),
1500 ldap_msgfree(result);
1501 return NT_STATUS_NO_SUCH_USER;
1502 } else if (count > 1) {
1503 DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID [%s]. Failing. count=%d\n", sid_to_string(sid_string, sid),
1505 ldap_msgfree(result);
1506 return NT_STATUS_NO_SUCH_USER;
1509 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1511 ldap_msgfree(result);
1512 return NT_STATUS_NO_SUCH_USER;
1515 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1516 DEBUG(1,("ldapsam_getsampwsid: init_sam_from_ldap failed!\n"));
1517 ldap_msgfree(result);
1518 return NT_STATUS_NO_SUCH_USER;
1521 pdb_set_backend_private_data(user, result, NULL,
1522 my_methods, PDB_CHANGED);
1523 talloc_autofree_ldapmsg(user, result);
1524 return NT_STATUS_OK;
1527 /********************************************************************
1528 Do the actual modification - also change a plaintext passord if
1530 **********************************************************************/
1532 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1533 struct samu *newpwd, char *dn,
1534 LDAPMod **mods, int ldap_op,
1535 bool (*need_update)(const struct samu *, enum pdb_elements))
1537 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1540 if (!newpwd || !dn) {
1541 return NT_STATUS_INVALID_PARAMETER;
1545 DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
1546 /* may be password change below however */
1550 if (ldap_state->is_nds_ldap) {
1551 smbldap_set_mod(&mods, LDAP_MOD_ADD,
1555 smbldap_set_mod(&mods, LDAP_MOD_ADD,
1559 rc = smbldap_add(ldap_state->smbldap_state,
1562 case LDAP_MOD_REPLACE:
1563 rc = smbldap_modify(ldap_state->smbldap_state,
1567 DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n",
1569 return NT_STATUS_INVALID_PARAMETER;
1572 if (rc!=LDAP_SUCCESS) {
1573 return NT_STATUS_UNSUCCESSFUL;
1577 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) &&
1578 (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) &&
1579 need_update(newpwd, PDB_PLAINTEXT_PW) &&
1580 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1583 char *retoid = NULL;
1584 struct berval *retdata = NULL;
1585 char *utf8_password;
1588 if (!ldap_state->is_nds_ldap) {
1590 if (!smbldap_has_extension(ldap_state->smbldap_state->ldap_struct,
1591 LDAP_EXOP_MODIFY_PASSWD)) {
1592 DEBUG(2, ("ldap password change requested, but LDAP "
1593 "server does not support it -- ignoring\n"));
1594 return NT_STATUS_OK;
1598 if (push_utf8_allocate(&utf8_password, pdb_get_plaintext_passwd(newpwd)) == (size_t)-1) {
1599 return NT_STATUS_NO_MEMORY;
1602 if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
1603 SAFE_FREE(utf8_password);
1604 return NT_STATUS_NO_MEMORY;
1607 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1608 DEBUG(0,("ber_alloc_t returns NULL\n"));
1609 SAFE_FREE(utf8_password);
1611 return NT_STATUS_UNSUCCESSFUL;
1614 ber_printf (ber, "{");
1615 ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn);
1616 ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password);
1617 ber_printf (ber, "n}");
1619 if ((rc = ber_flatten (ber, &bv))<0) {
1620 DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
1623 SAFE_FREE(utf8_password);
1624 return NT_STATUS_UNSUCCESSFUL;
1628 SAFE_FREE(utf8_password);
1631 if (!ldap_state->is_nds_ldap) {
1632 rc = smbldap_extended_operation(ldap_state->smbldap_state,
1633 LDAP_EXOP_MODIFY_PASSWD,
1634 bv, NULL, NULL, &retoid,
1637 rc = pdb_nds_set_password(ldap_state->smbldap_state, dn,
1638 pdb_get_plaintext_passwd(newpwd));
1640 if (rc != LDAP_SUCCESS) {
1641 char *ld_error = NULL;
1643 if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
1644 DEBUG(3, ("Could not set userPassword "
1645 "attribute due to an objectClass "
1646 "violation -- ignoring\n"));
1648 return NT_STATUS_OK;
1651 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1653 DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n",
1654 pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
1655 SAFE_FREE(ld_error);
1657 return NT_STATUS_UNSUCCESSFUL;
1659 DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1660 #ifdef DEBUG_PASSWORD
1661 DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd)));
1664 ber_bvfree(retdata);
1666 ldap_memfree(retoid);
1670 return NT_STATUS_OK;
1673 /**********************************************************************
1674 Delete entry from LDAP for username.
1675 *********************************************************************/
1677 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods,
1678 struct samu * sam_acct)
1680 struct ldapsam_privates *priv =
1681 (struct ldapsam_privates *)my_methods->private_data;
1684 LDAPMessage *msg, *entry;
1685 NTSTATUS result = NT_STATUS_NO_MEMORY;
1686 const char **attr_list;
1687 TALLOC_CTX *mem_ctx;
1690 DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n"));
1691 return NT_STATUS_INVALID_PARAMETER;
1694 sname = pdb_get_username(sam_acct);
1696 DEBUG(3, ("ldapsam_delete_sam_account: Deleting user %s from "
1699 mem_ctx = talloc_new(NULL);
1700 if (mem_ctx == NULL) {
1701 DEBUG(0, ("talloc_new failed\n"));
1705 attr_list = get_userattr_delete_list(mem_ctx, priv->schema_ver );
1706 if (attr_list == NULL) {
1710 rc = ldapsam_search_suffix_by_name(priv, sname, &msg, attr_list);
1712 if ((rc != LDAP_SUCCESS) ||
1713 (ldap_count_entries(priv2ld(priv), msg) != 1) ||
1714 ((entry = ldap_first_entry(priv2ld(priv), msg)) == NULL)) {
1715 DEBUG(5, ("Could not find user %s\n", sname));
1716 result = NT_STATUS_NO_SUCH_USER;
1720 rc = ldapsam_delete_entry(
1721 priv, mem_ctx, entry,
1722 priv->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ?
1723 LDAP_OBJ_SAMBASAMACCOUNT : LDAP_OBJ_SAMBAACCOUNT,
1726 result = (rc == LDAP_SUCCESS) ?
1727 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
1730 TALLOC_FREE(mem_ctx);
1734 /**********************************************************************
1735 Helper function to determine for update_sam_account whether
1736 we need LDAP modification.
1737 *********************************************************************/
1739 static bool element_is_changed(const struct samu *sampass,
1740 enum pdb_elements element)
1742 return IS_SAM_CHANGED(sampass, element);
1745 /**********************************************************************
1747 *********************************************************************/
1749 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struct samu * newpwd)
1751 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1752 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1755 LDAPMessage *result = NULL;
1756 LDAPMessage *entry = NULL;
1757 LDAPMod **mods = NULL;
1758 const char **attr_list;
1760 result = (LDAPMessage *)pdb_get_backend_private_data(newpwd, my_methods);
1762 attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
1763 if (pdb_get_username(newpwd) == NULL) {
1764 return NT_STATUS_INVALID_PARAMETER;
1766 rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
1767 TALLOC_FREE( attr_list );
1768 if (rc != LDAP_SUCCESS) {
1769 return NT_STATUS_UNSUCCESSFUL;
1771 pdb_set_backend_private_data(newpwd, result, NULL,
1772 my_methods, PDB_CHANGED);
1773 talloc_autofree_ldapmsg(newpwd, result);
1776 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
1777 DEBUG(0, ("ldapsam_update_sam_account: No user to modify!\n"));
1778 return NT_STATUS_UNSUCCESSFUL;
1781 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1782 dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
1784 return NT_STATUS_UNSUCCESSFUL;
1787 DEBUG(4, ("ldapsam_update_sam_account: user %s to be modified has dn: %s\n", pdb_get_username(newpwd), dn));
1789 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
1790 element_is_changed)) {
1791 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1794 ldap_mods_free(mods,True);
1795 return NT_STATUS_UNSUCCESSFUL;
1799 DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
1800 pdb_get_username(newpwd)));
1802 return NT_STATUS_OK;
1805 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed);
1806 ldap_mods_free(mods,True);
1810 * We need to set the backend private data to NULL here. For example
1811 * setuserinfo level 25 does a pdb_update_sam_account twice on the
1812 * same one, and with the explicit delete / add logic for attribute
1813 * values the second time we would use the wrong "old" value which
1814 * does not exist in LDAP anymore. Thus the LDAP server would refuse
1816 * The existing LDAPMessage is still being auto-freed by the
1819 pdb_set_backend_private_data(newpwd, NULL, NULL, my_methods,
1822 if (!NT_STATUS_IS_OK(ret)) {
1826 DEBUG(2, ("ldapsam_update_sam_account: successfully modified uid = %s in the LDAP database\n",
1827 pdb_get_username(newpwd)));
1828 return NT_STATUS_OK;
1831 /***************************************************************************
1832 Renames a struct samu
1833 - The "rename user script" has full responsibility for changing everything
1834 ***************************************************************************/
1836 static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
1837 struct samu *old_acct,
1838 const char *newname)
1840 const char *oldname;
1842 pstring rename_script;
1843 fstring oldname_lower, newname_lower;
1846 DEBUG(0, ("ldapsam_rename_sam_account: old_acct was NULL!\n"));
1847 return NT_STATUS_INVALID_PARAMETER;
1850 DEBUG(0, ("ldapsam_rename_sam_account: newname was NULL!\n"));
1851 return NT_STATUS_INVALID_PARAMETER;
1854 oldname = pdb_get_username(old_acct);
1856 /* rename the posix user */
1857 pstrcpy(rename_script, lp_renameuser_script());
1859 if (!(*rename_script))
1860 return NT_STATUS_ACCESS_DENIED;
1862 DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n",
1865 /* We have to allow the account name to end with a '$'.
1866 Also, follow the semantics in _samr_create_user() and lower case the
1867 posix name but preserve the case in passdb */
1869 fstrcpy( oldname_lower, oldname );
1870 strlower_m( oldname_lower );
1871 fstrcpy( newname_lower, newname );
1872 strlower_m( newname_lower );
1873 string_sub2(rename_script, "%unew", newname_lower, sizeof(pstring),
1875 string_sub2(rename_script, "%uold", oldname_lower, sizeof(pstring),
1877 rc = smbrun(rename_script, NULL);
1879 DEBUG(rc ? 0 : 3,("Running the command `%s' gave %d\n",
1880 rename_script, rc));
1883 smb_nscd_flush_user_cache();
1887 return NT_STATUS_UNSUCCESSFUL;
1889 return NT_STATUS_OK;
1892 /**********************************************************************
1893 Helper function to determine for update_sam_account whether
1894 we need LDAP modification.
1895 *********************************************************************/
1897 static bool element_is_set_or_changed(const struct samu *sampass,
1898 enum pdb_elements element)
1900 return (IS_SAM_SET(sampass, element) ||
1901 IS_SAM_CHANGED(sampass, element));
1904 /**********************************************************************
1905 Add struct samu to LDAP.
1906 *********************************************************************/
1908 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct samu * newpwd)
1910 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1911 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1913 LDAPMessage *result = NULL;
1914 LDAPMessage *entry = NULL;
1916 LDAPMod **mods = NULL;
1917 int ldap_op = LDAP_MOD_REPLACE;
1919 const char **attr_list;
1921 const char *username = pdb_get_username(newpwd);
1922 const DOM_SID *sid = pdb_get_user_sid(newpwd);
1926 if (!username || !*username) {
1927 DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
1928 return NT_STATUS_INVALID_PARAMETER;
1931 /* free this list after the second search or in case we exit on failure */
1932 attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
1934 rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
1936 if (rc != LDAP_SUCCESS) {
1937 TALLOC_FREE( attr_list );
1938 return NT_STATUS_UNSUCCESSFUL;
1941 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
1942 DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n",
1944 ldap_msgfree(result);
1945 TALLOC_FREE( attr_list );
1946 return NT_STATUS_UNSUCCESSFUL;
1948 ldap_msgfree(result);
1951 if (element_is_set_or_changed(newpwd, PDB_USERSID)) {
1952 rc = ldapsam_get_ldap_user_by_sid(ldap_state,
1954 if (rc == LDAP_SUCCESS) {
1955 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
1956 DEBUG(0,("ldapsam_add_sam_account: SID '%s' already in the base, with samba attributes\n",
1957 sid_to_string(sid_string, sid)));
1958 TALLOC_FREE( attr_list );
1959 ldap_msgfree(result);
1960 return NT_STATUS_UNSUCCESSFUL;
1962 ldap_msgfree(result);
1966 /* does the entry already exist but without a samba attributes?
1967 we need to return the samba attributes here */
1969 escape_user = escape_ldap_string_alloc( username );
1970 pstrcpy( filter, "(uid=%u)" );
1971 all_string_sub( filter, "%u", escape_user, sizeof(filter) );
1972 SAFE_FREE( escape_user );
1974 rc = smbldap_search_suffix(ldap_state->smbldap_state,
1975 filter, attr_list, &result);
1976 if ( rc != LDAP_SUCCESS ) {
1977 TALLOC_FREE( attr_list );
1978 return NT_STATUS_UNSUCCESSFUL;
1981 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1983 if (num_result > 1) {
1984 DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
1985 TALLOC_FREE( attr_list );
1986 ldap_msgfree(result);
1987 return NT_STATUS_UNSUCCESSFUL;
1990 /* Check if we need to update an existing entry */
1991 if (num_result == 1) {
1994 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
1995 ldap_op = LDAP_MOD_REPLACE;
1996 entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
1997 tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
1999 TALLOC_FREE( attr_list );
2000 ldap_msgfree(result);
2001 return NT_STATUS_UNSUCCESSFUL;
2003 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
2006 } else if (ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT) {
2008 /* There might be a SID for this account already - say an idmap entry */
2010 pstr_sprintf(filter, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
2011 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
2012 sid_to_string(sid_string, sid),
2013 LDAP_OBJ_IDMAP_ENTRY,
2014 LDAP_OBJ_SID_ENTRY);
2016 /* free old result before doing a new search */
2017 if (result != NULL) {
2018 ldap_msgfree(result);
2021 rc = smbldap_search_suffix(ldap_state->smbldap_state,
2022 filter, attr_list, &result);
2024 if ( rc != LDAP_SUCCESS ) {
2025 TALLOC_FREE( attr_list );
2026 return NT_STATUS_UNSUCCESSFUL;
2029 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2031 if (num_result > 1) {
2032 DEBUG (0, ("ldapsam_add_sam_account: More than one user with specified Sid exists: bailing out!\n"));
2033 TALLOC_FREE( attr_list );
2034 ldap_msgfree(result);
2035 return NT_STATUS_UNSUCCESSFUL;
2038 /* Check if we need to update an existing entry */
2039 if (num_result == 1) {
2042 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
2043 ldap_op = LDAP_MOD_REPLACE;
2044 entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
2045 tmp = smbldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
2047 TALLOC_FREE( attr_list );
2048 ldap_msgfree(result);
2049 return NT_STATUS_UNSUCCESSFUL;
2051 slprintf (dn, sizeof (dn) - 1, "%s", tmp);
2056 TALLOC_FREE( attr_list );
2058 if (num_result == 0) {
2059 char *escape_username;
2060 /* Check if we need to add an entry */
2061 DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
2062 ldap_op = LDAP_MOD_ADD;
2064 escape_username = escape_rdn_val_string_alloc(username);
2065 if (!escape_username) {
2066 DEBUG(0, ("Out of memory!\n"));
2067 ldap_msgfree(result);
2068 return NT_STATUS_NO_MEMORY;
2071 if (username[strlen(username)-1] == '$') {
2072 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", escape_username, lp_ldap_machine_suffix ());
2074 slprintf (dn, sizeof (dn) - 1, "uid=%s,%s", escape_username, lp_ldap_user_suffix ());
2077 SAFE_FREE(escape_username);
2080 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
2081 element_is_set_or_changed)) {
2082 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
2083 ldap_msgfree(result);
2085 ldap_mods_free(mods,True);
2086 return NT_STATUS_UNSUCCESSFUL;
2089 ldap_msgfree(result);
2092 DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
2093 return NT_STATUS_UNSUCCESSFUL;
2095 switch ( ldap_state->schema_ver ) {
2096 case SCHEMAVER_SAMBAACCOUNT:
2097 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT);
2099 case SCHEMAVER_SAMBASAMACCOUNT:
2100 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
2103 DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
2107 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, element_is_set_or_changed);
2108 if (!NT_STATUS_IS_OK(ret)) {
2109 DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
2110 pdb_get_username(newpwd),dn));
2111 ldap_mods_free(mods, True);
2115 DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
2116 ldap_mods_free(mods, True);
2118 return NT_STATUS_OK;
2121 /**********************************************************************
2122 *********************************************************************/
2124 static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
2126 LDAPMessage ** result)
2128 int scope = LDAP_SCOPE_SUBTREE;
2130 const char **attr_list;
2132 attr_list = get_attr_list(NULL, groupmap_attr_list);
2133 rc = smbldap_search(ldap_state->smbldap_state,
2134 lp_ldap_group_suffix (), scope,
2135 filter, attr_list, 0, result);
2136 TALLOC_FREE(attr_list);
2141 /**********************************************************************
2142 *********************************************************************/
2144 static bool init_group_from_ldap(struct ldapsam_privates *ldap_state,
2145 GROUP_MAP *map, LDAPMessage *entry)
2149 if (ldap_state == NULL || map == NULL || entry == NULL ||
2150 ldap_state->smbldap_state->ldap_struct == NULL) {
2151 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
2155 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
2156 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER), temp)) {
2157 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2158 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER)));
2161 DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp));
2163 map->gid = (gid_t)atol(temp);
2165 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
2166 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID), temp)) {
2167 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2168 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID)));
2172 if (!string_to_sid(&map->sid, temp)) {
2173 DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp));
2177 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
2178 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), temp)) {
2179 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2180 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
2183 map->sid_name_use = (enum lsa_SidType)atol(temp);
2185 if ((map->sid_name_use < SID_NAME_USER) ||
2186 (map->sid_name_use > SID_NAME_UNKNOWN)) {
2187 DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map->sid_name_use));
2191 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
2192 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), temp)) {
2194 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
2195 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_CN), temp))
2197 DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
2198 for gidNumber(%lu)\n",(unsigned long)map->gid));
2202 fstrcpy(map->nt_name, temp);
2204 if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
2205 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), temp)) {
2208 fstrcpy(map->comment, temp);
2210 if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
2211 store_gid_sid_cache(&map->sid, map->gid);
2217 /**********************************************************************
2218 *********************************************************************/
2220 static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
2224 struct ldapsam_privates *ldap_state =
2225 (struct ldapsam_privates *)methods->private_data;
2226 LDAPMessage *result = NULL;
2227 LDAPMessage *entry = NULL;
2230 if (ldapsam_search_one_group(ldap_state, filter, &result)
2232 return NT_STATUS_NO_SUCH_GROUP;
2235 count = ldap_count_entries(priv2ld(ldap_state), result);
2238 DEBUG(4, ("ldapsam_getgroup: Did not find group\n"));
2239 ldap_msgfree(result);
2240 return NT_STATUS_NO_SUCH_GROUP;
2244 DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: "
2245 "count=%d\n", filter, count));
2246 ldap_msgfree(result);
2247 return NT_STATUS_NO_SUCH_GROUP;
2250 entry = ldap_first_entry(priv2ld(ldap_state), result);
2253 ldap_msgfree(result);
2254 return NT_STATUS_UNSUCCESSFUL;
2257 if (!init_group_from_ldap(ldap_state, map, entry)) {
2258 DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for "
2259 "group filter %s\n", filter));
2260 ldap_msgfree(result);
2261 return NT_STATUS_NO_SUCH_GROUP;
2264 ldap_msgfree(result);
2265 return NT_STATUS_OK;
2268 /**********************************************************************
2269 *********************************************************************/
2271 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
2276 pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
2278 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
2279 sid_string_static(&sid));
2281 return ldapsam_getgroup(methods, filter, map);
2284 /**********************************************************************
2285 *********************************************************************/
2287 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
2292 pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
2294 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
2295 (unsigned long)gid);
2297 return ldapsam_getgroup(methods, filter, map);
2300 /**********************************************************************
2301 *********************************************************************/
2303 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
2307 char *escape_name = escape_ldap_string_alloc(name);
2310 return NT_STATUS_NO_MEMORY;
2313 pstr_sprintf(filter, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
2315 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
2316 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN), escape_name);
2318 SAFE_FREE(escape_name);
2320 return ldapsam_getgroup(methods, filter, map);
2323 static bool ldapsam_extract_rid_from_entry(LDAP *ldap_struct,
2325 const DOM_SID *domain_sid,
2331 if (!smbldap_get_single_attribute(ldap_struct, entry, "sambaSID",
2332 str, sizeof(str)-1)) {
2333 DEBUG(10, ("Could not find sambaSID attribute\n"));
2337 if (!string_to_sid(&sid, str)) {
2338 DEBUG(10, ("Could not convert string %s to sid\n", str));
2342 if (sid_compare_domain(&sid, domain_sid) != 0) {
2343 DEBUG(10, ("SID %s is not in expected domain %s\n",
2344 str, sid_string_static(domain_sid)));
2348 if (!sid_peek_rid(&sid, rid)) {
2349 DEBUG(10, ("Could not peek into RID\n"));
2356 static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
2357 TALLOC_CTX *mem_ctx,
2358 const DOM_SID *group,
2359 uint32 **pp_member_rids,
2360 size_t *p_num_members)
2362 struct ldapsam_privates *ldap_state =
2363 (struct ldapsam_privates *)methods->private_data;
2364 struct smbldap_state *conn = ldap_state->smbldap_state;
2365 const char *id_attrs[] = { "memberUid", "gidNumber", NULL };
2366 const char *sid_attrs[] = { "sambaSID", NULL };
2367 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2368 LDAPMessage *result = NULL;
2371 char **values = NULL;
2376 *pp_member_rids = NULL;
2379 filter = talloc_asprintf(mem_ctx,
2380 "(&(objectClass=%s)"
2383 LDAP_OBJ_POSIXGROUP,
2385 sid_string_static(group));
2386 if (filter == NULL) {
2387 ret = NT_STATUS_NO_MEMORY;
2391 rc = smbldap_search(conn, lp_ldap_group_suffix(),
2392 LDAP_SCOPE_SUBTREE, filter, id_attrs, 0,
2395 if (rc != LDAP_SUCCESS)
2398 talloc_autofree_ldapmsg(mem_ctx, result);
2400 count = ldap_count_entries(conn->ldap_struct, result);
2403 DEBUG(1, ("Found more than one groupmap entry for %s\n",
2404 sid_string_static(group)));
2405 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2410 ret = NT_STATUS_NO_SUCH_GROUP;
2414 entry = ldap_first_entry(conn->ldap_struct, result);
2418 gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
2420 DEBUG (0, ("ldapsam_enum_group_members: Unable to find the group's gid!\n"));
2421 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2425 values = ldap_get_values(conn->ldap_struct, entry, "memberUid");
2429 filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|", LDAP_OBJ_SAMBASAMACCOUNT);
2430 if (filter == NULL) {
2431 ret = NT_STATUS_NO_MEMORY;
2435 for (memberuid = values; *memberuid != NULL; memberuid += 1) {
2436 char *escape_memberuid;
2438 escape_memberuid = escape_ldap_string_alloc(*memberuid);
2439 if (escape_memberuid == NULL) {
2440 ret = NT_STATUS_NO_MEMORY;
2444 filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid);
2445 if (filter == NULL) {
2446 SAFE_FREE(escape_memberuid);
2447 ret = NT_STATUS_NO_MEMORY;
2451 SAFE_FREE(escape_memberuid);
2454 filter = talloc_asprintf_append_buffer(filter, "))");
2455 if (filter == NULL) {
2456 ret = NT_STATUS_NO_MEMORY;
2460 rc = smbldap_search(conn, lp_ldap_user_suffix(),
2461 LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
2464 if (rc != LDAP_SUCCESS)
2467 count = ldap_count_entries(conn->ldap_struct, result);
2468 DEBUG(10,("ldapsam_enum_group_members: found %d accounts\n", count));
2470 talloc_autofree_ldapmsg(mem_ctx, result);
2472 for (entry = ldap_first_entry(conn->ldap_struct, result);
2474 entry = ldap_next_entry(conn->ldap_struct, entry))
2480 sidstr = smbldap_talloc_single_attribute(conn->ldap_struct,
2484 DEBUG(0, ("Severe DB error, sambaSamAccount can't miss "
2485 "the sambaSID attribute\n"));
2486 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2490 if (!string_to_sid(&sid, sidstr))
2493 if (!sid_check_is_in_our_domain(&sid)) {
2494 DEBUG(0, ("Inconsistent SAM -- group member uid not "
2495 "in our domain\n"));
2496 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2500 sid_peek_rid(&sid, &rid);
2502 if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
2504 ret = NT_STATUS_NO_MEMORY;
2510 filter = talloc_asprintf(mem_ctx,
2511 "(&(objectClass=%s)"
2513 LDAP_OBJ_SAMBASAMACCOUNT,
2516 rc = smbldap_search(conn, lp_ldap_user_suffix(),
2517 LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
2520 if (rc != LDAP_SUCCESS)
2523 talloc_autofree_ldapmsg(mem_ctx, result);
2525 for (entry = ldap_first_entry(conn->ldap_struct, result);
2527 entry = ldap_next_entry(conn->ldap_struct, entry))
2531 if (!ldapsam_extract_rid_from_entry(conn->ldap_struct,
2533 get_global_sam_sid(),
2535 DEBUG(0, ("Severe DB error, sambaSamAccount can't miss "
2536 "the sambaSID attribute\n"));
2537 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2541 if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
2543 ret = NT_STATUS_NO_MEMORY;
2553 ldap_value_free(values);
2558 static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
2559 TALLOC_CTX *mem_ctx,
2563 size_t *p_num_groups)
2565 struct ldapsam_privates *ldap_state =
2566 (struct ldapsam_privates *)methods->private_data;
2567 struct smbldap_state *conn = ldap_state->smbldap_state;
2569 const char *attrs[] = { "gidNumber", "sambaSID", NULL };
2572 LDAPMessage *result = NULL;
2574 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2575 size_t num_sids, num_gids;
2577 gid_t primary_gid = -1;
2582 if (pdb_get_username(user) == NULL) {
2583 return NT_STATUS_INVALID_PARAMETER;
2586 escape_name = escape_ldap_string_alloc(pdb_get_username(user));
2587 if (escape_name == NULL)
2588 return NT_STATUS_NO_MEMORY;
2590 /* retrieve the users primary gid */
2591 filter = talloc_asprintf(mem_ctx,
2592 "(&(objectClass=%s)(uid=%s))",
2593 LDAP_OBJ_SAMBASAMACCOUNT,
2595 if (filter == NULL) {
2596 ret = NT_STATUS_NO_MEMORY;
2600 rc = smbldap_search(conn, lp_ldap_user_suffix(),
2601 LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
2603 if (rc != LDAP_SUCCESS)
2606 talloc_autofree_ldapmsg(mem_ctx, result);
2608 count = ldap_count_entries(priv2ld(ldap_state), result);
2612 DEBUG(1, ("User account [%s] not found!\n", pdb_get_username(user)));
2613 ret = NT_STATUS_NO_SUCH_USER;
2616 entry = ldap_first_entry(priv2ld(ldap_state), result);
2618 gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
2620 DEBUG (1, ("Unable to find the member's gid!\n"));
2621 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2624 primary_gid = strtoul(gidstr, NULL, 10);
2627 DEBUG(1, ("found more than one account with the same user name ?!\n"));
2628 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2632 filter = talloc_asprintf(mem_ctx,
2633 "(&(objectClass=%s)(|(memberUid=%s)(gidNumber=%d)))",
2634 LDAP_OBJ_POSIXGROUP, escape_name, primary_gid);
2635 if (filter == NULL) {
2636 ret = NT_STATUS_NO_MEMORY;
2640 rc = smbldap_search(conn, lp_ldap_group_suffix(),
2641 LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
2643 if (rc != LDAP_SUCCESS)
2646 talloc_autofree_ldapmsg(mem_ctx, result);
2654 /* We need to add the primary group as the first gid/sid */
2656 if (!add_gid_to_array_unique(mem_ctx, primary_gid, pp_gids, &num_gids)) {
2657 ret = NT_STATUS_NO_MEMORY;
2661 /* This sid will be replaced later */
2663 if (!add_sid_to_array_unique(mem_ctx, &global_sid_NULL, pp_sids, &num_sids)) {
2664 ret = NT_STATUS_NO_MEMORY;
2668 for (entry = ldap_first_entry(conn->ldap_struct, result);
2670 entry = ldap_next_entry(conn->ldap_struct, entry))
2677 if (!smbldap_get_single_attribute(conn->ldap_struct,
2679 str, sizeof(str)-1))
2682 if (!string_to_sid(&sid, str))
2685 if (!smbldap_get_single_attribute(conn->ldap_struct,
2687 str, sizeof(str)-1))
2690 gid = strtoul(str, &end, 10);
2692 if (PTR_DIFF(end, str) != strlen(str))
2695 if (gid == primary_gid) {
2696 sid_copy(&(*pp_sids)[0], &sid);
2698 if (!add_gid_to_array_unique(mem_ctx, gid, pp_gids,
2700 ret = NT_STATUS_NO_MEMORY;
2703 if (!add_sid_to_array_unique(mem_ctx, &sid, pp_sids,
2705 ret = NT_STATUS_NO_MEMORY;
2711 if (sid_compare(&global_sid_NULL, &(*pp_sids)[0]) == 0) {
2712 DEBUG(3, ("primary group of [%s] not found\n",
2713 pdb_get_username(user)));
2717 *p_num_groups = num_sids;
2723 SAFE_FREE(escape_name);
2727 /**********************************************************************
2728 * Augment a posixGroup object with a sambaGroupMapping domgroup
2729 *********************************************************************/
2731 static NTSTATUS ldapsam_map_posixgroup(TALLOC_CTX *mem_ctx,
2732 struct ldapsam_privates *ldap_state,
2735 const char *filter, *dn;
2736 LDAPMessage *msg, *entry;
2740 filter = talloc_asprintf(mem_ctx,
2741 "(&(objectClass=posixGroup)(gidNumber=%u))",
2743 if (filter == NULL) {
2744 return NT_STATUS_NO_MEMORY;
2747 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
2748 get_attr_list(mem_ctx, groupmap_attr_list),
2750 talloc_autofree_ldapmsg(mem_ctx, msg);
2752 if ((rc != LDAP_SUCCESS) ||
2753 (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg) != 1) ||
2754 ((entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, msg)) == NULL)) {
2755 return NT_STATUS_NO_SUCH_GROUP;
2758 dn = smbldap_talloc_dn(mem_ctx, ldap_state->smbldap_state->ldap_struct, entry);
2760 return NT_STATUS_NO_MEMORY;
2764 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass",
2765 "sambaGroupMapping");
2766 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaSid",
2767 sid_string_static(&map->sid));
2768 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaGroupType",
2769 talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
2770 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "displayName",
2772 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "description",
2774 talloc_autofree_ldapmod(mem_ctx, mods);
2776 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
2777 if (rc != LDAP_SUCCESS) {
2778 return NT_STATUS_ACCESS_DENIED;
2781 return NT_STATUS_OK;
2784 static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
2787 struct ldapsam_privates *ldap_state =
2788 (struct ldapsam_privates *)methods->private_data;
2789 LDAPMessage *msg = NULL;
2790 LDAPMod **mods = NULL;
2791 const char *attrs[] = { NULL };
2795 TALLOC_CTX *mem_ctx;
2802 mem_ctx = talloc_new(NULL);
2803 if (mem_ctx == NULL) {
2804 DEBUG(0, ("talloc_new failed\n"));
2805 return NT_STATUS_NO_MEMORY;
2808 filter = talloc_asprintf(mem_ctx, "(sambaSid=%s)",
2809 sid_string_static(&map->sid));
2810 if (filter == NULL) {
2811 result = NT_STATUS_NO_MEMORY;
2815 rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
2816 LDAP_SCOPE_SUBTREE, filter, attrs, True, &msg);
2817 talloc_autofree_ldapmsg(mem_ctx, msg);
2819 if ((rc == LDAP_SUCCESS) &&
2820 (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg) > 0)) {
2822 DEBUG(3, ("SID %s already present in LDAP, refusing to add "
2823 "group mapping entry\n",
2824 sid_string_static(&map->sid)));
2825 result = NT_STATUS_GROUP_EXISTS;
2829 switch (map->sid_name_use) {
2831 case SID_NAME_DOM_GRP:
2832 /* To map a domain group we need to have a posix group
2834 result = ldapsam_map_posixgroup(mem_ctx, ldap_state, map);
2838 case SID_NAME_ALIAS:
2839 if (!sid_check_is_in_our_domain(&map->sid)
2840 && !sid_check_is_in_builtin(&map->sid) )
2842 DEBUG(3, ("Refusing to map sid %s as an alias, not in our domain\n",
2843 sid_string_static(&map->sid)));
2844 result = NT_STATUS_INVALID_PARAMETER;
2850 DEBUG(3, ("Got invalid use '%s' for mapping\n",
2851 sid_type_lookup(map->sid_name_use)));
2852 result = NT_STATUS_INVALID_PARAMETER;
2856 /* Domain groups have been mapped in a separate routine, we have to
2857 * create an alias now */
2859 if (map->gid == -1) {
2860 DEBUG(10, ("Refusing to map gid==-1\n"));
2861 result = NT_STATUS_INVALID_PARAMETER;
2865 if (pdb_gid_to_sid(map->gid, &sid)) {
2866 DEBUG(3, ("Gid %d is already mapped to SID %s, refusing to "
2867 "add\n", map->gid, sid_string_static(&sid)));
2868 result = NT_STATUS_GROUP_EXISTS;
2872 /* Ok, enough checks done. It's still racy to go ahead now, but that's
2873 * the best we can get out of LDAP. */
2875 dn = talloc_asprintf(mem_ctx, "sambaSid=%s,%s",
2876 sid_string_static(&map->sid),
2877 lp_ldap_group_suffix());
2879 result = NT_STATUS_NO_MEMORY;
2885 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "objectClass",
2887 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "objectClass",
2888 "sambaGroupMapping");
2890 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "sambaSid",
2891 sid_string_static(&map->sid));
2892 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "sambaGroupType",
2893 talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
2894 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "displayName",
2896 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "description",
2898 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "gidNumber",
2899 talloc_asprintf(mem_ctx, "%u", map->gid));
2900 talloc_autofree_ldapmod(mem_ctx, mods);
2902 rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
2904 result = (rc == LDAP_SUCCESS) ?
2905 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
2908 TALLOC_FREE(mem_ctx);
2912 /**********************************************************************
2913 * Update a group mapping entry. We're quite strict about what can be changed:
2914 * Only the description and displayname may be changed. It simply does not
2915 * make any sense to change the SID, gid or the type in a mapping.
2916 *********************************************************************/
2918 static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
2921 struct ldapsam_privates *ldap_state =
2922 (struct ldapsam_privates *)methods->private_data;
2924 const char *filter, *dn;
2925 LDAPMessage *msg = NULL;
2926 LDAPMessage *entry = NULL;
2927 LDAPMod **mods = NULL;
2928 TALLOC_CTX *mem_ctx;
2931 mem_ctx = talloc_new(NULL);
2932 if (mem_ctx == NULL) {
2933 DEBUG(0, ("talloc_new failed\n"));
2934 return NT_STATUS_NO_MEMORY;
2937 /* Make 100% sure that sid, gid and type are not changed by looking up
2938 * exactly the values we're given in LDAP. */
2940 filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)"
2941 "(sambaSid=%s)(gidNumber=%u)"
2942 "(sambaGroupType=%d))",
2944 sid_string_static(&map->sid), map->gid,
2946 if (filter == NULL) {
2947 result = NT_STATUS_NO_MEMORY;
2951 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
2952 get_attr_list(mem_ctx, groupmap_attr_list),
2954 talloc_autofree_ldapmsg(mem_ctx, msg);
2956 if ((rc != LDAP_SUCCESS) ||
2957 (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg) != 1) ||
2958 ((entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, msg)) == NULL)) {
2959 result = NT_STATUS_NO_SUCH_GROUP;
2963 dn = smbldap_talloc_dn(mem_ctx, ldap_state->smbldap_state->ldap_struct, entry);
2966 result = NT_STATUS_NO_MEMORY;
2971 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "displayName",
2973 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "description",
2975 talloc_autofree_ldapmod(mem_ctx, mods);
2978 DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: "
2979 "nothing to do\n"));
2980 result = NT_STATUS_OK;
2984 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
2986 if (rc != LDAP_SUCCESS) {
2987 result = NT_STATUS_ACCESS_DENIED;
2991 DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified "
2992 "group %lu in LDAP\n", (unsigned long)map->gid));
2994 result = NT_STATUS_OK;
2997 TALLOC_FREE(mem_ctx);
3001 /**********************************************************************
3002 *********************************************************************/
3004 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
3007 struct ldapsam_privates *priv =
3008 (struct ldapsam_privates *)methods->private_data;
3009 LDAPMessage *msg, *entry;
3012 TALLOC_CTX *mem_ctx;
3015 mem_ctx = talloc_new(NULL);
3016 if (mem_ctx == NULL) {
3017 DEBUG(0, ("talloc_new failed\n"));
3018 return NT_STATUS_NO_MEMORY;
3021 filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%s))",
3022 LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID,
3023 sid_string_static(&sid));
3024 if (filter == NULL) {
3025 result = NT_STATUS_NO_MEMORY;
3028 rc = smbldap_search_suffix(priv->smbldap_state, filter,
3029 get_attr_list(mem_ctx, groupmap_attr_list),
3031 talloc_autofree_ldapmsg(mem_ctx, msg);
3033 if ((rc != LDAP_SUCCESS) ||
3034 (ldap_count_entries(priv2ld(priv), msg) != 1) ||
3035 ((entry = ldap_first_entry(priv2ld(priv), msg)) == NULL)) {
3036 result = NT_STATUS_NO_SUCH_GROUP;
3040 rc = ldapsam_delete_entry(priv, mem_ctx, entry, LDAP_OBJ_GROUPMAP,
3041 get_attr_list(mem_ctx,
3042 groupmap_attr_list_to_delete));
3044 if ((rc == LDAP_NAMING_VIOLATION) ||
3045 (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
3046 const char *attrs[] = { "sambaGroupType", "description",
3047 "displayName", "sambaSIDList",
3050 /* Second try. Don't delete the sambaSID attribute, this is
3051 for "old" entries that are tacked on a winbind
3054 rc = ldapsam_delete_entry(priv, mem_ctx, entry,
3055 LDAP_OBJ_GROUPMAP, attrs);
3058 if ((rc == LDAP_NAMING_VIOLATION) ||
3059 (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
3060 const char *attrs[] = { "sambaGroupType", "description",
3061 "displayName", "sambaSIDList",
3062 "gidNumber", NULL };
3064 /* Third try. This is a post-3.0.21 alias (containing only
3065 * sambaSidEntry and sambaGroupMapping classes), we also have
3066 * to delete the gidNumber attribute, only the sambaSidEntry
3069 rc = ldapsam_delete_entry(priv, mem_ctx, entry,
3070 LDAP_OBJ_GROUPMAP, attrs);
3073 result = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3076 TALLOC_FREE(mem_ctx);
3080 /**********************************************************************
3081 *********************************************************************/
3083 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
3086 struct ldapsam_privates *ldap_state =
3087 (struct ldapsam_privates *)my_methods->private_data;
3090 const char **attr_list;
3092 pstr_sprintf( filter, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
3093 attr_list = get_attr_list( NULL, groupmap_attr_list );
3094 rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
3095 LDAP_SCOPE_SUBTREE, filter,
3096 attr_list, 0, &ldap_state->result);
3097 TALLOC_FREE(attr_list);
3099 if (rc != LDAP_SUCCESS) {
3100 DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n",
3101 ldap_err2string(rc)));
3102 DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n",
3103 lp_ldap_group_suffix(), filter));
3104 ldap_msgfree(ldap_state->result);
3105 ldap_state->result = NULL;
3106 return NT_STATUS_UNSUCCESSFUL;
3109 DEBUG(2, ("ldapsam_setsamgrent: %d entries in the base!\n",
3110 ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
3111 ldap_state->result)));
3114 ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
3115 ldap_state->result);
3116 ldap_state->index = 0;
3118 return NT_STATUS_OK;
3121 /**********************************************************************
3122 *********************************************************************/
3124 static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
3126 ldapsam_endsampwent(my_methods);
3129 /**********************************************************************
3130 *********************************************************************/
3132 static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
3135 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
3136 struct ldapsam_privates *ldap_state =
3137 (struct ldapsam_privates *)my_methods->private_data;
3141 if (!ldap_state->entry)
3144 ldap_state->index++;
3145 bret = init_group_from_ldap(ldap_state, map,
3149 ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
3153 return NT_STATUS_OK;
3156 /**********************************************************************
3157 *********************************************************************/
3159 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
3160 const DOM_SID *domsid, enum lsa_SidType sid_name_use,
3161 GROUP_MAP **pp_rmap,
3162 size_t *p_num_entries,
3171 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
3172 DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open "
3174 return NT_STATUS_ACCESS_DENIED;
3177 while (NT_STATUS_IS_OK(ldapsam_getsamgrent(methods, &map))) {
3178 if (sid_name_use != SID_NAME_UNKNOWN &&
3179 sid_name_use != map.sid_name_use) {
3180 DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
3181 "not of the requested type\n", map.nt_name));
3184 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
3185 DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
3186 "non mapped\n", map.nt_name));
3190 (*pp_rmap)=SMB_REALLOC_ARRAY((*pp_rmap), GROUP_MAP, entries+1);
3192 DEBUG(0,("ldapsam_enum_group_mapping: Unable to "
3193 "enlarge group map!\n"));
3194 return NT_STATUS_UNSUCCESSFUL;
3197 (*pp_rmap)[entries] = map;
3202 ldapsam_endsamgrent(methods);
3204 *p_num_entries = entries;
3206 return NT_STATUS_OK;
3209 static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
3210 const DOM_SID *alias,
3211 const DOM_SID *member,
3214 struct ldapsam_privates *ldap_state =
3215 (struct ldapsam_privates *)methods->private_data;
3217 LDAPMessage *result = NULL;
3218 LDAPMessage *entry = NULL;
3220 LDAPMod **mods = NULL;
3222 enum lsa_SidType type = SID_NAME_USE_NONE;
3226 if (sid_check_is_in_builtin(alias)) {
3227 type = SID_NAME_ALIAS;
3230 if (sid_check_is_in_our_domain(alias)) {
3231 type = SID_NAME_ALIAS;
3234 if (type == SID_NAME_USE_NONE) {
3235 DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
3236 sid_string_static(alias)));
3237 return NT_STATUS_NO_SUCH_ALIAS;
3240 pstr_sprintf(filter,
3241 "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
3242 LDAP_OBJ_GROUPMAP, sid_string_static(alias),
3245 if (ldapsam_search_one_group(ldap_state, filter,
3246 &result) != LDAP_SUCCESS)
3247 return NT_STATUS_NO_SUCH_ALIAS;
3249 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
3253 DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
3254 ldap_msgfree(result);
3255 return NT_STATUS_NO_SUCH_ALIAS;
3259 DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for "
3260 "filter %s: count=%d\n", filter, count));
3261 ldap_msgfree(result);
3262 return NT_STATUS_NO_SUCH_ALIAS;
3265 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
3269 ldap_msgfree(result);
3270 return NT_STATUS_UNSUCCESSFUL;
3273 dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
3275 ldap_msgfree(result);
3276 return NT_STATUS_UNSUCCESSFUL;
3279 smbldap_set_mod(&mods, modop,
3280 get_attr_key2string(groupmap_attr_list,
3281 LDAP_ATTR_SID_LIST),
3282 sid_string_static(member));
3284 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3286 ldap_mods_free(mods, True);
3287 ldap_msgfree(result);
3290 if (rc == LDAP_TYPE_OR_VALUE_EXISTS) {
3291 return NT_STATUS_MEMBER_IN_ALIAS;
3294 if (rc == LDAP_NO_SUCH_ATTRIBUTE) {
3295 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
3298 if (rc != LDAP_SUCCESS) {
3299 return NT_STATUS_UNSUCCESSFUL;
3302 return NT_STATUS_OK;
3305 static NTSTATUS ldapsam_add_aliasmem(struct pdb_methods *methods,
3306 const DOM_SID *alias,
3307 const DOM_SID *member)
3309 return ldapsam_modify_aliasmem(methods, alias, member, LDAP_MOD_ADD);
3312 static NTSTATUS ldapsam_del_aliasmem(struct pdb_methods *methods,
3313 const DOM_SID *alias,
3314 const DOM_SID *member)
3316 return ldapsam_modify_aliasmem(methods, alias, member,
3320 static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
3321 const DOM_SID *alias,
3322 DOM_SID **pp_members,
3323 size_t *p_num_members)
3325 struct ldapsam_privates *ldap_state =
3326 (struct ldapsam_privates *)methods->private_data;
3327 LDAPMessage *result = NULL;
3328 LDAPMessage *entry = NULL;
3333 size_t num_members = 0;
3334 enum lsa_SidType type = SID_NAME_USE_NONE;
3339 if (sid_check_is_in_builtin(alias)) {
3340 type = SID_NAME_ALIAS;
3343 if (sid_check_is_in_our_domain(alias)) {
3344 type = SID_NAME_ALIAS;
3347 if (type == SID_NAME_USE_NONE) {
3348 DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
3349 sid_string_static(alias)));
3350 return NT_STATUS_NO_SUCH_ALIAS;
3353 pstr_sprintf(filter,
3354 "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
3355 LDAP_OBJ_GROUPMAP, sid_string_static(alias),
3358 if (ldapsam_search_one_group(ldap_state, filter,
3359 &result) != LDAP_SUCCESS)
3360 return NT_STATUS_NO_SUCH_ALIAS;
3362 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
3366 DEBUG(4, ("ldapsam_enum_aliasmem: Did not find alias\n"));
3367 ldap_msgfree(result);
3368 return NT_STATUS_NO_SUCH_ALIAS;
3372 DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for "
3373 "filter %s: count=%d\n", filter, count));
3374 ldap_msgfree(result);
3375 return NT_STATUS_NO_SUCH_ALIAS;
3378 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
3382 ldap_msgfree(result);
3383 return NT_STATUS_UNSUCCESSFUL;
3386 values = ldap_get_values(ldap_state->smbldap_state->ldap_struct,
3388 get_attr_key2string(groupmap_attr_list,
3389 LDAP_ATTR_SID_LIST));
3391 if (values == NULL) {
3392 ldap_msgfree(result);
3393 return NT_STATUS_OK;
3396 count = ldap_count_values(values);
3398 for (i=0; i<count; i++) {
3401 if (!string_to_sid(&member, values[i]))
3404 if (!add_sid_to_array(NULL, &member, pp_members, &num_members)) {
3405 ldap_value_free(values);
3406 ldap_msgfree(result);
3407 return NT_STATUS_NO_MEMORY;
3411 *p_num_members = num_members;
3412 ldap_value_free(values);
3413 ldap_msgfree(result);
3415 return NT_STATUS_OK;
3418 static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
3419 TALLOC_CTX *mem_ctx,
3420 const DOM_SID *domain_sid,
3421 const DOM_SID *members,
3423 uint32 **pp_alias_rids,
3424 size_t *p_num_alias_rids)
3426 struct ldapsam_privates *ldap_state =
3427 (struct ldapsam_privates *)methods->private_data;
3430 const char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL };
3432 LDAPMessage *result = NULL;
3433 LDAPMessage *entry = NULL;
3437 enum lsa_SidType type = SID_NAME_USE_NONE;
3439 if (sid_check_is_builtin(domain_sid)) {
3440 type = SID_NAME_ALIAS;
3443 if (sid_check_is_domain(domain_sid)) {
3444 type = SID_NAME_ALIAS;
3447 if (type == SID_NAME_USE_NONE) {
3448 DEBUG(5, ("SID %s is neither builtin nor domain!\n",
3449 sid_string_static(domain_sid)));
3450 return NT_STATUS_UNSUCCESSFUL;
3453 filter = talloc_asprintf(mem_ctx,
3454 "(&(|(objectclass=%s)(sambaGroupType=%d))(|",
3455 LDAP_OBJ_GROUPMAP, type);
3457 for (i=0; i<num_members; i++)
3458 filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)",
3460 sid_string_static(&members[i]));
3462 filter = talloc_asprintf(mem_ctx, "%s))", filter);
3464 if (filter == NULL) {
3465 return NT_STATUS_NO_MEMORY;
3468 rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
3469 LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
3471 if (rc != LDAP_SUCCESS)
3472 return NT_STATUS_UNSUCCESSFUL;
3474 ldap_struct = ldap_state->smbldap_state->ldap_struct;
3476 for (entry = ldap_first_entry(ldap_struct, result);
3478 entry = ldap_next_entry(ldap_struct, entry))
3484 if (!smbldap_get_single_attribute(ldap_struct, entry,
3490 if (!string_to_sid(&sid, sid_str))
3493 if (!sid_peek_check_rid(domain_sid, &sid, &rid))
3496 if (!add_rid_to_array_unique(mem_ctx, rid, pp_alias_rids,
3497 p_num_alias_rids)) {
3498 ldap_msgfree(result);
3499 return NT_STATUS_NO_MEMORY;
3503 ldap_msgfree(result);
3504 return NT_STATUS_OK;
3507 static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
3511 NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
3513 LDAPMod **mods = NULL;
3514 fstring value_string;
3515 const char *policy_attr = NULL;
3517 struct ldapsam_privates *ldap_state =
3518 (struct ldapsam_privates *)methods->private_data;
3520 DEBUG(10,("ldapsam_set_account_policy_in_ldap\n"));
3522 if (!ldap_state->domain_dn) {
3523 return NT_STATUS_INVALID_PARAMETER;
3526 policy_attr = get_account_policy_attr(policy_index);
3527 if (policy_attr == NULL) {
3528 DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid "
3533 slprintf(value_string, sizeof(value_string) - 1, "%i", value);
3535 smbldap_set_mod(&mods, LDAP_MOD_REPLACE, policy_attr, value_string);
3537 rc = smbldap_modify(ldap_state->smbldap_state, ldap_state->domain_dn,
3540 ldap_mods_free(mods, True);
3542 if (rc != LDAP_SUCCESS) {
3546 if (!cache_account_policy_set(policy_index, value)) {
3547 DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to "
3548 "update local tdb cache\n"));
3552 return NT_STATUS_OK;
3555 static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods,
3556 int policy_index, uint32 value)
3558 return ldapsam_set_account_policy_in_ldap(methods, policy_index,
3562 static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods,
3566 NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
3567 LDAPMessage *result = NULL;
3568 LDAPMessage *entry = NULL;
3572 const char *policy_attr = NULL;
3574 struct ldapsam_privates *ldap_state =
3575 (struct ldapsam_privates *)methods->private_data;
3577 const char *attrs[2];
3579 DEBUG(10,("ldapsam_get_account_policy_from_ldap\n"));
3581 if (!ldap_state->domain_dn) {
3582 return NT_STATUS_INVALID_PARAMETER;
3585 policy_attr = get_account_policy_attr(policy_index);
3587 DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid "
3588 "policy index: %d\n", policy_index));
3592 attrs[0] = policy_attr;
3595 rc = smbldap_search(ldap_state->smbldap_state, ldap_state->domain_dn,
3596 LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0,
3599 if (rc != LDAP_SUCCESS) {
3603 count = ldap_count_entries(priv2ld(ldap_state), result);
3608 entry = ldap_first_entry(priv2ld(ldap_state), result);
3609 if (entry == NULL) {
3613 vals = ldap_get_values(priv2ld(ldap_state), entry, policy_attr);
3618 *value = (uint32)atol(vals[0]);
3620 ntstatus = NT_STATUS_OK;
3624 ldap_value_free(vals);
3625 ldap_msgfree(result);
3630 /* wrapper around ldapsam_get_account_policy_from_ldap(), handles tdb as cache
3632 - if user hasn't decided to use account policies inside LDAP just reuse the
3635 - if there is a valid cache entry, return that
3636 - if there is an LDAP entry, update cache and return
3637 - otherwise set to default, update cache and return
3641 static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
3642 int policy_index, uint32 *value)
3644 NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
3646 if (cache_account_policy_get(policy_index, value)) {
3647 DEBUG(11,("ldapsam_get_account_policy: got valid value from "
3649 return NT_STATUS_OK;
3652 ntstatus = ldapsam_get_account_policy_from_ldap(methods, policy_index,
3654 if (NT_STATUS_IS_OK(ntstatus)) {
3658 DEBUG(10,("ldapsam_get_account_policy: failed to retrieve from "
3662 /* should we automagically migrate old tdb value here ? */
3663 if (account_policy_get(policy_index, value))
3666 DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying "
3667 "default\n", policy_index));
3670 if (!account_policy_get_default(policy_index, value)) {
3676 ntstatus = ldapsam_set_account_policy(methods, policy_index, *value);
3677 if (!NT_STATUS_IS_OK(ntstatus)) {
3683 if (!cache_account_policy_set(policy_index, *value)) {
3684 DEBUG(0,("ldapsam_get_account_policy: failed to update local "
3685 "tdb as a cache\n"));
3686 return NT_STATUS_UNSUCCESSFUL;
3689 return NT_STATUS_OK;
3692 static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
3693 const DOM_SID *domain_sid,
3697 enum lsa_SidType *attrs)
3699 struct ldapsam_privates *ldap_state =
3700 (struct ldapsam_privates *)methods->private_data;
3701 LDAPMessage *msg = NULL;
3703 char *allsids = NULL;
3704 int i, rc, num_mapped;
3705 NTSTATUS result = NT_STATUS_NO_MEMORY;
3706 TALLOC_CTX *mem_ctx;
3710 mem_ctx = talloc_new(NULL);
3711 if (mem_ctx == NULL) {
3712 DEBUG(0, ("talloc_new failed\n"));
3716 if (!sid_check_is_builtin(domain_sid) &&
3717 !sid_check_is_domain(domain_sid)) {
3718 result = NT_STATUS_INVALID_PARAMETER;
3722 for (i=0; i<num_rids; i++)
3723 attrs[i] = SID_NAME_UNKNOWN;
3725 allsids = talloc_strdup(mem_ctx, "");
3726 if (allsids == NULL) {
3730 for (i=0; i<num_rids; i++) {
3732 sid_compose(&sid, domain_sid, rids[i]);
3733 allsids = talloc_asprintf_append_buffer(allsids, "(sambaSid=%s)",
3734 sid_string_static(&sid));
3735 if (allsids == NULL) {
3740 /* First look for users */
3744 const char *ldap_attrs[] = { "uid", "sambaSid", NULL };
3746 filter = talloc_asprintf(
3747 mem_ctx, ("(&(objectClass=%s)(|%s))"),
3748 LDAP_OBJ_SAMBASAMACCOUNT, allsids);
3750 if (filter == NULL) {
3754 rc = smbldap_search(ldap_state->smbldap_state,
3755 lp_ldap_user_suffix(),
3756 LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
3758 talloc_autofree_ldapmsg(mem_ctx, msg);
3761 if (rc != LDAP_SUCCESS)
3764 ld = ldap_state->smbldap_state->ldap_struct;
3767 for (entry = ldap_first_entry(ld, msg);
3769 entry = ldap_next_entry(ld, entry)) {
3774 if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
3776 DEBUG(2, ("Could not find sid from ldap entry\n"));
3780 name = smbldap_talloc_single_attribute(ld, entry, "uid",
3783 DEBUG(2, ("Could not retrieve uid attribute\n"));
3787 for (rid_index = 0; rid_index < num_rids; rid_index++) {
3788 if (rid == rids[rid_index])
3792 if (rid_index == num_rids) {
3793 DEBUG(2, ("Got a RID not asked for: %d\n", rid));
3797 attrs[rid_index] = SID_NAME_USER;
3798 names[rid_index] = name;
3802 if (num_mapped == num_rids) {
3803 /* No need to look for groups anymore -- we're done */
3804 result = NT_STATUS_OK;
3808 /* Same game for groups */
3812 const char *ldap_attrs[] = { "cn", "displayName", "sambaSid",
3813 "sambaGroupType", NULL };
3815 filter = talloc_asprintf(
3816 mem_ctx, "(&(objectClass=%s)(|%s))",
3817 LDAP_OBJ_GROUPMAP, allsids);
3818 if (filter == NULL) {
3822 rc = smbldap_search(ldap_state->smbldap_state,
3823 lp_ldap_group_suffix(),
3824 LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
3826 talloc_autofree_ldapmsg(mem_ctx, msg);
3829 if (rc != LDAP_SUCCESS)
3832 /* ldap_struct might have changed due to a reconnect */
3834 ld = ldap_state->smbldap_state->ldap_struct;
3836 /* For consistency checks, we already checked we're only domain or builtin */
3838 is_builtin = sid_check_is_builtin(domain_sid);
3840 for (entry = ldap_first_entry(ld, msg);
3842 entry = ldap_next_entry(ld, entry))
3847 enum lsa_SidType type;
3848 const char *dn = smbldap_talloc_dn(mem_ctx, ld, entry);
3850 attr = smbldap_talloc_single_attribute(ld, entry, "sambaGroupType",
3853 DEBUG(2, ("Could not extract type from ldap entry %s\n",
3858 type = (enum lsa_SidType)atol(attr);
3860 /* Consistency checks */
3861 if ((is_builtin && (type != SID_NAME_ALIAS)) ||
3862 (!is_builtin && ((type != SID_NAME_ALIAS) &&
3863 (type != SID_NAME_DOM_GRP)))) {
3864 DEBUG(2, ("Rejecting invalid group mapping entry %s\n", dn));
3867 if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
3869 DEBUG(2, ("Could not find sid from ldap entry %s\n", dn));
3873 attr = smbldap_talloc_single_attribute(ld, entry, "displayName", names);
3876 DEBUG(10, ("Could not retrieve 'displayName' attribute from %s\n",
3878 attr = smbldap_talloc_single_attribute(ld, entry, "cn", names);
3882 DEBUG(2, ("Could not retrieve naming attribute from %s\n",
3887 for (rid_index = 0; rid_index < num_rids; rid_index++) {
3888 if (rid == rids[rid_index])
3892 if (rid_index == num_rids) {
3893 DEBUG(2, ("Got a RID not asked for: %d\n", rid));
3897 attrs[rid_index] = type;
3898 names[rid_index] = attr;
3902 result = NT_STATUS_NONE_MAPPED;
3905 result = (num_mapped == num_rids) ?
3906 NT_STATUS_OK : STATUS_SOME_UNMAPPED;
3908 TALLOC_FREE(mem_ctx);
3912 static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
3914 char *filter = NULL;
3915 char *escaped = NULL;
3916 char *result = NULL;
3918 asprintf(&filter, "(&%s(objectclass=sambaSamAccount))",
3920 if (filter == NULL) goto done;
3922 escaped = escape_ldap_string_alloc(username);
3923 if (escaped == NULL) goto done;
3925 result = talloc_string_sub(mem_ctx, filter, "%u", username);
3934 const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
3938 const char **result;
3940 va_start(ap, mem_ctx);
3941 while (va_arg(ap, const char *) != NULL)
3945 if ((result = TALLOC_ARRAY(mem_ctx, const char *, num+1)) == NULL) {
3949 va_start(ap, mem_ctx);
3950 for (i=0; i<num; i++) {
3951 result[i] = talloc_strdup(result, va_arg(ap, const char*));
3952 if (result[i] == NULL) {
3953 talloc_free(result);
3963 struct ldap_search_state {
3964 struct smbldap_state *connection;
3974 void *pagedresults_cookie;
3976 LDAPMessage *entries, *current_entry;
3977 bool (*ldap2displayentry)(struct ldap_search_state *state,
3978 TALLOC_CTX *mem_ctx,
3979 LDAP *ld, LDAPMessage *entry,
3980 struct samr_displayentry *result);
3983 static bool ldapsam_search_firstpage(struct pdb_search *search)
3985 struct ldap_search_state *state =
3986 (struct ldap_search_state *)search->private_data;
3988 int rc = LDAP_OPERATIONS_ERROR;
3990 state->entries = NULL;
3992 if (state->connection->paged_results) {
3993 rc = smbldap_search_paged(state->connection, state->base,
3994 state->scope, state->filter,
3995 state->attrs, state->attrsonly,
3996 lp_ldap_page_size(), &state->entries,
3997 &state->pagedresults_cookie);
4000 if ((rc != LDAP_SUCCESS) || (state->entries == NULL)) {
4002 if (state->entries != NULL) {
4003 /* Left over from unsuccessful paged attempt */
4004 ldap_msgfree(state->entries);
4005 state->entries = NULL;
4008 rc = smbldap_search(state->connection, state->base,
4009 state->scope, state->filter, state->attrs,
4010 state->attrsonly, &state->entries);
4012 if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
4015 /* Ok, the server was lying. It told us it could do paged
4016 * searches when it could not. */
4017 state->connection->paged_results = False;
4020 ld = state->connection->ldap_struct;
4022 DEBUG(5, ("Don't have an LDAP connection right after a "
4026 state->current_entry = ldap_first_entry(ld, state->entries);
4028 if (state->current_entry == NULL) {
4029 ldap_msgfree(state->entries);
4030 state->entries = NULL;
4036 static bool ldapsam_search_nextpage(struct pdb_search *search)
4038 struct ldap_search_state *state =
4039 (struct ldap_search_state *)search->private_data;
4042 if (!state->connection->paged_results) {
4043 /* There is no next page when there are no paged results */
4047 rc = smbldap_search_paged(state->connection, state->base,
4048 state->scope, state->filter, state->attrs,
4049 state->attrsonly, lp_ldap_page_size(),
4051 &state->pagedresults_cookie);
4053 if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
4056 state->current_entry = ldap_first_entry(state->connection->ldap_struct, state->entries);
4058 if (state->current_entry == NULL) {
4059 ldap_msgfree(state->entries);
4060 state->entries = NULL;
4066 static bool ldapsam_search_next_entry(struct pdb_search *search,
4067 struct samr_displayentry *entry)
4069 struct ldap_search_state *state =
4070 (struct ldap_search_state *)search->private_data;
4074 if ((state->entries == NULL) && (state->pagedresults_cookie == NULL))
4077 if ((state->entries == NULL) &&
4078 !ldapsam_search_nextpage(search))
4081 result = state->ldap2displayentry(state, search->mem_ctx, state->connection->ldap_struct,
4082 state->current_entry, entry);
4086 dn = ldap_get_dn(state->connection->ldap_struct, state->current_entry);
4087 DEBUG(5, ("Skipping entry %s\n", dn != NULL ? dn : "<NULL>"));
4088 if (dn != NULL) ldap_memfree(dn);
4091 state->current_entry = ldap_next_entry(state->connection->ldap_struct, state->current_entry);
4093 if (state->current_entry == NULL) {
4094 ldap_msgfree(state->entries);
4095 state->entries = NULL;
4098 if (!result) goto retry;
4103 static void ldapsam_search_end(struct pdb_search *search)
4105 struct ldap_search_state *state =
4106 (struct ldap_search_state *)search->private_data;
4109 if (state->pagedresults_cookie == NULL)
4112 if (state->entries != NULL)
4113 ldap_msgfree(state->entries);
4115 state->entries = NULL;
4116 state->current_entry = NULL;
4118 if (!state->connection->paged_results)
4121 /* Tell the LDAP server we're not interested in the rest anymore. */
4123 rc = smbldap_search_paged(state->connection, state->base, state->scope,
4124 state->filter, state->attrs,
4125 state->attrsonly, 0, &state->entries,
4126 &state->pagedresults_cookie);
4128 if (rc != LDAP_SUCCESS)
4129 DEBUG(5, ("Could not end search properly\n"));
4134 static bool ldapuser2displayentry(struct ldap_search_state *state,
4135 TALLOC_CTX *mem_ctx,
4136 LDAP *ld, LDAPMessage *entry,
4137 struct samr_displayentry *result)
4143 vals = ldap_get_values(ld, entry, "sambaAcctFlags");
4144 if ((vals == NULL) || (vals[0] == NULL)) {
4145 DEBUG(5, ("\"sambaAcctFlags\" not found\n"));
4148 acct_flags = pdb_decode_acct_ctrl(vals[0]);
4149 ldap_value_free(vals);
4151 if ((state->acct_flags != 0) &&
4152 ((state->acct_flags & acct_flags) == 0))
4155 result->acct_flags = acct_flags;
4156 result->account_name = "";
4157 result->fullname = "";
4158 result->description = "";
4160 vals = ldap_get_values(ld, entry, "uid");
4161 if ((vals == NULL) || (vals[0] == NULL)) {
4162 DEBUG(5, ("\"uid\" not found\n"));
4165 pull_utf8_talloc(mem_ctx,
4166 CONST_DISCARD(char **, &result->account_name),
4168 ldap_value_free(vals);
4170 vals = ldap_get_values(ld, entry, "displayName");
4171 if ((vals == NULL) || (vals[0] == NULL))
4172 DEBUG(8, ("\"displayName\" not found\n"));
4174 pull_utf8_talloc(mem_ctx,
4175 CONST_DISCARD(char **, &result->fullname),
4177 ldap_value_free(vals);
4179 vals = ldap_get_values(ld, entry, "description");
4180 if ((vals == NULL) || (vals[0] == NULL))
4181 DEBUG(8, ("\"description\" not found\n"));
4183 pull_utf8_talloc(mem_ctx,
4184 CONST_DISCARD(char **, &result->description),
4186 ldap_value_free(vals);
4188 if ((result->account_name == NULL) ||
4189 (result->fullname == NULL) ||
4190 (result->description == NULL)) {
4191 DEBUG(0, ("talloc failed\n"));
4195 vals = ldap_get_values(ld, entry, "sambaSid");
4196 if ((vals == NULL) || (vals[0] == NULL)) {
4197 DEBUG(0, ("\"objectSid\" not found\n"));
4201 if (!string_to_sid(&sid, vals[0])) {
4202 DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
4203 ldap_value_free(vals);
4206 ldap_value_free(vals);
4208 if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
4209 DEBUG(0, ("sid %s does not belong to our domain\n",
4210 sid_string_static(&sid)));
4218 static bool ldapsam_search_users(struct pdb_methods *methods,
4219 struct pdb_search *search,
4222 struct ldapsam_privates *ldap_state =
4223 (struct ldapsam_privates *)methods->private_data;
4224 struct ldap_search_state *state;
4226 state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
4227 if (state == NULL) {
4228 DEBUG(0, ("talloc failed\n"));
4232 state->connection = ldap_state->smbldap_state;
4234 if ((acct_flags != 0) && ((acct_flags & ACB_NORMAL) != 0))
4235 state->base = lp_ldap_user_suffix();
4236 else if ((acct_flags != 0) &&
4237 ((acct_flags & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) != 0))
4238 state->base = lp_ldap_machine_suffix();
4240 state->base = lp_ldap_suffix();
4242 state->acct_flags = acct_flags;
4243 state->base = talloc_strdup(search->mem_ctx, state->base);
4244 state->scope = LDAP_SCOPE_SUBTREE;
4245 state->filter = get_ldap_filter(search->mem_ctx, "*");
4246 state->attrs = talloc_attrs(search->mem_ctx, "uid", "sambaSid",
4247 "displayName", "description",
4248 "sambaAcctFlags", NULL);
4249 state->attrsonly = 0;
4250 state->pagedresults_cookie = NULL;
4251 state->entries = NULL;
4252 state->ldap2displayentry = ldapuser2displayentry;
4254 if ((state->filter == NULL) || (state->attrs == NULL)) {
4255 DEBUG(0, ("talloc failed\n"));
4259 search->private_data = state;
4260 search->next_entry = ldapsam_search_next_entry;
4261 search->search_end = ldapsam_search_end;
4263 return ldapsam_search_firstpage(search);
4266 static bool ldapgroup2displayentry(struct ldap_search_state *state,
4267 TALLOC_CTX *mem_ctx,
4268 LDAP *ld, LDAPMessage *entry,
4269 struct samr_displayentry *result)
4275 result->account_name = "";
4276 result->fullname = "";
4277 result->description = "";
4280 vals = ldap_get_values(ld, entry, "sambaGroupType");
4281 if ((vals == NULL) || (vals[0] == NULL)) {
4282 DEBUG(5, ("\"sambaGroupType\" not found\n"));
4284 ldap_value_free(vals);
4289 group_type = atoi(vals[0]);
4291 if ((state->group_type != 0) &&
4292 ((state->group_type != group_type))) {
4293 ldap_value_free(vals);
4297 ldap_value_free(vals);
4299 /* display name is the NT group name */
4301 vals = ldap_get_values(ld, entry, "displayName");
4302 if ((vals == NULL) || (vals[0] == NULL)) {
4303 DEBUG(8, ("\"displayName\" not found\n"));
4305 /* fallback to the 'cn' attribute */
4306 vals = ldap_get_values(ld, entry, "cn");
4307 if ((vals == NULL) || (vals[0] == NULL)) {
4308 DEBUG(5, ("\"cn\" not found\n"));
4311 pull_utf8_talloc(mem_ctx,
4312 CONST_DISCARD(char **, &result->account_name),
4316 pull_utf8_talloc(mem_ctx,
4317 CONST_DISCARD(char **, &result->account_name),
4321 ldap_value_free(vals);
4323 vals = ldap_get_values(ld, entry, "description");
4324 if ((vals == NULL) || (vals[0] == NULL))
4325 DEBUG(8, ("\"description\" not found\n"));
4327 pull_utf8_talloc(mem_ctx,
4328 CONST_DISCARD(char **, &result->description),
4330 ldap_value_free(vals);
4332 if ((result->account_name == NULL) ||
4333 (result->fullname == NULL) ||
4334 (result->description == NULL)) {
4335 DEBUG(0, ("talloc failed\n"));
4339 vals = ldap_get_values(ld, entry, "sambaSid");
4340 if ((vals == NULL) || (vals[0] == NULL)) {
4341 DEBUG(0, ("\"objectSid\" not found\n"));
4343 ldap_value_free(vals);
4348 if (!string_to_sid(&sid, vals[0])) {
4349 DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
4353 ldap_value_free(vals);
4355 switch (group_type) {
4356 case SID_NAME_DOM_GRP:
4357 case SID_NAME_ALIAS:
4359 if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)
4360 && !sid_peek_check_rid(&global_sid_Builtin, &sid, &result->rid))
4362 DEBUG(0, ("%s is not in our domain\n",
4363 sid_string_static(&sid)));
4369 DEBUG(0,("unkown group type: %d\n", group_type));
4376 static bool ldapsam_search_grouptype(struct pdb_methods *methods,
4377 struct pdb_search *search,
4379 enum lsa_SidType type)
4381 struct ldapsam_privates *ldap_state =
4382 (struct ldapsam_privates *)methods->private_data;
4383 struct ldap_search_state *state;
4385 state = TALLOC_P(search->mem_ctx, struct ldap_search_state);
4386 if (state == NULL) {
4387 DEBUG(0, ("talloc failed\n"));
4391 state->connection = ldap_state->smbldap_state;
4393 state->base = talloc_strdup(search->mem_ctx, lp_ldap_group_suffix());
4394 state->connection = ldap_state->smbldap_state;
4395 state->scope = LDAP_SCOPE_SUBTREE;
4396 state->filter = talloc_asprintf(search->mem_ctx,
4397 "(&(objectclass=sambaGroupMapping)"
4398 "(sambaGroupType=%d)(sambaSID=%s*))",
4399 type, sid_string_static(sid));
4400 state->attrs = talloc_attrs(search->mem_ctx, "cn", "sambaSid",
4401 "displayName", "description",
4402 "sambaGroupType", NULL);
4403 state->attrsonly = 0;
4404 state->pagedresults_cookie = NULL;
4405 state->entries = NULL;
4406 state->group_type = type;
4407 state->ldap2displayentry = ldapgroup2displayentry;
4409 if ((state->filter == NULL) || (state->attrs == NULL)) {
4410 DEBUG(0, ("talloc failed\n"));
4414 search->private_data = state;
4415 search->next_entry = ldapsam_search_next_entry;
4416 search->search_end = ldapsam_search_end;
4418 return ldapsam_search_firstpage(search);
4421 static bool ldapsam_search_groups(struct pdb_methods *methods,
4422 struct pdb_search *search)
4424 return ldapsam_search_grouptype(methods, search, get_global_sam_sid(), SID_NAME_DOM_GRP);
4427 static bool ldapsam_search_aliases(struct pdb_methods *methods,
4428 struct pdb_search *search,
4431 return ldapsam_search_grouptype(methods, search, sid, SID_NAME_ALIAS);
4434 static bool ldapsam_rid_algorithm(struct pdb_methods *methods)
4439 static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
4442 struct smbldap_state *smbldap_state = priv->smbldap_state;
4444 LDAPMessage *result = NULL;
4445 LDAPMessage *entry = NULL;
4446 LDAPMod **mods = NULL;
4453 TALLOC_CTX *mem_ctx;
4455 mem_ctx = talloc_new(NULL);
4456 if (mem_ctx == NULL) {
4457 DEBUG(0, ("talloc_new failed\n"));
4458 return NT_STATUS_NO_MEMORY;
4461 status = smbldap_search_domain_info(smbldap_state, &result,
4462 get_global_sam_name(), False);
4463 if (!NT_STATUS_IS_OK(status)) {
4464 DEBUG(3, ("Could not get domain info: %s\n",
4465 nt_errstr(status)));
4469 talloc_autofree_ldapmsg(mem_ctx, result);
4471 entry = ldap_first_entry(priv2ld(priv), result);
4472 if (entry == NULL) {
4473 DEBUG(0, ("Could not get domain info entry\n"));
4474 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
4478 /* Find the largest of the three attributes "sambaNextRid",
4479 "sambaNextGroupRid" and "sambaNextUserRid". I gave up on the
4480 concept of differentiating between user and group rids, and will
4481 use only "sambaNextRid" in the future. But for compatibility
4482 reasons I look if others have chosen different strategies -- VL */
4484 value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
4485 "sambaNextRid", mem_ctx);
4486 if (value != NULL) {
4487 uint32 tmp = (uint32)strtoul(value, NULL, 10);
4488 nextRid = MAX(nextRid, tmp);
4491 value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
4492 "sambaNextUserRid", mem_ctx);
4493 if (value != NULL) {
4494 uint32 tmp = (uint32)strtoul(value, NULL, 10);
4495 nextRid = MAX(nextRid, tmp);
4498 value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
4499 "sambaNextGroupRid", mem_ctx);
4500 if (value != NULL) {
4501 uint32 tmp = (uint32)strtoul(value, NULL, 10);
4502 nextRid = MAX(nextRid, tmp);
4506 nextRid = BASE_RID-1;
4511 smbldap_make_mod(priv2ld(priv), entry, &mods, "sambaNextRid",
4512 talloc_asprintf(mem_ctx, "%d", nextRid));
4513 talloc_autofree_ldapmod(mem_ctx, mods);
4515 if ((dn = smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)) == NULL) {
4516 status = NT_STATUS_NO_MEMORY;
4520 rc = smbldap_modify(smbldap_state, dn, mods);
4522 /* ACCESS_DENIED is used as a placeholder for "the modify failed,
4525 status = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
4528 if (NT_STATUS_IS_OK(status)) {
4532 TALLOC_FREE(mem_ctx);
4536 static NTSTATUS ldapsam_new_rid_internal(struct pdb_methods *methods, uint32 *rid)
4540 for (i=0; i<10; i++) {
4541 NTSTATUS result = ldapsam_get_new_rid(
4542 (struct ldapsam_privates *)methods->private_data, rid);
4543 if (NT_STATUS_IS_OK(result)) {
4547 if (!NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
4551 /* The ldap update failed (maybe a race condition), retry */
4554 /* Tried 10 times, fail. */
4555 return NT_STATUS_ACCESS_DENIED;
4558 static bool ldapsam_new_rid(struct pdb_methods *methods, uint32 *rid)
4560 NTSTATUS result = ldapsam_new_rid_internal(methods, rid);
4561 return NT_STATUS_IS_OK(result) ? True : False;
4564 static bool ldapsam_sid_to_id(struct pdb_methods *methods,
4566 union unid_t *id, enum lsa_SidType *type)
4568 struct ldapsam_privates *priv =
4569 (struct ldapsam_privates *)methods->private_data;
4571 const char *attrs[] = { "sambaGroupType", "gidNumber", "uidNumber",
4573 LDAPMessage *result = NULL;
4574 LDAPMessage *entry = NULL;
4579 TALLOC_CTX *mem_ctx;
4581 mem_ctx = talloc_new(NULL);
4582 if (mem_ctx == NULL) {
4583 DEBUG(0, ("talloc_new failed\n"));
4587 filter = talloc_asprintf(mem_ctx,
4589 "(|(objectClass=%s)(objectClass=%s)))",
4590 sid_string_static(sid),
4591 LDAP_OBJ_GROUPMAP, LDAP_OBJ_SAMBASAMACCOUNT);
4592 if (filter == NULL) {
4593 DEBUG(5, ("talloc_asprintf failed\n"));
4597 rc = smbldap_search_suffix(priv->smbldap_state, filter,
4599 if (rc != LDAP_SUCCESS) {
4602 talloc_autofree_ldapmsg(mem_ctx, result);
4604 if (ldap_count_entries(priv2ld(priv), result) != 1) {
4605 DEBUG(10, ("Got %d entries, expected one\n",
4606 ldap_count_entries(priv2ld(priv), result)));
4610 entry = ldap_first_entry(priv2ld(priv), result);
4612 value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
4613 "sambaGroupType", mem_ctx);
4615 if (value != NULL) {
4616 const char *gid_str;
4619 gid_str = smbldap_talloc_single_attribute(
4620 priv2ld(priv), entry, "gidNumber", mem_ctx);
4621 if (gid_str == NULL) {
4622 DEBUG(1, ("%s has sambaGroupType but no gidNumber\n",
4623 smbldap_talloc_dn(mem_ctx, priv2ld(priv),
4628 id->gid = strtoul(gid_str, NULL, 10);
4629 *type = (enum lsa_SidType)strtoul(value, NULL, 10);
4634 /* It must be a user */
4636 value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
4637 "uidNumber", mem_ctx);
4638 if (value == NULL) {
4639 DEBUG(1, ("Could not find uidNumber in %s\n",
4640 smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)));
4644 id->uid = strtoul(value, NULL, 10);
4645 *type = SID_NAME_USER;
4649 TALLOC_FREE(mem_ctx);
4654 * The following functions is called only if
4655 * ldapsam:trusted and ldapsam:editposix are
4660 * ldapsam_create_user creates a new
4661 * posixAccount and sambaSamAccount object
4662 * in the ldap users subtree
4664 * The uid is allocated by winbindd.
4667 static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
4668 TALLOC_CTX *tmp_ctx, const char *name,
4669 uint32 acb_info, uint32 *rid)
4671 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
4672 LDAPMessage *entry = NULL;
4673 LDAPMessage *result = NULL;
4675 bool is_machine = False;
4676 bool add_posix = False;
4677 LDAPMod **mods = NULL;
4685 const char *dn = NULL;
4693 if (((acb_info & ACB_NORMAL) && name[strlen(name)-1] == '$') ||
4694 acb_info & ACB_WSTRUST ||
4695 acb_info & ACB_SVRTRUST ||
4696 acb_info & ACB_DOMTRUST) {
4700 username = escape_ldap_string_alloc(name);
4701 filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass=%s))",
4702 username, LDAP_OBJ_POSIXACCOUNT);
4703 SAFE_FREE(username);
4705 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
4706 if (rc != LDAP_SUCCESS) {
4707 DEBUG(0,("ldapsam_create_user: ldap search failed!\n"));
4708 return NT_STATUS_UNSUCCESSFUL;
4710 talloc_autofree_ldapmsg(tmp_ctx, result);
4712 num_result = ldap_count_entries(priv2ld(ldap_state), result);
4714 if (num_result > 1) {
4715 DEBUG (0, ("ldapsam_create_user: More than one user with name [%s] ?!\n", name));
4716 return NT_STATUS_INTERNAL_DB_CORRUPTION;
4719 if (num_result == 1) {
4721 /* check if it is just a posix account.
4722 * or if there is a sid attached to this entry
4725 entry = ldap_first_entry(priv2ld(ldap_state), result);
4727 return NT_STATUS_UNSUCCESSFUL;
4730 tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
4732 DEBUG (1, ("ldapsam_create_user: The user [%s] already exist!\n", name));
4733 return NT_STATUS_USER_EXISTS;
4736 /* it is just a posix account, retrieve the dn for later use */
4737 dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
4739 DEBUG(0,("ldapsam_create_user: Out of memory!\n"));
4740 return NT_STATUS_NO_MEMORY;
4744 if (num_result == 0) {
4748 /* Create the basic samu structure and generate the mods for the ldap commit */
4749 if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
4750 DEBUG(1, ("ldapsam_create_user: Could not allocate a new RID\n"));
4754 sid_compose(&user_sid, get_global_sam_sid(), *rid);
4756 user = samu_new(tmp_ctx);
4758 DEBUG(1,("ldapsam_create_user: Unable to allocate user struct\n"));
4759 return NT_STATUS_NO_MEMORY;
4762 if (!pdb_set_username(user, name, PDB_SET)) {
4763 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
4764 return NT_STATUS_UNSUCCESSFUL;
4766 if (!pdb_set_domain(user, get_global_sam_name(), PDB_SET)) {
4767 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
4768 return NT_STATUS_UNSUCCESSFUL;
4771 if (acb_info & ACB_NORMAL) {
4772 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_SET)) {
4773 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
4774 return NT_STATUS_UNSUCCESSFUL;
4777 if (!pdb_set_acct_ctrl(user, acb_info, PDB_SET)) {
4778 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
4779 return NT_STATUS_UNSUCCESSFUL;
4783 if (!pdb_set_acct_ctrl(user, ACB_NORMAL | ACB_DISABLED, PDB_SET)) {
4784 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
4785 return NT_STATUS_UNSUCCESSFUL;
4789 if (!pdb_set_user_sid(user, &user_sid, PDB_SET)) {
4790 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
4791 return NT_STATUS_UNSUCCESSFUL;
4794 if (!init_ldap_from_sam(ldap_state, NULL, &mods, user, element_is_set_or_changed)) {
4795 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
4796 return NT_STATUS_UNSUCCESSFUL;
4799 if (ldap_state->schema_ver != SCHEMAVER_SAMBASAMACCOUNT) {
4800 DEBUG(1,("ldapsam_create_user: Unsupported schema version\n"));
4802 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
4807 DEBUG(3,("ldapsam_create_user: Creating new posix user\n"));
4809 /* retrieve the Domain Users group gid */
4810 if (!sid_compose(&group_sid, get_global_sam_sid(), DOMAIN_GROUP_RID_USERS) ||
4811 !sid_to_gid(&group_sid, &gid)) {
4812 DEBUG (0, ("ldapsam_create_user: Unable to get the Domain Users gid: bailing out!\n"));
4813 return NT_STATUS_INVALID_PRIMARY_GROUP;
4816 /* lets allocate a new userid for this user */
4817 if (!winbind_allocate_uid(&uid)) {
4818 DEBUG (0, ("ldapsam_create_user: Unable to allocate a new user id: bailing out!\n"));
4819 return NT_STATUS_UNSUCCESSFUL;
4824 /* TODO: choose a more appropriate default for machines */
4825 homedir = talloc_sub_specified(tmp_ctx, lp_template_homedir(), "SMB_workstations_home", ldap_state->domain_name, uid, gid);
4826 shell = talloc_strdup(tmp_ctx, "/bin/false");
4828 homedir = talloc_sub_specified(tmp_ctx, lp_template_homedir(), name, ldap_state->domain_name, uid, gid);
4829 shell = talloc_sub_specified(tmp_ctx, lp_template_shell(), name, ldap_state->domain_name, uid, gid);
4831 uidstr = talloc_asprintf(tmp_ctx, "%d", uid);
4832 gidstr = talloc_asprintf(tmp_ctx, "%d", gid);
4834 escape_name = escape_rdn_val_string_alloc(name);
4836 DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
4837 return NT_STATUS_NO_MEMORY;
4841 dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_machine_suffix ());
4843 dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_user_suffix ());
4846 SAFE_FREE(escape_name);
4848 if (!homedir || !shell || !uidstr || !gidstr || !dn) {
4849 DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
4850 return NT_STATUS_NO_MEMORY;
4853 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
4854 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
4855 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
4856 smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
4857 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
4858 smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", homedir);
4859 smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", shell);
4862 talloc_autofree_ldapmod(tmp_ctx, mods);
4865 rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
4867 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
4870 if (rc != LDAP_SUCCESS) {
4871 DEBUG(0,("ldapsam_create_user: failed to create a new user [%s] (dn = %s)\n", name ,dn));
4872 return NT_STATUS_UNSUCCESSFUL;
4875 DEBUG(2,("ldapsam_create_user: added account [%s] in the LDAP database\n", name));
4877 flush_pwnam_cache();
4879 return NT_STATUS_OK;
4882 static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, struct samu *sam_acct)
4884 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
4885 LDAPMessage *result = NULL;
4886 LDAPMessage *entry = NULL;
4892 DEBUG(0,("ldapsam_delete_user: Attempt to delete user [%s]\n", pdb_get_username(sam_acct)));
4894 filter = talloc_asprintf(tmp_ctx,
4897 "(objectClass=%s))",
4898 pdb_get_username(sam_acct),
4899 LDAP_OBJ_POSIXACCOUNT,
4900 LDAP_OBJ_SAMBASAMACCOUNT);
4901 if (filter == NULL) {
4902 return NT_STATUS_NO_MEMORY;
4905 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
4906 if (rc != LDAP_SUCCESS) {
4907 DEBUG(0,("ldapsam_delete_user: user search failed!\n"));
4908 return NT_STATUS_UNSUCCESSFUL;
4910 talloc_autofree_ldapmsg(tmp_ctx, result);
4912 num_result = ldap_count_entries(priv2ld(ldap_state), result);
4914 if (num_result == 0) {
4915 DEBUG(0,("ldapsam_delete_user: user not found!\n"));
4916 return NT_STATUS_NO_SUCH_USER;
4919 if (num_result > 1) {
4920 DEBUG (0, ("ldapsam_delete_user: More than one user with name [%s] ?!\n", pdb_get_username(sam_acct)));
4921 return NT_STATUS_INTERNAL_DB_CORRUPTION;
4924 entry = ldap_first_entry(priv2ld(ldap_state), result);
4926 return NT_STATUS_UNSUCCESSFUL;
4929 /* it is just a posix account, retrieve the dn for later use */
4930 dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
4932 DEBUG(0,("ldapsam_delete_user: Out of memory!\n"));
4933 return NT_STATUS_NO_MEMORY;
4936 rc = smbldap_delete(ldap_state->smbldap_state, dn);
4937 if (rc != LDAP_SUCCESS) {
4938 return NT_STATUS_UNSUCCESSFUL;
4941 flush_pwnam_cache();
4943 return NT_STATUS_OK;
4947 * ldapsam_create_group creates a new
4948 * posixGroup and sambaGroupMapping object
4949 * in the ldap groups subtree
4951 * The gid is allocated by winbindd.
4954 static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
4955 TALLOC_CTX *tmp_ctx,
4959 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
4961 LDAPMessage *entry = NULL;
4962 LDAPMessage *result = NULL;
4964 bool is_new_entry = False;
4965 LDAPMod **mods = NULL;
4971 const char *dn = NULL;
4976 groupname = escape_ldap_string_alloc(name);
4977 filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))",
4978 groupname, LDAP_OBJ_POSIXGROUP);
4979 SAFE_FREE(groupname);
4981 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
4982 if (rc != LDAP_SUCCESS) {
4983 DEBUG(0,("ldapsam_create_group: ldap search failed!\n"));
4984 return NT_STATUS_UNSUCCESSFUL;
4986 talloc_autofree_ldapmsg(tmp_ctx, result);
4988 num_result = ldap_count_entries(priv2ld(ldap_state), result);
4990 if (num_result > 1) {
4991 DEBUG (0, ("ldapsam_create_group: There exists more than one group with name [%s]: bailing out!\n", name));
4992 return NT_STATUS_INTERNAL_DB_CORRUPTION;
4995 if (num_result == 1) {
4997 /* check if it is just a posix group.
4998 * or if there is a sid attached to this entry
5001 entry = ldap_first_entry(priv2ld(ldap_state), result);
5003 return NT_STATUS_UNSUCCESSFUL;
5006 tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
5008 DEBUG (1, ("ldapsam_create_group: The group [%s] already exist!\n", name));
5009 return NT_STATUS_GROUP_EXISTS;
5012 /* it is just a posix group, retrieve the gid and the dn for later use */
5013 tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
5015 DEBUG (1, ("ldapsam_create_group: Couldn't retrieve the gidNumber for [%s]?!?!\n", name));
5016 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5019 gid = strtoul(tmp, NULL, 10);
5021 dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5023 DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
5024 return NT_STATUS_NO_MEMORY;
5028 if (num_result == 0) {
5031 DEBUG(3,("ldapsam_create_user: Creating new posix group\n"));
5033 is_new_entry = True;
5035 /* lets allocate a new groupid for this group */
5036 if (!winbind_allocate_gid(&gid)) {
5037 DEBUG (0, ("ldapsam_create_group: Unable to allocate a new group id: bailing out!\n"));
5038 return NT_STATUS_UNSUCCESSFUL;
5041 gidstr = talloc_asprintf(tmp_ctx, "%d", gid);
5043 escape_name = escape_rdn_val_string_alloc(name);
5045 DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
5046 return NT_STATUS_NO_MEMORY;
5049 dn = talloc_asprintf(tmp_ctx, "cn=%s,%s", escape_name, lp_ldap_group_suffix());
5051 SAFE_FREE(escape_name);
5053 if (!gidstr || !dn) {
5054 DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
5055 return NT_STATUS_NO_MEMORY;
5058 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_POSIXGROUP);
5059 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
5060 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
5063 if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
5064 DEBUG(1, ("ldapsam_create_group: Could not allocate a new RID\n"));
5068 sid_compose(&group_sid, get_global_sam_sid(), *rid);
5070 groupsidstr = talloc_strdup(tmp_ctx, sid_string_static(&group_sid));
5071 grouptype = talloc_asprintf(tmp_ctx, "%d", SID_NAME_DOM_GRP);
5073 if (!groupsidstr || !grouptype) {
5074 DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
5075 return NT_STATUS_NO_MEMORY;
5078 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
5079 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", groupsidstr);
5080 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", grouptype);
5081 smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
5082 talloc_autofree_ldapmod(tmp_ctx, mods);
5085 rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5087 if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
5088 /* This call may fail with rfc2307bis schema */
5089 /* Retry adding a structural class */
5090 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "????");
5091 rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5095 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
5098 if (rc != LDAP_SUCCESS) {
5099 DEBUG(0,("ldapsam_create_group: failed to create a new group [%s] (dn = %s)\n", name ,dn));
5100 return NT_STATUS_UNSUCCESSFUL;
5103 DEBUG(2,("ldapsam_create_group: added group [%s] in the LDAP database\n", name));
5105 return NT_STATUS_OK;
5108 static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, uint32 rid)
5110 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5111 LDAPMessage *result = NULL;
5112 LDAPMessage *entry = NULL;
5120 /* get the group sid */
5121 sid_compose(&group_sid, get_global_sam_sid(), rid);
5123 filter = talloc_asprintf(tmp_ctx,
5126 "(objectClass=%s))",
5127 sid_string_static(&group_sid),
5128 LDAP_OBJ_POSIXGROUP,
5130 if (filter == NULL) {
5131 return NT_STATUS_NO_MEMORY;
5134 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5135 if (rc != LDAP_SUCCESS) {
5136 DEBUG(1,("ldapsam_delete_dom_group: group search failed!\n"));
5137 return NT_STATUS_UNSUCCESSFUL;
5139 talloc_autofree_ldapmsg(tmp_ctx, result);
5141 num_result = ldap_count_entries(priv2ld(ldap_state), result);
5143 if (num_result == 0) {
5144 DEBUG(1,("ldapsam_delete_dom_group: group not found!\n"));
5145 return NT_STATUS_NO_SUCH_GROUP;
5148 if (num_result > 1) {
5149 DEBUG (0, ("ldapsam_delete_dom_group: More than one group with the same SID ?!\n"));
5150 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5153 entry = ldap_first_entry(priv2ld(ldap_state), result);
5155 return NT_STATUS_UNSUCCESSFUL;
5158 /* here it is, retrieve the dn for later use */
5159 dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5161 DEBUG(0,("ldapsam_delete_dom_group: Out of memory!\n"));
5162 return NT_STATUS_NO_MEMORY;
5165 gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
5167 DEBUG (0, ("ldapsam_delete_dom_group: Unable to find the group's gid!\n"));
5168 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5171 /* check no user have this group marked as primary group */
5172 filter = talloc_asprintf(tmp_ctx,
5175 "(objectClass=%s))",
5177 LDAP_OBJ_POSIXACCOUNT,
5178 LDAP_OBJ_SAMBASAMACCOUNT);
5180 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5181 if (rc != LDAP_SUCCESS) {
5182 DEBUG(1,("ldapsam_delete_dom_group: accounts search failed!\n"));
5183 return NT_STATUS_UNSUCCESSFUL;
5185 talloc_autofree_ldapmsg(tmp_ctx, result);
5187 num_result = ldap_count_entries(priv2ld(ldap_state), result);
5189 if (num_result != 0) {
5190 DEBUG(3,("ldapsam_delete_dom_group: Can't delete group, it is a primary group for %d users\n", num_result));
5191 return NT_STATUS_MEMBERS_PRIMARY_GROUP;
5194 rc = smbldap_delete(ldap_state->smbldap_state, dn);
5195 if (rc != LDAP_SUCCESS) {
5196 return NT_STATUS_UNSUCCESSFUL;
5199 return NT_STATUS_OK;
5202 static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
5203 TALLOC_CTX *tmp_ctx,
5208 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5209 LDAPMessage *entry = NULL;
5210 LDAPMessage *result = NULL;
5212 LDAPMod **mods = NULL;
5215 const char *dn = NULL;
5222 DEBUG(1,("ldapsam_change_groupmem: add new member(rid=%d) to a domain group(rid=%d)", member_rid, group_rid));
5224 case LDAP_MOD_DELETE:
5225 DEBUG(1,("ldapsam_change_groupmem: delete member(rid=%d) from a domain group(rid=%d)", member_rid, group_rid));
5228 return NT_STATUS_UNSUCCESSFUL;
5231 /* get member sid */
5232 sid_compose(&member_sid, get_global_sam_sid(), member_rid);
5234 /* get the group sid */
5235 sid_compose(&group_sid, get_global_sam_sid(), group_rid);
5237 filter = talloc_asprintf(tmp_ctx,
5240 "(objectClass=%s))",
5241 sid_string_static(&member_sid),
5242 LDAP_OBJ_POSIXACCOUNT,
5243 LDAP_OBJ_SAMBASAMACCOUNT);
5244 if (filter == NULL) {
5245 return NT_STATUS_NO_MEMORY;
5248 /* get the member uid */
5249 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5250 if (rc != LDAP_SUCCESS) {
5251 DEBUG(1,("ldapsam_change_groupmem: member search failed!\n"));
5252 return NT_STATUS_UNSUCCESSFUL;
5254 talloc_autofree_ldapmsg(tmp_ctx, result);
5256 num_result = ldap_count_entries(priv2ld(ldap_state), result);
5258 if (num_result == 0) {
5259 DEBUG(1,("ldapsam_change_groupmem: member not found!\n"));
5260 return NT_STATUS_NO_SUCH_MEMBER;
5263 if (num_result > 1) {
5264 DEBUG (0, ("ldapsam_change_groupmem: More than one account with the same SID ?!\n"));
5265 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5268 entry = ldap_first_entry(priv2ld(ldap_state), result);
5270 return NT_STATUS_UNSUCCESSFUL;
5273 if (modop == LDAP_MOD_DELETE) {
5274 /* check if we are trying to remove the member from his primary group */
5276 gid_t user_gid, group_gid;
5278 gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
5280 DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's gid!\n"));
5281 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5284 user_gid = strtoul(gidstr, NULL, 10);
5286 if (!sid_to_gid(&group_sid, &group_gid)) {
5287 DEBUG (0, ("ldapsam_change_groupmem: Unable to get group gid from SID!\n"));
5288 return NT_STATUS_UNSUCCESSFUL;
5291 if (user_gid == group_gid) {
5292 DEBUG (3, ("ldapsam_change_groupmem: can't remove user from it's own primary group!\n"));
5293 return NT_STATUS_MEMBERS_PRIMARY_GROUP;
5297 /* here it is, retrieve the uid for later use */
5298 uidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "uid", tmp_ctx);
5300 DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's name!\n"));
5301 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5304 filter = talloc_asprintf(tmp_ctx,
5307 "(objectClass=%s))",
5308 sid_string_static(&group_sid),
5309 LDAP_OBJ_POSIXGROUP,
5313 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5314 if (rc != LDAP_SUCCESS) {
5315 DEBUG(1,("ldapsam_change_groupmem: group search failed!\n"));
5316 return NT_STATUS_UNSUCCESSFUL;
5318 talloc_autofree_ldapmsg(tmp_ctx, result);
5320 num_result = ldap_count_entries(priv2ld(ldap_state), result);
5322 if (num_result == 0) {
5323 DEBUG(1,("ldapsam_change_groupmem: group not found!\n"));
5324 return NT_STATUS_NO_SUCH_GROUP;
5327 if (num_result > 1) {
5328 DEBUG (0, ("ldapsam_change_groupmem: More than one group with the same SID ?!\n"));
5329 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5332 entry = ldap_first_entry(priv2ld(ldap_state), result);
5334 return NT_STATUS_UNSUCCESSFUL;
5337 /* here it is, retrieve the dn for later use */
5338 dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5340 DEBUG(0,("ldapsam_change_groupmem: Out of memory!\n"));
5341 return NT_STATUS_NO_MEMORY;
5344 smbldap_set_mod(&mods, modop, "memberUid", uidstr);
5346 talloc_autofree_ldapmod(tmp_ctx, mods);
5348 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
5349 if (rc != LDAP_SUCCESS) {
5350 if (rc == LDAP_TYPE_OR_VALUE_EXISTS && modop == LDAP_MOD_ADD) {
5351 DEBUG(1,("ldapsam_change_groupmem: member is already in group, add failed!\n"));
5352 return NT_STATUS_MEMBER_IN_GROUP;
5354 if (rc == LDAP_NO_SUCH_ATTRIBUTE && modop == LDAP_MOD_DELETE) {
5355 DEBUG(1,("ldapsam_change_groupmem: member is not in group, delete failed!\n"));
5356 return NT_STATUS_MEMBER_NOT_IN_GROUP;
5358 return NT_STATUS_UNSUCCESSFUL;
5361 return NT_STATUS_OK;
5364 static NTSTATUS ldapsam_add_groupmem(struct pdb_methods *my_methods,
5365 TALLOC_CTX *tmp_ctx,
5369 return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_ADD);
5371 static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods,
5372 TALLOC_CTX *tmp_ctx,
5376 return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_DELETE);
5379 static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
5380 TALLOC_CTX *mem_ctx,
5381 struct samu *sampass)
5383 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5384 LDAPMessage *entry = NULL;
5385 LDAPMessage *result = NULL;
5387 LDAPMod **mods = NULL;
5389 char *escape_username;
5391 const char *dn = NULL;
5395 DEBUG(0,("ldapsam_set_primary_group: Attempt to set primary group for user [%s]\n", pdb_get_username(sampass)));
5397 if (!sid_to_gid(pdb_get_group_sid(sampass), &gid)) {
5398 DEBUG(0,("ldapsam_set_primary_group: failed to retieve gid from user's group SID!\n"));
5399 return NT_STATUS_UNSUCCESSFUL;
5401 gidstr = talloc_asprintf(mem_ctx, "%d", gid);
5403 DEBUG(0,("ldapsam_set_primary_group: Out of Memory!\n"));
5404 return NT_STATUS_NO_MEMORY;
5407 escape_username = escape_ldap_string_alloc(pdb_get_username(sampass));
5408 if (escape_username== NULL) {
5409 return NT_STATUS_NO_MEMORY;
5412 filter = talloc_asprintf(mem_ctx,
5415 "(objectClass=%s))",
5417 LDAP_OBJ_POSIXACCOUNT,
5418 LDAP_OBJ_SAMBASAMACCOUNT);
5420 SAFE_FREE(escape_username);
5422 if (filter == NULL) {
5423 return NT_STATUS_NO_MEMORY;
5426 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5427 if (rc != LDAP_SUCCESS) {
5428 DEBUG(0,("ldapsam_set_primary_group: user search failed!\n"));
5429 return NT_STATUS_UNSUCCESSFUL;
5431 talloc_autofree_ldapmsg(mem_ctx, result);
5433 num_result = ldap_count_entries(priv2ld(ldap_state), result);
5435 if (num_result == 0) {
5436 DEBUG(0,("ldapsam_set_primary_group: user not found!\n"));
5437 return NT_STATUS_NO_SUCH_USER;
5440 if (num_result > 1) {
5441 DEBUG (0, ("ldapsam_set_primary_group: More than one user with name [%s] ?!\n", pdb_get_username(sampass)));
5442 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5445 entry = ldap_first_entry(priv2ld(ldap_state), result);
5447 return NT_STATUS_UNSUCCESSFUL;
5450 /* retrieve the dn for later use */
5451 dn = smbldap_talloc_dn(mem_ctx, priv2ld(ldap_state), entry);
5453 DEBUG(0,("ldapsam_set_primary_group: Out of memory!\n"));
5454 return NT_STATUS_NO_MEMORY;
5457 /* remove the old one, and add the new one, this way we do not risk races */
5458 smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "gidNumber", gidstr);
5461 return NT_STATUS_OK;
5464 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
5466 if (rc != LDAP_SUCCESS) {
5467 DEBUG(0,("ldapsam_set_primary_group: failed to modify [%s] primary group to [%s]\n",
5468 pdb_get_username(sampass), gidstr));
5469 return NT_STATUS_UNSUCCESSFUL;
5472 flush_pwnam_cache();
5474 return NT_STATUS_OK;
5478 /**********************************************************************
5479 trusted domains functions
5480 *********************************************************************/
5482 static char *trusteddom_dn(struct ldapsam_privates *ldap_state,
5485 return talloc_asprintf(talloc_tos(), "sambaDomainName=%s,%s", domain,
5486 ldap_state->domain_dn);
5489 static bool get_trusteddom_pw_int(struct ldapsam_privates *ldap_state,
5490 const char *domain, LDAPMessage **entry)
5494 int scope = LDAP_SCOPE_SUBTREE;
5495 const char **attrs = NULL; /* NULL: get all attrs */
5496 int attrsonly = 0; /* 0: return values too */
5497 LDAPMessage *result = NULL;
5501 filter = talloc_asprintf(talloc_tos(),
5502 "(&(objectClass=%s)(sambaDomainName=%s))",
5503 LDAP_OBJ_TRUSTDOM_PASSWORD, domain);
5505 trusted_dn = trusteddom_dn(ldap_state, domain);
5506 if (trusted_dn == NULL) {
5509 rc = smbldap_search(ldap_state->smbldap_state, trusted_dn, scope,
5510 filter, attrs, attrsonly, &result);
5512 if (rc == LDAP_NO_SUCH_OBJECT) {
5517 if (rc != LDAP_SUCCESS) {
5521 num_result = ldap_count_entries(priv2ld(ldap_state), result);
5523 if (num_result > 1) {
5524 DEBUG(1, ("ldapsam_get_trusteddom_pw: more than one "
5525 "sambaTrustedDomainPassword object for domain '%s'"
5530 if (num_result == 0) {
5531 DEBUG(1, ("ldapsam_get_trusteddom_pw: no "
5532 "sambaTrustedDomainPassword object for domain %s.\n",
5536 *entry = ldap_first_entry(priv2ld(ldap_state), result);
5542 static bool ldapsam_get_trusteddom_pw(struct pdb_methods *methods,
5546 time_t *pass_last_set_time)
5548 struct ldapsam_privates *ldap_state =
5549 (struct ldapsam_privates *)methods->private_data;
5550 LDAPMessage *entry = NULL;
5552 DEBUG(10, ("ldapsam_get_trusteddom_pw called for domain %s\n", domain));
5554 if (!get_trusteddom_pw_int(ldap_state, domain, &entry) ||
5563 pwd_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
5564 entry, "sambaClearTextPassword", talloc_tos());
5565 if (pwd_str == NULL) {
5568 /* trusteddom_pw routines do not use talloc yet... */
5569 *pwd = SMB_STRDUP(pwd_str);
5575 /* last change time */
5576 if (pass_last_set_time != NULL) {
5578 time_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
5579 entry, "sambaPwdLastSet", talloc_tos());
5580 if (time_str == NULL) {
5583 *pass_last_set_time = (time_t)atol(time_str);
5590 sid_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
5593 if (sid_str == NULL) {
5596 dom_sid = string_sid_talloc(talloc_tos(), sid_str);
5597 if (dom_sid == NULL) {
5600 sid_copy(sid, dom_sid);
5606 static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods,
5611 struct ldapsam_privates *ldap_state =
5612 (struct ldapsam_privates *)methods->private_data;
5613 LDAPMessage *entry = NULL;
5614 LDAPMod **mods = NULL;
5615 char *prev_pwd = NULL;
5616 char *trusted_dn = NULL;
5619 DEBUG(10, ("ldapsam_set_trusteddom_pw called for domain %s\n", domain));
5622 * get the current entry (if there is one) in order to put the
5623 * current password into the previous password attribute
5625 if (!get_trusteddom_pw_int(ldap_state, domain, &entry)) {
5630 smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass",
5631 "sambaTrustedDomainPassword");
5632 smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaDomainName",
5634 smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaSID",
5635 sid_string_tos(sid));
5636 smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaPwdLastSet",
5637 talloc_asprintf(talloc_tos(), "%li", time(NULL)));
5638 smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
5639 "sambaClearTextPassword", pwd);
5640 if (entry != NULL) {
5641 prev_pwd = smbldap_talloc_single_attribute(priv2ld(ldap_state),
5642 entry, "sambaClearTextPassword", talloc_tos());
5643 if (prev_pwd != NULL) {
5644 smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
5645 "sambaPreviousClearTextPassword",
5650 trusted_dn = trusteddom_dn(ldap_state, domain);
5651 if (trusted_dn == NULL) {
5654 if (entry == NULL) {
5655 rc = smbldap_add(ldap_state->smbldap_state, trusted_dn, mods);
5657 rc = smbldap_modify(ldap_state->smbldap_state, trusted_dn, mods);
5660 if (rc != LDAP_SUCCESS) {
5661 DEBUG(1, ("error writing trusted domain password!\n"));
5668 static bool ldapsam_del_trusteddom_pw(struct pdb_methods *methods,
5672 struct ldapsam_privates *ldap_state =
5673 (struct ldapsam_privates *)methods->private_data;
5674 LDAPMessage *entry = NULL;
5675 const char *trusted_dn;
5677 if (!get_trusteddom_pw_int(ldap_state, domain, &entry)) {
5681 if (entry == NULL) {
5682 DEBUG(5, ("ldapsam_del_trusteddom_pw: no such trusted domain: "
5687 trusted_dn = smbldap_talloc_dn(talloc_tos(), priv2ld(ldap_state),
5689 if (trusted_dn == NULL) {
5690 DEBUG(0,("ldapsam_del_trusteddom_pw: Out of memory!\n"));
5694 rc = smbldap_delete(ldap_state->smbldap_state, trusted_dn);
5695 if (rc != LDAP_SUCCESS) {
5702 static NTSTATUS ldapsam_enum_trusteddoms(struct pdb_methods *methods,
5703 TALLOC_CTX *mem_ctx,
5704 uint32 *num_domains,
5705 struct trustdom_info ***domains)
5708 struct ldapsam_privates *ldap_state =
5709 (struct ldapsam_privates *)methods->private_data;
5711 int scope = LDAP_SCOPE_SUBTREE;
5712 const char *attrs[] = { "sambaDomainName", "sambaSID", NULL };
5713 int attrsonly = 0; /* 0: return values too */
5714 LDAPMessage *result = NULL;
5715 LDAPMessage *entry = NULL;
5717 filter = talloc_asprintf(talloc_tos(), "(objectClass=%s)",
5718 LDAP_OBJ_TRUSTDOM_PASSWORD);
5720 rc = smbldap_search(ldap_state->smbldap_state,
5721 ldap_state->domain_dn,
5728 if (rc != LDAP_SUCCESS) {
5729 return NT_STATUS_UNSUCCESSFUL;
5733 if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *, 1))) {
5734 DEBUG(1, ("talloc failed\n"));
5735 return NT_STATUS_NO_MEMORY;
5738 for (entry = ldap_first_entry(priv2ld(ldap_state), result);
5740 entry = ldap_next_entry(priv2ld(ldap_state), entry))
5742 char *dom_name, *dom_sid_str;
5743 struct trustdom_info *dom_info;
5745 dom_info = TALLOC_P(*domains, struct trustdom_info);
5746 if (dom_info == NULL) {
5747 DEBUG(1, ("talloc failed\n"));
5748 return NT_STATUS_NO_MEMORY;
5751 dom_name = smbldap_talloc_single_attribute(priv2ld(ldap_state),
5755 if (dom_name == NULL) {
5756 DEBUG(1, ("talloc failed\n"));
5757 return NT_STATUS_NO_MEMORY;
5759 dom_info->name = dom_name;
5761 dom_sid_str = smbldap_talloc_single_attribute(
5762 priv2ld(ldap_state), entry, "sambaSID",
5764 if (dom_sid_str == NULL) {
5765 DEBUG(1, ("talloc failed\n"));
5766 return NT_STATUS_NO_MEMORY;
5768 if (!string_to_sid(&dom_info->sid, dom_sid_str)) {
5769 DEBUG(1, ("Error calling string_to_sid on SID %s\n",
5771 return NT_STATUS_UNSUCCESSFUL;
5774 ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
5775 domains, num_domains);
5777 if (*domains == NULL) {
5778 DEBUG(1, ("talloc failed\n"));
5779 return NT_STATUS_NO_MEMORY;
5783 DEBUG(5, ("ldapsam_enum_trusteddoms: got %d domains\n", *num_domains));
5784 return NT_STATUS_OK;
5788 /**********************************************************************
5790 *********************************************************************/
5792 static void free_private_data(void **vp)
5794 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
5796 smbldap_free_struct(&(*ldap_state)->smbldap_state);
5798 if ((*ldap_state)->result != NULL) {
5799 ldap_msgfree((*ldap_state)->result);
5800 (*ldap_state)->result = NULL;
5802 if ((*ldap_state)->domain_dn != NULL) {
5803 SAFE_FREE((*ldap_state)->domain_dn);
5808 /* No need to free any further, as it is talloc()ed */
5811 /*********************************************************************
5812 Intitalise the parts of the pdb_methods structure that are common to
5814 *********************************************************************/
5816 static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const char *location)
5819 struct ldapsam_privates *ldap_state;
5821 if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) {
5825 (*pdb_method)->name = "ldapsam";
5827 (*pdb_method)->setsampwent = ldapsam_setsampwent;
5828 (*pdb_method)->endsampwent = ldapsam_endsampwent;
5829 (*pdb_method)->getsampwent = ldapsam_getsampwent;
5830 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
5831 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
5832 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
5833 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
5834 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
5835 (*pdb_method)->rename_sam_account = ldapsam_rename_sam_account;
5837 (*pdb_method)->getgrsid = ldapsam_getgrsid;
5838 (*pdb_method)->getgrgid = ldapsam_getgrgid;
5839 (*pdb_method)->getgrnam = ldapsam_getgrnam;
5840 (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
5841 (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
5842 (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
5843 (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
5845 (*pdb_method)->get_account_policy = ldapsam_get_account_policy;
5846 (*pdb_method)->set_account_policy = ldapsam_set_account_policy;
5848 (*pdb_method)->get_seq_num = ldapsam_get_seq_num;
5850 (*pdb_method)->rid_algorithm = ldapsam_rid_algorithm;
5851 (*pdb_method)->new_rid = ldapsam_new_rid;
5853 (*pdb_method)->get_trusteddom_pw = ldapsam_get_trusteddom_pw;
5854 (*pdb_method)->set_trusteddom_pw = ldapsam_set_trusteddom_pw;
5855 (*pdb_method)->del_trusteddom_pw = ldapsam_del_trusteddom_pw;
5856 (*pdb_method)->enum_trusteddoms = ldapsam_enum_trusteddoms;
5858 /* TODO: Setup private data and free */
5860 if ( !(ldap_state = TALLOC_ZERO_P(*pdb_method, struct ldapsam_privates)) ) {
5861 DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
5862 return NT_STATUS_NO_MEMORY;
5865 nt_status = smbldap_init(*pdb_method, pdb_get_event_context(),
5866 location, &ldap_state->smbldap_state);
5868 if ( !NT_STATUS_IS_OK(nt_status) ) {
5872 if ( !(ldap_state->domain_name = talloc_strdup(*pdb_method, get_global_sam_name()) ) ) {
5873 return NT_STATUS_NO_MEMORY;
5876 (*pdb_method)->private_data = ldap_state;
5878 (*pdb_method)->free_private_data = free_private_data;
5880 return NT_STATUS_OK;
5883 /**********************************************************************
5884 Initialise the 'compat' mode for pdb_ldap
5885 *********************************************************************/
5887 NTSTATUS pdb_init_ldapsam_compat(struct pdb_methods **pdb_method, const char *location)
5890 struct ldapsam_privates *ldap_state;
5891 char *uri = talloc_strdup( NULL, location );
5893 trim_char( uri, '\"', '\"' );
5894 nt_status = pdb_init_ldapsam_common( pdb_method, uri );
5898 if ( !NT_STATUS_IS_OK(nt_status) ) {
5902 (*pdb_method)->name = "ldapsam_compat";
5904 ldap_state = (struct ldapsam_privates *)((*pdb_method)->private_data);
5905 ldap_state->schema_ver = SCHEMAVER_SAMBAACCOUNT;
5907 sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
5909 return NT_STATUS_OK;
5912 /**********************************************************************
5913 Initialise the normal mode for pdb_ldap
5914 *********************************************************************/
5916 NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
5919 struct ldapsam_privates *ldap_state;
5920 uint32 alg_rid_base;
5921 pstring alg_rid_base_string;
5922 LDAPMessage *result = NULL;
5923 LDAPMessage *entry = NULL;
5924 DOM_SID ldap_domain_sid;
5925 DOM_SID secrets_domain_sid;
5926 pstring domain_sid_string;
5928 char *uri = talloc_strdup( NULL, location );
5930 trim_char( uri, '\"', '\"' );
5931 nt_status = pdb_init_ldapsam_common(pdb_method, uri);
5935 if (!NT_STATUS_IS_OK(nt_status)) {
5939 (*pdb_method)->name = "ldapsam";
5941 (*pdb_method)->add_aliasmem = ldapsam_add_aliasmem;
5942 (*pdb_method)->del_aliasmem = ldapsam_del_aliasmem;
5943 (*pdb_method)->enum_aliasmem = ldapsam_enum_aliasmem;
5944 (*pdb_method)->enum_alias_memberships = ldapsam_alias_memberships;
5945 (*pdb_method)->search_users = ldapsam_search_users;
5946 (*pdb_method)->search_groups = ldapsam_search_groups;
5947 (*pdb_method)->search_aliases = ldapsam_search_aliases;
5949 if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
5950 (*pdb_method)->enum_group_members = ldapsam_enum_group_members;
5951 (*pdb_method)->enum_group_memberships =
5952 ldapsam_enum_group_memberships;
5953 (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
5954 (*pdb_method)->sid_to_id = ldapsam_sid_to_id;
5956 if (lp_parm_bool(-1, "ldapsam", "editposix", False)) {
5957 (*pdb_method)->create_user = ldapsam_create_user;
5958 (*pdb_method)->delete_user = ldapsam_delete_user;
5959 (*pdb_method)->create_dom_group = ldapsam_create_dom_group;
5960 (*pdb_method)->delete_dom_group = ldapsam_delete_dom_group;
5961 (*pdb_method)->add_groupmem = ldapsam_add_groupmem;
5962 (*pdb_method)->del_groupmem = ldapsam_del_groupmem;
5963 (*pdb_method)->set_unix_primary_group = ldapsam_set_primary_group;
5967 ldap_state = (struct ldapsam_privates *)((*pdb_method)->private_data);
5968 ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
5970 /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
5972 nt_status = smbldap_search_domain_info(ldap_state->smbldap_state,
5974 ldap_state->domain_name, True);
5976 if ( !NT_STATUS_IS_OK(nt_status) ) {
5977 DEBUG(2, ("pdb_init_ldapsam: WARNING: Could not get domain "
5978 "info, nor add one to the domain\n"));
5979 DEBUGADD(2, ("pdb_init_ldapsam: Continuing on regardless, "
5980 "will be unable to allocate new users/groups, "
5981 "and will risk BDCs having inconsistant SIDs\n"));
5982 sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
5983 return NT_STATUS_OK;
5986 /* Given that the above might fail, everything below this must be
5989 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
5992 DEBUG(0, ("pdb_init_ldapsam: Could not get domain info "
5994 ldap_msgfree(result);
5995 return NT_STATUS_UNSUCCESSFUL;
5998 dn = smbldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
6000 ldap_msgfree(result);
6001 return NT_STATUS_UNSUCCESSFUL;
6004 ldap_state->domain_dn = smb_xstrdup(dn);
6007 if (smbldap_get_single_pstring(
6008 ldap_state->smbldap_state->ldap_struct,
6010 get_userattr_key2string(ldap_state->schema_ver,
6011 LDAP_ATTR_USER_SID),
6012 domain_sid_string)) {
6014 if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) {
6015 DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be "
6016 "read as a valid SID\n", domain_sid_string));
6017 ldap_msgfree(result);
6018 return NT_STATUS_INVALID_PARAMETER;
6020 found_sid = secrets_fetch_domain_sid(ldap_state->domain_name,
6021 &secrets_domain_sid);
6022 if (!found_sid || !sid_equal(&secrets_domain_sid,
6023 &ldap_domain_sid)) {
6024 fstring new_sid_str, old_sid_str;
6025 DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain "
6026 "%s based on pdb_ldap results %s -> %s\n",
6027 ldap_state->domain_name,
6028 sid_to_string(old_sid_str,
6029 &secrets_domain_sid),
6030 sid_to_string(new_sid_str,
6031 &ldap_domain_sid)));
6033 /* reset secrets.tdb sid */
6034 secrets_store_domain_sid(ldap_state->domain_name,
6036 DEBUG(1, ("New global sam SID: %s\n",
6037 sid_to_string(new_sid_str,
6038 get_global_sam_sid())));
6040 sid_copy(&ldap_state->domain_sid, &ldap_domain_sid);
6043 if (smbldap_get_single_pstring(
6044 ldap_state->smbldap_state->ldap_struct,
6046 get_attr_key2string( dominfo_attr_list,
6047 LDAP_ATTR_ALGORITHMIC_RID_BASE ),
6048 alg_rid_base_string)) {
6049 alg_rid_base = (uint32)atol(alg_rid_base_string);
6050 if (alg_rid_base != algorithmic_rid_base()) {
6051 DEBUG(0, ("The value of 'algorithmic RID base' has "
6052 "changed since the LDAP\n"
6053 "database was initialised. Aborting. \n"));
6054 ldap_msgfree(result);
6055 return NT_STATUS_UNSUCCESSFUL;
6058 ldap_msgfree(result);
6060 return NT_STATUS_OK;
6063 NTSTATUS pdb_ldap_init(void)
6066 if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam", pdb_init_ldapsam)))
6069 if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_compat", pdb_init_ldapsam_compat)))
6072 /* Let pdb_nds register backends */
6075 return NT_STATUS_OK;