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
48 #include "../libcli/auth/libcli_auth.h"
50 #include "idmap_cache.h"
51 #include "../libcli/security/security.h"
52 #include "../lib/util/util_pw.h"
53 #include "lib/winbind_util.h"
54 #include "librpc/gen_ndr/idmap.h"
55 #include "lib/param/loadparm.h"
56 #include "lib/util_sid_passdb.h"
57 #include "lib/util/smb_strtox.h"
58 #include "lib/util/string_wrappers.h"
59 #include "source3/lib/substitute.h"
62 #define DBGC_CLASS DBGC_PASSDB
69 #include "passdb/pdb_ldap.h"
70 #include "passdb/pdb_nds.h"
71 #include "passdb/pdb_ldap_util.h"
72 #include "passdb/pdb_ldap_schema.h"
74 /**********************************************************************
75 Simple helper function to make stuff better readable
76 **********************************************************************/
78 LDAP
*priv2ld(struct ldapsam_privates
*priv
)
80 return smbldap_get_ldap(priv
->smbldap_state
);
83 /**********************************************************************
84 Get the attribute name given a user schema version.
85 **********************************************************************/
87 static const char* get_userattr_key2string( int schema_ver
, int key
)
89 switch ( schema_ver
) {
90 case SCHEMAVER_SAMBASAMACCOUNT
:
91 return get_attr_key2string( attrib_map_v30
, key
);
94 DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
100 /**********************************************************************
101 Return the list of attribute names given a user schema version.
102 **********************************************************************/
104 const char** get_userattr_list( TALLOC_CTX
*mem_ctx
, int schema_ver
)
106 switch ( schema_ver
) {
107 case SCHEMAVER_SAMBASAMACCOUNT
:
108 return get_attr_list( mem_ctx
, attrib_map_v30
);
110 DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
117 /**************************************************************************
118 Return the list of attribute names to delete given a user schema version.
119 **************************************************************************/
121 static const char** get_userattr_delete_list( TALLOC_CTX
*mem_ctx
,
124 switch ( schema_ver
) {
125 case SCHEMAVER_SAMBASAMACCOUNT
:
126 return get_attr_list( mem_ctx
,
127 attrib_map_to_delete_v30
);
129 DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n"));
137 /*******************************************************************
138 Generate the LDAP search filter for the objectclass based on the
139 version of the schema we are using.
140 ******************************************************************/
142 static const char* get_objclass_filter( int schema_ver
)
144 fstring objclass_filter
;
147 switch( schema_ver
) {
148 case SCHEMAVER_SAMBASAMACCOUNT
:
149 fstr_sprintf( objclass_filter
, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT
);
152 DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));
153 objclass_filter
[0] = '\0';
157 result
= talloc_strdup(talloc_tos(), objclass_filter
);
158 SMB_ASSERT(result
!= NULL
);
162 /*****************************************************************
163 Scan a sequence number off OpenLDAP's syncrepl contextCSN
164 ******************************************************************/
166 static NTSTATUS
ldapsam_get_seq_num(struct pdb_methods
*my_methods
, time_t *seq_num
)
168 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
169 NTSTATUS ntstatus
= NT_STATUS_UNSUCCESSFUL
;
170 LDAPMessage
*msg
= NULL
;
171 LDAPMessage
*entry
= NULL
;
173 char **values
= NULL
;
174 int rc
, num_result
, num_values
, rid
;
180 /* Unfortunately there is no proper way to detect syncrepl-support in
181 * smbldap_connect_system(). The syncrepl OIDs are submitted for publication
182 * but do not show up in the root-DSE yet. Neither we can query the
183 * subschema-context for the syncProviderSubentry or syncConsumerSubentry
184 * objectclass. Currently we require lp_ldap_suffix() to show up as
185 * namingContext. - Guenther
188 if (!lp_parm_bool(-1, "ldapsam", "syncrepl_seqnum", False
)) {
193 DEBUG(3,("ldapsam_get_seq_num: no sequence_number\n"));
197 if (!smbldap_has_naming_context(
198 smbldap_get_ldap(ldap_state
->smbldap_state
),
200 DEBUG(3,("ldapsam_get_seq_num: DIT not configured to hold %s "
201 "as top-level namingContext\n", lp_ldap_suffix()));
205 mem_ctx
= talloc_init("ldapsam_get_seq_num");
208 return NT_STATUS_NO_MEMORY
;
210 if ((attrs
= talloc_array(mem_ctx
, const char *, 2)) == NULL
) {
211 ntstatus
= NT_STATUS_NO_MEMORY
;
215 /* if we got a syncrepl-rid (up to three digits long) we speak with a consumer */
216 rid
= lp_parm_int(-1, "ldapsam", "syncrepl_rid", -1);
219 /* consumer syncreplCookie: */
220 /* csn=20050126161620Z#0000001#00#00000 */
221 attrs
[0] = talloc_strdup(mem_ctx
, "syncreplCookie");
223 suffix
= talloc_asprintf(mem_ctx
,
224 "cn=syncrepl%d,%s", rid
, lp_ldap_suffix());
226 ntstatus
= NT_STATUS_NO_MEMORY
;
231 /* provider contextCSN */
232 /* 20050126161620Z#000009#00#000000 */
233 attrs
[0] = talloc_strdup(mem_ctx
, "contextCSN");
235 suffix
= talloc_asprintf(mem_ctx
,
236 "cn=ldapsync,%s", lp_ldap_suffix());
239 ntstatus
= NT_STATUS_NO_MEMORY
;
244 rc
= smbldap_search(ldap_state
->smbldap_state
, suffix
,
245 LDAP_SCOPE_BASE
, "(objectclass=*)", attrs
, 0, &msg
);
247 if (rc
!= LDAP_SUCCESS
) {
251 num_result
= ldap_count_entries(
252 smbldap_get_ldap(ldap_state
->smbldap_state
), msg
);
253 if (num_result
!= 1) {
254 DEBUG(3,("ldapsam_get_seq_num: Expected one entry, got %d\n", num_result
));
258 entry
= ldap_first_entry(
259 smbldap_get_ldap(ldap_state
->smbldap_state
), msg
);
261 DEBUG(3,("ldapsam_get_seq_num: Could not retrieve entry\n"));
265 values
= ldap_get_values(
266 smbldap_get_ldap(ldap_state
->smbldap_state
), entry
, attrs
[0]);
267 if (values
== NULL
) {
268 DEBUG(3,("ldapsam_get_seq_num: no values\n"));
272 num_values
= ldap_count_values(values
);
273 if (num_values
== 0) {
274 DEBUG(3,("ldapsam_get_seq_num: not a single value\n"));
279 if (!next_token_talloc(mem_ctx
, &p
, &tok
, "#")) {
280 DEBUG(0,("ldapsam_get_seq_num: failed to parse sequence number\n"));
285 if (!strncmp(p
, "csn=", strlen("csn=")))
288 DEBUG(10,("ldapsam_get_seq_num: got %s: %s\n", attrs
[0], p
));
290 *seq_num
= generalized_to_unix_time(p
);
292 /* very basic sanity check */
294 DEBUG(3,("ldapsam_get_seq_num: invalid sequence number: %d\n",
299 ntstatus
= NT_STATUS_OK
;
303 ldap_value_free(values
);
307 talloc_destroy(mem_ctx
);
312 /*******************************************************************
313 Run the search by name.
314 ******************************************************************/
316 int ldapsam_search_suffix_by_name(struct ldapsam_privates
*ldap_state
,
318 LDAPMessage
** result
,
322 char *escape_user
= escape_ldap_string(talloc_tos(), user
);
326 return LDAP_NO_MEMORY
;
330 * in the filter expression, replace %u with the real name
331 * so in ldap filter, %u MUST exist :-)
333 filter
= talloc_asprintf(talloc_tos(), "(&%s%s)", "(uid=%u)",
334 get_objclass_filter(ldap_state
->schema_ver
));
336 TALLOC_FREE(escape_user
);
337 return LDAP_NO_MEMORY
;
340 * have to use this here because $ is filtered out
344 filter
= talloc_all_string_sub(talloc_tos(),
345 filter
, "%u", escape_user
);
346 TALLOC_FREE(escape_user
);
348 return LDAP_NO_MEMORY
;
351 ret
= smbldap_search_suffix(ldap_state
->smbldap_state
,
352 filter
, attr
, result
);
357 /*******************************************************************
358 Run the search by SID.
359 ******************************************************************/
361 static int ldapsam_search_suffix_by_sid (struct ldapsam_privates
*ldap_state
,
362 const struct dom_sid
*sid
, LDAPMessage
** result
,
367 struct dom_sid_buf sid_string
;
369 filter
= talloc_asprintf(talloc_tos(), "(&(%s=%s)%s)",
370 get_userattr_key2string(ldap_state
->schema_ver
,
372 dom_sid_str_buf(sid
, &sid_string
),
373 get_objclass_filter(ldap_state
->schema_ver
));
375 return LDAP_NO_MEMORY
;
378 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
,
379 filter
, attr
, result
);
385 /*******************************************************************
386 Delete complete object or objectclass and attrs from
387 object found in search_result depending on lp_ldap_delete_dn
388 ******************************************************************/
390 static int ldapsam_delete_entry(struct ldapsam_privates
*priv
,
393 const char *objectclass
,
396 LDAPMod
**mods
= NULL
;
399 BerElement
*ptr
= NULL
;
401 dn
= smbldap_talloc_dn(mem_ctx
, priv2ld(priv
), entry
);
403 return LDAP_NO_MEMORY
;
406 if (lp_ldap_delete_dn()) {
407 return smbldap_delete(priv
->smbldap_state
, dn
);
410 /* Ok, delete only the SAM attributes */
412 for (name
= ldap_first_attribute(priv2ld(priv
), entry
, &ptr
);
414 name
= ldap_next_attribute(priv2ld(priv
), entry
, ptr
)) {
417 /* We are only allowed to delete the attributes that
420 for (attrib
= attrs
; *attrib
!= NULL
; attrib
++) {
421 if (strequal(*attrib
, name
)) {
422 DEBUG(10, ("ldapsam_delete_entry: deleting "
423 "attribute %s\n", name
));
424 smbldap_set_mod(&mods
, LDAP_MOD_DELETE
, name
,
435 smbldap_set_mod(&mods
, LDAP_MOD_DELETE
, "objectClass", objectclass
);
436 smbldap_talloc_autofree_ldapmod(mem_ctx
, mods
);
438 return smbldap_modify(priv
->smbldap_state
, dn
, mods
);
441 static time_t ldapsam_get_entry_timestamp( struct ldapsam_privates
*ldap_state
, LDAPMessage
* entry
)
446 temp
= smbldap_talloc_single_attribute(
447 smbldap_get_ldap(ldap_state
->smbldap_state
), entry
,
448 get_userattr_key2string(ldap_state
->schema_ver
,
449 LDAP_ATTR_MOD_TIMESTAMP
),
455 if ( !strptime(temp
, "%Y%m%d%H%M%SZ", &tm
)) {
456 DEBUG(2,("ldapsam_get_entry_timestamp: strptime failed on: %s\n",
466 /**********************************************************************
467 Initialize struct samu from an LDAP query.
468 (Based on init_sam_from_buffer in pdb_tdb.c)
469 *********************************************************************/
471 static bool init_sam_from_ldap(struct ldapsam_privates
*ldap_state
,
472 struct samu
* sampass
,
479 pass_can_change_time
,
482 char *username
= NULL
,
488 *logon_script
= NULL
,
489 *profile_path
= NULL
,
491 *workstations
= NULL
,
494 uint8_t smblmpwd
[LM_HASH_LEN
],
495 smbntpwd
[NT_HASH_LEN
];
496 bool use_samba_attrs
= True
;
498 uint16_t bad_password_count
= 0,
501 uint8_t hours
[MAX_HOURS_LEN
];
503 struct login_cache cache_entry
;
505 bool expand_explicit
= lp_passdb_expand_explicit();
507 TALLOC_CTX
*ctx
= talloc_init("init_sam_from_ldap");
512 if (sampass
== NULL
|| ldap_state
== NULL
|| entry
== NULL
) {
513 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
517 if (priv2ld(ldap_state
) == NULL
) {
518 DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->"
519 "ldap_struct is NULL!\n"));
523 if (!(username
= smbldap_talloc_first_attribute(priv2ld(ldap_state
),
527 DEBUG(1, ("init_sam_from_ldap: No uid attribute found for "
532 DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username
));
534 nt_username
= talloc_strdup(ctx
, username
);
539 domain
= talloc_strdup(ctx
, ldap_state
->domain_name
);
544 pdb_set_username(sampass
, username
, PDB_SET
);
546 pdb_set_domain(sampass
, domain
, PDB_DEFAULT
);
547 pdb_set_nt_username(sampass
, nt_username
, PDB_SET
);
549 /* deal with different attributes between the schema first */
551 if ( ldap_state
->schema_ver
== SCHEMAVER_SAMBASAMACCOUNT
) {
552 if ((temp
= smbldap_talloc_single_attribute(
553 smbldap_get_ldap(ldap_state
->smbldap_state
),
555 get_userattr_key2string(ldap_state
->schema_ver
,
558 pdb_set_user_sid_from_string(sampass
, temp
, PDB_SET
);
561 if ((temp
= smbldap_talloc_single_attribute(
562 smbldap_get_ldap(ldap_state
->smbldap_state
),
564 get_userattr_key2string(ldap_state
->schema_ver
,
567 user_rid
= (uint32_t)atol(temp
);
568 pdb_set_user_sid_from_rid(sampass
, user_rid
, PDB_SET
);
572 if (IS_SAM_DEFAULT(sampass
, PDB_USERSID
)) {
573 DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n",
574 get_userattr_key2string(ldap_state
->schema_ver
,
576 get_userattr_key2string(ldap_state
->schema_ver
,
582 temp
= smbldap_talloc_single_attribute(
583 smbldap_get_ldap(ldap_state
->smbldap_state
),
585 get_userattr_key2string(ldap_state
->schema_ver
,
586 LDAP_ATTR_PWD_LAST_SET
),
589 pass_last_set_time
= (time_t) atol(temp
);
590 pdb_set_pass_last_set_time(sampass
,
591 pass_last_set_time
, PDB_SET
);
594 temp
= smbldap_talloc_single_attribute(
595 smbldap_get_ldap(ldap_state
->smbldap_state
),
597 get_userattr_key2string(ldap_state
->schema_ver
,
598 LDAP_ATTR_LOGON_TIME
),
601 logon_time
= (time_t) atol(temp
);
602 pdb_set_logon_time(sampass
, logon_time
, PDB_SET
);
605 temp
= smbldap_talloc_single_attribute(
606 smbldap_get_ldap(ldap_state
->smbldap_state
),
608 get_userattr_key2string(ldap_state
->schema_ver
,
609 LDAP_ATTR_LOGOFF_TIME
),
612 logoff_time
= (time_t) atol(temp
);
613 pdb_set_logoff_time(sampass
, logoff_time
, PDB_SET
);
616 temp
= smbldap_talloc_single_attribute(
617 smbldap_get_ldap(ldap_state
->smbldap_state
),
619 get_userattr_key2string(ldap_state
->schema_ver
,
620 LDAP_ATTR_KICKOFF_TIME
),
623 kickoff_time
= (time_t) atol(temp
);
624 pdb_set_kickoff_time(sampass
, kickoff_time
, PDB_SET
);
627 temp
= smbldap_talloc_single_attribute(
628 smbldap_get_ldap(ldap_state
->smbldap_state
),
630 get_userattr_key2string(ldap_state
->schema_ver
,
631 LDAP_ATTR_PWD_CAN_CHANGE
),
634 pass_can_change_time
= (time_t) atol(temp
);
635 pdb_set_pass_can_change_time(sampass
,
636 pass_can_change_time
, PDB_SET
);
639 /* recommend that 'gecos' and 'displayName' should refer to the same
640 * attribute OID. userFullName depreciated, only used by Samba
641 * primary rules of LDAP: don't make a new attribute when one is already defined
642 * that fits your needs; using cn then displayName rather than 'userFullName'
645 fullname
= smbldap_talloc_single_attribute(
646 smbldap_get_ldap(ldap_state
->smbldap_state
),
648 get_userattr_key2string(ldap_state
->schema_ver
,
649 LDAP_ATTR_DISPLAY_NAME
),
652 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
654 fullname
= smbldap_talloc_single_attribute(
655 smbldap_get_ldap(ldap_state
->smbldap_state
),
657 get_userattr_key2string(ldap_state
->schema_ver
,
661 pdb_set_fullname(sampass
, fullname
, PDB_SET
);
665 dir_drive
= smbldap_talloc_single_attribute(
666 smbldap_get_ldap(ldap_state
->smbldap_state
),
668 get_userattr_key2string(ldap_state
->schema_ver
,
669 LDAP_ATTR_HOME_DRIVE
),
672 pdb_set_dir_drive(sampass
, dir_drive
, PDB_SET
);
674 pdb_set_dir_drive( sampass
, lp_logon_drive(), PDB_DEFAULT
);
677 homedir
= smbldap_talloc_single_attribute(
678 smbldap_get_ldap(ldap_state
->smbldap_state
),
680 get_userattr_key2string(ldap_state
->schema_ver
,
681 LDAP_ATTR_HOME_PATH
),
684 if (expand_explicit
) {
685 homedir
= talloc_sub_basic(ctx
,
693 pdb_set_homedir(sampass
, homedir
, PDB_SET
);
695 pdb_set_homedir(sampass
,
696 talloc_sub_basic(ctx
, username
, domain
,
701 logon_script
= smbldap_talloc_single_attribute(
702 smbldap_get_ldap(ldap_state
->smbldap_state
),
704 get_userattr_key2string(ldap_state
->schema_ver
,
705 LDAP_ATTR_LOGON_SCRIPT
),
708 if (expand_explicit
) {
709 logon_script
= talloc_sub_basic(ctx
,
717 pdb_set_logon_script(sampass
, logon_script
, PDB_SET
);
719 pdb_set_logon_script(sampass
,
720 talloc_sub_basic(ctx
, username
, domain
,
725 profile_path
= smbldap_talloc_single_attribute(
726 smbldap_get_ldap(ldap_state
->smbldap_state
),
728 get_userattr_key2string(ldap_state
->schema_ver
,
729 LDAP_ATTR_PROFILE_PATH
),
732 if (expand_explicit
) {
733 profile_path
= talloc_sub_basic(ctx
,
741 pdb_set_profile_path(sampass
, profile_path
, PDB_SET
);
743 pdb_set_profile_path(sampass
,
744 talloc_sub_basic(ctx
, username
, domain
,
749 acct_desc
= smbldap_talloc_single_attribute(
750 smbldap_get_ldap(ldap_state
->smbldap_state
),
752 get_userattr_key2string(ldap_state
->schema_ver
,
756 pdb_set_acct_desc(sampass
, acct_desc
, PDB_SET
);
759 workstations
= smbldap_talloc_single_attribute(
760 smbldap_get_ldap(ldap_state
->smbldap_state
),
762 get_userattr_key2string(ldap_state
->schema_ver
,
766 pdb_set_workstations(sampass
, workstations
, PDB_SET
);
769 munged_dial
= smbldap_talloc_single_attribute(
770 smbldap_get_ldap(ldap_state
->smbldap_state
),
772 get_userattr_key2string(ldap_state
->schema_ver
,
773 LDAP_ATTR_MUNGED_DIAL
),
776 pdb_set_munged_dial(sampass
, munged_dial
, PDB_SET
);
779 /* FIXME: hours stuff should be cleaner */
783 memset(hours
, 0xff, hours_len
);
785 if (ldap_state
->is_nds_ldap
) {
788 char clear_text_pw
[512];
790 /* Make call to Novell eDirectory ldap extension to get clear text password.
791 NOTE: This will only work if we have an SSL connection to eDirectory. */
792 user_dn
= smbldap_talloc_dn(
793 ctx
, smbldap_get_ldap(ldap_state
->smbldap_state
),
795 if (user_dn
!= NULL
) {
796 DEBUG(3, ("init_sam_from_ldap: smbldap_talloc_dn(ctx, %s) returned '%s'\n", username
, user_dn
));
798 pwd_len
= sizeof(clear_text_pw
);
799 if (pdb_nds_get_password(ldap_state
->smbldap_state
, user_dn
, &pwd_len
, clear_text_pw
) == LDAP_SUCCESS
) {
800 nt_lm_owf_gen(clear_text_pw
, smbntpwd
, smblmpwd
);
801 if (!pdb_set_lanman_passwd(sampass
, smblmpwd
, PDB_SET
)) {
802 TALLOC_FREE(user_dn
);
805 ZERO_STRUCT(smblmpwd
);
806 if (!pdb_set_nt_passwd(sampass
, smbntpwd
, PDB_SET
)) {
807 TALLOC_FREE(user_dn
);
810 ZERO_STRUCT(smbntpwd
);
811 use_samba_attrs
= False
;
814 TALLOC_FREE(user_dn
);
817 DEBUG(0, ("init_sam_from_ldap: failed to get user_dn for '%s'\n", username
));
821 if (use_samba_attrs
) {
822 temp
= smbldap_talloc_single_attribute(
823 smbldap_get_ldap(ldap_state
->smbldap_state
),
825 get_userattr_key2string(ldap_state
->schema_ver
,
829 pdb_gethexpwd(temp
, smblmpwd
);
830 memset((char *)temp
, '\0', strlen(temp
)+1);
831 if (!pdb_set_lanman_passwd(sampass
, smblmpwd
, PDB_SET
)) {
834 ZERO_STRUCT(smblmpwd
);
837 temp
= smbldap_talloc_single_attribute(
838 smbldap_get_ldap(ldap_state
->smbldap_state
),
840 get_userattr_key2string(ldap_state
->schema_ver
,
844 pdb_gethexpwd(temp
, smbntpwd
);
845 memset((char *)temp
, '\0', strlen(temp
)+1);
846 if (!pdb_set_nt_passwd(sampass
, smbntpwd
, PDB_SET
)) {
849 ZERO_STRUCT(smbntpwd
);
855 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
857 uint8_t *pwhist
= NULL
;
859 char *history_string
= talloc_array(ctx
, char,
860 MAX_PW_HISTORY_LEN
*64);
862 if (!history_string
) {
866 pwHistLen
= MIN(pwHistLen
, MAX_PW_HISTORY_LEN
);
868 pwhist
= talloc_zero_array(ctx
, uint8_t,
869 pwHistLen
* PW_HISTORY_ENTRY_LEN
);
870 if (pwhist
== NULL
) {
871 DEBUG(0, ("init_sam_from_ldap: talloc failed!\n"));
875 if (smbldap_get_single_attribute(
876 smbldap_get_ldap(ldap_state
->smbldap_state
),
878 get_userattr_key2string(ldap_state
->schema_ver
,
879 LDAP_ATTR_PWD_HISTORY
),
881 MAX_PW_HISTORY_LEN
*64)) {
882 bool hex_failed
= false;
883 for (i
= 0; i
< pwHistLen
; i
++){
884 /* Get the 16 byte salt. */
885 if (!pdb_gethexpwd(&history_string
[i
*64],
886 &pwhist
[i
*PW_HISTORY_ENTRY_LEN
])) {
890 /* Get the 16 byte MD5 hash of salt+passwd. */
891 if (!pdb_gethexpwd(&history_string
[(i
*64)+32],
892 &pwhist
[(i
*PW_HISTORY_ENTRY_LEN
)+
893 PW_HISTORY_SALT_LEN
])) {
899 DEBUG(2,("init_sam_from_ldap: Failed to get password history for user %s\n",
901 memset(pwhist
, '\0', pwHistLen
* PW_HISTORY_ENTRY_LEN
);
904 if (!pdb_set_pw_history(sampass
, pwhist
, pwHistLen
, PDB_SET
)){
909 temp
= smbldap_talloc_single_attribute(
910 smbldap_get_ldap(ldap_state
->smbldap_state
),
912 get_userattr_key2string(ldap_state
->schema_ver
,
916 uint32_t acct_ctrl
= 0;
917 acct_ctrl
= pdb_decode_acct_ctrl(temp
);
919 if (acct_ctrl
== 0) {
920 acct_ctrl
|= ACB_NORMAL
;
923 pdb_set_acct_ctrl(sampass
, acct_ctrl
, PDB_SET
);
926 pdb_set_hours_len(sampass
, hours_len
, PDB_SET
);
927 pdb_set_logon_divs(sampass
, logon_divs
, PDB_SET
);
929 temp
= smbldap_talloc_single_attribute(
930 smbldap_get_ldap(ldap_state
->smbldap_state
),
932 get_userattr_key2string(ldap_state
->schema_ver
,
933 LDAP_ATTR_BAD_PASSWORD_COUNT
),
936 bad_password_count
= (uint32_t) atol(temp
);
937 pdb_set_bad_password_count(sampass
,
938 bad_password_count
, PDB_SET
);
941 temp
= smbldap_talloc_single_attribute(
942 smbldap_get_ldap(ldap_state
->smbldap_state
),
944 get_userattr_key2string(ldap_state
->schema_ver
,
945 LDAP_ATTR_BAD_PASSWORD_TIME
),
948 bad_password_time
= (time_t) atol(temp
);
949 pdb_set_bad_password_time(sampass
, bad_password_time
, PDB_SET
);
953 temp
= smbldap_talloc_single_attribute(
954 smbldap_get_ldap(ldap_state
->smbldap_state
),
956 get_userattr_key2string(ldap_state
->schema_ver
,
957 LDAP_ATTR_LOGON_COUNT
),
960 logon_count
= (uint32_t) atol(temp
);
961 pdb_set_logon_count(sampass
, logon_count
, PDB_SET
);
964 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
966 temp
= smbldap_talloc_single_attribute(
967 smbldap_get_ldap(ldap_state
->smbldap_state
),
969 get_userattr_key2string(ldap_state
->schema_ver
,
970 LDAP_ATTR_LOGON_HOURS
),
973 pdb_gethexhours(temp
, hours
);
974 memset((char *)temp
, '\0', strlen(temp
) +1);
975 pdb_set_hours(sampass
, hours
, hours_len
, PDB_SET
);
979 if (lp_parm_bool(-1, "ldapsam", "trusted", False
)) {
980 struct passwd unix_pw
;
981 bool have_uid
= false;
982 bool have_gid
= false;
983 struct dom_sid mapped_gsid
;
984 const struct dom_sid
*primary_gsid
;
988 ZERO_STRUCT(unix_pw
);
990 unix_pw
.pw_name
= username
;
991 unix_pw
.pw_passwd
= discard_const_p(char, "x");
993 temp
= smbldap_talloc_single_attribute(
999 /* We've got a uid, feed the cache */
1000 unix_pw
.pw_uid
= smb_strtoul(temp
,
1006 DBG_ERR("Failed to convert UID\n");
1011 temp
= smbldap_talloc_single_attribute(
1012 priv2ld(ldap_state
),
1017 /* We've got a uid, feed the cache */
1018 unix_pw
.pw_gid
= smb_strtoul(temp
,
1024 DBG_ERR("Failed to convert GID\n");
1029 unix_pw
.pw_gecos
= smbldap_talloc_single_attribute(
1030 priv2ld(ldap_state
),
1034 if (unix_pw
.pw_gecos
== NULL
) {
1035 unix_pw
.pw_gecos
= fullname
;
1037 unix_pw
.pw_dir
= smbldap_talloc_single_attribute(
1038 priv2ld(ldap_state
),
1042 if (unix_pw
.pw_dir
== NULL
) {
1043 unix_pw
.pw_dir
= discard_const_p(char, "");
1045 unix_pw
.pw_shell
= smbldap_talloc_single_attribute(
1046 priv2ld(ldap_state
),
1050 if (unix_pw
.pw_shell
== NULL
) {
1051 unix_pw
.pw_shell
= discard_const_p(char, "");
1054 if (have_uid
&& have_gid
) {
1055 sampass
->unix_pw
= tcopy_passwd(sampass
, &unix_pw
);
1057 sampass
->unix_pw
= Get_Pwnam_alloc(sampass
, unix_pw
.pw_name
);
1060 if (sampass
->unix_pw
== NULL
) {
1061 DEBUG(0,("init_sam_from_ldap: Failed to find Unix account for %s\n",
1062 pdb_get_username(sampass
)));
1066 id
.id
= sampass
->unix_pw
->pw_uid
;
1067 id
.type
= ID_TYPE_UID
;
1069 idmap_cache_set_sid2unixid(pdb_get_user_sid(sampass
), &id
);
1071 gid_to_sid(&mapped_gsid
, sampass
->unix_pw
->pw_gid
);
1072 primary_gsid
= pdb_get_group_sid(sampass
);
1073 if (primary_gsid
&& dom_sid_equal(primary_gsid
, &mapped_gsid
)) {
1074 id
.id
= sampass
->unix_pw
->pw_gid
;
1075 id
.type
= ID_TYPE_GID
;
1077 idmap_cache_set_sid2unixid(primary_gsid
, &id
);
1081 /* check the timestamp of the cache vs ldap entry */
1082 if (!(ldap_entry_time
= ldapsam_get_entry_timestamp(ldap_state
,
1088 /* see if we have newer updates */
1089 if (!login_cache_read(sampass
, &cache_entry
)) {
1090 DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n",
1091 (unsigned int)pdb_get_bad_password_count(sampass
),
1092 (unsigned int)pdb_get_bad_password_time(sampass
)));
1097 DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n",
1098 (unsigned int)ldap_entry_time
,
1099 (unsigned int)cache_entry
.entry_timestamp
,
1100 (unsigned int)cache_entry
.bad_password_time
));
1102 if (ldap_entry_time
> cache_entry
.entry_timestamp
) {
1103 /* cache is older than directory , so
1104 we need to delete the entry but allow the
1105 fields to be written out */
1106 login_cache_delentry(sampass
);
1109 pdb_set_acct_ctrl(sampass
,
1110 pdb_get_acct_ctrl(sampass
) |
1111 (cache_entry
.acct_ctrl
& ACB_AUTOLOCK
),
1113 pdb_set_bad_password_count(sampass
,
1114 cache_entry
.bad_password_count
,
1116 pdb_set_bad_password_time(sampass
,
1117 cache_entry
.bad_password_time
,
1129 /**********************************************************************
1130 Initialize the ldap db from a struct samu. Called on update.
1131 (Based on init_buffer_from_sam in pdb_tdb.c)
1132 *********************************************************************/
1134 static bool init_ldap_from_sam (struct ldapsam_privates
*ldap_state
,
1135 LDAPMessage
*existing
,
1136 LDAPMod
*** mods
, struct samu
* sampass
,
1137 bool (*need_update
)(const struct samu
*,
1142 if (mods
== NULL
|| sampass
== NULL
) {
1143 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
1150 * took out adding "objectclass: sambaAccount"
1151 * do this on a per-mod basis
1153 if (need_update(sampass
, PDB_USERNAME
)) {
1154 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
),
1156 "uid", pdb_get_username(sampass
));
1157 if (ldap_state
->is_nds_ldap
) {
1159 smbldap_get_ldap(ldap_state
->smbldap_state
),
1161 "cn", pdb_get_username(sampass
));
1163 smbldap_get_ldap(ldap_state
->smbldap_state
),
1165 "sn", pdb_get_username(sampass
));
1169 DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass
)));
1171 /* only update the RID if we actually need to */
1172 if (need_update(sampass
, PDB_USERSID
)) {
1173 struct dom_sid_buf sid_str
;
1174 const struct dom_sid
*user_sid
= pdb_get_user_sid(sampass
);
1176 switch ( ldap_state
->schema_ver
) {
1177 case SCHEMAVER_SAMBASAMACCOUNT
:
1180 ldap_state
->smbldap_state
),
1182 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_SID
),
1183 dom_sid_str_buf(user_sid
, &sid_str
));
1187 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
1192 /* we don't need to store the primary group RID - so leaving it
1193 'free' to hang off the unix primary group makes life easier */
1195 if (need_update(sampass
, PDB_GROUPSID
)) {
1196 struct dom_sid_buf sid_str
;
1197 const struct dom_sid
*group_sid
= pdb_get_group_sid(sampass
);
1199 switch ( ldap_state
->schema_ver
) {
1200 case SCHEMAVER_SAMBASAMACCOUNT
:
1203 ldap_state
->smbldap_state
),
1205 get_userattr_key2string(ldap_state
->schema_ver
,
1206 LDAP_ATTR_PRIMARY_GROUP_SID
),
1207 dom_sid_str_buf(group_sid
, &sid_str
));
1211 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
1217 /* displayName, cn, and gecos should all be the same
1218 * most easily accomplished by giving them the same OID
1219 * gecos isn't set here b/c it should be handled by the
1221 * We change displayName only and fall back to cn if
1222 * it does not exist.
1225 if (need_update(sampass
, PDB_FULLNAME
))
1226 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
),
1228 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DISPLAY_NAME
),
1229 pdb_get_fullname(sampass
));
1231 if (need_update(sampass
, PDB_ACCTDESC
))
1232 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
),
1234 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_DESC
),
1235 pdb_get_acct_desc(sampass
));
1237 if (need_update(sampass
, PDB_WORKSTATIONS
))
1238 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
),
1240 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_USER_WKS
),
1241 pdb_get_workstations(sampass
));
1243 if (need_update(sampass
, PDB_MUNGEDDIAL
))
1244 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
),
1246 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_MUNGED_DIAL
),
1247 pdb_get_munged_dial(sampass
));
1249 if (need_update(sampass
, PDB_SMBHOME
))
1250 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
),
1252 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_PATH
),
1253 pdb_get_homedir(sampass
));
1255 if (need_update(sampass
, PDB_DRIVE
))
1256 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
),
1258 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_HOME_DRIVE
),
1259 pdb_get_dir_drive(sampass
));
1261 if (need_update(sampass
, PDB_LOGONSCRIPT
))
1262 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
),
1264 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_SCRIPT
),
1265 pdb_get_logon_script(sampass
));
1267 if (need_update(sampass
, PDB_PROFILE
))
1268 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
),
1270 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PROFILE_PATH
),
1271 pdb_get_profile_path(sampass
));
1273 if (asprintf(&temp
, "%li", (long int)pdb_get_logon_time(sampass
)) < 0) {
1276 if (need_update(sampass
, PDB_LOGONTIME
))
1277 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
),
1279 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGON_TIME
), temp
);
1282 if (asprintf(&temp
, "%li", (long int)pdb_get_logoff_time(sampass
)) < 0) {
1285 if (need_update(sampass
, PDB_LOGOFFTIME
))
1286 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
),
1288 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LOGOFF_TIME
), temp
);
1291 if (asprintf(&temp
, "%li", (long int)pdb_get_kickoff_time(sampass
)) < 0) {
1294 if (need_update(sampass
, PDB_KICKOFFTIME
))
1295 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
),
1297 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_KICKOFF_TIME
), temp
);
1300 if (asprintf(&temp
, "%li", (long int)pdb_get_pass_can_change_time_noncalc(sampass
)) < 0) {
1303 if (need_update(sampass
, PDB_CANCHANGETIME
))
1304 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
),
1306 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_CAN_CHANGE
), temp
);
1309 if ((pdb_get_acct_ctrl(sampass
)&(ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
))
1310 || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY
)) {
1312 if (need_update(sampass
, PDB_LMPASSWD
)) {
1313 const uchar
*lm_pw
= pdb_get_lanman_passwd(sampass
);
1316 pdb_sethexpwd(pwstr
, lm_pw
,
1317 pdb_get_acct_ctrl(sampass
));
1320 ldap_state
->smbldap_state
),
1322 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LMPW
),
1327 ldap_state
->smbldap_state
),
1329 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_LMPW
),
1333 if (need_update(sampass
, PDB_NTPASSWD
)) {
1334 const uchar
*nt_pw
= pdb_get_nt_passwd(sampass
);
1337 pdb_sethexpwd(pwstr
, nt_pw
,
1338 pdb_get_acct_ctrl(sampass
));
1341 ldap_state
->smbldap_state
),
1343 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_NTPW
),
1348 ldap_state
->smbldap_state
),
1350 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_NTPW
),
1355 if (need_update(sampass
, PDB_PWHISTORY
)) {
1357 uint32_t pwHistLen
= 0;
1358 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY
, &pwHistLen
);
1360 pwstr
= SMB_MALLOC_ARRAY(char, 1024);
1364 if (pwHistLen
== 0) {
1365 /* Remove any password history from the LDAP store. */
1366 memset(pwstr
, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
1370 uint32_t currHistLen
= 0;
1371 const uint8_t *pwhist
= pdb_get_pw_history(sampass
, &currHistLen
);
1372 if (pwhist
!= NULL
) {
1373 /* We can only store (1024-1/64 password history entries. */
1374 pwHistLen
= MIN(pwHistLen
, ((1024-1)/64));
1375 for (i
=0; i
< pwHistLen
&& i
< currHistLen
; i
++) {
1376 /* Store the salt. */
1377 pdb_sethexpwd(&pwstr
[i
*64], &pwhist
[i
*PW_HISTORY_ENTRY_LEN
], 0);
1378 /* Followed by the md5 hash of salt + md4 hash */
1379 pdb_sethexpwd(&pwstr
[(i
*64)+32],
1380 &pwhist
[(i
*PW_HISTORY_ENTRY_LEN
)+PW_HISTORY_SALT_LEN
], 0);
1381 DEBUG(100, ("pwstr=%s\n", pwstr
));
1386 smbldap_get_ldap(ldap_state
->smbldap_state
),
1388 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_HISTORY
),
1393 if (need_update(sampass
, PDB_PASSLASTSET
)) {
1394 if (asprintf(&temp
, "%li",
1395 (long int)pdb_get_pass_last_set_time(sampass
)) < 0) {
1399 smbldap_get_ldap(ldap_state
->smbldap_state
),
1401 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_PWD_LAST_SET
),
1407 if (need_update(sampass
, PDB_HOURS
)) {
1408 const uint8_t *hours
= pdb_get_hours(sampass
);
1411 pdb_sethexhours(hourstr
, hours
);
1413 smbldap_get_ldap(ldap_state
->smbldap_state
),
1416 get_userattr_key2string(ldap_state
->schema_ver
,
1417 LDAP_ATTR_LOGON_HOURS
),
1422 if (need_update(sampass
, PDB_ACCTCTRL
))
1424 smbldap_get_ldap(ldap_state
->smbldap_state
),
1426 get_userattr_key2string(ldap_state
->schema_ver
, LDAP_ATTR_ACB_INFO
),
1427 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass
), NEW_PW_FORMAT_SPACE_PADDED_LEN
));
1429 /* password lockout cache:
1430 - If we are now autolocking or clearing, we write to ldap
1431 - If we are clearing, we delete the cache entry
1432 - If the count is > 0, we update the cache
1434 This even means when autolocking, we cache, just in case the
1435 update doesn't work, and we have to cache the autolock flag */
1437 if (need_update(sampass
, PDB_BAD_PASSWORD_COUNT
)) /* &&
1438 need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ {
1439 uint16_t badcount
= pdb_get_bad_password_count(sampass
);
1440 time_t badtime
= pdb_get_bad_password_time(sampass
);
1442 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT
, &pol
);
1444 DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
1445 (unsigned int)pol
, (unsigned int)badcount
, (unsigned int)badtime
));
1447 if ((badcount
>= pol
) || (badcount
== 0)) {
1448 DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n",
1449 (unsigned int)badcount
, (unsigned int)badtime
));
1450 if (asprintf(&temp
, "%li", (long)badcount
) < 0) {
1454 smbldap_get_ldap(ldap_state
->smbldap_state
),
1456 get_userattr_key2string(
1457 ldap_state
->schema_ver
,
1458 LDAP_ATTR_BAD_PASSWORD_COUNT
),
1462 if (asprintf(&temp
, "%li", (long int)badtime
) < 0) {
1466 smbldap_get_ldap(ldap_state
->smbldap_state
),
1468 get_userattr_key2string(
1469 ldap_state
->schema_ver
,
1470 LDAP_ATTR_BAD_PASSWORD_TIME
),
1474 if (badcount
== 0) {
1475 DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass
)));
1476 login_cache_delentry(sampass
);
1478 struct login_cache cache_entry
;
1480 cache_entry
.entry_timestamp
= time(NULL
);
1481 cache_entry
.acct_ctrl
= pdb_get_acct_ctrl(sampass
);
1482 cache_entry
.bad_password_count
= badcount
;
1483 cache_entry
.bad_password_time
= badtime
;
1485 DEBUG(7, ("Updating bad password count and time in login cache\n"));
1486 login_cache_write(sampass
, &cache_entry
);
1493 /**********************************************************************
1494 End enumeration of the LDAP password list.
1495 *********************************************************************/
1497 static void ldapsam_endsampwent(struct pdb_methods
*my_methods
)
1499 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1500 if (ldap_state
->result
) {
1501 ldap_msgfree(ldap_state
->result
);
1502 ldap_state
->result
= NULL
;
1506 static void append_attr(TALLOC_CTX
*mem_ctx
, const char ***attr_list
,
1507 const char *new_attr
)
1511 if (new_attr
== NULL
) {
1515 for (i
=0; (*attr_list
)[i
] != NULL
; i
++) {
1519 (*attr_list
) = talloc_realloc(mem_ctx
, (*attr_list
),
1521 SMB_ASSERT((*attr_list
) != NULL
);
1522 (*attr_list
)[i
] = talloc_strdup((*attr_list
), new_attr
);
1523 (*attr_list
)[i
+1] = NULL
;
1526 static void ldapsam_add_unix_attributes(TALLOC_CTX
*mem_ctx
,
1527 const char ***attr_list
)
1529 append_attr(mem_ctx
, attr_list
, "uidNumber");
1530 append_attr(mem_ctx
, attr_list
, "gidNumber");
1531 append_attr(mem_ctx
, attr_list
, "homeDirectory");
1532 append_attr(mem_ctx
, attr_list
, "loginShell");
1533 append_attr(mem_ctx
, attr_list
, "gecos");
1536 /**********************************************************************
1537 Get struct samu entry from LDAP by username.
1538 *********************************************************************/
1540 static NTSTATUS
ldapsam_getsampwnam(struct pdb_methods
*my_methods
, struct samu
*user
, const char *sname
)
1542 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
1543 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1544 LDAPMessage
*result
= NULL
;
1545 LDAPMessage
*entry
= NULL
;
1547 const char ** attr_list
;
1550 attr_list
= get_userattr_list( user
, ldap_state
->schema_ver
);
1551 append_attr(user
, &attr_list
,
1552 get_userattr_key2string(ldap_state
->schema_ver
,
1553 LDAP_ATTR_MOD_TIMESTAMP
));
1554 ldapsam_add_unix_attributes(user
, &attr_list
);
1555 rc
= ldapsam_search_suffix_by_name(ldap_state
, sname
, &result
,
1557 TALLOC_FREE( attr_list
);
1559 if ( rc
!= LDAP_SUCCESS
)
1560 return NT_STATUS_NO_SUCH_USER
;
1562 count
= ldap_count_entries(smbldap_get_ldap(ldap_state
->smbldap_state
),
1566 DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname
, count
));
1567 ldap_msgfree(result
);
1568 return NT_STATUS_NO_SUCH_USER
;
1569 } else if (count
> 1) {
1570 DEBUG(1, ("ldapsam_getsampwnam: Duplicate entries for this user [%s] Failing. count=%d\n", sname
, count
));
1571 ldap_msgfree(result
);
1572 return NT_STATUS_NO_SUCH_USER
;
1575 entry
= ldap_first_entry(smbldap_get_ldap(ldap_state
->smbldap_state
),
1578 if (!init_sam_from_ldap(ldap_state
, user
, entry
)) {
1579 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname
));
1580 ldap_msgfree(result
);
1581 return NT_STATUS_NO_SUCH_USER
;
1583 pdb_set_backend_private_data(user
, result
, NULL
,
1584 my_methods
, PDB_CHANGED
);
1585 smbldap_talloc_autofree_ldapmsg(user
, result
);
1588 ldap_msgfree(result
);
1593 static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates
*ldap_state
,
1594 const struct dom_sid
*sid
, LDAPMessage
**result
)
1597 const char ** attr_list
;
1599 switch ( ldap_state
->schema_ver
) {
1600 case SCHEMAVER_SAMBASAMACCOUNT
: {
1601 TALLOC_CTX
*tmp_ctx
= talloc_new(NULL
);
1602 if (tmp_ctx
== NULL
) {
1603 return LDAP_NO_MEMORY
;
1606 attr_list
= get_userattr_list(tmp_ctx
,
1607 ldap_state
->schema_ver
);
1608 append_attr(tmp_ctx
, &attr_list
,
1609 get_userattr_key2string(
1610 ldap_state
->schema_ver
,
1611 LDAP_ATTR_MOD_TIMESTAMP
));
1612 ldapsam_add_unix_attributes(tmp_ctx
, &attr_list
);
1613 rc
= ldapsam_search_suffix_by_sid(ldap_state
, sid
,
1615 TALLOC_FREE(tmp_ctx
);
1617 if ( rc
!= LDAP_SUCCESS
)
1623 DEBUG(0,("Invalid schema version specified\n"));
1629 /**********************************************************************
1630 Get struct samu entry from LDAP by SID.
1631 *********************************************************************/
1633 static NTSTATUS
ldapsam_getsampwsid(struct pdb_methods
*my_methods
, struct samu
* user
, const struct dom_sid
*sid
)
1635 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1636 LDAPMessage
*result
= NULL
;
1637 LDAPMessage
*entry
= NULL
;
1641 rc
= ldapsam_get_ldap_user_by_sid(ldap_state
,
1643 if (rc
!= LDAP_SUCCESS
)
1644 return NT_STATUS_NO_SUCH_USER
;
1646 count
= ldap_count_entries(smbldap_get_ldap(ldap_state
->smbldap_state
),
1650 struct dom_sid_buf buf
;
1651 DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] "
1653 dom_sid_str_buf(sid
, &buf
),
1655 ldap_msgfree(result
);
1656 return NT_STATUS_NO_SUCH_USER
;
1657 } else if (count
> 1) {
1658 struct dom_sid_buf buf
;
1659 DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID "
1660 "[%s]. Failing. count=%d\n",
1661 dom_sid_str_buf(sid
, &buf
),
1663 ldap_msgfree(result
);
1664 return NT_STATUS_NO_SUCH_USER
;
1667 entry
= ldap_first_entry(smbldap_get_ldap(ldap_state
->smbldap_state
),
1670 ldap_msgfree(result
);
1671 return NT_STATUS_NO_SUCH_USER
;
1674 if (!init_sam_from_ldap(ldap_state
, user
, entry
)) {
1675 DEBUG(1,("ldapsam_getsampwsid: init_sam_from_ldap failed!\n"));
1676 ldap_msgfree(result
);
1677 return NT_STATUS_NO_SUCH_USER
;
1680 pdb_set_backend_private_data(user
, result
, NULL
,
1681 my_methods
, PDB_CHANGED
);
1682 smbldap_talloc_autofree_ldapmsg(user
, result
);
1683 return NT_STATUS_OK
;
1686 /********************************************************************
1687 Do the actual modification - also change a plaintext password if
1689 **********************************************************************/
1691 static NTSTATUS
ldapsam_modify_entry(struct pdb_methods
*my_methods
,
1692 struct samu
*newpwd
, char *dn
,
1693 LDAPMod
**mods
, int ldap_op
,
1694 bool (*need_update
)(const struct samu
*, enum pdb_elements
))
1696 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1699 if (!newpwd
|| !dn
) {
1700 return NT_STATUS_INVALID_PARAMETER
;
1703 if (!(pdb_get_acct_ctrl(newpwd
)&(ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
)) &&
1704 (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF
) &&
1705 need_update(newpwd
, PDB_PLAINTEXT_PW
) &&
1706 (pdb_get_plaintext_passwd(newpwd
)!=NULL
)) {
1709 char *retoid
= NULL
;
1710 struct berval
*retdata
= NULL
;
1711 char *utf8_password
;
1713 size_t converted_size
;
1716 if (!ldap_state
->is_nds_ldap
) {
1718 if (!smbldap_has_extension(
1720 ldap_state
->smbldap_state
),
1721 LDAP_EXOP_MODIFY_PASSWD
)) {
1722 DEBUG(2, ("ldap password change requested, but LDAP "
1723 "server does not support it -- ignoring\n"));
1724 return NT_STATUS_OK
;
1728 if (!push_utf8_talloc(talloc_tos(), &utf8_password
,
1729 pdb_get_plaintext_passwd(newpwd
),
1732 return NT_STATUS_NO_MEMORY
;
1735 if (!push_utf8_talloc(talloc_tos(), &utf8_dn
, dn
, &converted_size
)) {
1736 TALLOC_FREE(utf8_password
);
1737 return NT_STATUS_NO_MEMORY
;
1740 if ((ber
= ber_alloc_t(LBER_USE_DER
))==NULL
) {
1741 DEBUG(0,("ber_alloc_t returns NULL\n"));
1742 TALLOC_FREE(utf8_password
);
1743 TALLOC_FREE(utf8_dn
);
1744 return NT_STATUS_UNSUCCESSFUL
;
1747 if ((ber_printf (ber
, "{") < 0) ||
1748 (ber_printf (ber
, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID
,
1750 DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
1753 TALLOC_FREE(utf8_dn
);
1754 TALLOC_FREE(utf8_password
);
1755 return NT_STATUS_UNSUCCESSFUL
;
1758 if ((utf8_password
!= NULL
) && (*utf8_password
!= '\0')) {
1759 ret
= ber_printf(ber
, "ts}",
1760 LDAP_TAG_EXOP_MODIFY_PASSWD_NEW
,
1763 ret
= ber_printf(ber
, "}");
1767 DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
1770 TALLOC_FREE(utf8_dn
);
1771 TALLOC_FREE(utf8_password
);
1772 return NT_STATUS_UNSUCCESSFUL
;
1775 if ((rc
= ber_flatten (ber
, &bv
))<0) {
1776 DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
1778 TALLOC_FREE(utf8_dn
);
1779 TALLOC_FREE(utf8_password
);
1780 return NT_STATUS_UNSUCCESSFUL
;
1783 TALLOC_FREE(utf8_dn
);
1784 TALLOC_FREE(utf8_password
);
1787 if (!ldap_state
->is_nds_ldap
) {
1788 rc
= smbldap_extended_operation(ldap_state
->smbldap_state
,
1789 LDAP_EXOP_MODIFY_PASSWD
,
1790 bv
, NULL
, NULL
, &retoid
,
1793 rc
= pdb_nds_set_password(ldap_state
->smbldap_state
, dn
,
1794 pdb_get_plaintext_passwd(newpwd
));
1796 if (rc
!= LDAP_SUCCESS
) {
1797 char *ld_error
= NULL
;
1799 if (rc
== LDAP_OBJECT_CLASS_VIOLATION
) {
1800 DEBUG(3, ("Could not set userPassword "
1801 "attribute due to an objectClass "
1802 "violation -- ignoring\n"));
1804 return NT_STATUS_OK
;
1808 smbldap_get_ldap(ldap_state
->smbldap_state
),
1809 LDAP_OPT_ERROR_STRING
,
1811 DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n",
1812 pdb_get_username(newpwd
), ldap_err2string(rc
), ld_error
?ld_error
:"unknown"));
1813 SAFE_FREE(ld_error
);
1815 #if defined(LDAP_CONSTRAINT_VIOLATION)
1816 if (rc
== LDAP_CONSTRAINT_VIOLATION
)
1817 return NT_STATUS_PASSWORD_RESTRICTION
;
1819 return NT_STATUS_UNSUCCESSFUL
;
1821 DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd
)));
1822 #ifdef DEBUG_PASSWORD
1823 DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd
)));
1826 ber_bvfree(retdata
);
1828 ldap_memfree(retoid
);
1834 DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
1835 /* may be password change below however */
1839 if (ldap_state
->is_nds_ldap
) {
1840 smbldap_set_mod(&mods
, LDAP_MOD_ADD
,
1844 smbldap_set_mod(&mods
, LDAP_MOD_ADD
,
1848 rc
= smbldap_add(ldap_state
->smbldap_state
,
1851 case LDAP_MOD_REPLACE
:
1852 rc
= smbldap_modify(ldap_state
->smbldap_state
,
1856 DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n",
1858 return NT_STATUS_INVALID_PARAMETER
;
1861 if (rc
!=LDAP_SUCCESS
) {
1862 return NT_STATUS_UNSUCCESSFUL
;
1866 return NT_STATUS_OK
;
1869 /**********************************************************************
1870 Delete entry from LDAP for username.
1871 *********************************************************************/
1873 static NTSTATUS
ldapsam_delete_sam_account(struct pdb_methods
*my_methods
,
1874 struct samu
* sam_acct
)
1876 struct ldapsam_privates
*priv
=
1877 (struct ldapsam_privates
*)my_methods
->private_data
;
1880 LDAPMessage
*msg
, *entry
;
1881 NTSTATUS result
= NT_STATUS_NO_MEMORY
;
1882 const char **attr_list
;
1883 TALLOC_CTX
*mem_ctx
;
1886 DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n"));
1887 return NT_STATUS_INVALID_PARAMETER
;
1890 sname
= pdb_get_username(sam_acct
);
1892 DEBUG(3, ("ldapsam_delete_sam_account: Deleting user %s from "
1895 mem_ctx
= talloc_new(NULL
);
1896 if (mem_ctx
== NULL
) {
1897 DEBUG(0, ("talloc_new failed\n"));
1901 attr_list
= get_userattr_delete_list(mem_ctx
, priv
->schema_ver
);
1902 if (attr_list
== NULL
) {
1906 rc
= ldapsam_search_suffix_by_name(priv
, sname
, &msg
, attr_list
);
1908 if ((rc
!= LDAP_SUCCESS
) ||
1909 (ldap_count_entries(priv2ld(priv
), msg
) != 1) ||
1910 ((entry
= ldap_first_entry(priv2ld(priv
), msg
)) == NULL
)) {
1911 DEBUG(5, ("Could not find user %s\n", sname
));
1912 result
= NT_STATUS_NO_SUCH_USER
;
1916 rc
= ldapsam_delete_entry(
1917 priv
, mem_ctx
, entry
,
1918 priv
->schema_ver
== SCHEMAVER_SAMBASAMACCOUNT
?
1919 LDAP_OBJ_SAMBASAMACCOUNT
: 0,
1922 result
= (rc
== LDAP_SUCCESS
) ?
1923 NT_STATUS_OK
: NT_STATUS_ACCESS_DENIED
;
1926 TALLOC_FREE(mem_ctx
);
1930 /**********************************************************************
1932 *********************************************************************/
1934 static NTSTATUS
ldapsam_update_sam_account(struct pdb_methods
*my_methods
, struct samu
* newpwd
)
1937 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
1940 LDAPMessage
*result
= NULL
;
1941 LDAPMessage
*entry
= NULL
;
1942 LDAPMod
**mods
= NULL
;
1943 const char **attr_list
;
1945 result
= (LDAPMessage
*)pdb_get_backend_private_data(newpwd
, my_methods
);
1947 attr_list
= get_userattr_list(NULL
, ldap_state
->schema_ver
);
1948 if (pdb_get_username(newpwd
) == NULL
) {
1949 return NT_STATUS_INVALID_PARAMETER
;
1951 rc
= ldapsam_search_suffix_by_name(ldap_state
, pdb_get_username(newpwd
), &result
, attr_list
);
1952 TALLOC_FREE( attr_list
);
1953 if (rc
!= LDAP_SUCCESS
) {
1954 return NT_STATUS_UNSUCCESSFUL
;
1956 pdb_set_backend_private_data(newpwd
, result
, NULL
,
1957 my_methods
, PDB_CHANGED
);
1958 smbldap_talloc_autofree_ldapmsg(newpwd
, result
);
1961 if (ldap_count_entries(smbldap_get_ldap(ldap_state
->smbldap_state
),
1963 DEBUG(0, ("ldapsam_update_sam_account: No user to modify!\n"));
1964 return NT_STATUS_UNSUCCESSFUL
;
1967 entry
= ldap_first_entry(smbldap_get_ldap(ldap_state
->smbldap_state
),
1969 dn
= smbldap_talloc_dn(talloc_tos(),
1970 smbldap_get_ldap(ldap_state
->smbldap_state
),
1973 return NT_STATUS_UNSUCCESSFUL
;
1976 DEBUG(4, ("ldapsam_update_sam_account: user %s to be modified has dn: %s\n", pdb_get_username(newpwd
), dn
));
1978 if (!init_ldap_from_sam(ldap_state
, entry
, &mods
, newpwd
,
1979 pdb_element_is_changed
)) {
1980 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
1983 ldap_mods_free(mods
,True
);
1984 return NT_STATUS_UNSUCCESSFUL
;
1987 if ((lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_ONLY
)
1988 && (mods
== NULL
)) {
1989 DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
1990 pdb_get_username(newpwd
)));
1992 return NT_STATUS_OK
;
1995 ret
= ldapsam_modify_entry(my_methods
,newpwd
,dn
,mods
,LDAP_MOD_REPLACE
, pdb_element_is_changed
);
1998 ldap_mods_free(mods
,True
);
2004 * We need to set the backend private data to NULL here. For example
2005 * setuserinfo level 25 does a pdb_update_sam_account twice on the
2006 * same one, and with the explicit delete / add logic for attribute
2007 * values the second time we would use the wrong "old" value which
2008 * does not exist in LDAP anymore. Thus the LDAP server would refuse
2010 * The existing LDAPMessage is still being auto-freed by the
2013 pdb_set_backend_private_data(newpwd
, NULL
, NULL
, my_methods
,
2016 if (!NT_STATUS_IS_OK(ret
)) {
2020 DEBUG(2, ("ldapsam_update_sam_account: successfully modified uid = %s in the LDAP database\n",
2021 pdb_get_username(newpwd
)));
2022 return NT_STATUS_OK
;
2025 /***************************************************************************
2026 Renames a struct samu
2027 - The "rename user script" has full responsibility for changing everything
2028 ***************************************************************************/
2030 static NTSTATUS
ldapsam_del_groupmem(struct pdb_methods
*my_methods
,
2031 TALLOC_CTX
*tmp_ctx
,
2033 uint32_t member_rid
);
2035 static NTSTATUS
ldapsam_enum_group_memberships(struct pdb_methods
*methods
,
2036 TALLOC_CTX
*mem_ctx
,
2038 struct dom_sid
**pp_sids
,
2040 uint32_t *p_num_groups
);
2042 static NTSTATUS
ldapsam_rename_sam_account(struct pdb_methods
*my_methods
,
2043 struct samu
*old_acct
,
2044 const char *newname
)
2046 const struct loadparm_substitution
*lp_sub
=
2047 loadparm_s3_global_substitution();
2048 const char *oldname
;
2050 char *rename_script
= NULL
;
2051 fstring oldname_lower
, newname_lower
;
2054 DEBUG(0, ("ldapsam_rename_sam_account: old_acct was NULL!\n"));
2055 return NT_STATUS_INVALID_PARAMETER
;
2058 DEBUG(0, ("ldapsam_rename_sam_account: newname was NULL!\n"));
2059 return NT_STATUS_INVALID_PARAMETER
;
2062 oldname
= pdb_get_username(old_acct
);
2064 /* rename the posix user */
2065 rename_script
= lp_rename_user_script(talloc_tos(), lp_sub
);
2066 if (rename_script
== NULL
) {
2067 return NT_STATUS_NO_MEMORY
;
2070 if (!(*rename_script
)) {
2071 TALLOC_FREE(rename_script
);
2072 return NT_STATUS_ACCESS_DENIED
;
2075 DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n",
2078 /* We have to allow the account name to end with a '$'.
2079 Also, follow the semantics in _samr_create_user() and lower case the
2080 posix name but preserve the case in passdb */
2082 fstrcpy( oldname_lower
, oldname
);
2083 if (!strlower_m( oldname_lower
)) {
2084 return NT_STATUS_INVALID_PARAMETER
;
2086 fstrcpy( newname_lower
, newname
);
2087 if (!strlower_m( newname_lower
)) {
2088 return NT_STATUS_INVALID_PARAMETER
;
2091 rename_script
= realloc_string_sub2(rename_script
,
2096 if (!rename_script
) {
2097 return NT_STATUS_NO_MEMORY
;
2099 rename_script
= realloc_string_sub2(rename_script
,
2104 rc
= smbrun(rename_script
, NULL
, NULL
);
2106 DEBUG(rc
? 0 : 3,("Running the command `%s' gave %d\n",
2107 rename_script
, rc
));
2109 TALLOC_FREE(rename_script
);
2112 smb_nscd_flush_user_cache();
2116 return NT_STATUS_UNSUCCESSFUL
;
2118 return NT_STATUS_OK
;
2121 /**********************************************************************
2122 Add struct samu to LDAP.
2123 *********************************************************************/
2125 static NTSTATUS
ldapsam_add_sam_account(struct pdb_methods
*my_methods
, struct samu
* newpwd
)
2127 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
2129 LDAPMessage
*result
= NULL
;
2130 LDAPMessage
*entry
= NULL
;
2131 LDAPMod
**mods
= NULL
;
2132 int ldap_op
= LDAP_MOD_REPLACE
;
2133 uint32_t num_result
;
2134 const char **attr_list
;
2135 char *escape_user
= NULL
;
2136 const char *username
= pdb_get_username(newpwd
);
2137 const struct dom_sid
*sid
= pdb_get_user_sid(newpwd
);
2138 char *filter
= NULL
;
2140 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
2141 TALLOC_CTX
*ctx
= talloc_init("ldapsam_add_sam_account");
2144 return NT_STATUS_NO_MEMORY
;
2147 if (!username
|| !*username
) {
2148 DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
2149 status
= NT_STATUS_INVALID_PARAMETER
;
2153 /* free this list after the second search or in case we exit on failure */
2154 attr_list
= get_userattr_list(ctx
, ldap_state
->schema_ver
);
2156 rc
= ldapsam_search_suffix_by_name (ldap_state
, username
, &result
, attr_list
);
2158 if (rc
!= LDAP_SUCCESS
) {
2162 if (ldap_count_entries(smbldap_get_ldap(ldap_state
->smbldap_state
),
2164 DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n",
2168 ldap_msgfree(result
);
2171 if (pdb_element_is_set_or_changed(newpwd
, PDB_USERSID
)) {
2172 rc
= ldapsam_get_ldap_user_by_sid(ldap_state
,
2174 if (rc
== LDAP_SUCCESS
) {
2175 if (ldap_count_entries(
2177 ldap_state
->smbldap_state
),
2179 struct dom_sid_buf buf
;
2180 DEBUG(0,("ldapsam_add_sam_account: SID '%s' "
2181 "already in the base, with samba "
2183 dom_sid_str_buf(sid
, &buf
)));
2186 ldap_msgfree(result
);
2191 /* does the entry already exist but without a samba attributes?
2192 we need to return the samba attributes here */
2194 escape_user
= escape_ldap_string(talloc_tos(), username
);
2195 filter
= talloc_strdup(attr_list
, "(uid=%u)");
2197 status
= NT_STATUS_NO_MEMORY
;
2200 filter
= talloc_all_string_sub(attr_list
, filter
, "%u", escape_user
);
2201 TALLOC_FREE(escape_user
);
2203 status
= NT_STATUS_NO_MEMORY
;
2207 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
,
2208 filter
, attr_list
, &result
);
2209 if ( rc
!= LDAP_SUCCESS
) {
2213 num_result
= ldap_count_entries(
2214 smbldap_get_ldap(ldap_state
->smbldap_state
), result
);
2216 if (num_result
> 1) {
2217 DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
2221 /* Check if we need to update an existing entry */
2222 if (num_result
== 1) {
2223 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
2224 ldap_op
= LDAP_MOD_REPLACE
;
2225 entry
= ldap_first_entry(
2226 smbldap_get_ldap(ldap_state
->smbldap_state
), result
);
2227 dn
= smbldap_talloc_dn(
2228 ctx
, smbldap_get_ldap(ldap_state
->smbldap_state
),
2231 status
= NT_STATUS_NO_MEMORY
;
2235 } else if (ldap_state
->schema_ver
== SCHEMAVER_SAMBASAMACCOUNT
) {
2237 struct dom_sid_buf buf
;
2239 /* There might be a SID for this account already - say an idmap entry */
2241 filter
= talloc_asprintf(ctx
,
2242 "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
2243 get_userattr_key2string(ldap_state
->schema_ver
,
2244 LDAP_ATTR_USER_SID
),
2245 dom_sid_str_buf(sid
, &buf
),
2246 LDAP_OBJ_IDMAP_ENTRY
,
2247 LDAP_OBJ_SID_ENTRY
);
2249 status
= NT_STATUS_NO_MEMORY
;
2253 /* free old result before doing a new search */
2254 if (result
!= NULL
) {
2255 ldap_msgfree(result
);
2258 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
,
2259 filter
, attr_list
, &result
);
2261 if ( rc
!= LDAP_SUCCESS
) {
2265 num_result
= ldap_count_entries(
2266 smbldap_get_ldap(ldap_state
->smbldap_state
), result
);
2268 if (num_result
> 1) {
2269 DEBUG (0, ("ldapsam_add_sam_account: More than one user with specified Sid exists: bailing out!\n"));
2273 /* Check if we need to update an existing entry */
2274 if (num_result
== 1) {
2276 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
2277 ldap_op
= LDAP_MOD_REPLACE
;
2278 entry
= ldap_first_entry (
2279 smbldap_get_ldap(ldap_state
->smbldap_state
),
2281 dn
= smbldap_talloc_dn (
2283 smbldap_get_ldap(ldap_state
->smbldap_state
),
2286 status
= NT_STATUS_NO_MEMORY
;
2292 if (num_result
== 0) {
2293 char *escape_username
;
2294 /* Check if we need to add an entry */
2295 DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
2296 ldap_op
= LDAP_MOD_ADD
;
2298 escape_username
= escape_rdn_val_string_alloc(username
);
2299 if (!escape_username
) {
2300 status
= NT_STATUS_NO_MEMORY
;
2304 if (username
[strlen(username
)-1] == '$') {
2305 dn
= talloc_asprintf(ctx
,
2308 lp_ldap_machine_suffix(talloc_tos()));
2310 dn
= talloc_asprintf(ctx
,
2313 lp_ldap_user_suffix(talloc_tos()));
2316 SAFE_FREE(escape_username
);
2318 status
= NT_STATUS_NO_MEMORY
;
2323 if (!init_ldap_from_sam(ldap_state
, entry
, &mods
, newpwd
,
2324 pdb_element_is_set_or_changed
)) {
2325 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
2327 ldap_mods_free(mods
, true);
2333 DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd
)));
2336 switch ( ldap_state
->schema_ver
) {
2337 case SCHEMAVER_SAMBASAMACCOUNT
:
2338 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT
);
2341 DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
2345 status
= ldapsam_modify_entry(my_methods
,newpwd
,dn
,mods
,ldap_op
, pdb_element_is_set_or_changed
);
2346 if (!NT_STATUS_IS_OK(status
)) {
2347 DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
2348 pdb_get_username(newpwd
),dn
));
2349 ldap_mods_free(mods
, true);
2353 DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd
)));
2354 ldap_mods_free(mods
, true);
2356 status
= NT_STATUS_OK
;
2362 ldap_msgfree(result
);
2367 /**********************************************************************
2368 *********************************************************************/
2370 static int ldapsam_search_one_group (struct ldapsam_privates
*ldap_state
,
2372 LDAPMessage
** result
)
2374 int scope
= LDAP_SCOPE_SUBTREE
;
2376 const char **attr_list
;
2378 attr_list
= get_attr_list(NULL
, groupmap_attr_list
);
2379 rc
= smbldap_search(ldap_state
->smbldap_state
,
2380 lp_ldap_suffix(), scope
,
2381 filter
, attr_list
, 0, result
);
2382 TALLOC_FREE(attr_list
);
2387 /**********************************************************************
2388 *********************************************************************/
2390 static bool init_group_from_ldap(struct ldapsam_privates
*ldap_state
,
2391 GROUP_MAP
*map
, LDAPMessage
*entry
)
2394 TALLOC_CTX
*ctx
= talloc_init("init_group_from_ldap");
2396 if (ldap_state
== NULL
|| map
== NULL
|| entry
== NULL
||
2397 smbldap_get_ldap(ldap_state
->smbldap_state
) == NULL
) {
2398 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
2403 temp
= smbldap_talloc_single_attribute(
2404 smbldap_get_ldap(ldap_state
->smbldap_state
),
2406 get_attr_key2string(groupmap_attr_list
,
2407 LDAP_ATTR_GIDNUMBER
),
2410 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2411 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
)));
2415 DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp
));
2417 map
->gid
= (gid_t
)atol(temp
);
2420 temp
= smbldap_talloc_single_attribute(
2421 smbldap_get_ldap(ldap_state
->smbldap_state
),
2423 get_attr_key2string(groupmap_attr_list
,
2424 LDAP_ATTR_GROUP_SID
),
2427 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2428 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_SID
)));
2433 if (!string_to_sid(&map
->sid
, temp
)) {
2434 DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp
));
2440 temp
= smbldap_talloc_single_attribute(
2441 smbldap_get_ldap(ldap_state
->smbldap_state
),
2443 get_attr_key2string(groupmap_attr_list
,
2444 LDAP_ATTR_GROUP_TYPE
),
2447 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2448 get_attr_key2string( groupmap_attr_list
, LDAP_ATTR_GROUP_TYPE
)));
2452 map
->sid_name_use
= (enum lsa_SidType
)atol(temp
);
2454 if ((map
->sid_name_use
< SID_NAME_USER
) ||
2455 (map
->sid_name_use
> SID_NAME_UNKNOWN
)) {
2456 DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map
->sid_name_use
));
2462 temp
= smbldap_talloc_single_attribute(
2463 smbldap_get_ldap(ldap_state
->smbldap_state
),
2465 get_attr_key2string(groupmap_attr_list
,
2466 LDAP_ATTR_DISPLAY_NAME
),
2469 temp
= smbldap_talloc_single_attribute(
2470 smbldap_get_ldap(ldap_state
->smbldap_state
),
2472 get_attr_key2string(groupmap_attr_list
,
2476 DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
2477 for gidNumber(%lu)\n",(unsigned long)map
->gid
));
2482 map
->nt_name
= talloc_strdup(map
, temp
);
2483 if (!map
->nt_name
) {
2489 temp
= smbldap_talloc_single_attribute(
2490 smbldap_get_ldap(ldap_state
->smbldap_state
),
2492 get_attr_key2string(groupmap_attr_list
,
2496 temp
= talloc_strdup(ctx
, "");
2502 map
->comment
= talloc_strdup(map
, temp
);
2503 if (!map
->comment
) {
2508 if (lp_parm_bool(-1, "ldapsam", "trusted", false)) {
2511 id
.type
= ID_TYPE_GID
;
2513 idmap_cache_set_sid2unixid(&map
->sid
, &id
);
2520 /**********************************************************************
2521 *********************************************************************/
2523 static NTSTATUS
ldapsam_getgroup(struct pdb_methods
*methods
,
2527 struct ldapsam_privates
*ldap_state
=
2528 (struct ldapsam_privates
*)methods
->private_data
;
2529 LDAPMessage
*result
= NULL
;
2530 LDAPMessage
*entry
= NULL
;
2533 if (ldapsam_search_one_group(ldap_state
, filter
, &result
)
2535 return NT_STATUS_NO_SUCH_GROUP
;
2538 count
= ldap_count_entries(priv2ld(ldap_state
), result
);
2541 DEBUG(4, ("ldapsam_getgroup: Did not find group, filter was "
2543 ldap_msgfree(result
);
2544 return NT_STATUS_NO_SUCH_GROUP
;
2548 DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: "
2549 "count=%d\n", filter
, count
));
2550 ldap_msgfree(result
);
2551 return NT_STATUS_NO_SUCH_GROUP
;
2554 entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
2557 ldap_msgfree(result
);
2558 return NT_STATUS_UNSUCCESSFUL
;
2561 if (!init_group_from_ldap(ldap_state
, map
, entry
)) {
2562 DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for "
2563 "group filter %s\n", filter
));
2564 ldap_msgfree(result
);
2565 return NT_STATUS_NO_SUCH_GROUP
;
2568 ldap_msgfree(result
);
2569 return NT_STATUS_OK
;
2572 /**********************************************************************
2573 *********************************************************************/
2575 static NTSTATUS
ldapsam_getgrsid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
2578 char *filter
= NULL
;
2580 struct dom_sid_buf tmp
;
2582 if (asprintf(&filter
, "(&(objectClass=%s)(%s=%s))",
2584 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GROUP_SID
),
2585 dom_sid_str_buf(&sid
, &tmp
)) < 0) {
2586 return NT_STATUS_NO_MEMORY
;
2589 status
= ldapsam_getgroup(methods
, filter
, map
);
2594 /**********************************************************************
2595 *********************************************************************/
2597 static NTSTATUS
ldapsam_getgrgid(struct pdb_methods
*methods
, GROUP_MAP
*map
,
2600 char *filter
= NULL
;
2603 if (asprintf(&filter
, "(&(objectClass=%s)(%s=%lu))",
2605 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_GIDNUMBER
),
2606 (unsigned long)gid
) < 0) {
2607 return NT_STATUS_NO_MEMORY
;
2610 status
= ldapsam_getgroup(methods
, filter
, map
);
2615 /**********************************************************************
2616 *********************************************************************/
2618 static NTSTATUS
ldapsam_getgrnam(struct pdb_methods
*methods
, GROUP_MAP
*map
,
2621 char *filter
= NULL
;
2622 char *escape_name
= escape_ldap_string(talloc_tos(), name
);
2626 return NT_STATUS_NO_MEMORY
;
2629 if (asprintf(&filter
, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
2631 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_DISPLAY_NAME
), escape_name
,
2632 get_attr_key2string(groupmap_attr_list
, LDAP_ATTR_CN
),
2634 TALLOC_FREE(escape_name
);
2635 return NT_STATUS_NO_MEMORY
;
2638 TALLOC_FREE(escape_name
);
2639 status
= ldapsam_getgroup(methods
, filter
, map
);
2644 static bool ldapsam_extract_rid_from_entry(LDAP
*ldap_struct
,
2646 const struct dom_sid
*domain_sid
,
2652 if (!smbldap_get_single_attribute(ldap_struct
, entry
, "sambaSID",
2653 str
, sizeof(str
)-1)) {
2654 DEBUG(10, ("Could not find sambaSID attribute\n"));
2658 if (!string_to_sid(&sid
, str
)) {
2659 DEBUG(10, ("Could not convert string %s to sid\n", str
));
2663 if (dom_sid_compare_domain(&sid
, domain_sid
) != 0) {
2664 struct dom_sid_buf buf
;
2665 DEBUG(10, ("SID %s is not in expected domain %s\n",
2667 dom_sid_str_buf(domain_sid
, &buf
)));
2671 if (!sid_peek_rid(&sid
, rid
)) {
2672 DEBUG(10, ("Could not peek into RID\n"));
2679 static NTSTATUS
ldapsam_enum_group_members(struct pdb_methods
*methods
,
2680 TALLOC_CTX
*mem_ctx
,
2681 const struct dom_sid
*group
,
2682 uint32_t **pp_member_rids
,
2683 size_t *p_num_members
)
2685 struct ldapsam_privates
*ldap_state
=
2686 (struct ldapsam_privates
*)methods
->private_data
;
2687 struct smbldap_state
*conn
= ldap_state
->smbldap_state
;
2688 const char *id_attrs
[] = { "memberUid", "gidNumber", NULL
};
2689 const char *sid_attrs
[] = { "sambaSID", NULL
};
2690 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
2691 LDAPMessage
*result
= NULL
;
2694 char **values
= NULL
;
2698 struct dom_sid_buf buf
;
2700 *pp_member_rids
= NULL
;
2703 filter
= talloc_asprintf(mem_ctx
,
2704 "(&(objectClass="LDAP_OBJ_POSIXGROUP
")"
2705 "(objectClass="LDAP_OBJ_GROUPMAP
")"
2707 dom_sid_str_buf(group
, &buf
));
2708 if (filter
== NULL
) {
2709 ret
= NT_STATUS_NO_MEMORY
;
2713 rc
= smbldap_search(conn
, lp_ldap_suffix(),
2714 LDAP_SCOPE_SUBTREE
, filter
, id_attrs
, 0,
2717 if (rc
!= LDAP_SUCCESS
)
2720 smbldap_talloc_autofree_ldapmsg(mem_ctx
, result
);
2722 count
= ldap_count_entries(smbldap_get_ldap(conn
), result
);
2725 DEBUG(1, ("Found more than one groupmap entry for %s\n",
2726 dom_sid_str_buf(group
, &buf
)));
2727 ret
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2732 ret
= NT_STATUS_NO_SUCH_GROUP
;
2736 entry
= ldap_first_entry(smbldap_get_ldap(conn
), result
);
2740 gidstr
= smbldap_talloc_single_attribute(priv2ld(ldap_state
), entry
, "gidNumber", mem_ctx
);
2742 DEBUG (0, ("ldapsam_enum_group_members: Unable to find the group's gid!\n"));
2743 ret
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2747 values
= ldap_get_values(smbldap_get_ldap(conn
), entry
, "memberUid");
2749 if ((values
!= NULL
) && (values
[0] != NULL
)) {
2751 filter
= talloc_strdup(mem_ctx
, "(&(objectClass="LDAP_OBJ_SAMBASAMACCOUNT
")(|");
2753 for (memberuid
= values
; *memberuid
!= NULL
; memberuid
+= 1) {
2754 char *escape_memberuid
;
2756 escape_memberuid
= escape_ldap_string(talloc_tos(),
2758 if (escape_memberuid
== NULL
) {
2759 ret
= NT_STATUS_NO_MEMORY
;
2763 filter
= talloc_asprintf_append_buffer(filter
, "(uid=%s)", escape_memberuid
);
2764 TALLOC_FREE(escape_memberuid
);
2765 if (filter
== NULL
) {
2766 ret
= NT_STATUS_NO_MEMORY
;
2771 filter
= talloc_asprintf_append_buffer(filter
, "))");
2772 if (filter
== NULL
) {
2773 ret
= NT_STATUS_NO_MEMORY
;
2777 rc
= smbldap_search(conn
, lp_ldap_suffix(),
2778 LDAP_SCOPE_SUBTREE
, filter
, sid_attrs
, 0,
2781 if (rc
!= LDAP_SUCCESS
)
2784 count
= ldap_count_entries(smbldap_get_ldap(conn
), result
);
2785 DEBUG(10,("ldapsam_enum_group_members: found %d accounts\n", count
));
2787 smbldap_talloc_autofree_ldapmsg(mem_ctx
, result
);
2789 for (entry
= ldap_first_entry(smbldap_get_ldap(conn
), result
);
2791 entry
= ldap_next_entry(smbldap_get_ldap(conn
), entry
))
2797 sidstr
= smbldap_talloc_single_attribute(
2798 smbldap_get_ldap(conn
), entry
, "sambaSID",
2801 DEBUG(0, ("Severe DB error, %s can't miss the sambaSID"
2802 "attribute\n", LDAP_OBJ_SAMBASAMACCOUNT
));
2803 ret
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2807 if (!string_to_sid(&sid
, sidstr
))
2810 if (!sid_check_is_in_our_sam(&sid
)) {
2811 DEBUG(0, ("Inconsistent SAM -- group member uid not "
2812 "in our domain\n"));
2813 ret
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2817 sid_peek_rid(&sid
, &rid
);
2819 if (!add_rid_to_array_unique(mem_ctx
, rid
, pp_member_rids
,
2821 ret
= NT_STATUS_NO_MEMORY
;
2827 filter
= talloc_asprintf(mem_ctx
,
2828 "(&(objectClass=%s)"
2830 LDAP_OBJ_SAMBASAMACCOUNT
,
2833 rc
= smbldap_search(conn
, lp_ldap_suffix(),
2834 LDAP_SCOPE_SUBTREE
, filter
, sid_attrs
, 0,
2837 if (rc
!= LDAP_SUCCESS
)
2840 smbldap_talloc_autofree_ldapmsg(mem_ctx
, result
);
2842 for (entry
= ldap_first_entry(smbldap_get_ldap(conn
), result
);
2844 entry
= ldap_next_entry(smbldap_get_ldap(conn
), entry
))
2848 if (!ldapsam_extract_rid_from_entry(smbldap_get_ldap(conn
),
2850 get_global_sam_sid(),
2852 DEBUG(0, ("Severe DB error, %s can't miss the samba SID"
2853 "attribute\n", LDAP_OBJ_SAMBASAMACCOUNT
));
2854 ret
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2858 if (!add_rid_to_array_unique(mem_ctx
, rid
, pp_member_rids
,
2860 ret
= NT_STATUS_NO_MEMORY
;
2870 ldap_value_free(values
);
2875 static NTSTATUS
ldapsam_enum_group_memberships(struct pdb_methods
*methods
,
2876 TALLOC_CTX
*mem_ctx
,
2878 struct dom_sid
**pp_sids
,
2880 uint32_t *p_num_groups
)
2882 struct ldapsam_privates
*ldap_state
=
2883 (struct ldapsam_privates
*)methods
->private_data
;
2884 struct smbldap_state
*conn
= ldap_state
->smbldap_state
;
2886 const char *attrs
[] = { "gidNumber", "sambaSID", NULL
};
2889 LDAPMessage
*result
= NULL
;
2891 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
2895 gid_t primary_gid
= -1;
2901 if (pdb_get_username(user
) == NULL
) {
2902 return NT_STATUS_INVALID_PARAMETER
;
2905 escape_name
= escape_ldap_string(talloc_tos(), pdb_get_username(user
));
2906 if (escape_name
== NULL
)
2907 return NT_STATUS_NO_MEMORY
;
2909 if (user
->unix_pw
) {
2910 primary_gid
= user
->unix_pw
->pw_gid
;
2912 /* retrieve the users primary gid */
2913 filter
= talloc_asprintf(mem_ctx
,
2914 "(&(objectClass="LDAP_OBJ_SAMBASAMACCOUNT
")(uid=%s))",
2916 if (filter
== NULL
) {
2917 ret
= NT_STATUS_NO_MEMORY
;
2921 rc
= smbldap_search(conn
, lp_ldap_suffix(),
2922 LDAP_SCOPE_SUBTREE
, filter
, attrs
, 0, &result
);
2924 if (rc
!= LDAP_SUCCESS
)
2927 smbldap_talloc_autofree_ldapmsg(mem_ctx
, result
);
2929 count
= ldap_count_entries(priv2ld(ldap_state
), result
);
2933 DEBUG(1, ("User account [%s] not found!\n", pdb_get_username(user
)));
2934 ret
= NT_STATUS_NO_SUCH_USER
;
2937 entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
2939 gidstr
= smbldap_talloc_single_attribute(priv2ld(ldap_state
), entry
, "gidNumber", mem_ctx
);
2941 DEBUG (1, ("Unable to find the member's gid!\n"));
2942 ret
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2945 primary_gid
= smb_strtoul(gidstr
,
2951 DBG_ERR("Failed to convert GID\n");
2956 DEBUG(1, ("found more than one account with the same user name ?!\n"));
2957 ret
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
2962 filter
= talloc_asprintf(mem_ctx
,
2963 "(&(objectClass="LDAP_OBJ_POSIXGROUP
")(|(memberUid=%s)(gidNumber=%u)))",
2964 escape_name
, (unsigned int)primary_gid
);
2965 if (filter
== NULL
) {
2966 ret
= NT_STATUS_NO_MEMORY
;
2970 rc
= smbldap_search(conn
, lp_ldap_suffix(),
2971 LDAP_SCOPE_SUBTREE
, filter
, attrs
, 0, &result
);
2973 if (rc
!= LDAP_SUCCESS
)
2976 smbldap_talloc_autofree_ldapmsg(mem_ctx
, result
);
2984 /* We need to add the primary group as the first gid/sid */
2986 if (!add_gid_to_array_unique(mem_ctx
, primary_gid
, pp_gids
, &num_gids
)) {
2987 ret
= NT_STATUS_NO_MEMORY
;
2991 /* This sid will be replaced later */
2993 ret
= add_sid_to_array_unique(mem_ctx
, &global_sid_NULL
, pp_sids
,
2995 if (!NT_STATUS_IS_OK(ret
)) {
2999 for (entry
= ldap_first_entry(smbldap_get_ldap(conn
), result
);
3001 entry
= ldap_next_entry(smbldap_get_ldap(conn
), entry
))
3007 if (!smbldap_get_single_attribute(smbldap_get_ldap(conn
),
3009 str
, sizeof(str
)-1))
3012 if (!string_to_sid(&sid
, str
))
3015 if (!smbldap_get_single_attribute(smbldap_get_ldap(conn
),
3017 str
, sizeof(str
)-1))
3020 gid
= smb_strtoul(str
, NULL
, 10, &error
, SMB_STR_FULL_STR_CONV
);
3026 if (gid
== primary_gid
) {
3027 sid_copy(&(*pp_sids
)[0], &sid
);
3029 if (!add_gid_to_array_unique(mem_ctx
, gid
, pp_gids
,
3031 ret
= NT_STATUS_NO_MEMORY
;
3034 ret
= add_sid_to_array_unique(mem_ctx
, &sid
, pp_sids
,
3036 if (!NT_STATUS_IS_OK(ret
)) {
3042 if (dom_sid_compare(&global_sid_NULL
, &(*pp_sids
)[0]) == 0) {
3043 DEBUG(3, ("primary group of [%s] not found\n",
3044 pdb_get_username(user
)));
3045 ret
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
3049 *p_num_groups
= num_sids
;
3055 TALLOC_FREE(escape_name
);
3059 /**********************************************************************
3060 * Augment a posixGroup object with a sambaGroupMapping domgroup
3061 *********************************************************************/
3063 static NTSTATUS
ldapsam_map_posixgroup(TALLOC_CTX
*mem_ctx
,
3064 struct ldapsam_privates
*ldap_state
,
3067 const char *filter
, *dn
;
3068 LDAPMessage
*msg
, *entry
;
3070 struct dom_sid_buf buf
;
3073 filter
= talloc_asprintf(mem_ctx
,
3074 "(&(objectClass="LDAP_OBJ_POSIXGROUP
")(gidNumber=%u))",
3075 (unsigned int)map
->gid
);
3076 if (filter
== NULL
) {
3077 return NT_STATUS_NO_MEMORY
;
3080 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
,
3081 get_attr_list(mem_ctx
, groupmap_attr_list
),
3083 smbldap_talloc_autofree_ldapmsg(mem_ctx
, msg
);
3085 if ((rc
!= LDAP_SUCCESS
) ||
3086 (ldap_count_entries(smbldap_get_ldap(ldap_state
->smbldap_state
),
3088 ((entry
= ldap_first_entry(
3089 smbldap_get_ldap(ldap_state
->smbldap_state
),
3091 return NT_STATUS_NO_SUCH_GROUP
;
3094 dn
= smbldap_talloc_dn(mem_ctx
,
3095 smbldap_get_ldap(ldap_state
->smbldap_state
),
3098 return NT_STATUS_NO_MEMORY
;
3102 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectClass",
3104 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
), entry
,
3106 dom_sid_str_buf(&map
->sid
, &buf
));
3107 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
), entry
,
3108 &mods
, "sambaGroupType",
3109 talloc_asprintf(mem_ctx
, "%d", map
->sid_name_use
));
3110 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
), entry
,
3111 &mods
, "displayName",
3113 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
), entry
,
3114 &mods
, "description",
3116 smbldap_talloc_autofree_ldapmod(mem_ctx
, mods
);
3118 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
3119 if (rc
!= LDAP_SUCCESS
) {
3120 return NT_STATUS_ACCESS_DENIED
;
3123 return NT_STATUS_OK
;
3126 static NTSTATUS
ldapsam_add_group_mapping_entry(struct pdb_methods
*methods
,
3129 struct ldapsam_privates
*ldap_state
=
3130 (struct ldapsam_privates
*)methods
->private_data
;
3131 LDAPMessage
*msg
= NULL
;
3132 LDAPMod
**mods
= NULL
;
3133 const char *attrs
[] = { NULL
};
3137 TALLOC_CTX
*mem_ctx
;
3141 struct dom_sid_buf buf
;
3146 mem_ctx
= talloc_new(NULL
);
3147 if (mem_ctx
== NULL
) {
3148 DEBUG(0, ("talloc_new failed\n"));
3149 return NT_STATUS_NO_MEMORY
;
3152 filter
= talloc_asprintf(mem_ctx
, "(sambaSid=%s)",
3153 dom_sid_str_buf(&map
->sid
, &buf
));
3154 if (filter
== NULL
) {
3155 result
= NT_STATUS_NO_MEMORY
;
3159 rc
= smbldap_search(ldap_state
->smbldap_state
, lp_ldap_suffix(),
3160 LDAP_SCOPE_SUBTREE
, filter
, attrs
, True
, &msg
);
3161 smbldap_talloc_autofree_ldapmsg(mem_ctx
, msg
);
3163 if ((rc
== LDAP_SUCCESS
) &&
3164 (ldap_count_entries(smbldap_get_ldap(ldap_state
->smbldap_state
),
3167 DEBUG(3, ("SID %s already present in LDAP, refusing to add "
3168 "group mapping entry\n",
3169 dom_sid_str_buf(&map
->sid
, &buf
)));
3170 result
= NT_STATUS_GROUP_EXISTS
;
3174 switch (map
->sid_name_use
) {
3176 case SID_NAME_DOM_GRP
:
3177 /* To map a domain group we need to have a posix group
3179 result
= ldapsam_map_posixgroup(mem_ctx
, ldap_state
, map
);
3183 case SID_NAME_ALIAS
:
3184 if (!sid_check_is_in_our_sam(&map
->sid
)
3185 && !sid_check_is_in_builtin(&map
->sid
) )
3187 DEBUG(3, ("Refusing to map sid %s as an alias, not in our domain\n",
3188 dom_sid_str_buf(&map
->sid
, &buf
)));
3189 result
= NT_STATUS_INVALID_PARAMETER
;
3195 DEBUG(3, ("Got invalid use '%s' for mapping\n",
3196 sid_type_lookup(map
->sid_name_use
)));
3197 result
= NT_STATUS_INVALID_PARAMETER
;
3201 /* Domain groups have been mapped in a separate routine, we have to
3202 * create an alias now */
3204 if (map
->gid
== -1) {
3205 DEBUG(10, ("Refusing to map gid==-1\n"));
3206 result
= NT_STATUS_INVALID_PARAMETER
;
3211 id
.type
= ID_TYPE_GID
;
3213 if (pdb_id_to_sid(&id
, &sid
)) {
3214 DEBUG(3, ("Gid %u is already mapped to SID %s, refusing to "
3216 (unsigned int)map
->gid
,
3217 dom_sid_str_buf(&sid
, &buf
)));
3218 result
= NT_STATUS_GROUP_EXISTS
;
3222 /* Ok, enough checks done. It's still racy to go ahead now, but that's
3223 * the best we can get out of LDAP. */
3225 dn
= talloc_asprintf(mem_ctx
, "sambaSid=%s,%s",
3226 dom_sid_str_buf(&map
->sid
, &buf
),
3227 lp_ldap_group_suffix(talloc_tos()));
3229 result
= NT_STATUS_NO_MEMORY
;
3235 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
), NULL
,
3236 &mods
, "objectClass", LDAP_OBJ_SID_ENTRY
);
3237 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
), NULL
,
3238 &mods
, "objectClass", LDAP_OBJ_GROUPMAP
);
3239 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
), NULL
,
3241 dom_sid_str_buf(&map
->sid
, &buf
));
3242 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
), NULL
,
3243 &mods
, "sambaGroupType",
3244 talloc_asprintf(mem_ctx
, "%d", map
->sid_name_use
));
3245 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
), NULL
,
3246 &mods
, "displayName",
3248 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
), NULL
,
3249 &mods
, "description",
3251 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
), NULL
,
3253 talloc_asprintf(mem_ctx
, "%u",
3254 (unsigned int)map
->gid
));
3255 smbldap_talloc_autofree_ldapmod(mem_ctx
, mods
);
3257 rc
= smbldap_add(ldap_state
->smbldap_state
, dn
, mods
);
3259 result
= (rc
== LDAP_SUCCESS
) ?
3260 NT_STATUS_OK
: NT_STATUS_ACCESS_DENIED
;
3263 TALLOC_FREE(mem_ctx
);
3267 /**********************************************************************
3268 * Update a group mapping entry. We're quite strict about what can be changed:
3269 * Only the description and displayname may be changed. It simply does not
3270 * make any sense to change the SID, gid or the type in a mapping.
3271 *********************************************************************/
3273 static NTSTATUS
ldapsam_update_group_mapping_entry(struct pdb_methods
*methods
,
3276 struct ldapsam_privates
*ldap_state
=
3277 (struct ldapsam_privates
*)methods
->private_data
;
3279 const char *filter
, *dn
;
3280 LDAPMessage
*msg
= NULL
;
3281 LDAPMessage
*entry
= NULL
;
3282 LDAPMod
**mods
= NULL
;
3283 TALLOC_CTX
*mem_ctx
;
3285 struct dom_sid_buf buf
;
3287 mem_ctx
= talloc_new(NULL
);
3288 if (mem_ctx
== NULL
) {
3289 DEBUG(0, ("talloc_new failed\n"));
3290 return NT_STATUS_NO_MEMORY
;
3293 /* Make 100% sure that sid, gid and type are not changed by looking up
3294 * exactly the values we're given in LDAP. */
3296 filter
= talloc_asprintf(mem_ctx
, "(&(objectClass="LDAP_OBJ_GROUPMAP
")"
3297 "(sambaSid=%s)(gidNumber=%u)"
3298 "(sambaGroupType=%d))",
3299 dom_sid_str_buf(&map
->sid
, &buf
),
3300 (unsigned int)map
->gid
, map
->sid_name_use
);
3301 if (filter
== NULL
) {
3302 result
= NT_STATUS_NO_MEMORY
;
3306 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
,
3307 get_attr_list(mem_ctx
, groupmap_attr_list
),
3309 smbldap_talloc_autofree_ldapmsg(mem_ctx
, msg
);
3311 if ((rc
!= LDAP_SUCCESS
) ||
3312 (ldap_count_entries(smbldap_get_ldap(ldap_state
->smbldap_state
),
3314 ((entry
= ldap_first_entry(
3315 smbldap_get_ldap(ldap_state
->smbldap_state
),
3317 result
= NT_STATUS_NO_SUCH_GROUP
;
3321 dn
= smbldap_talloc_dn(
3322 mem_ctx
, smbldap_get_ldap(ldap_state
->smbldap_state
), entry
);
3325 result
= NT_STATUS_NO_MEMORY
;
3330 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
), entry
,
3331 &mods
, "displayName", map
->nt_name
);
3332 smbldap_make_mod(smbldap_get_ldap(ldap_state
->smbldap_state
), entry
,
3333 &mods
, "description", map
->comment
);
3334 smbldap_talloc_autofree_ldapmod(mem_ctx
, mods
);
3337 DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: "
3338 "nothing to do\n"));
3339 result
= NT_STATUS_OK
;
3343 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
3345 if (rc
!= LDAP_SUCCESS
) {
3346 result
= NT_STATUS_ACCESS_DENIED
;
3350 DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified "
3351 "group %lu in LDAP\n", (unsigned long)map
->gid
));
3353 result
= NT_STATUS_OK
;
3356 TALLOC_FREE(mem_ctx
);
3360 /**********************************************************************
3361 *********************************************************************/
3363 static NTSTATUS
ldapsam_delete_group_mapping_entry(struct pdb_methods
*methods
,
3366 struct ldapsam_privates
*priv
=
3367 (struct ldapsam_privates
*)methods
->private_data
;
3368 LDAPMessage
*msg
, *entry
;
3371 TALLOC_CTX
*mem_ctx
;
3373 struct dom_sid_buf buf
;
3375 mem_ctx
= talloc_new(NULL
);
3376 if (mem_ctx
== NULL
) {
3377 DEBUG(0, ("talloc_new failed\n"));
3378 return NT_STATUS_NO_MEMORY
;
3381 filter
= talloc_asprintf(mem_ctx
, "(&(objectClass="LDAP_OBJ_GROUPMAP
")("LDAP_ATTRIBUTE_SID
"=%s))",
3382 dom_sid_str_buf(&sid
, &buf
));
3383 if (filter
== NULL
) {
3384 result
= NT_STATUS_NO_MEMORY
;
3387 rc
= smbldap_search_suffix(priv
->smbldap_state
, filter
,
3388 get_attr_list(mem_ctx
, groupmap_attr_list
),
3390 smbldap_talloc_autofree_ldapmsg(mem_ctx
, msg
);
3392 if ((rc
!= LDAP_SUCCESS
) ||
3393 (ldap_count_entries(priv2ld(priv
), msg
) != 1) ||
3394 ((entry
= ldap_first_entry(priv2ld(priv
), msg
)) == NULL
)) {
3395 result
= NT_STATUS_NO_SUCH_GROUP
;
3399 rc
= ldapsam_delete_entry(priv
, mem_ctx
, entry
, LDAP_OBJ_GROUPMAP
,
3400 get_attr_list(mem_ctx
,
3401 groupmap_attr_list_to_delete
));
3403 if ((rc
== LDAP_NAMING_VIOLATION
) ||
3404 (rc
== LDAP_NOT_ALLOWED_ON_RDN
) ||
3405 (rc
== LDAP_OBJECT_CLASS_VIOLATION
)) {
3406 const char *attrs
[] = { "sambaGroupType", "description",
3407 "displayName", "sambaSIDList",
3410 /* Second try. Don't delete the sambaSID attribute, this is
3411 for "old" entries that are tacked on a winbind
3414 rc
= ldapsam_delete_entry(priv
, mem_ctx
, entry
,
3415 LDAP_OBJ_GROUPMAP
, attrs
);
3418 if ((rc
== LDAP_NAMING_VIOLATION
) ||
3419 (rc
== LDAP_NOT_ALLOWED_ON_RDN
) ||
3420 (rc
== LDAP_OBJECT_CLASS_VIOLATION
)) {
3421 const char *attrs
[] = { "sambaGroupType", "description",
3422 "displayName", "sambaSIDList",
3423 "gidNumber", NULL
};
3425 /* Third try. This is a post-3.0.21 alias (containing only
3426 * sambaSidEntry and sambaGroupMapping classes), we also have
3427 * to delete the gidNumber attribute, only the sambaSidEntry
3430 rc
= ldapsam_delete_entry(priv
, mem_ctx
, entry
,
3431 LDAP_OBJ_GROUPMAP
, attrs
);
3434 result
= (rc
== LDAP_SUCCESS
) ? NT_STATUS_OK
: NT_STATUS_UNSUCCESSFUL
;
3437 TALLOC_FREE(mem_ctx
);
3441 /**********************************************************************
3442 *********************************************************************/
3444 static NTSTATUS
ldapsam_setsamgrent(struct pdb_methods
*my_methods
,
3447 struct ldapsam_privates
*ldap_state
=
3448 (struct ldapsam_privates
*)my_methods
->private_data
;
3449 const char *filter
= NULL
;
3451 const char **attr_list
;
3453 filter
= "(objectclass="LDAP_OBJ_GROUPMAP
")";
3454 attr_list
= get_attr_list( NULL
, groupmap_attr_list
);
3455 rc
= smbldap_search(ldap_state
->smbldap_state
, lp_ldap_suffix(),
3456 LDAP_SCOPE_SUBTREE
, filter
,
3457 attr_list
, 0, &ldap_state
->result
);
3458 TALLOC_FREE(attr_list
);
3460 if (rc
!= LDAP_SUCCESS
) {
3461 DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n",
3462 ldap_err2string(rc
)));
3463 DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n",
3464 lp_ldap_suffix(), filter
));
3465 ldap_msgfree(ldap_state
->result
);
3466 ldap_state
->result
= NULL
;
3467 return NT_STATUS_UNSUCCESSFUL
;
3470 DEBUG(2, ("ldapsam_setsamgrent: %d entries in the base!\n",
3472 smbldap_get_ldap(ldap_state
->smbldap_state
),
3473 ldap_state
->result
)));
3476 ldap_first_entry(smbldap_get_ldap(ldap_state
->smbldap_state
),
3477 ldap_state
->result
);
3478 ldap_state
->index
= 0;
3480 return NT_STATUS_OK
;
3483 /**********************************************************************
3484 *********************************************************************/
3486 static void ldapsam_endsamgrent(struct pdb_methods
*my_methods
)
3488 ldapsam_endsampwent(my_methods
);
3491 /**********************************************************************
3492 *********************************************************************/
3494 static NTSTATUS
ldapsam_getsamgrent(struct pdb_methods
*my_methods
,
3497 NTSTATUS ret
= NT_STATUS_UNSUCCESSFUL
;
3498 struct ldapsam_privates
*ldap_state
=
3499 (struct ldapsam_privates
*)my_methods
->private_data
;
3503 if (!ldap_state
->entry
)
3506 ldap_state
->index
++;
3507 bret
= init_group_from_ldap(ldap_state
, map
,
3510 ldap_state
->entry
= ldap_next_entry(
3511 smbldap_get_ldap(ldap_state
->smbldap_state
),
3515 return NT_STATUS_OK
;
3518 /**********************************************************************
3519 *********************************************************************/
3521 static NTSTATUS
ldapsam_enum_group_mapping(struct pdb_methods
*methods
,
3522 const struct dom_sid
*domsid
, enum lsa_SidType sid_name_use
,
3523 GROUP_MAP
***pp_rmap
,
3524 size_t *p_num_entries
,
3527 GROUP_MAP
*map
= NULL
;
3533 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods
, False
))) {
3534 DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open "
3536 return NT_STATUS_ACCESS_DENIED
;
3541 map
= talloc_zero(NULL
, GROUP_MAP
);
3543 return NT_STATUS_NO_MEMORY
;
3546 if (!NT_STATUS_IS_OK(ldapsam_getsamgrent(methods
, map
))) {
3551 if (sid_name_use
!= SID_NAME_UNKNOWN
&&
3552 sid_name_use
!= map
->sid_name_use
) {
3553 DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
3554 "not of the requested type\n",
3558 if (unix_only
== ENUM_ONLY_MAPPED
&& map
->gid
== -1) {
3559 DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
3560 "non mapped\n", map
->nt_name
));
3564 *pp_rmap
= talloc_realloc(NULL
, *pp_rmap
,
3565 GROUP_MAP
*, entries
+ 1);
3567 DEBUG(0,("ldapsam_enum_group_mapping: Unable to "
3568 "enlarge group map!\n"));
3569 return NT_STATUS_UNSUCCESSFUL
;
3572 (*pp_rmap
)[entries
] = talloc_move((*pp_rmap
), &map
);
3577 ldapsam_endsamgrent(methods
);
3579 *p_num_entries
= entries
;
3581 return NT_STATUS_OK
;
3584 static NTSTATUS
ldapsam_modify_aliasmem(struct pdb_methods
*methods
,
3585 const struct dom_sid
*alias
,
3586 const struct dom_sid
*member
,
3589 struct ldapsam_privates
*ldap_state
=
3590 (struct ldapsam_privates
*)methods
->private_data
;
3592 LDAPMessage
*result
= NULL
;
3593 LDAPMessage
*entry
= NULL
;
3595 LDAPMod
**mods
= NULL
;
3597 enum lsa_SidType type
= SID_NAME_USE_NONE
;
3598 struct dom_sid_buf tmp
;
3600 char *filter
= NULL
;
3602 if (sid_check_is_in_builtin(alias
)) {
3603 type
= SID_NAME_ALIAS
;
3606 if (sid_check_is_in_our_sam(alias
)) {
3607 type
= SID_NAME_ALIAS
;
3610 if (type
== SID_NAME_USE_NONE
) {
3611 struct dom_sid_buf buf
;
3612 DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
3613 dom_sid_str_buf(alias
, &buf
)));
3614 return NT_STATUS_NO_SUCH_ALIAS
;
3617 if (asprintf(&filter
,
3618 "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
3620 dom_sid_str_buf(alias
, &tmp
),
3622 return NT_STATUS_NO_MEMORY
;
3625 if (ldapsam_search_one_group(ldap_state
, filter
,
3626 &result
) != LDAP_SUCCESS
) {
3628 return NT_STATUS_NO_SUCH_ALIAS
;
3631 count
= ldap_count_entries(smbldap_get_ldap(ldap_state
->smbldap_state
),
3635 DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
3636 ldap_msgfree(result
);
3638 return NT_STATUS_NO_SUCH_ALIAS
;
3642 DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for "
3643 "filter %s: count=%d\n", filter
, count
));
3644 ldap_msgfree(result
);
3646 return NT_STATUS_NO_SUCH_ALIAS
;
3651 entry
= ldap_first_entry(smbldap_get_ldap(ldap_state
->smbldap_state
),
3655 ldap_msgfree(result
);
3656 return NT_STATUS_UNSUCCESSFUL
;
3659 dn
= smbldap_talloc_dn(talloc_tos(),
3660 smbldap_get_ldap(ldap_state
->smbldap_state
),
3663 ldap_msgfree(result
);
3664 return NT_STATUS_UNSUCCESSFUL
;
3667 smbldap_set_mod(&mods
, modop
,
3668 get_attr_key2string(groupmap_attr_list
,
3669 LDAP_ATTR_SID_LIST
),
3670 dom_sid_str_buf(member
, &tmp
));
3672 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
3674 ldap_mods_free(mods
, True
);
3675 ldap_msgfree(result
);
3678 if (rc
== LDAP_TYPE_OR_VALUE_EXISTS
) {
3679 return NT_STATUS_MEMBER_IN_ALIAS
;
3682 if (rc
== LDAP_NO_SUCH_ATTRIBUTE
) {
3683 return NT_STATUS_MEMBER_NOT_IN_ALIAS
;
3686 if (rc
!= LDAP_SUCCESS
) {
3687 return NT_STATUS_UNSUCCESSFUL
;
3690 return NT_STATUS_OK
;
3693 static NTSTATUS
ldapsam_add_aliasmem(struct pdb_methods
*methods
,
3694 const struct dom_sid
*alias
,
3695 const struct dom_sid
*member
)
3697 return ldapsam_modify_aliasmem(methods
, alias
, member
, LDAP_MOD_ADD
);
3700 static NTSTATUS
ldapsam_del_aliasmem(struct pdb_methods
*methods
,
3701 const struct dom_sid
*alias
,
3702 const struct dom_sid
*member
)
3704 return ldapsam_modify_aliasmem(methods
, alias
, member
,
3708 static NTSTATUS
ldapsam_enum_aliasmem(struct pdb_methods
*methods
,
3709 const struct dom_sid
*alias
,
3710 TALLOC_CTX
*mem_ctx
,
3711 struct dom_sid
**pp_members
,
3712 size_t *p_num_members
)
3714 struct ldapsam_privates
*ldap_state
=
3715 (struct ldapsam_privates
*)methods
->private_data
;
3716 LDAPMessage
*result
= NULL
;
3717 LDAPMessage
*entry
= NULL
;
3719 char **values
= NULL
;
3721 char *filter
= NULL
;
3722 uint32_t num_members
= 0;
3723 enum lsa_SidType type
= SID_NAME_USE_NONE
;
3724 struct dom_sid_buf tmp
;
3729 if (sid_check_is_in_builtin(alias
)) {
3730 type
= SID_NAME_ALIAS
;
3733 if (sid_check_is_in_our_sam(alias
)) {
3734 type
= SID_NAME_ALIAS
;
3737 if (type
== SID_NAME_USE_NONE
) {
3738 DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
3739 dom_sid_str_buf(alias
, &tmp
)));
3740 return NT_STATUS_NO_SUCH_ALIAS
;
3743 if (asprintf(&filter
,
3744 "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
3746 dom_sid_str_buf(alias
, &tmp
),
3748 return NT_STATUS_NO_MEMORY
;
3751 if (ldapsam_search_one_group(ldap_state
, filter
,
3752 &result
) != LDAP_SUCCESS
) {
3754 return NT_STATUS_NO_SUCH_ALIAS
;
3757 count
= ldap_count_entries(smbldap_get_ldap(ldap_state
->smbldap_state
),
3761 DEBUG(4, ("ldapsam_enum_aliasmem: Did not find alias\n"));
3762 ldap_msgfree(result
);
3764 return NT_STATUS_NO_SUCH_ALIAS
;
3768 DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for "
3769 "filter %s: count=%d\n", filter
, count
));
3770 ldap_msgfree(result
);
3772 return NT_STATUS_NO_SUCH_ALIAS
;
3777 entry
= ldap_first_entry(smbldap_get_ldap(ldap_state
->smbldap_state
),
3781 ldap_msgfree(result
);
3782 return NT_STATUS_UNSUCCESSFUL
;
3785 values
= ldap_get_values(smbldap_get_ldap(ldap_state
->smbldap_state
),
3787 get_attr_key2string(groupmap_attr_list
,
3788 LDAP_ATTR_SID_LIST
));
3790 if (values
== NULL
) {
3791 ldap_msgfree(result
);
3792 return NT_STATUS_OK
;
3795 count
= ldap_count_values(values
);
3797 for (i
=0; i
<count
; i
++) {
3798 struct dom_sid member
;
3801 if (!string_to_sid(&member
, values
[i
]))
3804 status
= add_sid_to_array(mem_ctx
, &member
, pp_members
,
3806 if (!NT_STATUS_IS_OK(status
)) {
3807 ldap_value_free(values
);
3808 ldap_msgfree(result
);
3813 *p_num_members
= num_members
;
3814 ldap_value_free(values
);
3815 ldap_msgfree(result
);
3817 return NT_STATUS_OK
;
3820 static NTSTATUS
ldapsam_alias_memberships(struct pdb_methods
*methods
,
3821 TALLOC_CTX
*mem_ctx
,
3822 const struct dom_sid
*domain_sid
,
3823 const struct dom_sid
*members
,
3825 uint32_t **pp_alias_rids
,
3826 size_t *p_num_alias_rids
)
3828 struct ldapsam_privates
*ldap_state
=
3829 (struct ldapsam_privates
*)methods
->private_data
;
3832 const char *attrs
[] = { LDAP_ATTRIBUTE_SID
, NULL
};
3834 LDAPMessage
*result
= NULL
;
3835 LDAPMessage
*entry
= NULL
;
3839 enum lsa_SidType type
= SID_NAME_USE_NONE
;
3840 bool is_builtin
= false;
3841 bool sid_added
= false;
3843 *pp_alias_rids
= NULL
;
3844 *p_num_alias_rids
= 0;
3846 if (sid_check_is_builtin(domain_sid
)) {
3848 type
= SID_NAME_ALIAS
;
3851 if (sid_check_is_our_sam(domain_sid
)) {
3852 type
= SID_NAME_ALIAS
;
3855 if (type
== SID_NAME_USE_NONE
) {
3856 struct dom_sid_buf buf
;
3857 DEBUG(5, ("SID %s is neither builtin nor domain!\n",
3858 dom_sid_str_buf(domain_sid
, &buf
)));
3859 return NT_STATUS_UNSUCCESSFUL
;
3862 if (num_members
== 0) {
3863 return NT_STATUS_OK
;
3866 filter
= talloc_asprintf(mem_ctx
,
3867 "(&(objectclass="LDAP_OBJ_GROUPMAP
")(sambaGroupType=%d)(|",
3870 for (i
=0; i
<num_members
; i
++) {
3871 struct dom_sid_buf buf
;
3872 filter
= talloc_asprintf(mem_ctx
, "%s(sambaSIDList=%s)",
3874 dom_sid_str_buf(&members
[i
], &buf
));
3877 filter
= talloc_asprintf(mem_ctx
, "%s))", filter
);
3879 if (filter
== NULL
) {
3880 return NT_STATUS_NO_MEMORY
;
3884 ldap_state
->search_cache
.filter
&&
3885 strcmp(ldap_state
->search_cache
.filter
, filter
) == 0) {
3886 filter
= talloc_move(filter
, &ldap_state
->search_cache
.filter
);
3887 result
= ldap_state
->search_cache
.result
;
3888 ldap_state
->search_cache
.result
= NULL
;
3890 rc
= smbldap_search(ldap_state
->smbldap_state
, lp_ldap_suffix(),
3891 LDAP_SCOPE_SUBTREE
, filter
, attrs
, 0, &result
);
3892 if (rc
!= LDAP_SUCCESS
) {
3893 return NT_STATUS_UNSUCCESSFUL
;
3895 smbldap_talloc_autofree_ldapmsg(filter
, result
);
3898 ldap_struct
= smbldap_get_ldap(ldap_state
->smbldap_state
);
3900 for (entry
= ldap_first_entry(ldap_struct
, result
);
3902 entry
= ldap_next_entry(ldap_struct
, entry
))
3908 if (!smbldap_get_single_attribute(ldap_struct
, entry
,
3914 if (!string_to_sid(&sid
, sid_str
))
3917 if (!sid_peek_check_rid(domain_sid
, &sid
, &rid
))
3922 if (!add_rid_to_array_unique(mem_ctx
, rid
, pp_alias_rids
,
3923 p_num_alias_rids
)) {
3924 return NT_STATUS_NO_MEMORY
;
3928 if (!is_builtin
&& !sid_added
) {
3929 TALLOC_FREE(ldap_state
->search_cache
.filter
);
3931 * Note: result is a talloc child of filter because of the
3932 * smbldap_talloc_autofree_ldapmsg() usage
3934 ldap_state
->search_cache
.filter
= talloc_move(ldap_state
, &filter
);
3935 ldap_state
->search_cache
.result
= result
;
3938 return NT_STATUS_OK
;
3941 static NTSTATUS
ldapsam_set_account_policy_in_ldap(struct pdb_methods
*methods
,
3942 enum pdb_policy_type type
,
3945 NTSTATUS ntstatus
= NT_STATUS_UNSUCCESSFUL
;
3947 LDAPMod
**mods
= NULL
;
3948 fstring value_string
;
3949 const char *policy_attr
= NULL
;
3951 struct ldapsam_privates
*ldap_state
=
3952 (struct ldapsam_privates
*)methods
->private_data
;
3954 DEBUG(10,("ldapsam_set_account_policy_in_ldap\n"));
3956 if (!ldap_state
->domain_dn
) {
3957 return NT_STATUS_INVALID_PARAMETER
;
3960 policy_attr
= get_account_policy_attr(type
);
3961 if (policy_attr
== NULL
) {
3962 DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid "
3967 slprintf(value_string
, sizeof(value_string
) - 1, "%i", value
);
3969 smbldap_set_mod(&mods
, LDAP_MOD_REPLACE
, policy_attr
, value_string
);
3971 rc
= smbldap_modify(ldap_state
->smbldap_state
, ldap_state
->domain_dn
,
3974 ldap_mods_free(mods
, True
);
3976 if (rc
!= LDAP_SUCCESS
) {
3980 if (!cache_account_policy_set(type
, value
)) {
3981 DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to "
3982 "update local tdb cache\n"));
3986 return NT_STATUS_OK
;
3989 static NTSTATUS
ldapsam_set_account_policy(struct pdb_methods
*methods
,
3990 enum pdb_policy_type type
,
3993 return ldapsam_set_account_policy_in_ldap(methods
, type
,
3997 static NTSTATUS
ldapsam_get_account_policy_from_ldap(struct pdb_methods
*methods
,
3998 enum pdb_policy_type type
,
4001 NTSTATUS ntstatus
= NT_STATUS_UNSUCCESSFUL
;
4002 LDAPMessage
*result
= NULL
;
4003 LDAPMessage
*entry
= NULL
;
4008 const char *policy_attr
= NULL
;
4010 struct ldapsam_privates
*ldap_state
=
4011 (struct ldapsam_privates
*)methods
->private_data
;
4013 const char *attrs
[2];
4015 DEBUG(10,("ldapsam_get_account_policy_from_ldap\n"));
4017 if (!ldap_state
->domain_dn
) {
4018 return NT_STATUS_INVALID_PARAMETER
;
4021 policy_attr
= get_account_policy_attr(type
);
4023 DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid "
4024 "policy index: %d\n", type
));
4028 attrs
[0] = policy_attr
;
4031 filter
= "(objectClass="LDAP_OBJ_DOMINFO
")";
4032 rc
= smbldap_search(ldap_state
->smbldap_state
, ldap_state
->domain_dn
,
4033 LDAP_SCOPE_BASE
, filter
, attrs
, 0,
4035 if (rc
!= LDAP_SUCCESS
) {
4039 count
= ldap_count_entries(priv2ld(ldap_state
), result
);
4044 entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
4045 if (entry
== NULL
) {
4049 vals
= ldap_get_values(priv2ld(ldap_state
), entry
, policy_attr
);
4054 *value
= (uint32_t)atol(vals
[0]);
4056 ntstatus
= NT_STATUS_OK
;
4060 ldap_value_free(vals
);
4061 ldap_msgfree(result
);
4066 /* wrapper around ldapsam_get_account_policy_from_ldap(), handles tdb as cache
4068 - if user hasn't decided to use account policies inside LDAP just reuse the
4071 - if there is a valid cache entry, return that
4072 - if there is an LDAP entry, update cache and return
4073 - otherwise set to default, update cache and return
4077 static NTSTATUS
ldapsam_get_account_policy(struct pdb_methods
*methods
,
4078 enum pdb_policy_type type
,
4083 if (cache_account_policy_get(type
, value
)) {
4084 DEBUG(11,("ldapsam_get_account_policy: got valid value from "
4086 return NT_STATUS_OK
;
4089 ntstatus
= ldapsam_get_account_policy_from_ldap(methods
, type
,
4091 if (NT_STATUS_IS_OK(ntstatus
)) {
4095 DEBUG(10,("ldapsam_get_account_policy: failed to retrieve from "
4099 /* should we automagically migrate old tdb value here ? */
4100 if (account_policy_get(type
, value
))
4103 DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying "
4104 "default\n", type
));
4107 if (!account_policy_get_default(type
, value
)) {
4113 ntstatus
= ldapsam_set_account_policy(methods
, type
, *value
);
4114 if (!NT_STATUS_IS_OK(ntstatus
)) {
4120 if (!cache_account_policy_set(type
, *value
)) {
4121 DEBUG(0,("ldapsam_get_account_policy: failed to update local "
4122 "tdb as a cache\n"));
4123 return NT_STATUS_UNSUCCESSFUL
;
4126 return NT_STATUS_OK
;
4129 static NTSTATUS
ldapsam_lookup_rids(struct pdb_methods
*methods
,
4130 const struct dom_sid
*domain_sid
,
4134 enum lsa_SidType
*attrs
)
4136 struct ldapsam_privates
*ldap_state
=
4137 (struct ldapsam_privates
*)methods
->private_data
;
4138 LDAPMessage
*msg
= NULL
;
4140 char *allsids
= NULL
;
4141 size_t i
, num_mapped
;
4143 NTSTATUS result
= NT_STATUS_NO_MEMORY
;
4144 TALLOC_CTX
*mem_ctx
;
4148 mem_ctx
= talloc_new(NULL
);
4149 if (mem_ctx
== NULL
) {
4150 DEBUG(0, ("talloc_new failed\n"));
4154 if (!sid_check_is_builtin(domain_sid
) &&
4155 !sid_check_is_our_sam(domain_sid
)) {
4156 result
= NT_STATUS_INVALID_PARAMETER
;
4160 if (num_rids
== 0) {
4161 result
= NT_STATUS_NONE_MAPPED
;
4165 for (i
=0; i
<num_rids
; i
++)
4166 attrs
[i
] = SID_NAME_UNKNOWN
;
4168 allsids
= talloc_strdup(mem_ctx
, "");
4169 if (allsids
== NULL
) {
4173 for (i
=0; i
<num_rids
; i
++) {
4175 struct dom_sid_buf buf
;
4176 sid_compose(&sid
, domain_sid
, rids
[i
]);
4177 allsids
= talloc_asprintf_append_buffer(
4180 dom_sid_str_buf(&sid
, &buf
));
4181 if (allsids
== NULL
) {
4186 /* First look for users */
4190 const char *ldap_attrs
[] = { "uid", "sambaSid", NULL
};
4192 filter
= talloc_asprintf(
4193 mem_ctx
, ("(&(objectClass="LDAP_OBJ_SAMBASAMACCOUNT
")(|%s))"),
4196 if (filter
== NULL
) {
4200 rc
= smbldap_search(ldap_state
->smbldap_state
,
4201 lp_ldap_user_suffix(talloc_tos()),
4202 LDAP_SCOPE_SUBTREE
, filter
, ldap_attrs
, 0,
4204 smbldap_talloc_autofree_ldapmsg(mem_ctx
, msg
);
4207 if (rc
!= LDAP_SUCCESS
)
4210 ld
= smbldap_get_ldap(ldap_state
->smbldap_state
);
4213 for (entry
= ldap_first_entry(ld
, msg
);
4215 entry
= ldap_next_entry(ld
, entry
)) {
4220 if (!ldapsam_extract_rid_from_entry(ld
, entry
, domain_sid
,
4222 DEBUG(2, ("Could not find sid from ldap entry\n"));
4226 name
= smbldap_talloc_single_attribute(ld
, entry
, "uid",
4229 DEBUG(2, ("Could not retrieve uid attribute\n"));
4233 for (rid_index
= 0; rid_index
< num_rids
; rid_index
++) {
4234 if (rid
== rids
[rid_index
])
4238 if (rid_index
== num_rids
) {
4239 DEBUG(2, ("Got a RID not asked for: %d\n", rid
));
4243 attrs
[rid_index
] = SID_NAME_USER
;
4244 names
[rid_index
] = name
;
4248 if (num_mapped
== num_rids
) {
4249 /* No need to look for groups anymore -- we're done */
4250 result
= NT_STATUS_OK
;
4254 /* Same game for groups */
4258 const char *ldap_attrs
[] = { "cn", "displayName", "sambaSid",
4259 "sambaGroupType", NULL
};
4261 filter
= talloc_asprintf(
4262 mem_ctx
, "(&(objectClass="LDAP_OBJ_GROUPMAP
")(|%s))",
4264 if (filter
== NULL
) {
4268 rc
= smbldap_search(ldap_state
->smbldap_state
,
4270 LDAP_SCOPE_SUBTREE
, filter
, ldap_attrs
, 0,
4272 smbldap_talloc_autofree_ldapmsg(mem_ctx
, msg
);
4275 if (rc
!= LDAP_SUCCESS
)
4278 /* ldap_struct might have changed due to a reconnect */
4280 ld
= smbldap_get_ldap(ldap_state
->smbldap_state
);
4282 /* For consistency checks, we already checked we're only domain or builtin */
4284 is_builtin
= sid_check_is_builtin(domain_sid
);
4286 for (entry
= ldap_first_entry(ld
, msg
);
4288 entry
= ldap_next_entry(ld
, entry
))
4293 enum lsa_SidType type
;
4294 const char *dn
= smbldap_talloc_dn(mem_ctx
, ld
, entry
);
4296 attr
= smbldap_talloc_single_attribute(ld
, entry
, "sambaGroupType",
4299 DEBUG(2, ("Could not extract type from ldap entry %s\n",
4304 type
= (enum lsa_SidType
)atol(attr
);
4306 /* Consistency checks */
4307 if ((is_builtin
&& (type
!= SID_NAME_ALIAS
)) ||
4308 (!is_builtin
&& ((type
!= SID_NAME_ALIAS
) &&
4309 (type
!= SID_NAME_DOM_GRP
)))) {
4310 DEBUG(2, ("Rejecting invalid group mapping entry %s\n", dn
));
4313 if (!ldapsam_extract_rid_from_entry(ld
, entry
, domain_sid
,
4315 DEBUG(2, ("Could not find sid from ldap entry %s\n", dn
));
4319 attr
= smbldap_talloc_single_attribute(ld
, entry
, "displayName", names
);
4322 DEBUG(10, ("Could not retrieve 'displayName' attribute from %s\n",
4324 attr
= smbldap_talloc_single_attribute(ld
, entry
, "cn", names
);
4328 DEBUG(2, ("Could not retrieve naming attribute from %s\n",
4333 for (rid_index
= 0; rid_index
< num_rids
; rid_index
++) {
4334 if (rid
== rids
[rid_index
])
4338 if (rid_index
== num_rids
) {
4339 DEBUG(2, ("Got a RID not asked for: %d\n", rid
));
4343 attrs
[rid_index
] = type
;
4344 names
[rid_index
] = attr
;
4348 result
= NT_STATUS_NONE_MAPPED
;
4351 result
= (num_mapped
== num_rids
) ?
4352 NT_STATUS_OK
: STATUS_SOME_UNMAPPED
;
4354 TALLOC_FREE(mem_ctx
);
4358 static char *get_ldap_filter(TALLOC_CTX
*mem_ctx
, const char *username
)
4360 char *filter
= NULL
;
4361 char *escaped
= NULL
;
4362 char *result
= NULL
;
4364 if (asprintf(&filter
, "(&%s(objectclass=%s))",
4365 "(uid=%u)", LDAP_OBJ_SAMBASAMACCOUNT
) < 0) {
4369 escaped
= escape_ldap_string(talloc_tos(), username
);
4370 if (escaped
== NULL
) goto done
;
4372 result
= talloc_string_sub(mem_ctx
, filter
, "%u", username
);
4376 TALLOC_FREE(escaped
);
4381 static const char **talloc_attrs(TALLOC_CTX
*mem_ctx
, ...)
4385 const char **result
;
4387 va_start(ap
, mem_ctx
);
4388 while (va_arg(ap
, const char *) != NULL
)
4392 if ((result
= talloc_array(mem_ctx
, const char *, num
+1)) == NULL
) {
4396 va_start(ap
, mem_ctx
);
4397 for (i
=0; i
<num
; i
++) {
4398 result
[i
] = talloc_strdup(result
, va_arg(ap
, const char*));
4399 if (result
[i
] == NULL
) {
4400 talloc_free(result
);
4411 struct ldap_search_state
{
4412 struct smbldap_state
*connection
;
4414 uint32_t acct_flags
;
4415 uint16_t group_type
;
4422 void *pagedresults_cookie
;
4424 LDAPMessage
*entries
, *current_entry
;
4425 bool (*ldap2displayentry
)(struct ldap_search_state
*state
,
4426 TALLOC_CTX
*mem_ctx
,
4427 LDAP
*ld
, LDAPMessage
*entry
,
4428 struct samr_displayentry
*result
);
4431 static bool ldapsam_search_firstpage(struct pdb_search
*search
)
4433 struct ldap_search_state
*state
=
4434 (struct ldap_search_state
*)search
->private_data
;
4436 int rc
= LDAP_OPERATIONS_ERROR
;
4438 state
->entries
= NULL
;
4440 if (smbldap_get_paged_results(state
->connection
)) {
4441 rc
= smbldap_search_paged(state
->connection
, state
->base
,
4442 state
->scope
, state
->filter
,
4443 state
->attrs
, state
->attrsonly
,
4444 lp_ldap_page_size(), &state
->entries
,
4445 &state
->pagedresults_cookie
);
4448 if ((rc
!= LDAP_SUCCESS
) || (state
->entries
== NULL
)) {
4450 if (state
->entries
!= NULL
) {
4451 /* Left over from unsuccessful paged attempt */
4452 ldap_msgfree(state
->entries
);
4453 state
->entries
= NULL
;
4456 rc
= smbldap_search(state
->connection
, state
->base
,
4457 state
->scope
, state
->filter
, state
->attrs
,
4458 state
->attrsonly
, &state
->entries
);
4460 if ((rc
!= LDAP_SUCCESS
) || (state
->entries
== NULL
))
4463 /* Ok, the server was lying. It told us it could do paged
4464 * searches when it could not. */
4465 smbldap_set_paged_results(state
->connection
, false);
4468 ld
= smbldap_get_ldap(state
->connection
);
4470 DEBUG(5, ("Don't have an LDAP connection right after a "
4474 state
->current_entry
= ldap_first_entry(ld
, state
->entries
);
4479 static bool ldapsam_search_nextpage(struct pdb_search
*search
)
4481 struct ldap_search_state
*state
=
4482 (struct ldap_search_state
*)search
->private_data
;
4485 if (!smbldap_get_paged_results(state
->connection
)) {
4486 /* There is no next page when there are no paged results */
4490 rc
= smbldap_search_paged(state
->connection
, state
->base
,
4491 state
->scope
, state
->filter
, state
->attrs
,
4492 state
->attrsonly
, lp_ldap_page_size(),
4494 &state
->pagedresults_cookie
);
4496 if ((rc
!= LDAP_SUCCESS
) || (state
->entries
== NULL
))
4499 state
->current_entry
= ldap_first_entry(
4500 smbldap_get_ldap(state
->connection
), state
->entries
);
4502 if (state
->current_entry
== NULL
) {
4503 ldap_msgfree(state
->entries
);
4504 state
->entries
= NULL
;
4511 static bool ldapsam_search_next_entry(struct pdb_search
*search
,
4512 struct samr_displayentry
*entry
)
4514 struct ldap_search_state
*state
=
4515 (struct ldap_search_state
*)search
->private_data
;
4519 if ((state
->entries
== NULL
) && (state
->pagedresults_cookie
== NULL
))
4522 if ((state
->entries
== NULL
) &&
4523 !ldapsam_search_nextpage(search
))
4526 if (state
->current_entry
== NULL
) {
4530 result
= state
->ldap2displayentry(state
, search
,
4531 smbldap_get_ldap(state
->connection
),
4532 state
->current_entry
, entry
);
4536 dn
= ldap_get_dn(smbldap_get_ldap(state
->connection
),
4537 state
->current_entry
);
4538 DEBUG(5, ("Skipping entry %s\n", dn
!= NULL
? dn
: "<NULL>"));
4539 if (dn
!= NULL
) ldap_memfree(dn
);
4542 state
->current_entry
= ldap_next_entry(
4543 smbldap_get_ldap(state
->connection
), state
->current_entry
);
4545 if (state
->current_entry
== NULL
) {
4546 ldap_msgfree(state
->entries
);
4547 state
->entries
= NULL
;
4550 if (!result
) goto retry
;
4555 static void ldapsam_search_end(struct pdb_search
*search
)
4557 struct ldap_search_state
*state
=
4558 (struct ldap_search_state
*)search
->private_data
;
4561 if (state
->pagedresults_cookie
== NULL
)
4564 if (state
->entries
!= NULL
)
4565 ldap_msgfree(state
->entries
);
4567 state
->entries
= NULL
;
4568 state
->current_entry
= NULL
;
4570 if (!smbldap_get_paged_results(state
->connection
)) {
4574 /* Tell the LDAP server we're not interested in the rest anymore. */
4576 rc
= smbldap_search_paged(state
->connection
, state
->base
, state
->scope
,
4577 state
->filter
, state
->attrs
,
4578 state
->attrsonly
, 0, &state
->entries
,
4579 &state
->pagedresults_cookie
);
4581 if (rc
!= LDAP_SUCCESS
)
4582 DEBUG(5, ("Could not end search properly\n"));
4587 static bool ldapuser2displayentry(struct ldap_search_state
*state
,
4588 TALLOC_CTX
*mem_ctx
,
4589 LDAP
*ld
, LDAPMessage
*entry
,
4590 struct samr_displayentry
*result
)
4593 size_t converted_size
;
4595 uint32_t acct_flags
;
4597 vals
= ldap_get_values(ld
, entry
, "sambaAcctFlags");
4598 if ((vals
== NULL
) || (vals
[0] == NULL
)) {
4599 acct_flags
= ACB_NORMAL
;
4601 acct_flags
= pdb_decode_acct_ctrl(vals
[0]);
4602 ldap_value_free(vals
);
4605 if ((state
->acct_flags
!= 0) &&
4606 ((state
->acct_flags
& acct_flags
) == 0))
4609 result
->acct_flags
= acct_flags
;
4610 result
->account_name
= "";
4611 result
->fullname
= "";
4612 result
->description
= "";
4614 vals
= ldap_get_values(ld
, entry
, "uid");
4615 if ((vals
== NULL
) || (vals
[0] == NULL
)) {
4616 DEBUG(5, ("\"uid\" not found\n"));
4619 if (!pull_utf8_talloc(mem_ctx
,
4620 discard_const_p(char *, &result
->account_name
),
4621 vals
[0], &converted_size
))
4623 DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s\n",
4627 ldap_value_free(vals
);
4629 vals
= ldap_get_values(ld
, entry
, "displayName");
4630 if ((vals
== NULL
) || (vals
[0] == NULL
))
4631 DEBUG(8, ("\"displayName\" not found\n"));
4632 else if (!pull_utf8_talloc(mem_ctx
,
4633 discard_const_p(char *, &result
->fullname
),
4634 vals
[0], &converted_size
))
4636 DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s\n",
4640 ldap_value_free(vals
);
4642 vals
= ldap_get_values(ld
, entry
, "description");
4643 if ((vals
== NULL
) || (vals
[0] == NULL
))
4644 DEBUG(8, ("\"description\" not found\n"));
4645 else if (!pull_utf8_talloc(mem_ctx
,
4646 discard_const_p(char *, &result
->description
),
4647 vals
[0], &converted_size
))
4649 DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s\n",
4653 ldap_value_free(vals
);
4655 if ((result
->account_name
== NULL
) ||
4656 (result
->fullname
== NULL
) ||
4657 (result
->description
== NULL
)) {
4658 DEBUG(0, ("talloc failed\n"));
4662 vals
= ldap_get_values(ld
, entry
, "sambaSid");
4663 if ((vals
== NULL
) || (vals
[0] == NULL
)) {
4664 DEBUG(0, ("\"objectSid\" not found\n"));
4668 if (!string_to_sid(&sid
, vals
[0])) {
4669 DEBUG(0, ("Could not convert %s to SID\n", vals
[0]));
4670 ldap_value_free(vals
);
4673 ldap_value_free(vals
);
4675 if (!sid_peek_check_rid(get_global_sam_sid(), &sid
, &result
->rid
)) {
4676 struct dom_sid_buf buf
;
4677 DEBUG(0, ("sid %s does not belong to our domain\n",
4678 dom_sid_str_buf(&sid
, &buf
)));
4686 static bool ldapsam_search_users(struct pdb_methods
*methods
,
4687 struct pdb_search
*search
,
4688 uint32_t acct_flags
)
4690 struct ldapsam_privates
*ldap_state
=
4691 (struct ldapsam_privates
*)methods
->private_data
;
4692 struct ldap_search_state
*state
;
4694 state
= talloc(search
, struct ldap_search_state
);
4695 if (state
== NULL
) {
4696 DEBUG(0, ("talloc failed\n"));
4700 state
->connection
= ldap_state
->smbldap_state
;
4702 if ((acct_flags
!= 0) && ((acct_flags
& ACB_NORMAL
) != 0))
4703 state
->base
= lp_ldap_user_suffix(talloc_tos());
4704 else if ((acct_flags
!= 0) &&
4705 ((acct_flags
& (ACB_WSTRUST
|ACB_SVRTRUST
|ACB_DOMTRUST
)) != 0))
4706 state
->base
= lp_ldap_machine_suffix(talloc_tos());
4708 state
->base
= lp_ldap_suffix();
4710 state
->acct_flags
= acct_flags
;
4711 state
->base
= talloc_strdup(search
, state
->base
);
4712 state
->scope
= LDAP_SCOPE_SUBTREE
;
4713 state
->filter
= get_ldap_filter(search
, "*");
4714 state
->attrs
= talloc_attrs(search
, "uid", "sambaSid",
4715 "displayName", "description",
4716 "sambaAcctFlags", NULL
);
4717 state
->attrsonly
= 0;
4718 state
->pagedresults_cookie
= NULL
;
4719 state
->entries
= NULL
;
4720 state
->ldap2displayentry
= ldapuser2displayentry
;
4722 if ((state
->filter
== NULL
) || (state
->attrs
== NULL
)) {
4723 DEBUG(0, ("talloc failed\n"));
4727 search
->private_data
= state
;
4728 search
->next_entry
= ldapsam_search_next_entry
;
4729 search
->search_end
= ldapsam_search_end
;
4731 return ldapsam_search_firstpage(search
);
4734 static bool ldapgroup2displayentry(struct ldap_search_state
*state
,
4735 TALLOC_CTX
*mem_ctx
,
4736 LDAP
*ld
, LDAPMessage
*entry
,
4737 struct samr_displayentry
*result
)
4740 size_t converted_size
;
4742 uint16_t group_type
;
4744 result
->account_name
= "";
4745 result
->fullname
= "";
4746 result
->description
= "";
4749 vals
= ldap_get_values(ld
, entry
, "sambaGroupType");
4750 if ((vals
== NULL
) || (vals
[0] == NULL
)) {
4751 DEBUG(5, ("\"sambaGroupType\" not found\n"));
4753 ldap_value_free(vals
);
4758 group_type
= atoi(vals
[0]);
4760 if ((state
->group_type
!= 0) &&
4761 ((state
->group_type
!= group_type
))) {
4762 ldap_value_free(vals
);
4766 ldap_value_free(vals
);
4768 /* display name is the NT group name */
4770 vals
= ldap_get_values(ld
, entry
, "displayName");
4771 if ((vals
== NULL
) || (vals
[0] == NULL
)) {
4772 DEBUG(8, ("\"displayName\" not found\n"));
4774 /* fallback to the 'cn' attribute */
4775 vals
= ldap_get_values(ld
, entry
, "cn");
4776 if ((vals
== NULL
) || (vals
[0] == NULL
)) {
4777 DEBUG(5, ("\"cn\" not found\n"));
4780 if (!pull_utf8_talloc(mem_ctx
,
4781 discard_const_p(char *,
4782 &result
->account_name
),
4783 vals
[0], &converted_size
))
4785 DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc "
4786 "failed: %s\n", strerror(errno
)));
4789 else if (!pull_utf8_talloc(mem_ctx
,
4790 discard_const_p(char *,
4791 &result
->account_name
),
4792 vals
[0], &converted_size
))
4794 DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s\n",
4798 ldap_value_free(vals
);
4800 vals
= ldap_get_values(ld
, entry
, "description");
4801 if ((vals
== NULL
) || (vals
[0] == NULL
))
4802 DEBUG(8, ("\"description\" not found\n"));
4803 else if (!pull_utf8_talloc(mem_ctx
,
4804 discard_const_p(char *, &result
->description
),
4805 vals
[0], &converted_size
))
4807 DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s\n",
4810 ldap_value_free(vals
);
4812 if ((result
->account_name
== NULL
) ||
4813 (result
->fullname
== NULL
) ||
4814 (result
->description
== NULL
)) {
4815 DEBUG(0, ("talloc failed\n"));
4819 vals
= ldap_get_values(ld
, entry
, "sambaSid");
4820 if ((vals
== NULL
) || (vals
[0] == NULL
)) {
4821 DEBUG(0, ("\"objectSid\" not found\n"));
4823 ldap_value_free(vals
);
4828 if (!string_to_sid(&sid
, vals
[0])) {
4829 DEBUG(0, ("Could not convert %s to SID\n", vals
[0]));
4833 ldap_value_free(vals
);
4835 switch (group_type
) {
4836 case SID_NAME_DOM_GRP
:
4837 case SID_NAME_ALIAS
:
4839 if (!sid_peek_check_rid(get_global_sam_sid(), &sid
, &result
->rid
)
4840 && !sid_peek_check_rid(&global_sid_Builtin
, &sid
, &result
->rid
))
4842 struct dom_sid_buf buf
;
4843 DEBUG(0, ("%s is not in our domain\n",
4844 dom_sid_str_buf(&sid
, &buf
)));
4850 DEBUG(0,("unknown group type: %d\n", group_type
));
4854 result
->acct_flags
= 0;
4859 static bool ldapsam_search_grouptype(struct pdb_methods
*methods
,
4860 struct pdb_search
*search
,
4861 const struct dom_sid
*sid
,
4862 enum lsa_SidType type
)
4864 struct ldapsam_privates
*ldap_state
=
4865 (struct ldapsam_privates
*)methods
->private_data
;
4866 struct ldap_search_state
*state
;
4867 struct dom_sid_buf tmp
;
4869 state
= talloc(search
, struct ldap_search_state
);
4870 if (state
== NULL
) {
4871 DEBUG(0, ("talloc failed\n"));
4875 state
->connection
= ldap_state
->smbldap_state
;
4877 state
->base
= lp_ldap_suffix();
4878 state
->connection
= ldap_state
->smbldap_state
;
4879 state
->scope
= LDAP_SCOPE_SUBTREE
;
4880 state
->filter
= talloc_asprintf(search
, "(&(objectclass="LDAP_OBJ_GROUPMAP
")"
4881 "(sambaGroupType=%d)(sambaSID=%s*))",
4883 dom_sid_str_buf(sid
, &tmp
));
4884 state
->attrs
= talloc_attrs(search
, "cn", "sambaSid",
4885 "displayName", "description",
4886 "sambaGroupType", NULL
);
4887 state
->attrsonly
= 0;
4888 state
->pagedresults_cookie
= NULL
;
4889 state
->entries
= NULL
;
4890 state
->group_type
= type
;
4891 state
->ldap2displayentry
= ldapgroup2displayentry
;
4893 if ((state
->filter
== NULL
) || (state
->attrs
== NULL
)) {
4894 DEBUG(0, ("talloc failed\n"));
4898 search
->private_data
= state
;
4899 search
->next_entry
= ldapsam_search_next_entry
;
4900 search
->search_end
= ldapsam_search_end
;
4902 return ldapsam_search_firstpage(search
);
4905 static bool ldapsam_search_groups(struct pdb_methods
*methods
,
4906 struct pdb_search
*search
)
4908 return ldapsam_search_grouptype(methods
, search
, get_global_sam_sid(), SID_NAME_DOM_GRP
);
4911 static bool ldapsam_search_aliases(struct pdb_methods
*methods
,
4912 struct pdb_search
*search
,
4913 const struct dom_sid
*sid
)
4915 return ldapsam_search_grouptype(methods
, search
, sid
, SID_NAME_ALIAS
);
4918 static uint32_t ldapsam_capabilities(struct pdb_methods
*methods
)
4920 return PDB_CAP_STORE_RIDS
;
4923 static NTSTATUS
ldapsam_get_new_rid(struct ldapsam_privates
*priv
,
4926 struct smbldap_state
*smbldap_state
= priv
->smbldap_state
;
4928 LDAPMessage
*result
= NULL
;
4929 LDAPMessage
*entry
= NULL
;
4930 LDAPMod
**mods
= NULL
;
4934 uint32_t nextRid
= 0;
4939 TALLOC_CTX
*mem_ctx
;
4941 mem_ctx
= talloc_new(NULL
);
4942 if (mem_ctx
== NULL
) {
4943 DEBUG(0, ("talloc_new failed\n"));
4944 return NT_STATUS_NO_MEMORY
;
4947 status
= smbldap_search_domain_info(smbldap_state
, &result
,
4948 get_global_sam_name(), False
);
4949 if (!NT_STATUS_IS_OK(status
)) {
4950 DEBUG(3, ("Could not get domain info: %s\n",
4951 nt_errstr(status
)));
4955 smbldap_talloc_autofree_ldapmsg(mem_ctx
, result
);
4957 entry
= ldap_first_entry(priv2ld(priv
), result
);
4958 if (entry
== NULL
) {
4959 DEBUG(0, ("Could not get domain info entry\n"));
4960 status
= NT_STATUS_INTERNAL_DB_CORRUPTION
;
4964 /* Find the largest of the three attributes "sambaNextRid",
4965 "sambaNextGroupRid" and "sambaNextUserRid". I gave up on the
4966 concept of differentiating between user and group rids, and will
4967 use only "sambaNextRid" in the future. But for compatibility
4968 reasons I look if others have chosen different strategies -- VL */
4970 value
= smbldap_talloc_single_attribute(priv2ld(priv
), entry
,
4971 "sambaNextRid", mem_ctx
);
4972 if (value
!= NULL
) {
4973 tmp
= (uint32_t)smb_strtoul(value
,
4982 nextRid
= MAX(nextRid
, tmp
);
4985 value
= smbldap_talloc_single_attribute(priv2ld(priv
), entry
,
4986 "sambaNextUserRid", mem_ctx
);
4987 if (value
!= NULL
) {
4988 tmp
= (uint32_t)smb_strtoul(value
,
4997 nextRid
= MAX(nextRid
, tmp
);
5000 value
= smbldap_talloc_single_attribute(priv2ld(priv
), entry
,
5001 "sambaNextGroupRid", mem_ctx
);
5002 if (value
!= NULL
) {
5003 tmp
= (uint32_t)smb_strtoul(value
,
5012 nextRid
= MAX(nextRid
, tmp
);
5016 nextRid
= BASE_RID
-1;
5021 smbldap_make_mod(priv2ld(priv
), entry
, &mods
, "sambaNextRid",
5022 talloc_asprintf(mem_ctx
, "%d", nextRid
));
5023 smbldap_talloc_autofree_ldapmod(mem_ctx
, mods
);
5025 if ((dn
= smbldap_talloc_dn(mem_ctx
, priv2ld(priv
), entry
)) == NULL
) {
5026 status
= NT_STATUS_NO_MEMORY
;
5030 rc
= smbldap_modify(smbldap_state
, dn
, mods
);
5032 /* ACCESS_DENIED is used as a placeholder for "the modify failed,
5035 status
= (rc
== LDAP_SUCCESS
) ? NT_STATUS_OK
: NT_STATUS_ACCESS_DENIED
;
5038 if (NT_STATUS_IS_OK(status
)) {
5042 TALLOC_FREE(mem_ctx
);
5046 static NTSTATUS
ldapsam_new_rid_internal(struct pdb_methods
*methods
, uint32_t *rid
)
5050 for (i
=0; i
<10; i
++) {
5051 NTSTATUS result
= ldapsam_get_new_rid(
5052 (struct ldapsam_privates
*)methods
->private_data
, rid
);
5053 if (NT_STATUS_IS_OK(result
)) {
5057 if (!NT_STATUS_EQUAL(result
, NT_STATUS_ACCESS_DENIED
)) {
5061 /* The ldap update failed (maybe a race condition), retry */
5064 /* Tried 10 times, fail. */
5065 return NT_STATUS_ACCESS_DENIED
;
5068 static bool ldapsam_new_rid(struct pdb_methods
*methods
, uint32_t *rid
)
5070 NTSTATUS result
= ldapsam_new_rid_internal(methods
, rid
);
5071 return NT_STATUS_IS_OK(result
) ? True
: False
;
5074 static bool ldapsam_sid_to_id(struct pdb_methods
*methods
,
5075 const struct dom_sid
*sid
,
5078 struct ldapsam_privates
*priv
=
5079 (struct ldapsam_privates
*)methods
->private_data
;
5082 struct dom_sid_buf buf
;
5083 const char *attrs
[] = { "sambaGroupType", "gidNumber", "uidNumber",
5085 LDAPMessage
*result
= NULL
;
5086 LDAPMessage
*entry
= NULL
;
5091 TALLOC_CTX
*mem_ctx
;
5093 ret
= pdb_sid_to_id_unix_users_and_groups(sid
, id
);
5098 mem_ctx
= talloc_new(NULL
);
5099 if (mem_ctx
== NULL
) {
5100 DEBUG(0, ("talloc_new failed\n"));
5104 filter
= talloc_asprintf(mem_ctx
,
5106 "(|(objectClass="LDAP_OBJ_GROUPMAP
")(objectClass="LDAP_OBJ_SAMBASAMACCOUNT
")))",
5107 dom_sid_str_buf(sid
, &buf
));
5108 if (filter
== NULL
) {
5109 DEBUG(5, ("talloc_asprintf failed\n"));
5113 rc
= smbldap_search_suffix(priv
->smbldap_state
, filter
,
5115 if (rc
!= LDAP_SUCCESS
) {
5118 smbldap_talloc_autofree_ldapmsg(mem_ctx
, result
);
5120 if (ldap_count_entries(priv2ld(priv
), result
) != 1) {
5121 DEBUG(10, ("Got %d entries, expected one\n",
5122 ldap_count_entries(priv2ld(priv
), result
)));
5126 entry
= ldap_first_entry(priv2ld(priv
), result
);
5128 value
= smbldap_talloc_single_attribute(priv2ld(priv
), entry
,
5129 "sambaGroupType", mem_ctx
);
5131 if (value
!= NULL
) {
5132 const char *gid_str
;
5135 gid_str
= smbldap_talloc_single_attribute(
5136 priv2ld(priv
), entry
, "gidNumber", mem_ctx
);
5137 if (gid_str
== NULL
) {
5138 DEBUG(1, ("%s has sambaGroupType but no gidNumber\n",
5139 smbldap_talloc_dn(mem_ctx
, priv2ld(priv
),
5144 id
->id
= smb_strtoul(gid_str
,
5153 id
->type
= ID_TYPE_GID
;
5158 /* It must be a user */
5160 value
= smbldap_talloc_single_attribute(priv2ld(priv
), entry
,
5161 "uidNumber", mem_ctx
);
5162 if (value
== NULL
) {
5163 DEBUG(1, ("Could not find uidNumber in %s\n",
5164 smbldap_talloc_dn(mem_ctx
, priv2ld(priv
), entry
)));
5168 id
->id
= smb_strtoul(value
, NULL
, 10, &error
, SMB_STR_STANDARD
);
5173 id
->type
= ID_TYPE_UID
;
5176 TALLOC_FREE(mem_ctx
);
5181 * Find the SID for a uid.
5182 * This is shortcut is only used if ldapsam:trusted is set to true.
5184 static bool ldapsam_uid_to_sid(struct pdb_methods
*methods
, uid_t uid
,
5185 struct dom_sid
*sid
)
5187 struct ldapsam_privates
*priv
=
5188 (struct ldapsam_privates
*)methods
->private_data
;
5190 const char *attrs
[] = { "sambaSID", NULL
};
5191 LDAPMessage
*result
= NULL
;
5192 LDAPMessage
*entry
= NULL
;
5194 char *user_sid_string
;
5195 struct dom_sid user_sid
;
5197 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
5199 filter
= talloc_asprintf(tmp_ctx
,
5201 "(objectClass="LDAP_OBJ_POSIXACCOUNT
")"
5202 "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT
"))",
5204 if (filter
== NULL
) {
5205 DEBUG(3, ("talloc_asprintf failed\n"));
5209 rc
= smbldap_search_suffix(priv
->smbldap_state
, filter
, attrs
, &result
);
5210 if (rc
!= LDAP_SUCCESS
) {
5213 smbldap_talloc_autofree_ldapmsg(tmp_ctx
, result
);
5215 if (ldap_count_entries(priv2ld(priv
), result
) != 1) {
5216 DEBUG(3, ("ERROR: Got %d entries for uid %u, expected one\n",
5217 ldap_count_entries(priv2ld(priv
), result
),
5218 (unsigned int)uid
));
5222 entry
= ldap_first_entry(priv2ld(priv
), result
);
5224 user_sid_string
= smbldap_talloc_single_attribute(priv2ld(priv
), entry
,
5225 "sambaSID", tmp_ctx
);
5226 if (user_sid_string
== NULL
) {
5227 DEBUG(1, ("Could not find sambaSID in object '%s'\n",
5228 smbldap_talloc_dn(tmp_ctx
, priv2ld(priv
), entry
)));
5232 if (!string_to_sid(&user_sid
, user_sid_string
)) {
5233 DEBUG(3, ("Error calling string_to_sid for sid '%s'\n",
5238 sid_copy(sid
, &user_sid
);
5243 TALLOC_FREE(tmp_ctx
);
5248 * Find the SID for a gid.
5249 * This is shortcut is only used if ldapsam:trusted is set to true.
5251 static bool ldapsam_gid_to_sid(struct pdb_methods
*methods
, gid_t gid
,
5252 struct dom_sid
*sid
)
5254 struct ldapsam_privates
*priv
=
5255 (struct ldapsam_privates
*)methods
->private_data
;
5257 const char *attrs
[] = { "sambaSID", NULL
};
5258 LDAPMessage
*result
= NULL
;
5259 LDAPMessage
*entry
= NULL
;
5261 char *group_sid_string
;
5262 struct dom_sid group_sid
;
5264 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
5266 filter
= talloc_asprintf(tmp_ctx
,
5268 "(objectClass="LDAP_OBJ_GROUPMAP
"))",
5270 if (filter
== NULL
) {
5271 DEBUG(3, ("talloc_asprintf failed\n"));
5275 rc
= smbldap_search_suffix(priv
->smbldap_state
, filter
, attrs
, &result
);
5276 if (rc
!= LDAP_SUCCESS
) {
5279 smbldap_talloc_autofree_ldapmsg(tmp_ctx
, result
);
5281 if (ldap_count_entries(priv2ld(priv
), result
) != 1) {
5282 DEBUG(3, ("ERROR: Got %d entries for gid %u, expected one\n",
5283 ldap_count_entries(priv2ld(priv
), result
),
5284 (unsigned int)gid
));
5288 entry
= ldap_first_entry(priv2ld(priv
), result
);
5290 group_sid_string
= smbldap_talloc_single_attribute(priv2ld(priv
), entry
,
5291 "sambaSID", tmp_ctx
);
5292 if (group_sid_string
== NULL
) {
5293 DEBUG(1, ("Could not find sambaSID in object '%s'\n",
5294 smbldap_talloc_dn(tmp_ctx
, priv2ld(priv
), entry
)));
5298 if (!string_to_sid(&group_sid
, group_sid_string
)) {
5299 DEBUG(3, ("Error calling string_to_sid for sid '%s'\n",
5304 sid_copy(sid
, &group_sid
);
5309 TALLOC_FREE(tmp_ctx
);
5313 static bool ldapsam_id_to_sid(struct pdb_methods
*methods
, struct unixid
*id
,
5314 struct dom_sid
*sid
)
5318 return ldapsam_uid_to_sid(methods
, id
->id
, sid
);
5321 return ldapsam_gid_to_sid(methods
, id
->id
, sid
);
5330 * The following functions are called only if
5331 * ldapsam:trusted and ldapsam:editposix are
5336 * ldapsam_create_user creates a new
5337 * posixAccount and sambaSamAccount object
5338 * in the ldap users subtree
5340 * The uid is allocated by winbindd.
5343 static NTSTATUS
ldapsam_create_user(struct pdb_methods
*my_methods
,
5344 TALLOC_CTX
*tmp_ctx
, const char *name
,
5345 uint32_t acb_info
, uint32_t *rid
)
5347 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
5348 LDAPMessage
*entry
= NULL
;
5349 LDAPMessage
*result
= NULL
;
5350 uint32_t num_result
;
5351 bool is_machine
= False
;
5352 bool add_posix
= False
;
5353 bool init_okay
= False
;
5354 LDAPMod
**mods
= NULL
;
5362 const char *dn
= NULL
;
5363 struct dom_sid group_sid
;
5364 struct dom_sid user_sid
;
5370 if (((acb_info
& ACB_NORMAL
) && name
[strlen(name
)-1] == '$') ||
5371 acb_info
& ACB_WSTRUST
||
5372 acb_info
& ACB_SVRTRUST
||
5373 acb_info
& ACB_DOMTRUST
) {
5377 username
= escape_ldap_string(talloc_tos(), name
);
5378 filter
= talloc_asprintf(tmp_ctx
, "(&(uid=%s)(objectClass="LDAP_OBJ_POSIXACCOUNT
"))",
5380 TALLOC_FREE(username
);
5382 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, NULL
, &result
);
5383 if (rc
!= LDAP_SUCCESS
) {
5384 DEBUG(0,("ldapsam_create_user: ldap search failed!\n"));
5385 return NT_STATUS_ACCESS_DENIED
;
5387 smbldap_talloc_autofree_ldapmsg(tmp_ctx
, result
);
5389 num_result
= ldap_count_entries(priv2ld(ldap_state
), result
);
5391 if (num_result
> 1) {
5392 DEBUG (0, ("ldapsam_create_user: More than one user with name [%s] ?!\n", name
));
5393 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
5396 if (num_result
== 1) {
5398 /* check if it is just a posix account.
5399 * or if there is a sid attached to this entry
5402 entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
5404 return NT_STATUS_UNSUCCESSFUL
;
5407 tmp
= smbldap_talloc_single_attribute(priv2ld(ldap_state
), entry
, "sambaSID", tmp_ctx
);
5409 DEBUG (1, ("ldapsam_create_user: The user [%s] already exist!\n", name
));
5410 return NT_STATUS_USER_EXISTS
;
5413 /* it is just a posix account, retrieve the dn for later use */
5414 dn
= smbldap_talloc_dn(tmp_ctx
, priv2ld(ldap_state
), entry
);
5416 DEBUG(0,("ldapsam_create_user: Out of memory!\n"));
5417 return NT_STATUS_NO_MEMORY
;
5421 if (num_result
== 0) {
5425 /* Create the basic samu structure and generate the mods for the ldap commit */
5426 if (!NT_STATUS_IS_OK((ret
= ldapsam_new_rid_internal(my_methods
, rid
)))) {
5427 DEBUG(1, ("ldapsam_create_user: Could not allocate a new RID\n"));
5431 sid_compose(&user_sid
, get_global_sam_sid(), *rid
);
5433 user
= samu_new(tmp_ctx
);
5435 DEBUG(1,("ldapsam_create_user: Unable to allocate user struct\n"));
5436 return NT_STATUS_NO_MEMORY
;
5439 if (!pdb_set_username(user
, name
, PDB_SET
)) {
5440 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5441 return NT_STATUS_UNSUCCESSFUL
;
5443 if (!pdb_set_domain(user
, get_global_sam_name(), PDB_SET
)) {
5444 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5445 return NT_STATUS_UNSUCCESSFUL
;
5448 if (acb_info
& ACB_NORMAL
) {
5449 if (!pdb_set_acct_ctrl(user
, ACB_WSTRUST
, PDB_SET
)) {
5450 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5451 return NT_STATUS_UNSUCCESSFUL
;
5454 if (!pdb_set_acct_ctrl(user
, acb_info
, PDB_SET
)) {
5455 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5456 return NT_STATUS_UNSUCCESSFUL
;
5460 if (!pdb_set_acct_ctrl(user
, ACB_NORMAL
| ACB_DISABLED
, PDB_SET
)) {
5461 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5462 return NT_STATUS_UNSUCCESSFUL
;
5466 if (!pdb_set_user_sid(user
, &user_sid
, PDB_SET
)) {
5467 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5468 return NT_STATUS_UNSUCCESSFUL
;
5471 init_okay
= init_ldap_from_sam(ldap_state
, entry
, &mods
, user
, pdb_element_is_set_or_changed
);
5474 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5475 ldap_mods_free(mods
, true);
5476 return NT_STATUS_UNSUCCESSFUL
;
5479 if (ldap_state
->schema_ver
!= SCHEMAVER_SAMBASAMACCOUNT
) {
5480 DEBUG(1,("ldapsam_create_user: Unsupported schema version\n"));
5482 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT
);
5487 DEBUG(3,("ldapsam_create_user: Creating new posix user\n"));
5489 /* retrieve the Domain Users group gid */
5490 if (!sid_compose(&group_sid
, get_global_sam_sid(), DOMAIN_RID_USERS
) ||
5491 !sid_to_gid(&group_sid
, &gid
)) {
5492 DEBUG (0, ("ldapsam_create_user: Unable to get the Domain Users gid: bailing out!\n"));
5493 ldap_mods_free(mods
, true);
5494 return NT_STATUS_INVALID_PRIMARY_GROUP
;
5497 /* lets allocate a new userid for this user */
5498 if (!winbind_allocate_uid(&uid
)) {
5499 DEBUG (0, ("ldapsam_create_user: Unable to allocate a new user id: bailing out!\n"));
5500 ldap_mods_free(mods
, true);
5501 return NT_STATUS_UNSUCCESSFUL
;
5506 /* TODO: choose a more appropriate default for machines */
5507 homedir
= talloc_sub_specified(tmp_ctx
,
5508 lp_template_homedir(),
5509 "SMB_workstations_home",
5511 ldap_state
->domain_name
,
5514 shell
= talloc_strdup(tmp_ctx
, "/bin/false");
5516 homedir
= talloc_sub_specified(tmp_ctx
,
5517 lp_template_homedir(),
5520 ldap_state
->domain_name
,
5523 shell
= talloc_sub_specified(tmp_ctx
,
5524 lp_template_shell(),
5527 ldap_state
->domain_name
,
5531 uidstr
= talloc_asprintf(tmp_ctx
, "%u", (unsigned int)uid
);
5532 gidstr
= talloc_asprintf(tmp_ctx
, "%u", (unsigned int)gid
);
5534 escape_name
= escape_rdn_val_string_alloc(name
);
5536 DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
5537 ldap_mods_free(mods
, true);
5538 return NT_STATUS_NO_MEMORY
;
5542 dn
= talloc_asprintf(tmp_ctx
, "uid=%s,%s", escape_name
, lp_ldap_machine_suffix (talloc_tos()));
5544 dn
= talloc_asprintf(tmp_ctx
, "uid=%s,%s", escape_name
, lp_ldap_user_suffix (talloc_tos()));
5547 SAFE_FREE(escape_name
);
5549 if (!homedir
|| !shell
|| !uidstr
|| !gidstr
|| !dn
) {
5550 DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
5551 ldap_mods_free(mods
, true);
5552 return NT_STATUS_NO_MEMORY
;
5555 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_ACCOUNT
);
5556 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_POSIXACCOUNT
);
5557 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "cn", name
);
5558 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "uidNumber", uidstr
);
5559 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "gidNumber", gidstr
);
5560 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "homeDirectory", homedir
);
5561 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "loginShell", shell
);
5565 rc
= smbldap_add(ldap_state
->smbldap_state
, dn
, mods
);
5567 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
5570 ldap_mods_free(mods
, true);
5572 if (rc
!= LDAP_SUCCESS
) {
5573 DEBUG(0,("ldapsam_create_user: failed to create a new user [%s] (dn = %s)\n", name
,dn
));
5574 return NT_STATUS_UNSUCCESSFUL
;
5577 DEBUG(2,("ldapsam_create_user: added account [%s] in the LDAP database\n", name
));
5579 flush_pwnam_cache();
5581 return NT_STATUS_OK
;
5584 static NTSTATUS
ldapsam_delete_user(struct pdb_methods
*my_methods
, TALLOC_CTX
*tmp_ctx
, struct samu
*sam_acct
)
5586 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
5587 LDAPMessage
*result
= NULL
;
5588 LDAPMessage
*entry
= NULL
;
5594 DEBUG(0,("ldapsam_delete_user: Attempt to delete user [%s]\n", pdb_get_username(sam_acct
)));
5596 filter
= talloc_asprintf(tmp_ctx
,
5598 "(objectClass="LDAP_OBJ_POSIXACCOUNT
")"
5599 "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT
"))",
5600 pdb_get_username(sam_acct
));
5601 if (filter
== NULL
) {
5602 return NT_STATUS_NO_MEMORY
;
5605 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, NULL
, &result
);
5606 if (rc
!= LDAP_SUCCESS
) {
5607 DEBUG(0,("ldapsam_delete_user: user search failed!\n"));
5608 return NT_STATUS_UNSUCCESSFUL
;
5610 smbldap_talloc_autofree_ldapmsg(tmp_ctx
, result
);
5612 num_result
= ldap_count_entries(priv2ld(ldap_state
), result
);
5614 if (num_result
== 0) {
5615 DEBUG(0,("ldapsam_delete_user: user not found!\n"));
5616 return NT_STATUS_NO_SUCH_USER
;
5619 if (num_result
> 1) {
5620 DEBUG (0, ("ldapsam_delete_user: More than one user with name [%s] ?!\n", pdb_get_username(sam_acct
)));
5621 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
5624 entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
5626 return NT_STATUS_UNSUCCESSFUL
;
5629 /* it is just a posix account, retrieve the dn for later use */
5630 dn
= smbldap_talloc_dn(tmp_ctx
, priv2ld(ldap_state
), entry
);
5632 DEBUG(0,("ldapsam_delete_user: Out of memory!\n"));
5633 return NT_STATUS_NO_MEMORY
;
5636 /* try to remove memberships first */
5639 struct dom_sid
*sids
= NULL
;
5641 uint32_t num_groups
= 0;
5643 uint32_t user_rid
= pdb_get_user_rid(sam_acct
);
5645 status
= ldapsam_enum_group_memberships(my_methods
,
5651 if (!NT_STATUS_IS_OK(status
)) {
5655 for (i
=0; i
< num_groups
; i
++) {
5659 sid_peek_rid(&sids
[i
], &group_rid
);
5661 ldapsam_del_groupmem(my_methods
,
5670 rc
= smbldap_delete(ldap_state
->smbldap_state
, dn
);
5671 if (rc
!= LDAP_SUCCESS
) {
5672 return NT_STATUS_UNSUCCESSFUL
;
5675 flush_pwnam_cache();
5677 return NT_STATUS_OK
;
5681 * ldapsam_create_group creates a new
5682 * posixGroup and sambaGroupMapping object
5683 * in the ldap groups subtree
5685 * The gid is allocated by winbindd.
5688 static NTSTATUS
ldapsam_create_dom_group(struct pdb_methods
*my_methods
,
5689 TALLOC_CTX
*tmp_ctx
,
5693 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
5695 LDAPMessage
*entry
= NULL
;
5696 LDAPMessage
*result
= NULL
;
5697 uint32_t num_result
;
5698 bool is_new_entry
= False
;
5699 LDAPMod
**mods
= NULL
;
5702 const char *grouptype
;
5704 const char *dn
= NULL
;
5705 struct dom_sid group_sid
;
5706 struct dom_sid_buf buf
;
5711 groupname
= escape_ldap_string(talloc_tos(), name
);
5712 filter
= talloc_asprintf(tmp_ctx
, "(&(cn=%s)(objectClass="LDAP_OBJ_POSIXGROUP
"))",
5714 TALLOC_FREE(groupname
);
5716 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, NULL
, &result
);
5717 if (rc
!= LDAP_SUCCESS
) {
5718 DEBUG(0,("ldapsam_create_group: ldap search failed!\n"));
5719 return NT_STATUS_UNSUCCESSFUL
;
5721 smbldap_talloc_autofree_ldapmsg(tmp_ctx
, result
);
5723 num_result
= ldap_count_entries(priv2ld(ldap_state
), result
);
5725 if (num_result
> 1) {
5726 DEBUG (0, ("ldapsam_create_group: There exists more than one group with name [%s]: bailing out!\n", name
));
5727 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
5730 if (num_result
== 1) {
5732 /* check if it is just a posix group.
5733 * or if there is a sid attached to this entry
5736 entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
5738 return NT_STATUS_UNSUCCESSFUL
;
5741 tmp
= smbldap_talloc_single_attribute(priv2ld(ldap_state
), entry
, "sambaSID", tmp_ctx
);
5743 DEBUG (1, ("ldapsam_create_group: The group [%s] already exist!\n", name
));
5744 return NT_STATUS_GROUP_EXISTS
;
5747 /* it is just a posix group, retrieve the gid and the dn for later use */
5748 tmp
= smbldap_talloc_single_attribute(priv2ld(ldap_state
), entry
, "gidNumber", tmp_ctx
);
5750 DEBUG (1, ("ldapsam_create_group: Couldn't retrieve the gidNumber for [%s]?!?!\n", name
));
5751 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
5754 gid
= smb_strtoul(tmp
, NULL
, 10, &error
, SMB_STR_STANDARD
);
5756 DBG_ERR("Failed to convert gidNumber\n");
5757 return NT_STATUS_UNSUCCESSFUL
;
5760 dn
= smbldap_talloc_dn(tmp_ctx
, priv2ld(ldap_state
), entry
);
5762 DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
5763 return NT_STATUS_NO_MEMORY
;
5767 if (num_result
== 0) {
5768 is_new_entry
= true;
5771 if (!NT_STATUS_IS_OK((ret
= ldapsam_new_rid_internal(my_methods
, rid
)))) {
5772 DEBUG(1, ("ldapsam_create_group: Could not allocate a new RID\n"));
5776 sid_compose(&group_sid
, get_global_sam_sid(), *rid
);
5778 grouptype
= talloc_asprintf(tmp_ctx
, "%d", SID_NAME_DOM_GRP
);
5781 DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
5782 return NT_STATUS_NO_MEMORY
;
5785 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectClass", LDAP_OBJ_GROUPMAP
);
5786 smbldap_set_mod(&mods
,
5789 dom_sid_str_buf(&group_sid
, &buf
));
5790 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "sambaGroupType", grouptype
);
5791 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "displayName", name
);
5796 DEBUG(3,("ldapsam_create_user: Creating new posix group\n"));
5798 /* lets allocate a new groupid for this group */
5799 if (!winbind_allocate_gid(&gid
)) {
5800 DEBUG (0, ("ldapsam_create_group: Unable to allocate a new group id: bailing out!\n"));
5801 return NT_STATUS_UNSUCCESSFUL
;
5804 gidstr
= talloc_asprintf(tmp_ctx
, "%u", (unsigned int)gid
);
5806 escape_name
= escape_rdn_val_string_alloc(name
);
5808 DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
5809 return NT_STATUS_NO_MEMORY
;
5812 dn
= talloc_asprintf(tmp_ctx
, "cn=%s,%s", escape_name
, lp_ldap_group_suffix(talloc_tos()));
5814 SAFE_FREE(escape_name
);
5816 if (!gidstr
|| !dn
) {
5817 DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
5818 return NT_STATUS_NO_MEMORY
;
5821 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectclass", LDAP_OBJ_POSIXGROUP
);
5822 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "cn", name
);
5823 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "gidNumber", gidstr
);
5826 smbldap_talloc_autofree_ldapmod(tmp_ctx
, mods
);
5829 rc
= smbldap_add(ldap_state
->smbldap_state
, dn
, mods
);
5831 if (rc
== LDAP_OBJECT_CLASS_VIOLATION
) {
5832 /* This call may fail with rfc2307bis schema */
5833 /* Retry adding a structural class */
5834 smbldap_set_mod(&mods
, LDAP_MOD_ADD
, "objectClass", "????");
5835 rc
= smbldap_add(ldap_state
->smbldap_state
, dn
, mods
);
5839 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
5842 if (rc
!= LDAP_SUCCESS
) {
5843 DEBUG(0,("ldapsam_create_group: failed to create a new group [%s] (dn = %s)\n", name
,dn
));
5844 return NT_STATUS_UNSUCCESSFUL
;
5847 DEBUG(2,("ldapsam_create_group: added group [%s] in the LDAP database\n", name
));
5849 return NT_STATUS_OK
;
5852 static NTSTATUS
ldapsam_delete_dom_group(struct pdb_methods
*my_methods
, TALLOC_CTX
*tmp_ctx
, uint32_t rid
)
5854 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
5855 LDAPMessage
*result
= NULL
;
5856 LDAPMessage
*entry
= NULL
;
5861 struct dom_sid group_sid
;
5862 struct dom_sid_buf buf
;
5865 /* get the group sid */
5866 sid_compose(&group_sid
, get_global_sam_sid(), rid
);
5868 filter
= talloc_asprintf(tmp_ctx
,
5870 "(objectClass="LDAP_OBJ_POSIXGROUP
")"
5871 "(objectClass="LDAP_OBJ_GROUPMAP
"))",
5872 dom_sid_str_buf(&group_sid
, &buf
));
5873 if (filter
== NULL
) {
5874 return NT_STATUS_NO_MEMORY
;
5877 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, NULL
, &result
);
5878 if (rc
!= LDAP_SUCCESS
) {
5879 DEBUG(1,("ldapsam_delete_dom_group: group search failed!\n"));
5880 return NT_STATUS_UNSUCCESSFUL
;
5882 smbldap_talloc_autofree_ldapmsg(tmp_ctx
, result
);
5884 num_result
= ldap_count_entries(priv2ld(ldap_state
), result
);
5886 if (num_result
== 0) {
5887 DEBUG(1,("ldapsam_delete_dom_group: group not found!\n"));
5888 return NT_STATUS_NO_SUCH_GROUP
;
5891 if (num_result
> 1) {
5892 DEBUG (0, ("ldapsam_delete_dom_group: More than one group with the same SID ?!\n"));
5893 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
5896 entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
5898 return NT_STATUS_UNSUCCESSFUL
;
5901 /* here it is, retrieve the dn for later use */
5902 dn
= smbldap_talloc_dn(tmp_ctx
, priv2ld(ldap_state
), entry
);
5904 DEBUG(0,("ldapsam_delete_dom_group: Out of memory!\n"));
5905 return NT_STATUS_NO_MEMORY
;
5908 gidstr
= smbldap_talloc_single_attribute(priv2ld(ldap_state
), entry
, "gidNumber", tmp_ctx
);
5910 DEBUG (0, ("ldapsam_delete_dom_group: Unable to find the group's gid!\n"));
5911 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
5914 /* check no user have this group marked as primary group */
5915 filter
= talloc_asprintf(tmp_ctx
,
5917 "(objectClass="LDAP_OBJ_POSIXACCOUNT
")"
5918 "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT
"))",
5921 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, NULL
, &result
);
5922 if (rc
!= LDAP_SUCCESS
) {
5923 DEBUG(1,("ldapsam_delete_dom_group: accounts search failed!\n"));
5924 return NT_STATUS_UNSUCCESSFUL
;
5926 smbldap_talloc_autofree_ldapmsg(tmp_ctx
, result
);
5928 num_result
= ldap_count_entries(priv2ld(ldap_state
), result
);
5930 if (num_result
!= 0) {
5931 DEBUG(3,("ldapsam_delete_dom_group: Can't delete group, it is a primary group for %d users\n", num_result
));
5932 return NT_STATUS_MEMBERS_PRIMARY_GROUP
;
5935 rc
= smbldap_delete(ldap_state
->smbldap_state
, dn
);
5936 if (rc
!= LDAP_SUCCESS
) {
5937 return NT_STATUS_UNSUCCESSFUL
;
5940 return NT_STATUS_OK
;
5943 static NTSTATUS
ldapsam_change_groupmem(struct pdb_methods
*my_methods
,
5944 TALLOC_CTX
*tmp_ctx
,
5946 uint32_t member_rid
,
5949 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
5950 LDAPMessage
*entry
= NULL
;
5951 LDAPMessage
*result
= NULL
;
5952 uint32_t num_result
;
5953 LDAPMod
**mods
= NULL
;
5956 const char *dn
= NULL
;
5957 struct dom_sid group_sid
;
5958 struct dom_sid member_sid
;
5959 struct dom_sid_buf buf
;
5965 DEBUG(1,("ldapsam_change_groupmem: add new member(rid=%d) to a domain group(rid=%d)\n", member_rid
, group_rid
));
5967 case LDAP_MOD_DELETE
:
5968 DEBUG(1,("ldapsam_change_groupmem: delete member(rid=%d) from a domain group(rid=%d)\n", member_rid
, group_rid
));
5971 return NT_STATUS_UNSUCCESSFUL
;
5974 /* get member sid */
5975 sid_compose(&member_sid
, get_global_sam_sid(), member_rid
);
5977 /* get the group sid */
5978 sid_compose(&group_sid
, get_global_sam_sid(), group_rid
);
5980 filter
= talloc_asprintf(tmp_ctx
,
5982 "(objectClass="LDAP_OBJ_POSIXACCOUNT
")"
5983 "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT
"))",
5984 dom_sid_str_buf(&member_sid
, &buf
));
5985 if (filter
== NULL
) {
5986 return NT_STATUS_NO_MEMORY
;
5989 /* get the member uid */
5990 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, NULL
, &result
);
5991 if (rc
!= LDAP_SUCCESS
) {
5992 DEBUG(1,("ldapsam_change_groupmem: member search failed!\n"));
5993 return NT_STATUS_UNSUCCESSFUL
;
5995 smbldap_talloc_autofree_ldapmsg(tmp_ctx
, result
);
5997 num_result
= ldap_count_entries(priv2ld(ldap_state
), result
);
5999 if (num_result
== 0) {
6000 DEBUG(1,("ldapsam_change_groupmem: member not found!\n"));
6001 return NT_STATUS_NO_SUCH_MEMBER
;
6004 if (num_result
> 1) {
6005 DEBUG (0, ("ldapsam_change_groupmem: More than one account with the same SID ?!\n"));
6006 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
6009 entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
6011 return NT_STATUS_UNSUCCESSFUL
;
6014 if (modop
== LDAP_MOD_DELETE
) {
6015 /* check if we are trying to remove the member from his primary group */
6017 gid_t user_gid
, group_gid
;
6019 gidstr
= smbldap_talloc_single_attribute(priv2ld(ldap_state
), entry
, "gidNumber", tmp_ctx
);
6021 DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's gid!\n"));
6022 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
6025 user_gid
= smb_strtoul(gidstr
, NULL
, 10, &error
, SMB_STR_STANDARD
);
6027 DBG_ERR("Failed to convert user gid\n");
6028 return NT_STATUS_UNSUCCESSFUL
;
6031 if (!sid_to_gid(&group_sid
, &group_gid
)) {
6032 DEBUG (0, ("ldapsam_change_groupmem: Unable to get group gid from SID!\n"));
6033 return NT_STATUS_UNSUCCESSFUL
;
6036 if (user_gid
== group_gid
) {
6037 DEBUG (3, ("ldapsam_change_groupmem: can't remove user from its own primary group!\n"));
6038 return NT_STATUS_MEMBERS_PRIMARY_GROUP
;
6042 /* here it is, retrieve the uid for later use */
6043 uidstr
= smbldap_talloc_single_attribute(priv2ld(ldap_state
), entry
, "uid", tmp_ctx
);
6045 DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's name!\n"));
6046 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
6049 filter
= talloc_asprintf(tmp_ctx
,
6051 "(objectClass="LDAP_OBJ_POSIXGROUP
")"
6052 "(objectClass="LDAP_OBJ_GROUPMAP
"))",
6053 dom_sid_str_buf(&group_sid
, &buf
));
6056 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, NULL
, &result
);
6057 if (rc
!= LDAP_SUCCESS
) {
6058 DEBUG(1,("ldapsam_change_groupmem: group search failed!\n"));
6059 return NT_STATUS_UNSUCCESSFUL
;
6061 smbldap_talloc_autofree_ldapmsg(tmp_ctx
, result
);
6063 num_result
= ldap_count_entries(priv2ld(ldap_state
), result
);
6065 if (num_result
== 0) {
6066 DEBUG(1,("ldapsam_change_groupmem: group not found!\n"));
6067 return NT_STATUS_NO_SUCH_GROUP
;
6070 if (num_result
> 1) {
6071 DEBUG (0, ("ldapsam_change_groupmem: More than one group with the same SID ?!\n"));
6072 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
6075 entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
6077 return NT_STATUS_UNSUCCESSFUL
;
6080 /* here it is, retrieve the dn for later use */
6081 dn
= smbldap_talloc_dn(tmp_ctx
, priv2ld(ldap_state
), entry
);
6083 DEBUG(0,("ldapsam_change_groupmem: Out of memory!\n"));
6084 return NT_STATUS_NO_MEMORY
;
6087 smbldap_set_mod(&mods
, modop
, "memberUid", uidstr
);
6089 smbldap_talloc_autofree_ldapmod(tmp_ctx
, mods
);
6091 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
6092 if (rc
!= LDAP_SUCCESS
) {
6093 if (rc
== LDAP_TYPE_OR_VALUE_EXISTS
&& modop
== LDAP_MOD_ADD
) {
6094 DEBUG(1,("ldapsam_change_groupmem: member is already in group, add failed!\n"));
6095 return NT_STATUS_MEMBER_IN_GROUP
;
6097 if (rc
== LDAP_NO_SUCH_ATTRIBUTE
&& modop
== LDAP_MOD_DELETE
) {
6098 DEBUG(1,("ldapsam_change_groupmem: member is not in group, delete failed!\n"));
6099 return NT_STATUS_MEMBER_NOT_IN_GROUP
;
6101 return NT_STATUS_UNSUCCESSFUL
;
6104 return NT_STATUS_OK
;
6107 static NTSTATUS
ldapsam_add_groupmem(struct pdb_methods
*my_methods
,
6108 TALLOC_CTX
*tmp_ctx
,
6110 uint32_t member_rid
)
6112 return ldapsam_change_groupmem(my_methods
, tmp_ctx
, group_rid
, member_rid
, LDAP_MOD_ADD
);
6114 static NTSTATUS
ldapsam_del_groupmem(struct pdb_methods
*my_methods
,
6115 TALLOC_CTX
*tmp_ctx
,
6117 uint32_t member_rid
)
6119 return ldapsam_change_groupmem(my_methods
, tmp_ctx
, group_rid
, member_rid
, LDAP_MOD_DELETE
);
6122 static NTSTATUS
ldapsam_set_primary_group(struct pdb_methods
*my_methods
,
6123 TALLOC_CTX
*mem_ctx
,
6124 struct samu
*sampass
)
6126 struct ldapsam_privates
*ldap_state
= (struct ldapsam_privates
*)my_methods
->private_data
;
6127 LDAPMessage
*entry
= NULL
;
6128 LDAPMessage
*result
= NULL
;
6129 uint32_t num_result
;
6130 LDAPMod
**mods
= NULL
;
6132 char *escape_username
;
6138 DEBUG(0,("ldapsam_set_primary_group: Attempt to set primary group for user [%s]\n", pdb_get_username(sampass
)));
6140 if (!sid_to_gid(pdb_get_group_sid(sampass
), &gid
)) {
6141 DEBUG(0,("ldapsam_set_primary_group: failed to retrieve gid from user's group SID!\n"));
6142 return NT_STATUS_UNSUCCESSFUL
;
6144 gidstr
= talloc_asprintf(mem_ctx
, "%u", (unsigned int)gid
);
6146 DEBUG(0,("ldapsam_set_primary_group: Out of Memory!\n"));
6147 return NT_STATUS_NO_MEMORY
;
6150 escape_username
= escape_ldap_string(talloc_tos(),
6151 pdb_get_username(sampass
));
6152 if (escape_username
== NULL
) {
6153 return NT_STATUS_NO_MEMORY
;
6156 filter
= talloc_asprintf(mem_ctx
,
6158 "(objectClass="LDAP_OBJ_POSIXACCOUNT
")"
6159 "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT
"))",
6162 TALLOC_FREE(escape_username
);
6164 if (filter
== NULL
) {
6165 return NT_STATUS_NO_MEMORY
;
6168 rc
= smbldap_search_suffix(ldap_state
->smbldap_state
, filter
, NULL
, &result
);
6169 if (rc
!= LDAP_SUCCESS
) {
6170 DEBUG(0,("ldapsam_set_primary_group: user search failed!\n"));
6171 return NT_STATUS_UNSUCCESSFUL
;
6173 smbldap_talloc_autofree_ldapmsg(mem_ctx
, result
);
6175 num_result
= ldap_count_entries(priv2ld(ldap_state
), result
);
6177 if (num_result
== 0) {
6178 DEBUG(0,("ldapsam_set_primary_group: user not found!\n"));
6179 return NT_STATUS_NO_SUCH_USER
;
6182 if (num_result
> 1) {
6183 DEBUG (0, ("ldapsam_set_primary_group: More than one user with name [%s] ?!\n", pdb_get_username(sampass
)));
6184 return NT_STATUS_INTERNAL_DB_CORRUPTION
;
6187 entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
6189 return NT_STATUS_UNSUCCESSFUL
;
6192 /* retrieve the dn for later use */
6193 dn
= smbldap_talloc_dn(mem_ctx
, priv2ld(ldap_state
), entry
);
6195 DEBUG(0,("ldapsam_set_primary_group: Out of memory!\n"));
6196 return NT_STATUS_NO_MEMORY
;
6199 /* remove the old one, and add the new one, this way we do not risk races */
6200 smbldap_make_mod(priv2ld(ldap_state
), entry
, &mods
, "gidNumber", gidstr
);
6204 return NT_STATUS_OK
;
6207 rc
= smbldap_modify(ldap_state
->smbldap_state
, dn
, mods
);
6209 if (rc
!= LDAP_SUCCESS
) {
6210 DEBUG(0,("ldapsam_set_primary_group: failed to modify [%s] primary group to [%s]\n",
6211 pdb_get_username(sampass
), gidstr
));
6212 return NT_STATUS_UNSUCCESSFUL
;
6215 flush_pwnam_cache();
6217 return NT_STATUS_OK
;
6221 /**********************************************************************
6222 trusted domains functions
6223 *********************************************************************/
6225 static char *trusteddom_dn(struct ldapsam_privates
*ldap_state
,
6228 return talloc_asprintf(talloc_tos(), "sambaDomainName=%s,%s", domain
,
6229 ldap_state
->domain_dn
);
6232 static bool get_trusteddom_pw_int(struct ldapsam_privates
*ldap_state
,
6233 TALLOC_CTX
*mem_ctx
,
6234 const char *domain
, LDAPMessage
**entry
)
6238 int scope
= LDAP_SCOPE_SUBTREE
;
6239 const char **attrs
= NULL
; /* NULL: get all attrs */
6240 int attrsonly
= 0; /* 0: return values too */
6241 LDAPMessage
*result
= NULL
;
6243 uint32_t num_result
;
6245 filter
= talloc_asprintf(talloc_tos(),
6246 "(&(objectClass="LDAP_OBJ_TRUSTDOM_PASSWORD
")(sambaDomainName=%s))",
6249 trusted_dn
= trusteddom_dn(ldap_state
, domain
);
6250 if (trusted_dn
== NULL
) {
6253 rc
= smbldap_search(ldap_state
->smbldap_state
, trusted_dn
, scope
,
6254 filter
, attrs
, attrsonly
, &result
);
6256 if (result
!= NULL
) {
6257 smbldap_talloc_autofree_ldapmsg(mem_ctx
, result
);
6260 if (rc
== LDAP_NO_SUCH_OBJECT
) {
6265 if (rc
!= LDAP_SUCCESS
) {
6269 num_result
= ldap_count_entries(priv2ld(ldap_state
), result
);
6271 if (num_result
> 1) {
6272 DEBUG(1, ("ldapsam_get_trusteddom_pw: more than one "
6273 "%s object for domain '%s'?!\n",
6274 LDAP_OBJ_TRUSTDOM_PASSWORD
, domain
));
6278 if (num_result
== 0) {
6279 DEBUG(1, ("ldapsam_get_trusteddom_pw: no "
6280 "%s object for domain %s.\n",
6281 LDAP_OBJ_TRUSTDOM_PASSWORD
, domain
));
6284 *entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
6290 static bool ldapsam_get_trusteddom_pw(struct pdb_methods
*methods
,
6293 struct dom_sid
*sid
,
6294 time_t *pass_last_set_time
)
6296 struct ldapsam_privates
*ldap_state
=
6297 (struct ldapsam_privates
*)methods
->private_data
;
6298 LDAPMessage
*entry
= NULL
;
6300 DEBUG(10, ("ldapsam_get_trusteddom_pw called for domain %s\n", domain
));
6302 if (!get_trusteddom_pw_int(ldap_state
, talloc_tos(), domain
, &entry
) ||
6311 pwd_str
= smbldap_talloc_single_attribute(priv2ld(ldap_state
),
6312 entry
, "sambaClearTextPassword", talloc_tos());
6313 if (pwd_str
== NULL
) {
6316 /* trusteddom_pw routines do not use talloc yet... */
6317 *pwd
= SMB_STRDUP(pwd_str
);
6323 /* last change time */
6324 if (pass_last_set_time
!= NULL
) {
6326 time_str
= smbldap_talloc_single_attribute(priv2ld(ldap_state
),
6327 entry
, "sambaPwdLastSet", talloc_tos());
6328 if (time_str
== NULL
) {
6331 *pass_last_set_time
= (time_t)atol(time_str
);
6337 struct dom_sid dom_sid
;
6338 sid_str
= smbldap_talloc_single_attribute(priv2ld(ldap_state
),
6341 if (sid_str
== NULL
) {
6344 if (!string_to_sid(&dom_sid
, sid_str
)) {
6347 sid_copy(sid
, &dom_sid
);
6353 static bool ldapsam_set_trusteddom_pw(struct pdb_methods
*methods
,
6356 const struct dom_sid
*sid
)
6358 struct ldapsam_privates
*ldap_state
=
6359 (struct ldapsam_privates
*)methods
->private_data
;
6360 LDAPMessage
*entry
= NULL
;
6361 LDAPMod
**mods
= NULL
;
6362 char *prev_pwd
= NULL
;
6363 char *trusted_dn
= NULL
;
6364 struct dom_sid_buf buf
;
6367 DEBUG(10, ("ldapsam_set_trusteddom_pw called for domain %s\n", domain
));
6370 * get the current entry (if there is one) in order to put the
6371 * current password into the previous password attribute
6373 if (!get_trusteddom_pw_int(ldap_state
, talloc_tos(), domain
, &entry
)) {
6378 smbldap_make_mod(priv2ld(ldap_state
), entry
, &mods
, "objectClass",
6379 LDAP_OBJ_TRUSTDOM_PASSWORD
);
6380 smbldap_make_mod(priv2ld(ldap_state
), entry
, &mods
, "sambaDomainName",
6382 smbldap_make_mod(priv2ld(ldap_state
), entry
, &mods
, "sambaSID",
6383 dom_sid_str_buf(sid
, &buf
));
6384 smbldap_make_mod(priv2ld(ldap_state
), entry
, &mods
, "sambaPwdLastSet",
6385 talloc_asprintf(talloc_tos(), "%li", (long int)time(NULL
)));
6386 smbldap_make_mod(priv2ld(ldap_state
), entry
, &mods
,
6387 "sambaClearTextPassword", pwd
);
6389 if (entry
!= NULL
) {
6390 prev_pwd
= smbldap_talloc_single_attribute(priv2ld(ldap_state
),
6391 entry
, "sambaClearTextPassword", talloc_tos());
6392 if (prev_pwd
!= NULL
) {
6393 smbldap_make_mod(priv2ld(ldap_state
), entry
, &mods
,
6394 "sambaPreviousClearTextPassword",
6399 smbldap_talloc_autofree_ldapmod(talloc_tos(), mods
);
6401 trusted_dn
= trusteddom_dn(ldap_state
, domain
);
6402 if (trusted_dn
== NULL
) {
6405 if (entry
== NULL
) {
6406 rc
= smbldap_add(ldap_state
->smbldap_state
, trusted_dn
, mods
);
6408 rc
= smbldap_modify(ldap_state
->smbldap_state
, trusted_dn
, mods
);
6411 if (rc
!= LDAP_SUCCESS
) {
6412 DEBUG(1, ("error writing trusted domain password!\n"));
6419 static bool ldapsam_del_trusteddom_pw(struct pdb_methods
*methods
,
6423 struct ldapsam_privates
*ldap_state
=
6424 (struct ldapsam_privates
*)methods
->private_data
;
6425 LDAPMessage
*entry
= NULL
;
6426 const char *trusted_dn
;
6428 if (!get_trusteddom_pw_int(ldap_state
, talloc_tos(), domain
, &entry
)) {
6432 if (entry
== NULL
) {
6433 DEBUG(5, ("ldapsam_del_trusteddom_pw: no such trusted domain: "
6438 trusted_dn
= smbldap_talloc_dn(talloc_tos(), priv2ld(ldap_state
),
6440 if (trusted_dn
== NULL
) {
6441 DEBUG(0,("ldapsam_del_trusteddom_pw: Out of memory!\n"));
6445 rc
= smbldap_delete(ldap_state
->smbldap_state
, trusted_dn
);
6446 if (rc
!= LDAP_SUCCESS
) {
6453 static NTSTATUS
ldapsam_enum_trusteddoms(struct pdb_methods
*methods
,
6454 TALLOC_CTX
*mem_ctx
,
6455 uint32_t *num_domains
,
6456 struct trustdom_info
***domains
)
6459 struct ldapsam_privates
*ldap_state
=
6460 (struct ldapsam_privates
*)methods
->private_data
;
6462 int scope
= LDAP_SCOPE_SUBTREE
;
6463 const char *attrs
[] = { "sambaDomainName", "sambaSID", NULL
};
6464 int attrsonly
= 0; /* 0: return values too */
6465 LDAPMessage
*result
= NULL
;
6466 LDAPMessage
*entry
= NULL
;
6468 filter
= "(objectClass="LDAP_OBJ_TRUSTDOM_PASSWORD
")";
6470 rc
= smbldap_search(ldap_state
->smbldap_state
,
6471 ldap_state
->domain_dn
,
6478 if (result
!= NULL
) {
6479 smbldap_talloc_autofree_ldapmsg(mem_ctx
, result
);
6482 if (rc
!= LDAP_SUCCESS
) {
6483 return NT_STATUS_UNSUCCESSFUL
;
6487 if (!(*domains
= talloc_array(mem_ctx
, struct trustdom_info
*, 1))) {
6488 DEBUG(1, ("talloc failed\n"));
6489 return NT_STATUS_NO_MEMORY
;
6492 for (entry
= ldap_first_entry(priv2ld(ldap_state
), result
);
6494 entry
= ldap_next_entry(priv2ld(ldap_state
), entry
))
6496 char *dom_name
, *dom_sid_str
;
6497 struct trustdom_info
*dom_info
;
6499 dom_info
= talloc(*domains
, struct trustdom_info
);
6500 if (dom_info
== NULL
) {
6501 DEBUG(1, ("talloc failed\n"));
6502 return NT_STATUS_NO_MEMORY
;
6505 dom_name
= smbldap_talloc_single_attribute(priv2ld(ldap_state
),
6509 if (dom_name
== NULL
) {
6510 DEBUG(1, ("talloc failed\n"));
6511 return NT_STATUS_NO_MEMORY
;
6513 dom_info
->name
= dom_name
;
6515 dom_sid_str
= smbldap_talloc_single_attribute(
6516 priv2ld(ldap_state
), entry
, "sambaSID",
6518 if (dom_sid_str
== NULL
) {
6519 DEBUG(1, ("talloc failed\n"));
6520 return NT_STATUS_NO_MEMORY
;
6522 if (!string_to_sid(&dom_info
->sid
, dom_sid_str
)) {
6523 DEBUG(1, ("Error calling string_to_sid on SID %s\n",
6525 return NT_STATUS_UNSUCCESSFUL
;
6528 ADD_TO_ARRAY(*domains
, struct trustdom_info
*, dom_info
,
6529 domains
, num_domains
);
6531 if (*domains
== NULL
) {
6532 DEBUG(1, ("talloc failed\n"));
6533 return NT_STATUS_NO_MEMORY
;
6537 DEBUG(5, ("ldapsam_enum_trusteddoms: got %d domains\n", *num_domains
));
6538 return NT_STATUS_OK
;
6542 /**********************************************************************
6544 *********************************************************************/
6546 static void free_private_data(void **vp
)
6548 struct ldapsam_privates
**ldap_state
= (struct ldapsam_privates
**)vp
;
6550 smbldap_free_struct(&(*ldap_state
)->smbldap_state
);
6552 if ((*ldap_state
)->result
!= NULL
) {
6553 ldap_msgfree((*ldap_state
)->result
);
6554 (*ldap_state
)->result
= NULL
;
6556 if ((*ldap_state
)->domain_dn
!= NULL
) {
6557 SAFE_FREE((*ldap_state
)->domain_dn
);
6562 /* No need to free any further, as it is talloc()ed */
6565 /*********************************************************************
6566 Initialise the parts of the pdb_methods structure that are common to
6568 *********************************************************************/
6570 static NTSTATUS
pdb_init_ldapsam_common(struct pdb_methods
**pdb_method
, const char *location
)
6573 struct ldapsam_privates
*ldap_state
;
6574 char *bind_dn
= NULL
;
6575 char *bind_secret
= NULL
;
6577 if (!NT_STATUS_IS_OK(nt_status
= make_pdb_method( pdb_method
))) {
6581 (*pdb_method
)->name
= "ldapsam";
6583 (*pdb_method
)->getsampwnam
= ldapsam_getsampwnam
;
6584 (*pdb_method
)->getsampwsid
= ldapsam_getsampwsid
;
6585 (*pdb_method
)->add_sam_account
= ldapsam_add_sam_account
;
6586 (*pdb_method
)->update_sam_account
= ldapsam_update_sam_account
;
6587 (*pdb_method
)->delete_sam_account
= ldapsam_delete_sam_account
;
6588 (*pdb_method
)->rename_sam_account
= ldapsam_rename_sam_account
;
6590 (*pdb_method
)->getgrsid
= ldapsam_getgrsid
;
6591 (*pdb_method
)->getgrgid
= ldapsam_getgrgid
;
6592 (*pdb_method
)->getgrnam
= ldapsam_getgrnam
;
6593 (*pdb_method
)->add_group_mapping_entry
= ldapsam_add_group_mapping_entry
;
6594 (*pdb_method
)->update_group_mapping_entry
= ldapsam_update_group_mapping_entry
;
6595 (*pdb_method
)->delete_group_mapping_entry
= ldapsam_delete_group_mapping_entry
;
6596 (*pdb_method
)->enum_group_mapping
= ldapsam_enum_group_mapping
;
6598 (*pdb_method
)->get_account_policy
= ldapsam_get_account_policy
;
6599 (*pdb_method
)->set_account_policy
= ldapsam_set_account_policy
;
6601 (*pdb_method
)->get_seq_num
= ldapsam_get_seq_num
;
6603 (*pdb_method
)->capabilities
= ldapsam_capabilities
;
6604 (*pdb_method
)->new_rid
= ldapsam_new_rid
;
6606 (*pdb_method
)->get_trusteddom_pw
= ldapsam_get_trusteddom_pw
;
6607 (*pdb_method
)->set_trusteddom_pw
= ldapsam_set_trusteddom_pw
;
6608 (*pdb_method
)->del_trusteddom_pw
= ldapsam_del_trusteddom_pw
;
6609 (*pdb_method
)->enum_trusteddoms
= ldapsam_enum_trusteddoms
;
6611 /* TODO: Setup private data and free */
6613 if ( !(ldap_state
= talloc_zero(*pdb_method
, struct ldapsam_privates
)) ) {
6614 DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
6615 return NT_STATUS_NO_MEMORY
;
6618 if (!fetch_ldap_pw(&bind_dn
, &bind_secret
)) {
6619 DEBUG(0, ("pdb_init_ldapsam_common: Failed to retrieve LDAP password from secrets.tdb\n"));
6620 return NT_STATUS_NO_MEMORY
;
6623 nt_status
= smbldap_init(*pdb_method
, pdb_get_tevent_context(),
6624 location
, false, bind_dn
, bind_secret
,
6625 &ldap_state
->smbldap_state
);
6626 BURN_FREE_STR(bind_secret
);
6628 if ( !NT_STATUS_IS_OK(nt_status
) ) {
6632 if ( !(ldap_state
->domain_name
= talloc_strdup(*pdb_method
, get_global_sam_name()) ) ) {
6633 return NT_STATUS_NO_MEMORY
;
6636 (*pdb_method
)->private_data
= ldap_state
;
6638 (*pdb_method
)->free_private_data
= free_private_data
;
6640 return NT_STATUS_OK
;
6643 static bool ldapsam_is_responsible_for_wellknown(struct pdb_methods
*m
)
6648 /**********************************************************************
6649 Initialise the normal mode for pdb_ldap
6650 *********************************************************************/
6652 NTSTATUS
pdb_ldapsam_init_common(struct pdb_methods
**pdb_method
,
6653 const char *location
)
6656 struct ldapsam_privates
*ldap_state
= NULL
;
6657 uint32_t alg_rid_base
;
6658 char *alg_rid_base_string
= NULL
;
6659 LDAPMessage
*result
= NULL
;
6660 LDAPMessage
*entry
= NULL
;
6661 struct dom_sid ldap_domain_sid
;
6662 struct dom_sid secrets_domain_sid
;
6663 char *domain_sid_string
= NULL
;
6665 char *uri
= talloc_strdup( NULL
, location
);
6667 trim_char( uri
, '\"', '\"' );
6668 nt_status
= pdb_init_ldapsam_common(pdb_method
, uri
);
6672 if (!NT_STATUS_IS_OK(nt_status
)) {
6676 (*pdb_method
)->name
= "ldapsam";
6678 (*pdb_method
)->add_aliasmem
= ldapsam_add_aliasmem
;
6679 (*pdb_method
)->del_aliasmem
= ldapsam_del_aliasmem
;
6680 (*pdb_method
)->enum_aliasmem
= ldapsam_enum_aliasmem
;
6681 (*pdb_method
)->enum_alias_memberships
= ldapsam_alias_memberships
;
6682 (*pdb_method
)->search_users
= ldapsam_search_users
;
6683 (*pdb_method
)->search_groups
= ldapsam_search_groups
;
6684 (*pdb_method
)->search_aliases
= ldapsam_search_aliases
;
6685 (*pdb_method
)->is_responsible_for_wellknown
=
6686 ldapsam_is_responsible_for_wellknown
;
6688 if (lp_parm_bool(-1, "ldapsam", "trusted", False
)) {
6689 (*pdb_method
)->enum_group_members
= ldapsam_enum_group_members
;
6690 (*pdb_method
)->enum_group_memberships
=
6691 ldapsam_enum_group_memberships
;
6692 (*pdb_method
)->lookup_rids
= ldapsam_lookup_rids
;
6693 (*pdb_method
)->sid_to_id
= ldapsam_sid_to_id
;
6694 (*pdb_method
)->id_to_sid
= ldapsam_id_to_sid
;
6696 if (lp_parm_bool(-1, "ldapsam", "editposix", False
)) {
6697 (*pdb_method
)->create_user
= ldapsam_create_user
;
6698 (*pdb_method
)->delete_user
= ldapsam_delete_user
;
6699 (*pdb_method
)->create_dom_group
= ldapsam_create_dom_group
;
6700 (*pdb_method
)->delete_dom_group
= ldapsam_delete_dom_group
;
6701 (*pdb_method
)->add_groupmem
= ldapsam_add_groupmem
;
6702 (*pdb_method
)->del_groupmem
= ldapsam_del_groupmem
;
6703 (*pdb_method
)->set_unix_primary_group
= ldapsam_set_primary_group
;
6707 ldap_state
= (struct ldapsam_privates
*)((*pdb_method
)->private_data
);
6708 ldap_state
->schema_ver
= SCHEMAVER_SAMBASAMACCOUNT
;
6710 /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
6712 nt_status
= smbldap_search_domain_info(ldap_state
->smbldap_state
,
6714 ldap_state
->domain_name
, True
);
6716 if ( !NT_STATUS_IS_OK(nt_status
) ) {
6717 DEBUG(0, ("pdb_init_ldapsam: WARNING: Could not get domain "
6718 "info, nor add one to the domain. "
6719 "We cannot work reliably without it.\n"));
6720 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
6723 /* Given that the above might fail, everything below this must be
6726 entry
= ldap_first_entry(smbldap_get_ldap(ldap_state
->smbldap_state
),
6729 DEBUG(0, ("pdb_init_ldapsam: Could not get domain info "
6731 ldap_msgfree(result
);
6732 return NT_STATUS_UNSUCCESSFUL
;
6735 dn
= smbldap_talloc_dn(talloc_tos(),
6736 smbldap_get_ldap(ldap_state
->smbldap_state
),
6739 ldap_msgfree(result
);
6740 return NT_STATUS_UNSUCCESSFUL
;
6743 ldap_state
->domain_dn
= smb_xstrdup(dn
);
6746 domain_sid_string
= smbldap_talloc_single_attribute(
6747 smbldap_get_ldap(ldap_state
->smbldap_state
),
6749 get_userattr_key2string(ldap_state
->schema_ver
,
6750 LDAP_ATTR_USER_SID
),
6753 if (domain_sid_string
) {
6755 if (!string_to_sid(&ldap_domain_sid
, domain_sid_string
)) {
6756 DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be "
6757 "read as a valid SID\n", domain_sid_string
));
6758 ldap_msgfree(result
);
6759 TALLOC_FREE(domain_sid_string
);
6760 return NT_STATUS_INVALID_PARAMETER
;
6762 found_sid
= PDB_secrets_fetch_domain_sid(ldap_state
->domain_name
,
6763 &secrets_domain_sid
);
6764 if (!found_sid
|| !dom_sid_equal(&secrets_domain_sid
,
6765 &ldap_domain_sid
)) {
6766 struct dom_sid_buf buf1
, buf2
;
6767 DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain "
6768 "%s based on pdb_ldap results %s -> %s\n",
6769 ldap_state
->domain_name
,
6770 dom_sid_str_buf(&secrets_domain_sid
, &buf1
),
6771 dom_sid_str_buf(&ldap_domain_sid
, &buf2
)));
6773 /* reset secrets.tdb sid */
6774 PDB_secrets_store_domain_sid(ldap_state
->domain_name
,
6776 DEBUG(1, ("New global sam SID: %s\n",
6777 dom_sid_str_buf(get_global_sam_sid(),
6780 sid_copy(&ldap_state
->domain_sid
, &ldap_domain_sid
);
6781 TALLOC_FREE(domain_sid_string
);
6784 alg_rid_base_string
= smbldap_talloc_single_attribute(
6785 smbldap_get_ldap(ldap_state
->smbldap_state
),
6787 get_attr_key2string( dominfo_attr_list
,
6788 LDAP_ATTR_ALGORITHMIC_RID_BASE
),
6790 if (alg_rid_base_string
) {
6791 alg_rid_base
= (uint32_t)atol(alg_rid_base_string
);
6792 if (alg_rid_base
!= algorithmic_rid_base()) {
6793 DEBUG(0, ("The value of 'algorithmic RID base' has "
6794 "changed since the LDAP\n"
6795 "database was initialised. Aborting. \n"));
6796 ldap_msgfree(result
);
6797 TALLOC_FREE(alg_rid_base_string
);
6798 return NT_STATUS_UNSUCCESSFUL
;
6800 TALLOC_FREE(alg_rid_base_string
);
6802 ldap_msgfree(result
);
6804 return NT_STATUS_OK
;
6807 NTSTATUS
pdb_ldapsam_init(TALLOC_CTX
*ctx
)
6811 nt_status
= smb_register_passdb(PASSDB_INTERFACE_VERSION
,
6813 pdb_ldapsam_init_common
);
6814 if (!NT_STATUS_IS_OK(nt_status
)) {
6818 /* Let pdb_nds register backends */
6821 return NT_STATUS_OK
;