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
47 #include "../libcli/auth/libcli_auth.h"
49 #include "idmap_cache.h"
50 #include "../libcli/security/security.h"
51 #include "../lib/util/util_pw.h"
54 #define DBGC_CLASS DBGC_PASSDB
62 /**********************************************************************
63 Simple helper function to make stuff better readable
64 **********************************************************************/
66 LDAP *priv2ld(struct ldapsam_privates *priv)
68 return priv->smbldap_state->ldap_struct;
71 /**********************************************************************
72 Get the attribute name given a user schame version.
73 **********************************************************************/
75 static const char* get_userattr_key2string( int schema_ver, int key )
77 switch ( schema_ver ) {
78 case SCHEMAVER_SAMBAACCOUNT:
79 return get_attr_key2string( attrib_map_v22, key );
81 case SCHEMAVER_SAMBASAMACCOUNT:
82 return get_attr_key2string( attrib_map_v30, key );
85 DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
91 /**********************************************************************
92 Return the list of attribute names given a user schema version.
93 **********************************************************************/
95 const char** get_userattr_list( TALLOC_CTX *mem_ctx, int schema_ver )
97 switch ( schema_ver ) {
98 case SCHEMAVER_SAMBAACCOUNT:
99 return get_attr_list( mem_ctx, attrib_map_v22 );
101 case SCHEMAVER_SAMBASAMACCOUNT:
102 return get_attr_list( mem_ctx, attrib_map_v30 );
104 DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
111 /**************************************************************************
112 Return the list of attribute names to delete given a user schema version.
113 **************************************************************************/
115 static const char** get_userattr_delete_list( TALLOC_CTX *mem_ctx,
118 switch ( schema_ver ) {
119 case SCHEMAVER_SAMBAACCOUNT:
120 return get_attr_list( mem_ctx,
121 attrib_map_to_delete_v22 );
123 case SCHEMAVER_SAMBASAMACCOUNT:
124 return get_attr_list( mem_ctx,
125 attrib_map_to_delete_v30 );
127 DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n"));
135 /*******************************************************************
136 Generate the LDAP search filter for the objectclass based on the
137 version of the schema we are using.
138 ******************************************************************/
140 static const char* get_objclass_filter( int schema_ver )
142 fstring objclass_filter;
145 switch( schema_ver ) {
146 case SCHEMAVER_SAMBAACCOUNT:
147 fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT );
149 case SCHEMAVER_SAMBASAMACCOUNT:
150 fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
153 DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));
154 objclass_filter[0] = '\0';
158 result = talloc_strdup(talloc_tos(), objclass_filter);
159 SMB_ASSERT(result != NULL);
163 /*****************************************************************
164 Scan a sequence number off OpenLDAP's syncrepl contextCSN
165 ******************************************************************/
167 static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_num)
169 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
170 NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
171 LDAPMessage *msg = NULL;
172 LDAPMessage *entry = NULL;
174 char **values = NULL;
175 int rc, num_result, num_values, rid;
181 /* Unfortunatly there is no proper way to detect syncrepl-support in
182 * smbldap_connect_system(). The syncrepl OIDs are submitted for publication
183 * but do not show up in the root-DSE yet. Neither we can query the
184 * subschema-context for the syncProviderSubentry or syncConsumerSubentry
185 * objectclass. Currently we require lp_ldap_suffix() to show up as
186 * namingContext. - Guenther
189 if (!lp_parm_bool(-1, "ldapsam", "syncrepl_seqnum", False)) {
194 DEBUG(3,("ldapsam_get_seq_num: no sequence_number\n"));
198 if (!smbldap_has_naming_context(ldap_state->smbldap_state->ldap_struct, lp_ldap_suffix())) {
199 DEBUG(3,("ldapsam_get_seq_num: DIT not configured to hold %s "
200 "as top-level namingContext\n", lp_ldap_suffix()));
204 mem_ctx = talloc_init("ldapsam_get_seq_num");
207 return NT_STATUS_NO_MEMORY;
209 if ((attrs = TALLOC_ARRAY(mem_ctx, const char *, 2)) == NULL) {
210 ntstatus = NT_STATUS_NO_MEMORY;
214 /* if we got a syncrepl-rid (up to three digits long) we speak with a consumer */
215 rid = lp_parm_int(-1, "ldapsam", "syncrepl_rid", -1);
218 /* consumer syncreplCookie: */
219 /* csn=20050126161620Z#0000001#00#00000 */
220 attrs[0] = talloc_strdup(mem_ctx, "syncreplCookie");
222 suffix = talloc_asprintf(mem_ctx,
223 "cn=syncrepl%d,%s", rid, lp_ldap_suffix());
225 ntstatus = NT_STATUS_NO_MEMORY;
230 /* provider contextCSN */
231 /* 20050126161620Z#000009#00#000000 */
232 attrs[0] = talloc_strdup(mem_ctx, "contextCSN");
234 suffix = talloc_asprintf(mem_ctx,
235 "cn=ldapsync,%s", lp_ldap_suffix());
238 ntstatus = NT_STATUS_NO_MEMORY;
243 rc = smbldap_search(ldap_state->smbldap_state, suffix,
244 LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &msg);
246 if (rc != LDAP_SUCCESS) {
250 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg);
251 if (num_result != 1) {
252 DEBUG(3,("ldapsam_get_seq_num: Expected one entry, got %d\n", num_result));
256 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, msg);
258 DEBUG(3,("ldapsam_get_seq_num: Could not retrieve entry\n"));
262 values = ldap_get_values(ldap_state->smbldap_state->ldap_struct, entry, attrs[0]);
263 if (values == NULL) {
264 DEBUG(3,("ldapsam_get_seq_num: no values\n"));
268 num_values = ldap_count_values(values);
269 if (num_values == 0) {
270 DEBUG(3,("ldapsam_get_seq_num: not a single value\n"));
275 if (!next_token_talloc(mem_ctx, &p, &tok, "#")) {
276 DEBUG(0,("ldapsam_get_seq_num: failed to parse sequence number\n"));
281 if (!strncmp(p, "csn=", strlen("csn=")))
284 DEBUG(10,("ldapsam_get_seq_num: got %s: %s\n", attrs[0], p));
286 *seq_num = generalized_to_unix_time(p);
288 /* very basic sanity check */
290 DEBUG(3,("ldapsam_get_seq_num: invalid sequence number: %d\n",
295 ntstatus = NT_STATUS_OK;
299 ldap_value_free(values);
303 talloc_destroy(mem_ctx);
308 /*******************************************************************
309 Run the search by name.
310 ******************************************************************/
312 int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
314 LDAPMessage ** result,
318 char *escape_user = escape_ldap_string(talloc_tos(), user);
322 return LDAP_NO_MEMORY;
326 * in the filter expression, replace %u with the real name
327 * so in ldap filter, %u MUST exist :-)
329 filter = talloc_asprintf(talloc_tos(), "(&%s%s)", "(uid=%u)",
330 get_objclass_filter(ldap_state->schema_ver));
332 TALLOC_FREE(escape_user);
333 return LDAP_NO_MEMORY;
336 * have to use this here because $ is filtered out
340 filter = talloc_all_string_sub(talloc_tos(),
341 filter, "%u", escape_user);
342 TALLOC_FREE(escape_user);
344 return LDAP_NO_MEMORY;
347 ret = smbldap_search_suffix(ldap_state->smbldap_state,
348 filter, attr, result);
353 /*******************************************************************
354 Run the search by rid.
355 ******************************************************************/
357 static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
358 uint32_t rid, LDAPMessage ** result,
364 filter = talloc_asprintf(talloc_tos(), "(&(rid=%i)%s)", rid,
365 get_objclass_filter(ldap_state->schema_ver));
367 return LDAP_NO_MEMORY;
370 rc = smbldap_search_suffix(ldap_state->smbldap_state,
371 filter, attr, result);
376 /*******************************************************************
377 Run the search by SID.
378 ******************************************************************/
380 static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
381 const struct dom_sid *sid, LDAPMessage ** result,
388 filter = talloc_asprintf(talloc_tos(), "(&(%s=%s)%s)",
389 get_userattr_key2string(ldap_state->schema_ver,
391 sid_to_fstring(sid_string, sid),
392 get_objclass_filter(ldap_state->schema_ver));
394 return LDAP_NO_MEMORY;
397 rc = smbldap_search_suffix(ldap_state->smbldap_state,
398 filter, attr, result);
404 /*******************************************************************
405 Delete complete object or objectclass and attrs from
406 object found in search_result depending on lp_ldap_delete_dn
407 ******************************************************************/
409 static int ldapsam_delete_entry(struct ldapsam_privates *priv,
412 const char *objectclass,
415 LDAPMod **mods = NULL;
418 BerElement *ptr = NULL;
420 dn = smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry);
422 return LDAP_NO_MEMORY;
425 if (lp_ldap_delete_dn()) {
426 return smbldap_delete(priv->smbldap_state, dn);
429 /* Ok, delete only the SAM attributes */
431 for (name = ldap_first_attribute(priv2ld(priv), entry, &ptr);
433 name = ldap_next_attribute(priv2ld(priv), entry, ptr)) {
436 /* We are only allowed to delete the attributes that
439 for (attrib = attrs; *attrib != NULL; attrib++) {
440 if (strequal(*attrib, name)) {
441 DEBUG(10, ("ldapsam_delete_entry: deleting "
442 "attribute %s\n", name));
443 smbldap_set_mod(&mods, LDAP_MOD_DELETE, name,
454 smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
455 talloc_autofree_ldapmod(mem_ctx, mods);
457 return smbldap_modify(priv->smbldap_state, dn, mods);
460 static time_t ldapsam_get_entry_timestamp( struct ldapsam_privates *ldap_state, LDAPMessage * entry)
465 temp = smbldap_talloc_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
466 get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP),
472 if ( !strptime(temp, "%Y%m%d%H%M%SZ", &tm)) {
473 DEBUG(2,("ldapsam_get_entry_timestamp: strptime failed on: %s\n",
483 /**********************************************************************
484 Initialize struct samu from an LDAP query.
485 (Based on init_sam_from_buffer in pdb_tdb.c)
486 *********************************************************************/
488 static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
489 struct samu * sampass,
496 pass_can_change_time,
497 pass_must_change_time,
500 char *username = NULL,
506 *logon_script = NULL,
507 *profile_path = NULL,
509 *workstations = NULL,
512 uint8 smblmpwd[LM_HASH_LEN],
513 smbntpwd[NT_HASH_LEN];
514 bool use_samba_attrs = True;
515 uint32_t acct_ctrl = 0;
517 uint16_t bad_password_count = 0,
520 uint8 hours[MAX_HOURS_LEN];
522 struct login_cache cache_entry;
524 bool expand_explicit = lp_passdb_expand_explicit();
526 TALLOC_CTX *ctx = talloc_init("init_sam_from_ldap");
531 if (sampass == NULL || ldap_state == NULL || entry == NULL) {
532 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
536 if (priv2ld(ldap_state) == NULL) {
537 DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->"
538 "ldap_struct is NULL!\n"));
542 if (!(username = smbldap_talloc_first_attribute(priv2ld(ldap_state),
546 DEBUG(1, ("init_sam_from_ldap: No uid attribute found for "
551 DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username));
553 nt_username = talloc_strdup(ctx, username);
558 domain = talloc_strdup(ctx, ldap_state->domain_name);
563 pdb_set_username(sampass, username, PDB_SET);
565 pdb_set_domain(sampass, domain, PDB_DEFAULT);
566 pdb_set_nt_username(sampass, nt_username, PDB_SET);
568 /* deal with different attributes between the schema first */
570 if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ) {
571 if ((temp = smbldap_talloc_single_attribute(
572 ldap_state->smbldap_state->ldap_struct,
574 get_userattr_key2string(ldap_state->schema_ver,
577 pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
580 if ((temp = smbldap_talloc_single_attribute(
581 ldap_state->smbldap_state->ldap_struct,
583 get_userattr_key2string(ldap_state->schema_ver,
586 user_rid = (uint32_t)atol(temp);
587 pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
591 if (IS_SAM_DEFAULT(sampass, PDB_USERSID)) {
592 DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n",
593 get_userattr_key2string(ldap_state->schema_ver,
595 get_userattr_key2string(ldap_state->schema_ver,
601 temp = smbldap_talloc_single_attribute(
602 ldap_state->smbldap_state->ldap_struct,
604 get_userattr_key2string(ldap_state->schema_ver,
605 LDAP_ATTR_PWD_LAST_SET),
608 pass_last_set_time = (time_t) atol(temp);
609 pdb_set_pass_last_set_time(sampass,
610 pass_last_set_time, PDB_SET);
613 temp = smbldap_talloc_single_attribute(
614 ldap_state->smbldap_state->ldap_struct,
616 get_userattr_key2string(ldap_state->schema_ver,
617 LDAP_ATTR_LOGON_TIME),
620 logon_time = (time_t) atol(temp);
621 pdb_set_logon_time(sampass, logon_time, PDB_SET);
624 temp = smbldap_talloc_single_attribute(
625 ldap_state->smbldap_state->ldap_struct,
627 get_userattr_key2string(ldap_state->schema_ver,
628 LDAP_ATTR_LOGOFF_TIME),
631 logoff_time = (time_t) atol(temp);
632 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
635 temp = smbldap_talloc_single_attribute(
636 ldap_state->smbldap_state->ldap_struct,
638 get_userattr_key2string(ldap_state->schema_ver,
639 LDAP_ATTR_KICKOFF_TIME),
642 kickoff_time = (time_t) atol(temp);
643 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
646 temp = smbldap_talloc_single_attribute(
647 ldap_state->smbldap_state->ldap_struct,
649 get_userattr_key2string(ldap_state->schema_ver,
650 LDAP_ATTR_PWD_CAN_CHANGE),
653 pass_can_change_time = (time_t) atol(temp);
654 pdb_set_pass_can_change_time(sampass,
655 pass_can_change_time, PDB_SET);
658 temp = smbldap_talloc_single_attribute(
659 ldap_state->smbldap_state->ldap_struct,
661 get_userattr_key2string(ldap_state->schema_ver,
662 LDAP_ATTR_PWD_MUST_CHANGE),
665 pass_must_change_time = (time_t) atol(temp);
666 pdb_set_pass_must_change_time(sampass,
667 pass_must_change_time, PDB_SET);
670 /* recommend that 'gecos' and 'displayName' should refer to the same
671 * attribute OID. userFullName depreciated, only used by Samba
672 * primary rules of LDAP: don't make a new attribute when one is already defined
673 * that fits your needs; using cn then displayName rather than 'userFullName'
676 fullname = smbldap_talloc_single_attribute(
677 ldap_state->smbldap_state->ldap_struct,
679 get_userattr_key2string(ldap_state->schema_ver,
680 LDAP_ATTR_DISPLAY_NAME),
683 pdb_set_fullname(sampass, fullname, PDB_SET);
685 fullname = smbldap_talloc_single_attribute(
686 ldap_state->smbldap_state->ldap_struct,
688 get_userattr_key2string(ldap_state->schema_ver,
692 pdb_set_fullname(sampass, fullname, PDB_SET);
696 dir_drive = smbldap_talloc_single_attribute(
697 ldap_state->smbldap_state->ldap_struct,
699 get_userattr_key2string(ldap_state->schema_ver,
700 LDAP_ATTR_HOME_DRIVE),
703 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
705 pdb_set_dir_drive( sampass, lp_logon_drive(), PDB_DEFAULT );
708 homedir = smbldap_talloc_single_attribute(
709 ldap_state->smbldap_state->ldap_struct,
711 get_userattr_key2string(ldap_state->schema_ver,
712 LDAP_ATTR_HOME_PATH),
715 if (expand_explicit) {
716 homedir = talloc_sub_basic(ctx,
724 pdb_set_homedir(sampass, homedir, PDB_SET);
726 pdb_set_homedir(sampass,
727 talloc_sub_basic(ctx, username, domain,
732 logon_script = smbldap_talloc_single_attribute(
733 ldap_state->smbldap_state->ldap_struct,
735 get_userattr_key2string(ldap_state->schema_ver,
736 LDAP_ATTR_LOGON_SCRIPT),
739 if (expand_explicit) {
740 logon_script = talloc_sub_basic(ctx,
748 pdb_set_logon_script(sampass, logon_script, PDB_SET);
750 pdb_set_logon_script(sampass,
751 talloc_sub_basic(ctx, username, domain,
756 profile_path = smbldap_talloc_single_attribute(
757 ldap_state->smbldap_state->ldap_struct,
759 get_userattr_key2string(ldap_state->schema_ver,
760 LDAP_ATTR_PROFILE_PATH),
763 if (expand_explicit) {
764 profile_path = talloc_sub_basic(ctx,
772 pdb_set_profile_path(sampass, profile_path, PDB_SET);
774 pdb_set_profile_path(sampass,
775 talloc_sub_basic(ctx, username, domain,
780 acct_desc = smbldap_talloc_single_attribute(
781 ldap_state->smbldap_state->ldap_struct,
783 get_userattr_key2string(ldap_state->schema_ver,
787 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
790 workstations = smbldap_talloc_single_attribute(
791 ldap_state->smbldap_state->ldap_struct,
793 get_userattr_key2string(ldap_state->schema_ver,
797 pdb_set_workstations(sampass, workstations, PDB_SET);
800 munged_dial = smbldap_talloc_single_attribute(
801 ldap_state->smbldap_state->ldap_struct,
803 get_userattr_key2string(ldap_state->schema_ver,
804 LDAP_ATTR_MUNGED_DIAL),
807 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
810 /* FIXME: hours stuff should be cleaner */
814 memset(hours, 0xff, hours_len);
816 if (ldap_state->is_nds_ldap) {
819 char clear_text_pw[512];
821 /* Make call to Novell eDirectory ldap extension to get clear text password.
822 NOTE: This will only work if we have an SSL connection to eDirectory. */
823 user_dn = smbldap_talloc_dn(ctx, ldap_state->smbldap_state->ldap_struct, entry);
824 if (user_dn != NULL) {
825 DEBUG(3, ("init_sam_from_ldap: smbldap_talloc_dn(ctx, %s) returned '%s'\n", username, user_dn));
827 pwd_len = sizeof(clear_text_pw);
828 if (pdb_nds_get_password(ldap_state->smbldap_state, user_dn, &pwd_len, clear_text_pw) == LDAP_SUCCESS) {
829 nt_lm_owf_gen(clear_text_pw, smbntpwd, smblmpwd);
830 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET)) {
831 TALLOC_FREE(user_dn);
834 ZERO_STRUCT(smblmpwd);
835 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET)) {
836 TALLOC_FREE(user_dn);
839 ZERO_STRUCT(smbntpwd);
840 use_samba_attrs = False;
843 TALLOC_FREE(user_dn);
846 DEBUG(0, ("init_sam_from_ldap: failed to get user_dn for '%s'\n", username));
850 if (use_samba_attrs) {
851 temp = smbldap_talloc_single_attribute(
852 ldap_state->smbldap_state->ldap_struct,
854 get_userattr_key2string(ldap_state->schema_ver,
858 pdb_gethexpwd(temp, smblmpwd);
859 memset((char *)temp, '\0', strlen(temp)+1);
860 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET)) {
863 ZERO_STRUCT(smblmpwd);
866 temp = smbldap_talloc_single_attribute(
867 ldap_state->smbldap_state->ldap_struct,
869 get_userattr_key2string(ldap_state->schema_ver,
873 pdb_gethexpwd(temp, smbntpwd);
874 memset((char *)temp, '\0', strlen(temp)+1);
875 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET)) {
878 ZERO_STRUCT(smbntpwd);
884 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
886 uint8 *pwhist = NULL;
888 char *history_string = TALLOC_ARRAY(ctx, char,
889 MAX_PW_HISTORY_LEN*64);
891 if (!history_string) {
895 pwHistLen = MIN(pwHistLen, MAX_PW_HISTORY_LEN);
897 pwhist = TALLOC_ARRAY(ctx, uint8,
898 pwHistLen * PW_HISTORY_ENTRY_LEN);
899 if (pwhist == NULL) {
900 DEBUG(0, ("init_sam_from_ldap: talloc failed!\n"));
903 memset(pwhist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
905 if (smbldap_get_single_attribute(
906 ldap_state->smbldap_state->ldap_struct,
908 get_userattr_key2string(ldap_state->schema_ver,
909 LDAP_ATTR_PWD_HISTORY),
911 MAX_PW_HISTORY_LEN*64)) {
912 bool hex_failed = false;
913 for (i = 0; i < pwHistLen; i++){
914 /* Get the 16 byte salt. */
915 if (!pdb_gethexpwd(&history_string[i*64],
916 &pwhist[i*PW_HISTORY_ENTRY_LEN])) {
920 /* Get the 16 byte MD5 hash of salt+passwd. */
921 if (!pdb_gethexpwd(&history_string[(i*64)+32],
922 &pwhist[(i*PW_HISTORY_ENTRY_LEN)+
923 PW_HISTORY_SALT_LEN])) {
929 DEBUG(2,("init_sam_from_ldap: Failed to get password history for user %s\n",
931 memset(pwhist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
934 if (!pdb_set_pw_history(sampass, pwhist, pwHistLen, PDB_SET)){
939 temp = smbldap_talloc_single_attribute(
940 ldap_state->smbldap_state->ldap_struct,
942 get_userattr_key2string(ldap_state->schema_ver,
946 acct_ctrl = pdb_decode_acct_ctrl(temp);
948 if (acct_ctrl == 0) {
949 acct_ctrl |= ACB_NORMAL;
952 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
954 acct_ctrl |= ACB_NORMAL;
957 pdb_set_hours_len(sampass, hours_len, PDB_SET);
958 pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
960 temp = smbldap_talloc_single_attribute(
961 ldap_state->smbldap_state->ldap_struct,
963 get_userattr_key2string(ldap_state->schema_ver,
964 LDAP_ATTR_BAD_PASSWORD_COUNT),
967 bad_password_count = (uint32_t) atol(temp);
968 pdb_set_bad_password_count(sampass,
969 bad_password_count, PDB_SET);
972 temp = smbldap_talloc_single_attribute(
973 ldap_state->smbldap_state->ldap_struct,
975 get_userattr_key2string(ldap_state->schema_ver,
976 LDAP_ATTR_BAD_PASSWORD_TIME),
979 bad_password_time = (time_t) atol(temp);
980 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
984 temp = smbldap_talloc_single_attribute(
985 ldap_state->smbldap_state->ldap_struct,
987 get_userattr_key2string(ldap_state->schema_ver,
988 LDAP_ATTR_LOGON_COUNT),
991 logon_count = (uint32_t) atol(temp);
992 pdb_set_logon_count(sampass, logon_count, PDB_SET);
995 /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
997 temp = smbldap_talloc_single_attribute(
998 ldap_state->smbldap_state->ldap_struct,
1000 get_userattr_key2string(ldap_state->schema_ver,
1001 LDAP_ATTR_LOGON_HOURS),
1004 pdb_gethexhours(temp, hours);
1005 memset((char *)temp, '\0', strlen(temp) +1);
1006 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
1010 if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
1011 struct passwd unix_pw;
1012 bool have_uid = false;
1013 bool have_gid = false;
1014 struct dom_sid mapped_gsid;
1015 const struct dom_sid *primary_gsid;
1017 ZERO_STRUCT(unix_pw);
1019 unix_pw.pw_name = username;
1020 unix_pw.pw_passwd = discard_const_p(char, "x");
1022 temp = smbldap_talloc_single_attribute(
1023 priv2ld(ldap_state),
1028 /* We've got a uid, feed the cache */
1029 unix_pw.pw_uid = strtoul(temp, NULL, 10);
1032 temp = smbldap_talloc_single_attribute(
1033 priv2ld(ldap_state),
1038 /* We've got a uid, feed the cache */
1039 unix_pw.pw_gid = strtoul(temp, NULL, 10);
1042 unix_pw.pw_gecos = smbldap_talloc_single_attribute(
1043 priv2ld(ldap_state),
1047 if (unix_pw.pw_gecos) {
1048 unix_pw.pw_gecos = fullname;
1050 unix_pw.pw_dir = smbldap_talloc_single_attribute(
1051 priv2ld(ldap_state),
1055 if (unix_pw.pw_dir) {
1056 unix_pw.pw_dir = discard_const_p(char, "");
1058 unix_pw.pw_shell = smbldap_talloc_single_attribute(
1059 priv2ld(ldap_state),
1063 if (unix_pw.pw_shell) {
1064 unix_pw.pw_shell = discard_const_p(char, "");
1067 if (have_uid && have_gid) {
1068 sampass->unix_pw = tcopy_passwd(sampass, &unix_pw);
1070 sampass->unix_pw = Get_Pwnam_alloc(sampass, unix_pw.pw_name);
1073 if (sampass->unix_pw == NULL) {
1074 DEBUG(0,("init_sam_from_ldap: Failed to find Unix account for %s\n",
1075 pdb_get_username(sampass)));
1079 store_uid_sid_cache(pdb_get_user_sid(sampass),
1080 sampass->unix_pw->pw_uid);
1081 idmap_cache_set_sid2uid(pdb_get_user_sid(sampass),
1082 sampass->unix_pw->pw_uid);
1084 gid_to_sid(&mapped_gsid, sampass->unix_pw->pw_gid);
1085 primary_gsid = pdb_get_group_sid(sampass);
1086 if (primary_gsid && dom_sid_equal(primary_gsid, &mapped_gsid)) {
1087 store_gid_sid_cache(primary_gsid,
1088 sampass->unix_pw->pw_gid);
1089 idmap_cache_set_sid2gid(primary_gsid,
1090 sampass->unix_pw->pw_gid);
1094 /* check the timestamp of the cache vs ldap entry */
1095 if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state,
1101 /* see if we have newer updates */
1102 if (!login_cache_read(sampass, &cache_entry)) {
1103 DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n",
1104 (unsigned int)pdb_get_bad_password_count(sampass),
1105 (unsigned int)pdb_get_bad_password_time(sampass)));
1110 DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n",
1111 (unsigned int)ldap_entry_time,
1112 (unsigned int)cache_entry.entry_timestamp,
1113 (unsigned int)cache_entry.bad_password_time));
1115 if (ldap_entry_time > cache_entry.entry_timestamp) {
1116 /* cache is older than directory , so
1117 we need to delete the entry but allow the
1118 fields to be written out */
1119 login_cache_delentry(sampass);
1122 pdb_set_acct_ctrl(sampass,
1123 pdb_get_acct_ctrl(sampass) |
1124 (cache_entry.acct_ctrl & ACB_AUTOLOCK),
1126 pdb_set_bad_password_count(sampass,
1127 cache_entry.bad_password_count,
1129 pdb_set_bad_password_time(sampass,
1130 cache_entry.bad_password_time,
1142 /**********************************************************************
1143 Initialize the ldap db from a struct samu. Called on update.
1144 (Based on init_buffer_from_sam in pdb_tdb.c)
1145 *********************************************************************/
1147 static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
1148 LDAPMessage *existing,
1149 LDAPMod *** mods, struct samu * sampass,
1150 bool (*need_update)(const struct samu *,
1156 if (mods == NULL || sampass == NULL) {
1157 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
1164 * took out adding "objectclass: sambaAccount"
1165 * do this on a per-mod basis
1167 if (need_update(sampass, PDB_USERNAME)) {
1168 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1169 "uid", pdb_get_username(sampass));
1170 if (ldap_state->is_nds_ldap) {
1171 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1172 "cn", pdb_get_username(sampass));
1173 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1174 "sn", pdb_get_username(sampass));
1178 DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass)));
1180 /* only update the RID if we actually need to */
1181 if (need_update(sampass, PDB_USERSID)) {
1183 const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
1185 switch ( ldap_state->schema_ver ) {
1186 case SCHEMAVER_SAMBAACCOUNT:
1187 if (!sid_peek_check_rid(&ldap_state->domain_sid, user_sid, &rid)) {
1188 DEBUG(1, ("init_ldap_from_sam: User's SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
1189 sid_string_dbg(user_sid),
1191 &ldap_state->domain_sid)));
1194 if (asprintf(&temp, "%i", rid) < 0) {
1197 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1198 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
1203 case SCHEMAVER_SAMBASAMACCOUNT:
1204 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1205 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
1206 sid_to_fstring(sid_string, user_sid));
1210 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
1215 /* we don't need to store the primary group RID - so leaving it
1216 'free' to hang off the unix primary group makes life easier */
1218 if (need_update(sampass, PDB_GROUPSID)) {
1220 const struct dom_sid *group_sid = pdb_get_group_sid(sampass);
1222 switch ( ldap_state->schema_ver ) {
1223 case SCHEMAVER_SAMBAACCOUNT:
1224 if (!sid_peek_check_rid(&ldap_state->domain_sid, group_sid, &rid)) {
1225 DEBUG(1, ("init_ldap_from_sam: User's Primary Group SID (%s) is not for this domain (%s), cannot add to LDAP!\n",
1226 sid_string_dbg(group_sid),
1228 &ldap_state->domain_sid)));
1232 if (asprintf(&temp, "%i", rid) < 0) {
1235 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1236 get_userattr_key2string(ldap_state->schema_ver,
1237 LDAP_ATTR_PRIMARY_GROUP_RID), temp);
1241 case SCHEMAVER_SAMBASAMACCOUNT:
1242 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1243 get_userattr_key2string(ldap_state->schema_ver,
1244 LDAP_ATTR_PRIMARY_GROUP_SID), sid_to_fstring(sid_string, group_sid));
1248 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
1254 /* displayName, cn, and gecos should all be the same
1255 * most easily accomplished by giving them the same OID
1256 * gecos isn't set here b/c it should be handled by the
1258 * We change displayName only and fall back to cn if
1259 * it does not exist.
1262 if (need_update(sampass, PDB_FULLNAME))
1263 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1264 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME),
1265 pdb_get_fullname(sampass));
1267 if (need_update(sampass, PDB_ACCTDESC))
1268 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1269 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC),
1270 pdb_get_acct_desc(sampass));
1272 if (need_update(sampass, PDB_WORKSTATIONS))
1273 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1274 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS),
1275 pdb_get_workstations(sampass));
1277 if (need_update(sampass, PDB_MUNGEDDIAL))
1278 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1279 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL),
1280 pdb_get_munged_dial(sampass));
1282 if (need_update(sampass, PDB_SMBHOME))
1283 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1284 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH),
1285 pdb_get_homedir(sampass));
1287 if (need_update(sampass, PDB_DRIVE))
1288 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1289 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE),
1290 pdb_get_dir_drive(sampass));
1292 if (need_update(sampass, PDB_LOGONSCRIPT))
1293 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1294 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT),
1295 pdb_get_logon_script(sampass));
1297 if (need_update(sampass, PDB_PROFILE))
1298 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1299 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH),
1300 pdb_get_profile_path(sampass));
1302 if (asprintf(&temp, "%li", (long int)pdb_get_logon_time(sampass)) < 0) {
1305 if (need_update(sampass, PDB_LOGONTIME))
1306 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1307 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
1310 if (asprintf(&temp, "%li", (long int)pdb_get_logoff_time(sampass)) < 0) {
1313 if (need_update(sampass, PDB_LOGOFFTIME))
1314 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1315 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
1318 if (asprintf(&temp, "%li", (long int)pdb_get_kickoff_time(sampass)) < 0) {
1321 if (need_update(sampass, PDB_KICKOFFTIME))
1322 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1323 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
1326 if (asprintf(&temp, "%li", (long int)pdb_get_pass_can_change_time_noncalc(sampass)) < 0) {
1329 if (need_update(sampass, PDB_CANCHANGETIME))
1330 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1331 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
1334 if (asprintf(&temp, "%li", (long int)pdb_get_pass_must_change_time(sampass)) < 0) {
1337 if (need_update(sampass, PDB_MUSTCHANGETIME))
1338 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1339 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp);
1342 if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
1343 || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
1345 if (need_update(sampass, PDB_LMPASSWD)) {
1346 const uchar *lm_pw = pdb_get_lanman_passwd(sampass);
1349 pdb_sethexpwd(pwstr, lm_pw,
1350 pdb_get_acct_ctrl(sampass));
1351 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1352 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
1355 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1356 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
1360 if (need_update(sampass, PDB_NTPASSWD)) {
1361 const uchar *nt_pw = pdb_get_nt_passwd(sampass);
1364 pdb_sethexpwd(pwstr, nt_pw,
1365 pdb_get_acct_ctrl(sampass));
1366 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1367 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
1370 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1371 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
1376 if (need_update(sampass, PDB_PWHISTORY)) {
1378 uint32_t pwHistLen = 0;
1379 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
1381 pwstr = SMB_MALLOC_ARRAY(char, 1024);
1385 if (pwHistLen == 0) {
1386 /* Remove any password history from the LDAP store. */
1387 memset(pwstr, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
1391 uint32_t currHistLen = 0;
1392 const uint8 *pwhist = pdb_get_pw_history(sampass, &currHistLen);
1393 if (pwhist != NULL) {
1394 /* We can only store (1024-1/64 password history entries. */
1395 pwHistLen = MIN(pwHistLen, ((1024-1)/64));
1396 for (i=0; i< pwHistLen && i < currHistLen; i++) {
1397 /* Store the salt. */
1398 pdb_sethexpwd(&pwstr[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN], 0);
1399 /* Followed by the md5 hash of salt + md4 hash */
1400 pdb_sethexpwd(&pwstr[(i*64)+32],
1401 &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN], 0);
1402 DEBUG(100, ("pwstr=%s\n", pwstr));
1406 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1407 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY),
1412 if (need_update(sampass, PDB_PASSLASTSET)) {
1413 if (asprintf(&temp, "%li",
1414 (long int)pdb_get_pass_last_set_time(sampass)) < 0) {
1417 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1418 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET),
1424 if (need_update(sampass, PDB_HOURS)) {
1425 const uint8 *hours = pdb_get_hours(sampass);
1428 pdb_sethexhours(hourstr, hours);
1429 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct,
1432 get_userattr_key2string(ldap_state->schema_ver,
1433 LDAP_ATTR_LOGON_HOURS),
1438 if (need_update(sampass, PDB_ACCTCTRL))
1439 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
1440 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO),
1441 pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
1443 /* password lockout cache:
1444 - If we are now autolocking or clearing, we write to ldap
1445 - If we are clearing, we delete the cache entry
1446 - If the count is > 0, we update the cache
1448 This even means when autolocking, we cache, just in case the
1449 update doesn't work, and we have to cache the autolock flag */
1451 if (need_update(sampass, PDB_BAD_PASSWORD_COUNT)) /* &&
1452 need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ {
1453 uint16_t badcount = pdb_get_bad_password_count(sampass);
1454 time_t badtime = pdb_get_bad_password_time(sampass);
1456 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &pol);
1458 DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
1459 (unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime));
1461 if ((badcount >= pol) || (badcount == 0)) {
1462 DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n",
1463 (unsigned int)badcount, (unsigned int)badtime));
1464 if (asprintf(&temp, "%li", (long)badcount) < 0) {
1468 ldap_state->smbldap_state->ldap_struct,
1470 get_userattr_key2string(
1471 ldap_state->schema_ver,
1472 LDAP_ATTR_BAD_PASSWORD_COUNT),
1476 if (asprintf(&temp, "%li", (long int)badtime) < 0) {
1480 ldap_state->smbldap_state->ldap_struct,
1482 get_userattr_key2string(
1483 ldap_state->schema_ver,
1484 LDAP_ATTR_BAD_PASSWORD_TIME),
1488 if (badcount == 0) {
1489 DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass)));
1490 login_cache_delentry(sampass);
1492 struct login_cache cache_entry;
1494 cache_entry.entry_timestamp = time(NULL);
1495 cache_entry.acct_ctrl = pdb_get_acct_ctrl(sampass);
1496 cache_entry.bad_password_count = badcount;
1497 cache_entry.bad_password_time = badtime;
1499 DEBUG(7, ("Updating bad password count and time in login cache\n"));
1500 login_cache_write(sampass, &cache_entry);
1507 /**********************************************************************
1508 End enumeration of the LDAP password list.
1509 *********************************************************************/
1511 static void ldapsam_endsampwent(struct pdb_methods *my_methods)
1513 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1514 if (ldap_state->result) {
1515 ldap_msgfree(ldap_state->result);
1516 ldap_state->result = NULL;
1520 static void append_attr(TALLOC_CTX *mem_ctx, const char ***attr_list,
1521 const char *new_attr)
1525 if (new_attr == NULL) {
1529 for (i=0; (*attr_list)[i] != NULL; i++) {
1533 (*attr_list) = TALLOC_REALLOC_ARRAY(mem_ctx, (*attr_list),
1535 SMB_ASSERT((*attr_list) != NULL);
1536 (*attr_list)[i] = talloc_strdup((*attr_list), new_attr);
1537 (*attr_list)[i+1] = NULL;
1540 static void ldapsam_add_unix_attributes(TALLOC_CTX *mem_ctx,
1541 const char ***attr_list)
1543 append_attr(mem_ctx, attr_list, "uidNumber");
1544 append_attr(mem_ctx, attr_list, "gidNumber");
1545 append_attr(mem_ctx, attr_list, "homeDirectory");
1546 append_attr(mem_ctx, attr_list, "loginShell");
1547 append_attr(mem_ctx, attr_list, "gecos");
1550 /**********************************************************************
1551 Get struct samu entry from LDAP by username.
1552 *********************************************************************/
1554 static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu *user, const char *sname)
1556 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1557 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1558 LDAPMessage *result = NULL;
1559 LDAPMessage *entry = NULL;
1561 const char ** attr_list;
1564 attr_list = get_userattr_list( user, ldap_state->schema_ver );
1565 append_attr(user, &attr_list,
1566 get_userattr_key2string(ldap_state->schema_ver,
1567 LDAP_ATTR_MOD_TIMESTAMP));
1568 ldapsam_add_unix_attributes(user, &attr_list);
1569 rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result,
1571 TALLOC_FREE( attr_list );
1573 if ( rc != LDAP_SUCCESS )
1574 return NT_STATUS_NO_SUCH_USER;
1576 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1579 DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname, count));
1580 ldap_msgfree(result);
1581 return NT_STATUS_NO_SUCH_USER;
1582 } else if (count > 1) {
1583 DEBUG(1, ("ldapsam_getsampwnam: Duplicate entries for this user [%s] Failing. count=%d\n", sname, count));
1584 ldap_msgfree(result);
1585 return NT_STATUS_NO_SUCH_USER;
1588 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1590 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1591 DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
1592 ldap_msgfree(result);
1593 return NT_STATUS_NO_SUCH_USER;
1595 pdb_set_backend_private_data(user, result, NULL,
1596 my_methods, PDB_CHANGED);
1597 talloc_autofree_ldapmsg(user, result);
1600 ldap_msgfree(result);
1605 static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
1606 const struct dom_sid *sid, LDAPMessage **result)
1609 const char ** attr_list;
1612 switch ( ldap_state->schema_ver ) {
1613 case SCHEMAVER_SAMBASAMACCOUNT: {
1614 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
1615 if (tmp_ctx == NULL) {
1616 return LDAP_NO_MEMORY;
1619 attr_list = get_userattr_list(tmp_ctx,
1620 ldap_state->schema_ver);
1621 append_attr(tmp_ctx, &attr_list,
1622 get_userattr_key2string(
1623 ldap_state->schema_ver,
1624 LDAP_ATTR_MOD_TIMESTAMP));
1625 ldapsam_add_unix_attributes(tmp_ctx, &attr_list);
1626 rc = ldapsam_search_suffix_by_sid(ldap_state, sid,
1628 TALLOC_FREE(tmp_ctx);
1630 if ( rc != LDAP_SUCCESS )
1635 case SCHEMAVER_SAMBAACCOUNT:
1636 if (!sid_peek_check_rid(&ldap_state->domain_sid, sid, &rid)) {
1640 attr_list = get_userattr_list(NULL,
1641 ldap_state->schema_ver);
1642 rc = ldapsam_search_suffix_by_rid(ldap_state, rid, result, attr_list );
1643 TALLOC_FREE( attr_list );
1645 if ( rc != LDAP_SUCCESS )
1652 /**********************************************************************
1653 Get struct samu entry from LDAP by SID.
1654 *********************************************************************/
1656 static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const struct dom_sid *sid)
1658 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1659 LDAPMessage *result = NULL;
1660 LDAPMessage *entry = NULL;
1664 rc = ldapsam_get_ldap_user_by_sid(ldap_state,
1666 if (rc != LDAP_SUCCESS)
1667 return NT_STATUS_NO_SUCH_USER;
1669 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
1672 DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] "
1673 "count=%d\n", sid_string_dbg(sid), count));
1674 ldap_msgfree(result);
1675 return NT_STATUS_NO_SUCH_USER;
1676 } else if (count > 1) {
1677 DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID "
1678 "[%s]. Failing. count=%d\n", sid_string_dbg(sid),
1680 ldap_msgfree(result);
1681 return NT_STATUS_NO_SUCH_USER;
1684 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1686 ldap_msgfree(result);
1687 return NT_STATUS_NO_SUCH_USER;
1690 if (!init_sam_from_ldap(ldap_state, user, entry)) {
1691 DEBUG(1,("ldapsam_getsampwsid: init_sam_from_ldap failed!\n"));
1692 ldap_msgfree(result);
1693 return NT_STATUS_NO_SUCH_USER;
1696 pdb_set_backend_private_data(user, result, NULL,
1697 my_methods, PDB_CHANGED);
1698 talloc_autofree_ldapmsg(user, result);
1699 return NT_STATUS_OK;
1702 /********************************************************************
1703 Do the actual modification - also change a plaintext passord if
1705 **********************************************************************/
1707 static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
1708 struct samu *newpwd, char *dn,
1709 LDAPMod **mods, int ldap_op,
1710 bool (*need_update)(const struct samu *, enum pdb_elements))
1712 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1715 if (!newpwd || !dn) {
1716 return NT_STATUS_INVALID_PARAMETER;
1719 if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) &&
1720 (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) &&
1721 need_update(newpwd, PDB_PLAINTEXT_PW) &&
1722 (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
1725 char *retoid = NULL;
1726 struct berval *retdata = NULL;
1727 char *utf8_password;
1729 size_t converted_size;
1732 if (!ldap_state->is_nds_ldap) {
1734 if (!smbldap_has_extension(ldap_state->smbldap_state->ldap_struct,
1735 LDAP_EXOP_MODIFY_PASSWD)) {
1736 DEBUG(2, ("ldap password change requested, but LDAP "
1737 "server does not support it -- ignoring\n"));
1738 return NT_STATUS_OK;
1742 if (!push_utf8_talloc(talloc_tos(), &utf8_password,
1743 pdb_get_plaintext_passwd(newpwd),
1746 return NT_STATUS_NO_MEMORY;
1749 if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
1750 TALLOC_FREE(utf8_password);
1751 return NT_STATUS_NO_MEMORY;
1754 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
1755 DEBUG(0,("ber_alloc_t returns NULL\n"));
1756 TALLOC_FREE(utf8_password);
1757 TALLOC_FREE(utf8_dn);
1758 return NT_STATUS_UNSUCCESSFUL;
1761 if ((ber_printf (ber, "{") < 0) ||
1762 (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID,
1764 DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
1767 TALLOC_FREE(utf8_dn);
1768 TALLOC_FREE(utf8_password);
1769 return NT_STATUS_UNSUCCESSFUL;
1772 if ((utf8_password != NULL) && (*utf8_password != '\0')) {
1773 ret = ber_printf(ber, "ts}",
1774 LDAP_TAG_EXOP_MODIFY_PASSWD_NEW,
1777 ret = ber_printf(ber, "}");
1781 DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
1784 TALLOC_FREE(utf8_dn);
1785 TALLOC_FREE(utf8_password);
1786 return NT_STATUS_UNSUCCESSFUL;
1789 if ((rc = ber_flatten (ber, &bv))<0) {
1790 DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
1792 TALLOC_FREE(utf8_dn);
1793 TALLOC_FREE(utf8_password);
1794 return NT_STATUS_UNSUCCESSFUL;
1797 TALLOC_FREE(utf8_dn);
1798 TALLOC_FREE(utf8_password);
1801 if (!ldap_state->is_nds_ldap) {
1802 rc = smbldap_extended_operation(ldap_state->smbldap_state,
1803 LDAP_EXOP_MODIFY_PASSWD,
1804 bv, NULL, NULL, &retoid,
1807 rc = pdb_nds_set_password(ldap_state->smbldap_state, dn,
1808 pdb_get_plaintext_passwd(newpwd));
1810 if (rc != LDAP_SUCCESS) {
1811 char *ld_error = NULL;
1813 if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
1814 DEBUG(3, ("Could not set userPassword "
1815 "attribute due to an objectClass "
1816 "violation -- ignoring\n"));
1818 return NT_STATUS_OK;
1821 ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
1823 DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n",
1824 pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
1825 SAFE_FREE(ld_error);
1827 #if defined(LDAP_CONSTRAINT_VIOLATION)
1828 if (rc == LDAP_CONSTRAINT_VIOLATION)
1829 return NT_STATUS_PASSWORD_RESTRICTION;
1831 return NT_STATUS_UNSUCCESSFUL;
1833 DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
1834 #ifdef DEBUG_PASSWORD
1835 DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd)));
1838 ber_bvfree(retdata);
1840 ldap_memfree(retoid);
1846 DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
1847 /* may be password change below however */
1851 if (ldap_state->is_nds_ldap) {
1852 smbldap_set_mod(&mods, LDAP_MOD_ADD,
1856 smbldap_set_mod(&mods, LDAP_MOD_ADD,
1860 rc = smbldap_add(ldap_state->smbldap_state,
1863 case LDAP_MOD_REPLACE:
1864 rc = smbldap_modify(ldap_state->smbldap_state,
1868 DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n",
1870 return NT_STATUS_INVALID_PARAMETER;
1873 if (rc!=LDAP_SUCCESS) {
1874 return NT_STATUS_UNSUCCESSFUL;
1878 return NT_STATUS_OK;
1881 /**********************************************************************
1882 Delete entry from LDAP for username.
1883 *********************************************************************/
1885 static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods,
1886 struct samu * sam_acct)
1888 struct ldapsam_privates *priv =
1889 (struct ldapsam_privates *)my_methods->private_data;
1892 LDAPMessage *msg, *entry;
1893 NTSTATUS result = NT_STATUS_NO_MEMORY;
1894 const char **attr_list;
1895 TALLOC_CTX *mem_ctx;
1898 DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n"));
1899 return NT_STATUS_INVALID_PARAMETER;
1902 sname = pdb_get_username(sam_acct);
1904 DEBUG(3, ("ldapsam_delete_sam_account: Deleting user %s from "
1907 mem_ctx = talloc_new(NULL);
1908 if (mem_ctx == NULL) {
1909 DEBUG(0, ("talloc_new failed\n"));
1913 attr_list = get_userattr_delete_list(mem_ctx, priv->schema_ver );
1914 if (attr_list == NULL) {
1918 rc = ldapsam_search_suffix_by_name(priv, sname, &msg, attr_list);
1920 if ((rc != LDAP_SUCCESS) ||
1921 (ldap_count_entries(priv2ld(priv), msg) != 1) ||
1922 ((entry = ldap_first_entry(priv2ld(priv), msg)) == NULL)) {
1923 DEBUG(5, ("Could not find user %s\n", sname));
1924 result = NT_STATUS_NO_SUCH_USER;
1928 rc = ldapsam_delete_entry(
1929 priv, mem_ctx, entry,
1930 priv->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ?
1931 LDAP_OBJ_SAMBASAMACCOUNT : LDAP_OBJ_SAMBAACCOUNT,
1934 result = (rc == LDAP_SUCCESS) ?
1935 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
1938 TALLOC_FREE(mem_ctx);
1942 /**********************************************************************
1943 Helper function to determine for update_sam_account whether
1944 we need LDAP modification.
1945 *********************************************************************/
1947 static bool element_is_changed(const struct samu *sampass,
1948 enum pdb_elements element)
1950 return IS_SAM_CHANGED(sampass, element);
1953 /**********************************************************************
1955 *********************************************************************/
1957 static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struct samu * newpwd)
1959 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
1960 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
1963 LDAPMessage *result = NULL;
1964 LDAPMessage *entry = NULL;
1965 LDAPMod **mods = NULL;
1966 const char **attr_list;
1968 result = (LDAPMessage *)pdb_get_backend_private_data(newpwd, my_methods);
1970 attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
1971 if (pdb_get_username(newpwd) == NULL) {
1972 return NT_STATUS_INVALID_PARAMETER;
1974 rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
1975 TALLOC_FREE( attr_list );
1976 if (rc != LDAP_SUCCESS) {
1977 return NT_STATUS_UNSUCCESSFUL;
1979 pdb_set_backend_private_data(newpwd, result, NULL,
1980 my_methods, PDB_CHANGED);
1981 talloc_autofree_ldapmsg(newpwd, result);
1984 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
1985 DEBUG(0, ("ldapsam_update_sam_account: No user to modify!\n"));
1986 return NT_STATUS_UNSUCCESSFUL;
1989 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
1990 dn = smbldap_talloc_dn(talloc_tos(), ldap_state->smbldap_state->ldap_struct, entry);
1992 return NT_STATUS_UNSUCCESSFUL;
1995 DEBUG(4, ("ldapsam_update_sam_account: user %s to be modified has dn: %s\n", pdb_get_username(newpwd), dn));
1997 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
1998 element_is_changed)) {
1999 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
2002 ldap_mods_free(mods,True);
2003 return NT_STATUS_UNSUCCESSFUL;
2006 if ((lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_ONLY)
2007 && (mods == NULL)) {
2008 DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
2009 pdb_get_username(newpwd)));
2011 return NT_STATUS_OK;
2014 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed);
2017 ldap_mods_free(mods,True);
2023 * We need to set the backend private data to NULL here. For example
2024 * setuserinfo level 25 does a pdb_update_sam_account twice on the
2025 * same one, and with the explicit delete / add logic for attribute
2026 * values the second time we would use the wrong "old" value which
2027 * does not exist in LDAP anymore. Thus the LDAP server would refuse
2029 * The existing LDAPMessage is still being auto-freed by the
2032 pdb_set_backend_private_data(newpwd, NULL, NULL, my_methods,
2035 if (!NT_STATUS_IS_OK(ret)) {
2039 DEBUG(2, ("ldapsam_update_sam_account: successfully modified uid = %s in the LDAP database\n",
2040 pdb_get_username(newpwd)));
2041 return NT_STATUS_OK;
2044 /***************************************************************************
2045 Renames a struct samu
2046 - The "rename user script" has full responsibility for changing everything
2047 ***************************************************************************/
2049 static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods,
2050 TALLOC_CTX *tmp_ctx,
2052 uint32_t member_rid);
2054 static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
2055 TALLOC_CTX *mem_ctx,
2057 struct dom_sid **pp_sids,
2059 uint32_t *p_num_groups);
2061 static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
2062 struct samu *old_acct,
2063 const char *newname)
2065 const char *oldname;
2067 char *rename_script = NULL;
2068 fstring oldname_lower, newname_lower;
2071 DEBUG(0, ("ldapsam_rename_sam_account: old_acct was NULL!\n"));
2072 return NT_STATUS_INVALID_PARAMETER;
2075 DEBUG(0, ("ldapsam_rename_sam_account: newname was NULL!\n"));
2076 return NT_STATUS_INVALID_PARAMETER;
2079 oldname = pdb_get_username(old_acct);
2081 /* rename the posix user */
2082 rename_script = SMB_STRDUP(lp_renameuser_script());
2083 if (rename_script == NULL) {
2084 return NT_STATUS_NO_MEMORY;
2087 if (!(*rename_script)) {
2088 SAFE_FREE(rename_script);
2089 return NT_STATUS_ACCESS_DENIED;
2092 DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n",
2095 /* We have to allow the account name to end with a '$'.
2096 Also, follow the semantics in _samr_create_user() and lower case the
2097 posix name but preserve the case in passdb */
2099 fstrcpy( oldname_lower, oldname );
2100 strlower_m( oldname_lower );
2101 fstrcpy( newname_lower, newname );
2102 strlower_m( newname_lower );
2103 rename_script = realloc_string_sub2(rename_script,
2108 if (!rename_script) {
2109 return NT_STATUS_NO_MEMORY;
2111 rename_script = realloc_string_sub2(rename_script,
2116 rc = smbrun(rename_script, NULL);
2118 DEBUG(rc ? 0 : 3,("Running the command `%s' gave %d\n",
2119 rename_script, rc));
2121 SAFE_FREE(rename_script);
2124 smb_nscd_flush_user_cache();
2128 return NT_STATUS_UNSUCCESSFUL;
2130 return NT_STATUS_OK;
2133 /**********************************************************************
2134 Helper function to determine for update_sam_account whether
2135 we need LDAP modification.
2136 *********************************************************************/
2138 static bool element_is_set_or_changed(const struct samu *sampass,
2139 enum pdb_elements element)
2141 return (IS_SAM_SET(sampass, element) ||
2142 IS_SAM_CHANGED(sampass, element));
2145 /**********************************************************************
2146 Add struct samu to LDAP.
2147 *********************************************************************/
2149 static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct samu * newpwd)
2151 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2152 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
2154 LDAPMessage *result = NULL;
2155 LDAPMessage *entry = NULL;
2156 LDAPMod **mods = NULL;
2157 int ldap_op = LDAP_MOD_REPLACE;
2158 uint32_t num_result;
2159 const char **attr_list;
2160 char *escape_user = NULL;
2161 const char *username = pdb_get_username(newpwd);
2162 const struct dom_sid *sid = pdb_get_user_sid(newpwd);
2163 char *filter = NULL;
2165 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2166 TALLOC_CTX *ctx = talloc_init("ldapsam_add_sam_account");
2169 return NT_STATUS_NO_MEMORY;
2172 if (!username || !*username) {
2173 DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
2174 status = NT_STATUS_INVALID_PARAMETER;
2178 /* free this list after the second search or in case we exit on failure */
2179 attr_list = get_userattr_list(ctx, ldap_state->schema_ver);
2181 rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
2183 if (rc != LDAP_SUCCESS) {
2187 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
2188 DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n",
2192 ldap_msgfree(result);
2195 if (element_is_set_or_changed(newpwd, PDB_USERSID)) {
2196 rc = ldapsam_get_ldap_user_by_sid(ldap_state,
2198 if (rc == LDAP_SUCCESS) {
2199 if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
2200 DEBUG(0,("ldapsam_add_sam_account: SID '%s' "
2201 "already in the base, with samba "
2202 "attributes\n", sid_string_dbg(sid)));
2205 ldap_msgfree(result);
2210 /* does the entry already exist but without a samba attributes?
2211 we need to return the samba attributes here */
2213 escape_user = escape_ldap_string(talloc_tos(), username);
2214 filter = talloc_strdup(attr_list, "(uid=%u)");
2216 status = NT_STATUS_NO_MEMORY;
2219 filter = talloc_all_string_sub(attr_list, filter, "%u", escape_user);
2220 TALLOC_FREE(escape_user);
2222 status = NT_STATUS_NO_MEMORY;
2226 rc = smbldap_search_suffix(ldap_state->smbldap_state,
2227 filter, attr_list, &result);
2228 if ( rc != LDAP_SUCCESS ) {
2232 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2234 if (num_result > 1) {
2235 DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
2239 /* Check if we need to update an existing entry */
2240 if (num_result == 1) {
2241 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
2242 ldap_op = LDAP_MOD_REPLACE;
2243 entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
2244 dn = smbldap_talloc_dn(ctx, ldap_state->smbldap_state->ldap_struct, entry);
2246 status = NT_STATUS_NO_MEMORY;
2250 } else if (ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT) {
2252 /* There might be a SID for this account already - say an idmap entry */
2254 filter = talloc_asprintf(ctx,
2255 "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
2256 get_userattr_key2string(ldap_state->schema_ver,
2257 LDAP_ATTR_USER_SID),
2258 sid_string_talloc(ctx, sid),
2259 LDAP_OBJ_IDMAP_ENTRY,
2260 LDAP_OBJ_SID_ENTRY);
2262 status = NT_STATUS_NO_MEMORY;
2266 /* free old result before doing a new search */
2267 if (result != NULL) {
2268 ldap_msgfree(result);
2271 rc = smbldap_search_suffix(ldap_state->smbldap_state,
2272 filter, attr_list, &result);
2274 if ( rc != LDAP_SUCCESS ) {
2278 num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
2280 if (num_result > 1) {
2281 DEBUG (0, ("ldapsam_add_sam_account: More than one user with specified Sid exists: bailing out!\n"));
2285 /* Check if we need to update an existing entry */
2286 if (num_result == 1) {
2288 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
2289 ldap_op = LDAP_MOD_REPLACE;
2290 entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
2291 dn = smbldap_talloc_dn (ctx, ldap_state->smbldap_state->ldap_struct, entry);
2293 status = NT_STATUS_NO_MEMORY;
2299 if (num_result == 0) {
2300 char *escape_username;
2301 /* Check if we need to add an entry */
2302 DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
2303 ldap_op = LDAP_MOD_ADD;
2305 escape_username = escape_rdn_val_string_alloc(username);
2306 if (!escape_username) {
2307 status = NT_STATUS_NO_MEMORY;
2311 if (username[strlen(username)-1] == '$') {
2312 dn = talloc_asprintf(ctx,
2315 lp_ldap_machine_suffix());
2317 dn = talloc_asprintf(ctx,
2320 lp_ldap_user_suffix());
2323 SAFE_FREE(escape_username);
2325 status = NT_STATUS_NO_MEMORY;
2330 if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
2331 element_is_set_or_changed)) {
2332 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
2334 ldap_mods_free(mods, true);
2340 DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
2343 switch ( ldap_state->schema_ver ) {
2344 case SCHEMAVER_SAMBAACCOUNT:
2345 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT);
2347 case SCHEMAVER_SAMBASAMACCOUNT:
2348 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
2351 DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
2355 ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, element_is_set_or_changed);
2356 if (!NT_STATUS_IS_OK(ret)) {
2357 DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
2358 pdb_get_username(newpwd),dn));
2359 ldap_mods_free(mods, true);
2363 DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
2364 ldap_mods_free(mods, true);
2366 status = NT_STATUS_OK;
2372 ldap_msgfree(result);
2377 /**********************************************************************
2378 *********************************************************************/
2380 static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
2382 LDAPMessage ** result)
2384 int scope = LDAP_SCOPE_SUBTREE;
2386 const char **attr_list;
2388 attr_list = get_attr_list(NULL, groupmap_attr_list);
2389 rc = smbldap_search(ldap_state->smbldap_state,
2390 lp_ldap_suffix (), scope,
2391 filter, attr_list, 0, result);
2392 TALLOC_FREE(attr_list);
2397 /**********************************************************************
2398 *********************************************************************/
2400 static bool init_group_from_ldap(struct ldapsam_privates *ldap_state,
2401 GROUP_MAP *map, LDAPMessage *entry)
2404 TALLOC_CTX *ctx = talloc_init("init_group_from_ldap");
2406 if (ldap_state == NULL || map == NULL || entry == NULL ||
2407 ldap_state->smbldap_state->ldap_struct == NULL) {
2408 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
2413 temp = smbldap_talloc_single_attribute(
2414 ldap_state->smbldap_state->ldap_struct,
2416 get_attr_key2string(groupmap_attr_list,
2417 LDAP_ATTR_GIDNUMBER),
2420 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2421 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER)));
2425 DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp));
2427 map->gid = (gid_t)atol(temp);
2430 temp = smbldap_talloc_single_attribute(
2431 ldap_state->smbldap_state->ldap_struct,
2433 get_attr_key2string(groupmap_attr_list,
2434 LDAP_ATTR_GROUP_SID),
2437 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2438 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID)));
2443 if (!string_to_sid(&map->sid, temp)) {
2444 DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp));
2450 temp = smbldap_talloc_single_attribute(
2451 ldap_state->smbldap_state->ldap_struct,
2453 get_attr_key2string(groupmap_attr_list,
2454 LDAP_ATTR_GROUP_TYPE),
2457 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
2458 get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
2462 map->sid_name_use = (enum lsa_SidType)atol(temp);
2464 if ((map->sid_name_use < SID_NAME_USER) ||
2465 (map->sid_name_use > SID_NAME_UNKNOWN)) {
2466 DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map->sid_name_use));
2472 temp = smbldap_talloc_single_attribute(
2473 ldap_state->smbldap_state->ldap_struct,
2475 get_attr_key2string(groupmap_attr_list,
2476 LDAP_ATTR_DISPLAY_NAME),
2479 temp = smbldap_talloc_single_attribute(
2480 ldap_state->smbldap_state->ldap_struct,
2482 get_attr_key2string(groupmap_attr_list,
2486 DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
2487 for gidNumber(%lu)\n",(unsigned long)map->gid));
2492 fstrcpy(map->nt_name, temp);
2495 temp = smbldap_talloc_single_attribute(
2496 ldap_state->smbldap_state->ldap_struct,
2498 get_attr_key2string(groupmap_attr_list,
2502 temp = talloc_strdup(ctx, "");
2508 fstrcpy(map->comment, temp);
2510 if (lp_parm_bool(-1, "ldapsam", "trusted", false)) {
2511 store_gid_sid_cache(&map->sid, map->gid);
2512 idmap_cache_set_sid2gid(&map->sid, map->gid);
2519 /**********************************************************************
2520 *********************************************************************/
2522 static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
2526 struct ldapsam_privates *ldap_state =
2527 (struct ldapsam_privates *)methods->private_data;
2528 LDAPMessage *result = NULL;
2529 LDAPMessage *entry = NULL;
2532 if (ldapsam_search_one_group(ldap_state, filter, &result)
2534 return NT_STATUS_NO_SUCH_GROUP;
2537 count = ldap_count_entries(priv2ld(ldap_state), result);
2540 DEBUG(4, ("ldapsam_getgroup: Did not find group, filter was "
2542 ldap_msgfree(result);
2543 return NT_STATUS_NO_SUCH_GROUP;
2547 DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: "
2548 "count=%d\n", filter, count));
2549 ldap_msgfree(result);
2550 return NT_STATUS_NO_SUCH_GROUP;
2553 entry = ldap_first_entry(priv2ld(ldap_state), result);
2556 ldap_msgfree(result);
2557 return NT_STATUS_UNSUCCESSFUL;
2560 if (!init_group_from_ldap(ldap_state, map, entry)) {
2561 DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for "
2562 "group filter %s\n", filter));
2563 ldap_msgfree(result);
2564 return NT_STATUS_NO_SUCH_GROUP;
2567 ldap_msgfree(result);
2568 return NT_STATUS_OK;
2571 /**********************************************************************
2572 *********************************************************************/
2574 static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
2577 char *filter = NULL;
2581 if (asprintf(&filter, "(&(objectClass=%s)(%s=%s))",
2583 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
2584 sid_to_fstring(tmp, &sid)) < 0) {
2585 return NT_STATUS_NO_MEMORY;
2588 status = ldapsam_getgroup(methods, filter, map);
2593 /**********************************************************************
2594 *********************************************************************/
2596 static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
2599 char *filter = NULL;
2602 if (asprintf(&filter, "(&(objectClass=%s)(%s=%lu))",
2604 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
2605 (unsigned long)gid) < 0) {
2606 return NT_STATUS_NO_MEMORY;
2609 status = ldapsam_getgroup(methods, filter, map);
2614 /**********************************************************************
2615 *********************************************************************/
2617 static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
2620 char *filter = NULL;
2621 char *escape_name = escape_ldap_string(talloc_tos(), name);
2625 return NT_STATUS_NO_MEMORY;
2628 if (asprintf(&filter, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
2630 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
2631 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN),
2633 TALLOC_FREE(escape_name);
2634 return NT_STATUS_NO_MEMORY;
2637 TALLOC_FREE(escape_name);
2638 status = ldapsam_getgroup(methods, filter, map);
2643 static bool ldapsam_extract_rid_from_entry(LDAP *ldap_struct,
2645 const struct dom_sid *domain_sid,
2651 if (!smbldap_get_single_attribute(ldap_struct, entry, "sambaSID",
2652 str, sizeof(str)-1)) {
2653 DEBUG(10, ("Could not find sambaSID attribute\n"));
2657 if (!string_to_sid(&sid, str)) {
2658 DEBUG(10, ("Could not convert string %s to sid\n", str));
2662 if (dom_sid_compare_domain(&sid, domain_sid) != 0) {
2663 DEBUG(10, ("SID %s is not in expected domain %s\n",
2664 str, sid_string_dbg(domain_sid)));
2668 if (!sid_peek_rid(&sid, rid)) {
2669 DEBUG(10, ("Could not peek into RID\n"));
2676 static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
2677 TALLOC_CTX *mem_ctx,
2678 const struct dom_sid *group,
2679 uint32_t **pp_member_rids,
2680 size_t *p_num_members)
2682 struct ldapsam_privates *ldap_state =
2683 (struct ldapsam_privates *)methods->private_data;
2684 struct smbldap_state *conn = ldap_state->smbldap_state;
2685 const char *id_attrs[] = { "memberUid", "gidNumber", NULL };
2686 const char *sid_attrs[] = { "sambaSID", NULL };
2687 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2688 LDAPMessage *result = NULL;
2691 char **values = NULL;
2696 *pp_member_rids = NULL;
2699 filter = talloc_asprintf(mem_ctx,
2700 "(&(objectClass=%s)"
2703 LDAP_OBJ_POSIXGROUP,
2705 sid_string_talloc(mem_ctx, group));
2706 if (filter == NULL) {
2707 ret = NT_STATUS_NO_MEMORY;
2711 rc = smbldap_search(conn, lp_ldap_suffix(),
2712 LDAP_SCOPE_SUBTREE, filter, id_attrs, 0,
2715 if (rc != LDAP_SUCCESS)
2718 talloc_autofree_ldapmsg(mem_ctx, result);
2720 count = ldap_count_entries(conn->ldap_struct, result);
2723 DEBUG(1, ("Found more than one groupmap entry for %s\n",
2724 sid_string_dbg(group)));
2725 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2730 ret = NT_STATUS_NO_SUCH_GROUP;
2734 entry = ldap_first_entry(conn->ldap_struct, result);
2738 gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
2740 DEBUG (0, ("ldapsam_enum_group_members: Unable to find the group's gid!\n"));
2741 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2745 values = ldap_get_values(conn->ldap_struct, entry, "memberUid");
2747 if ((values != NULL) && (values[0] != NULL)) {
2749 filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|", LDAP_OBJ_SAMBASAMACCOUNT);
2750 if (filter == NULL) {
2751 ret = NT_STATUS_NO_MEMORY;
2755 for (memberuid = values; *memberuid != NULL; memberuid += 1) {
2756 char *escape_memberuid;
2758 escape_memberuid = escape_ldap_string(talloc_tos(),
2760 if (escape_memberuid == NULL) {
2761 ret = NT_STATUS_NO_MEMORY;
2765 filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid);
2766 TALLOC_FREE(escape_memberuid);
2767 if (filter == NULL) {
2768 ret = NT_STATUS_NO_MEMORY;
2773 filter = talloc_asprintf_append_buffer(filter, "))");
2774 if (filter == NULL) {
2775 ret = NT_STATUS_NO_MEMORY;
2779 rc = smbldap_search(conn, lp_ldap_suffix(),
2780 LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
2783 if (rc != LDAP_SUCCESS)
2786 count = ldap_count_entries(conn->ldap_struct, result);
2787 DEBUG(10,("ldapsam_enum_group_members: found %d accounts\n", count));
2789 talloc_autofree_ldapmsg(mem_ctx, result);
2791 for (entry = ldap_first_entry(conn->ldap_struct, result);
2793 entry = ldap_next_entry(conn->ldap_struct, entry))
2799 sidstr = smbldap_talloc_single_attribute(conn->ldap_struct,
2803 DEBUG(0, ("Severe DB error, %s can't miss the sambaSID"
2804 "attribute\n", LDAP_OBJ_SAMBASAMACCOUNT));
2805 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2809 if (!string_to_sid(&sid, sidstr))
2812 if (!sid_check_is_in_our_domain(&sid)) {
2813 DEBUG(0, ("Inconsistent SAM -- group member uid not "
2814 "in our domain\n"));
2815 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2819 sid_peek_rid(&sid, &rid);
2821 if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
2823 ret = NT_STATUS_NO_MEMORY;
2829 filter = talloc_asprintf(mem_ctx,
2830 "(&(objectClass=%s)"
2832 LDAP_OBJ_SAMBASAMACCOUNT,
2835 rc = smbldap_search(conn, lp_ldap_suffix(),
2836 LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
2839 if (rc != LDAP_SUCCESS)
2842 talloc_autofree_ldapmsg(mem_ctx, result);
2844 for (entry = ldap_first_entry(conn->ldap_struct, result);
2846 entry = ldap_next_entry(conn->ldap_struct, entry))
2850 if (!ldapsam_extract_rid_from_entry(conn->ldap_struct,
2852 get_global_sam_sid(),
2854 DEBUG(0, ("Severe DB error, %s can't miss the samba SID" "attribute\n", LDAP_OBJ_SAMBASAMACCOUNT));
2855 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2859 if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
2861 ret = NT_STATUS_NO_MEMORY;
2871 ldap_value_free(values);
2876 static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
2877 TALLOC_CTX *mem_ctx,
2879 struct dom_sid **pp_sids,
2881 uint32_t *p_num_groups)
2883 struct ldapsam_privates *ldap_state =
2884 (struct ldapsam_privates *)methods->private_data;
2885 struct smbldap_state *conn = ldap_state->smbldap_state;
2887 const char *attrs[] = { "gidNumber", "sambaSID", NULL };
2890 LDAPMessage *result = NULL;
2892 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
2896 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=%s)(uid=%s))",
2915 LDAP_OBJ_SAMBASAMACCOUNT,
2917 if (filter == NULL) {
2918 ret = NT_STATUS_NO_MEMORY;
2922 rc = smbldap_search(conn, lp_ldap_suffix(),
2923 LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
2925 if (rc != LDAP_SUCCESS)
2928 talloc_autofree_ldapmsg(mem_ctx, result);
2930 count = ldap_count_entries(priv2ld(ldap_state), result);
2934 DEBUG(1, ("User account [%s] not found!\n", pdb_get_username(user)));
2935 ret = NT_STATUS_NO_SUCH_USER;
2938 entry = ldap_first_entry(priv2ld(ldap_state), result);
2940 gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
2942 DEBUG (1, ("Unable to find the member's gid!\n"));
2943 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2946 primary_gid = strtoul(gidstr, NULL, 10);
2949 DEBUG(1, ("found more than one account with the same user name ?!\n"));
2950 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
2955 filter = talloc_asprintf(mem_ctx,
2956 "(&(objectClass=%s)(|(memberUid=%s)(gidNumber=%u)))",
2957 LDAP_OBJ_POSIXGROUP, escape_name, (unsigned int)primary_gid);
2958 if (filter == NULL) {
2959 ret = NT_STATUS_NO_MEMORY;
2963 rc = smbldap_search(conn, lp_ldap_suffix(),
2964 LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
2966 if (rc != LDAP_SUCCESS)
2969 talloc_autofree_ldapmsg(mem_ctx, result);
2977 /* We need to add the primary group as the first gid/sid */
2979 if (!add_gid_to_array_unique(mem_ctx, primary_gid, pp_gids, &num_gids)) {
2980 ret = NT_STATUS_NO_MEMORY;
2984 /* This sid will be replaced later */
2986 ret = add_sid_to_array_unique(mem_ctx, &global_sid_NULL, pp_sids,
2988 if (!NT_STATUS_IS_OK(ret)) {
2992 for (entry = ldap_first_entry(conn->ldap_struct, result);
2994 entry = ldap_next_entry(conn->ldap_struct, entry))
3001 if (!smbldap_get_single_attribute(conn->ldap_struct,
3003 str, sizeof(str)-1))
3006 if (!string_to_sid(&sid, str))
3009 if (!smbldap_get_single_attribute(conn->ldap_struct,
3011 str, sizeof(str)-1))
3014 gid = strtoul(str, &end, 10);
3016 if (PTR_DIFF(end, str) != strlen(str))
3019 if (gid == primary_gid) {
3020 sid_copy(&(*pp_sids)[0], &sid);
3022 if (!add_gid_to_array_unique(mem_ctx, gid, pp_gids,
3024 ret = NT_STATUS_NO_MEMORY;
3027 ret = add_sid_to_array_unique(mem_ctx, &sid, pp_sids,
3029 if (!NT_STATUS_IS_OK(ret)) {
3035 if (dom_sid_compare(&global_sid_NULL, &(*pp_sids)[0]) == 0) {
3036 DEBUG(3, ("primary group of [%s] not found\n",
3037 pdb_get_username(user)));
3041 *p_num_groups = num_sids;
3047 TALLOC_FREE(escape_name);
3051 /**********************************************************************
3052 * Augment a posixGroup object with a sambaGroupMapping domgroup
3053 *********************************************************************/
3055 static NTSTATUS ldapsam_map_posixgroup(TALLOC_CTX *mem_ctx,
3056 struct ldapsam_privates *ldap_state,
3059 const char *filter, *dn;
3060 LDAPMessage *msg, *entry;
3064 filter = talloc_asprintf(mem_ctx,
3065 "(&(objectClass=%s)(gidNumber=%u))",
3066 LDAP_OBJ_POSIXGROUP, (unsigned int)map->gid);
3067 if (filter == NULL) {
3068 return NT_STATUS_NO_MEMORY;
3071 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
3072 get_attr_list(mem_ctx, groupmap_attr_list),
3074 talloc_autofree_ldapmsg(mem_ctx, msg);
3076 if ((rc != LDAP_SUCCESS) ||
3077 (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg) != 1) ||
3078 ((entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, msg)) == NULL)) {
3079 return NT_STATUS_NO_SUCH_GROUP;
3082 dn = smbldap_talloc_dn(mem_ctx, ldap_state->smbldap_state->ldap_struct, entry);
3084 return NT_STATUS_NO_MEMORY;
3088 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass",
3090 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaSid",
3091 sid_string_talloc(mem_ctx, &map->sid));
3092 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "sambaGroupType",
3093 talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
3094 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "displayName",
3096 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "description",
3098 talloc_autofree_ldapmod(mem_ctx, mods);
3100 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3101 if (rc != LDAP_SUCCESS) {
3102 return NT_STATUS_ACCESS_DENIED;
3105 return NT_STATUS_OK;
3108 static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
3111 struct ldapsam_privates *ldap_state =
3112 (struct ldapsam_privates *)methods->private_data;
3113 LDAPMessage *msg = NULL;
3114 LDAPMod **mods = NULL;
3115 const char *attrs[] = { NULL };
3119 TALLOC_CTX *mem_ctx;
3126 mem_ctx = talloc_new(NULL);
3127 if (mem_ctx == NULL) {
3128 DEBUG(0, ("talloc_new failed\n"));
3129 return NT_STATUS_NO_MEMORY;
3132 filter = talloc_asprintf(mem_ctx, "(sambaSid=%s)",
3133 sid_string_talloc(mem_ctx, &map->sid));
3134 if (filter == NULL) {
3135 result = NT_STATUS_NO_MEMORY;
3139 rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
3140 LDAP_SCOPE_SUBTREE, filter, attrs, True, &msg);
3141 talloc_autofree_ldapmsg(mem_ctx, msg);
3143 if ((rc == LDAP_SUCCESS) &&
3144 (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg) > 0)) {
3146 DEBUG(3, ("SID %s already present in LDAP, refusing to add "
3147 "group mapping entry\n", sid_string_dbg(&map->sid)));
3148 result = NT_STATUS_GROUP_EXISTS;
3152 switch (map->sid_name_use) {
3154 case SID_NAME_DOM_GRP:
3155 /* To map a domain group we need to have a posix group
3157 result = ldapsam_map_posixgroup(mem_ctx, ldap_state, map);
3161 case SID_NAME_ALIAS:
3162 if (!sid_check_is_in_our_domain(&map->sid)
3163 && !sid_check_is_in_builtin(&map->sid) )
3165 DEBUG(3, ("Refusing to map sid %s as an alias, not in our domain\n",
3166 sid_string_dbg(&map->sid)));
3167 result = NT_STATUS_INVALID_PARAMETER;
3173 DEBUG(3, ("Got invalid use '%s' for mapping\n",
3174 sid_type_lookup(map->sid_name_use)));
3175 result = NT_STATUS_INVALID_PARAMETER;
3179 /* Domain groups have been mapped in a separate routine, we have to
3180 * create an alias now */
3182 if (map->gid == -1) {
3183 DEBUG(10, ("Refusing to map gid==-1\n"));
3184 result = NT_STATUS_INVALID_PARAMETER;
3188 if (pdb_gid_to_sid(map->gid, &sid)) {
3189 DEBUG(3, ("Gid %u is already mapped to SID %s, refusing to "
3190 "add\n", (unsigned int)map->gid, sid_string_dbg(&sid)));
3191 result = NT_STATUS_GROUP_EXISTS;
3195 /* Ok, enough checks done. It's still racy to go ahead now, but that's
3196 * the best we can get out of LDAP. */
3198 dn = talloc_asprintf(mem_ctx, "sambaSid=%s,%s",
3199 sid_string_talloc(mem_ctx, &map->sid),
3200 lp_ldap_group_suffix());
3202 result = NT_STATUS_NO_MEMORY;
3208 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "objectClass",
3209 LDAP_OBJ_SID_ENTRY);
3210 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "objectClass",
3212 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "sambaSid",
3213 sid_string_talloc(mem_ctx, &map->sid));
3214 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "sambaGroupType",
3215 talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
3216 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "displayName",
3218 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "description",
3220 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, NULL, &mods, "gidNumber",
3221 talloc_asprintf(mem_ctx, "%u", (unsigned int)map->gid));
3222 talloc_autofree_ldapmod(mem_ctx, mods);
3224 rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
3226 result = (rc == LDAP_SUCCESS) ?
3227 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3230 TALLOC_FREE(mem_ctx);
3234 /**********************************************************************
3235 * Update a group mapping entry. We're quite strict about what can be changed:
3236 * Only the description and displayname may be changed. It simply does not
3237 * make any sense to change the SID, gid or the type in a mapping.
3238 *********************************************************************/
3240 static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
3243 struct ldapsam_privates *ldap_state =
3244 (struct ldapsam_privates *)methods->private_data;
3246 const char *filter, *dn;
3247 LDAPMessage *msg = NULL;
3248 LDAPMessage *entry = NULL;
3249 LDAPMod **mods = NULL;
3250 TALLOC_CTX *mem_ctx;
3253 mem_ctx = talloc_new(NULL);
3254 if (mem_ctx == NULL) {
3255 DEBUG(0, ("talloc_new failed\n"));
3256 return NT_STATUS_NO_MEMORY;
3259 /* Make 100% sure that sid, gid and type are not changed by looking up
3260 * exactly the values we're given in LDAP. */
3262 filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)"
3263 "(sambaSid=%s)(gidNumber=%u)"
3264 "(sambaGroupType=%d))",
3266 sid_string_talloc(mem_ctx, &map->sid),
3267 (unsigned int)map->gid, map->sid_name_use);
3268 if (filter == NULL) {
3269 result = NT_STATUS_NO_MEMORY;
3273 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
3274 get_attr_list(mem_ctx, groupmap_attr_list),
3276 talloc_autofree_ldapmsg(mem_ctx, msg);
3278 if ((rc != LDAP_SUCCESS) ||
3279 (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, msg) != 1) ||
3280 ((entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, msg)) == NULL)) {
3281 result = NT_STATUS_NO_SUCH_GROUP;
3285 dn = smbldap_talloc_dn(mem_ctx, ldap_state->smbldap_state->ldap_struct, entry);
3288 result = NT_STATUS_NO_MEMORY;
3293 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "displayName",
3295 smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods, "description",
3297 talloc_autofree_ldapmod(mem_ctx, mods);
3300 DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: "
3301 "nothing to do\n"));
3302 result = NT_STATUS_OK;
3306 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3308 if (rc != LDAP_SUCCESS) {
3309 result = NT_STATUS_ACCESS_DENIED;
3313 DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified "
3314 "group %lu in LDAP\n", (unsigned long)map->gid));
3316 result = NT_STATUS_OK;
3319 TALLOC_FREE(mem_ctx);
3323 /**********************************************************************
3324 *********************************************************************/
3326 static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
3329 struct ldapsam_privates *priv =
3330 (struct ldapsam_privates *)methods->private_data;
3331 LDAPMessage *msg, *entry;
3334 TALLOC_CTX *mem_ctx;
3337 mem_ctx = talloc_new(NULL);
3338 if (mem_ctx == NULL) {
3339 DEBUG(0, ("talloc_new failed\n"));
3340 return NT_STATUS_NO_MEMORY;
3343 filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%s))",
3344 LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID,
3345 sid_string_talloc(mem_ctx, &sid));
3346 if (filter == NULL) {
3347 result = NT_STATUS_NO_MEMORY;
3350 rc = smbldap_search_suffix(priv->smbldap_state, filter,
3351 get_attr_list(mem_ctx, groupmap_attr_list),
3353 talloc_autofree_ldapmsg(mem_ctx, msg);
3355 if ((rc != LDAP_SUCCESS) ||
3356 (ldap_count_entries(priv2ld(priv), msg) != 1) ||
3357 ((entry = ldap_first_entry(priv2ld(priv), msg)) == NULL)) {
3358 result = NT_STATUS_NO_SUCH_GROUP;
3362 rc = ldapsam_delete_entry(priv, mem_ctx, entry, LDAP_OBJ_GROUPMAP,
3363 get_attr_list(mem_ctx,
3364 groupmap_attr_list_to_delete));
3366 if ((rc == LDAP_NAMING_VIOLATION) ||
3367 (rc == LDAP_NOT_ALLOWED_ON_RDN) ||
3368 (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
3369 const char *attrs[] = { "sambaGroupType", "description",
3370 "displayName", "sambaSIDList",
3373 /* Second try. Don't delete the sambaSID attribute, this is
3374 for "old" entries that are tacked on a winbind
3377 rc = ldapsam_delete_entry(priv, mem_ctx, entry,
3378 LDAP_OBJ_GROUPMAP, attrs);
3381 if ((rc == LDAP_NAMING_VIOLATION) ||
3382 (rc == LDAP_NOT_ALLOWED_ON_RDN) ||
3383 (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
3384 const char *attrs[] = { "sambaGroupType", "description",
3385 "displayName", "sambaSIDList",
3386 "gidNumber", NULL };
3388 /* Third try. This is a post-3.0.21 alias (containing only
3389 * sambaSidEntry and sambaGroupMapping classes), we also have
3390 * to delete the gidNumber attribute, only the sambaSidEntry
3393 rc = ldapsam_delete_entry(priv, mem_ctx, entry,
3394 LDAP_OBJ_GROUPMAP, attrs);
3397 result = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
3400 TALLOC_FREE(mem_ctx);
3404 /**********************************************************************
3405 *********************************************************************/
3407 static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
3410 struct ldapsam_privates *ldap_state =
3411 (struct ldapsam_privates *)my_methods->private_data;
3412 char *filter = NULL;
3414 const char **attr_list;
3416 filter = talloc_asprintf(NULL, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
3418 return NT_STATUS_NO_MEMORY;
3420 attr_list = get_attr_list( NULL, groupmap_attr_list );
3421 rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
3422 LDAP_SCOPE_SUBTREE, filter,
3423 attr_list, 0, &ldap_state->result);
3424 TALLOC_FREE(attr_list);
3426 if (rc != LDAP_SUCCESS) {
3427 DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n",
3428 ldap_err2string(rc)));
3429 DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n",
3430 lp_ldap_suffix(), filter));
3431 ldap_msgfree(ldap_state->result);
3432 ldap_state->result = NULL;
3433 TALLOC_FREE(filter);
3434 return NT_STATUS_UNSUCCESSFUL;
3437 TALLOC_FREE(filter);
3439 DEBUG(2, ("ldapsam_setsamgrent: %d entries in the base!\n",
3440 ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
3441 ldap_state->result)));
3444 ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
3445 ldap_state->result);
3446 ldap_state->index = 0;
3448 return NT_STATUS_OK;
3451 /**********************************************************************
3452 *********************************************************************/
3454 static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
3456 ldapsam_endsampwent(my_methods);
3459 /**********************************************************************
3460 *********************************************************************/
3462 static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
3465 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
3466 struct ldapsam_privates *ldap_state =
3467 (struct ldapsam_privates *)my_methods->private_data;
3471 if (!ldap_state->entry)
3474 ldap_state->index++;
3475 bret = init_group_from_ldap(ldap_state, map,
3479 ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
3483 return NT_STATUS_OK;
3486 /**********************************************************************
3487 *********************************************************************/
3489 static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
3490 const struct dom_sid *domsid, enum lsa_SidType sid_name_use,
3491 GROUP_MAP **pp_rmap,
3492 size_t *p_num_entries,
3495 GROUP_MAP map = { 0, };
3501 if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
3502 DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open "
3504 return NT_STATUS_ACCESS_DENIED;
3507 while (NT_STATUS_IS_OK(ldapsam_getsamgrent(methods, &map))) {
3508 if (sid_name_use != SID_NAME_UNKNOWN &&
3509 sid_name_use != map.sid_name_use) {
3510 DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
3511 "not of the requested type\n", map.nt_name));
3514 if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
3515 DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
3516 "non mapped\n", map.nt_name));
3520 (*pp_rmap)=SMB_REALLOC_ARRAY((*pp_rmap), GROUP_MAP, entries+1);
3522 DEBUG(0,("ldapsam_enum_group_mapping: Unable to "
3523 "enlarge group map!\n"));
3524 return NT_STATUS_UNSUCCESSFUL;
3527 (*pp_rmap)[entries] = map;
3532 ldapsam_endsamgrent(methods);
3534 *p_num_entries = entries;
3536 return NT_STATUS_OK;
3539 static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
3540 const struct dom_sid *alias,
3541 const struct dom_sid *member,
3544 struct ldapsam_privates *ldap_state =
3545 (struct ldapsam_privates *)methods->private_data;
3547 LDAPMessage *result = NULL;
3548 LDAPMessage *entry = NULL;
3550 LDAPMod **mods = NULL;
3552 enum lsa_SidType type = SID_NAME_USE_NONE;
3555 char *filter = NULL;
3557 if (sid_check_is_in_builtin(alias)) {
3558 type = SID_NAME_ALIAS;
3561 if (sid_check_is_in_our_domain(alias)) {
3562 type = SID_NAME_ALIAS;
3565 if (type == SID_NAME_USE_NONE) {
3566 DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
3567 sid_string_dbg(alias)));
3568 return NT_STATUS_NO_SUCH_ALIAS;
3571 if (asprintf(&filter,
3572 "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
3573 LDAP_OBJ_GROUPMAP, sid_to_fstring(tmp, alias),
3575 return NT_STATUS_NO_MEMORY;
3578 if (ldapsam_search_one_group(ldap_state, filter,
3579 &result) != LDAP_SUCCESS) {
3581 return NT_STATUS_NO_SUCH_ALIAS;
3584 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
3588 DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
3589 ldap_msgfree(result);
3591 return NT_STATUS_NO_SUCH_ALIAS;
3595 DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for "
3596 "filter %s: count=%d\n", filter, count));
3597 ldap_msgfree(result);
3599 return NT_STATUS_NO_SUCH_ALIAS;
3604 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
3608 ldap_msgfree(result);
3609 return NT_STATUS_UNSUCCESSFUL;
3612 dn = smbldap_talloc_dn(talloc_tos(), ldap_state->smbldap_state->ldap_struct, entry);
3614 ldap_msgfree(result);
3615 return NT_STATUS_UNSUCCESSFUL;
3618 smbldap_set_mod(&mods, modop,
3619 get_attr_key2string(groupmap_attr_list,
3620 LDAP_ATTR_SID_LIST),
3621 sid_to_fstring(tmp, member));
3623 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
3625 ldap_mods_free(mods, True);
3626 ldap_msgfree(result);
3629 if (rc == LDAP_TYPE_OR_VALUE_EXISTS) {
3630 return NT_STATUS_MEMBER_IN_ALIAS;
3633 if (rc == LDAP_NO_SUCH_ATTRIBUTE) {
3634 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
3637 if (rc != LDAP_SUCCESS) {
3638 return NT_STATUS_UNSUCCESSFUL;
3641 return NT_STATUS_OK;
3644 static NTSTATUS ldapsam_add_aliasmem(struct pdb_methods *methods,
3645 const struct dom_sid *alias,
3646 const struct dom_sid *member)
3648 return ldapsam_modify_aliasmem(methods, alias, member, LDAP_MOD_ADD);
3651 static NTSTATUS ldapsam_del_aliasmem(struct pdb_methods *methods,
3652 const struct dom_sid *alias,
3653 const struct dom_sid *member)
3655 return ldapsam_modify_aliasmem(methods, alias, member,
3659 static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
3660 const struct dom_sid *alias,
3661 TALLOC_CTX *mem_ctx,
3662 struct dom_sid **pp_members,
3663 size_t *p_num_members)
3665 struct ldapsam_privates *ldap_state =
3666 (struct ldapsam_privates *)methods->private_data;
3667 LDAPMessage *result = NULL;
3668 LDAPMessage *entry = NULL;
3670 char **values = NULL;
3672 char *filter = NULL;
3673 uint32_t num_members = 0;
3674 enum lsa_SidType type = SID_NAME_USE_NONE;
3680 if (sid_check_is_in_builtin(alias)) {
3681 type = SID_NAME_ALIAS;
3684 if (sid_check_is_in_our_domain(alias)) {
3685 type = SID_NAME_ALIAS;
3688 if (type == SID_NAME_USE_NONE) {
3689 DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
3690 sid_string_dbg(alias)));
3691 return NT_STATUS_NO_SUCH_ALIAS;
3694 if (asprintf(&filter,
3695 "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
3696 LDAP_OBJ_GROUPMAP, sid_to_fstring(tmp, alias),
3698 return NT_STATUS_NO_MEMORY;
3701 if (ldapsam_search_one_group(ldap_state, filter,
3702 &result) != LDAP_SUCCESS) {
3704 return NT_STATUS_NO_SUCH_ALIAS;
3707 count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
3711 DEBUG(4, ("ldapsam_enum_aliasmem: Did not find alias\n"));
3712 ldap_msgfree(result);
3714 return NT_STATUS_NO_SUCH_ALIAS;
3718 DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for "
3719 "filter %s: count=%d\n", filter, count));
3720 ldap_msgfree(result);
3722 return NT_STATUS_NO_SUCH_ALIAS;
3727 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
3731 ldap_msgfree(result);
3732 return NT_STATUS_UNSUCCESSFUL;
3735 values = ldap_get_values(ldap_state->smbldap_state->ldap_struct,
3737 get_attr_key2string(groupmap_attr_list,
3738 LDAP_ATTR_SID_LIST));
3740 if (values == NULL) {
3741 ldap_msgfree(result);
3742 return NT_STATUS_OK;
3745 count = ldap_count_values(values);
3747 for (i=0; i<count; i++) {
3748 struct dom_sid member;
3751 if (!string_to_sid(&member, values[i]))
3754 status = add_sid_to_array(mem_ctx, &member, pp_members,
3756 if (!NT_STATUS_IS_OK(status)) {
3757 ldap_value_free(values);
3758 ldap_msgfree(result);
3763 *p_num_members = num_members;
3764 ldap_value_free(values);
3765 ldap_msgfree(result);
3767 return NT_STATUS_OK;
3770 static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
3771 TALLOC_CTX *mem_ctx,
3772 const struct dom_sid *domain_sid,
3773 const struct dom_sid *members,
3775 uint32_t **pp_alias_rids,
3776 size_t *p_num_alias_rids)
3778 struct ldapsam_privates *ldap_state =
3779 (struct ldapsam_privates *)methods->private_data;
3782 const char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL };
3784 LDAPMessage *result = NULL;
3785 LDAPMessage *entry = NULL;
3789 enum lsa_SidType type = SID_NAME_USE_NONE;
3790 bool is_builtin = false;
3791 bool sid_added = false;
3793 *pp_alias_rids = NULL;
3794 *p_num_alias_rids = 0;
3796 if (sid_check_is_builtin(domain_sid)) {
3798 type = SID_NAME_ALIAS;
3801 if (sid_check_is_domain(domain_sid)) {
3802 type = SID_NAME_ALIAS;
3805 if (type == SID_NAME_USE_NONE) {
3806 DEBUG(5, ("SID %s is neither builtin nor domain!\n",
3807 sid_string_dbg(domain_sid)));
3808 return NT_STATUS_UNSUCCESSFUL;
3811 if (num_members == 0) {
3812 return NT_STATUS_OK;
3815 filter = talloc_asprintf(mem_ctx,
3816 "(&(objectclass=%s)(sambaGroupType=%d)(|",
3817 LDAP_OBJ_GROUPMAP, type);
3819 for (i=0; i<num_members; i++)
3820 filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)",
3822 sid_string_talloc(mem_ctx,
3825 filter = talloc_asprintf(mem_ctx, "%s))", filter);
3827 if (filter == NULL) {
3828 return NT_STATUS_NO_MEMORY;
3832 ldap_state->search_cache.filter &&
3833 strcmp(ldap_state->search_cache.filter, filter) == 0) {
3834 filter = talloc_move(filter, &ldap_state->search_cache.filter);
3835 result = ldap_state->search_cache.result;
3836 ldap_state->search_cache.result = NULL;
3838 rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
3839 LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
3840 if (rc != LDAP_SUCCESS) {
3841 return NT_STATUS_UNSUCCESSFUL;
3843 talloc_autofree_ldapmsg(filter, result);
3846 ldap_struct = ldap_state->smbldap_state->ldap_struct;
3848 for (entry = ldap_first_entry(ldap_struct, result);
3850 entry = ldap_next_entry(ldap_struct, entry))
3856 if (!smbldap_get_single_attribute(ldap_struct, entry,
3862 if (!string_to_sid(&sid, sid_str))
3865 if (!sid_peek_check_rid(domain_sid, &sid, &rid))
3870 if (!add_rid_to_array_unique(mem_ctx, rid, pp_alias_rids,
3871 p_num_alias_rids)) {
3872 return NT_STATUS_NO_MEMORY;
3876 if (!is_builtin && !sid_added) {
3877 TALLOC_FREE(ldap_state->search_cache.filter);
3879 * Note: result is a talloc child of filter because of the
3880 * talloc_autofree_ldapmsg() usage
3882 ldap_state->search_cache.filter = talloc_move(ldap_state, &filter);
3883 ldap_state->search_cache.result = result;
3886 return NT_STATUS_OK;
3889 static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
3890 enum pdb_policy_type type,
3893 NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
3895 LDAPMod **mods = NULL;
3896 fstring value_string;
3897 const char *policy_attr = NULL;
3899 struct ldapsam_privates *ldap_state =
3900 (struct ldapsam_privates *)methods->private_data;
3902 DEBUG(10,("ldapsam_set_account_policy_in_ldap\n"));
3904 if (!ldap_state->domain_dn) {
3905 return NT_STATUS_INVALID_PARAMETER;
3908 policy_attr = get_account_policy_attr(type);
3909 if (policy_attr == NULL) {
3910 DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid "
3915 slprintf(value_string, sizeof(value_string) - 1, "%i", value);
3917 smbldap_set_mod(&mods, LDAP_MOD_REPLACE, policy_attr, value_string);
3919 rc = smbldap_modify(ldap_state->smbldap_state, ldap_state->domain_dn,
3922 ldap_mods_free(mods, True);
3924 if (rc != LDAP_SUCCESS) {
3928 if (!cache_account_policy_set(type, value)) {
3929 DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to "
3930 "update local tdb cache\n"));
3934 return NT_STATUS_OK;
3937 static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods,
3938 enum pdb_policy_type type,
3941 return ldapsam_set_account_policy_in_ldap(methods, type,
3945 static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods,
3946 enum pdb_policy_type type,
3949 NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
3950 LDAPMessage *result = NULL;
3951 LDAPMessage *entry = NULL;
3956 const char *policy_attr = NULL;
3958 struct ldapsam_privates *ldap_state =
3959 (struct ldapsam_privates *)methods->private_data;
3961 const char *attrs[2];
3963 DEBUG(10,("ldapsam_get_account_policy_from_ldap\n"));
3965 if (!ldap_state->domain_dn) {
3966 return NT_STATUS_INVALID_PARAMETER;
3969 policy_attr = get_account_policy_attr(type);
3971 DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid "
3972 "policy index: %d\n", type));
3976 attrs[0] = policy_attr;
3979 filter = talloc_asprintf(talloc_tos(), "(objectClass=%s)", LDAP_OBJ_DOMINFO);
3980 if (filter == NULL) {
3981 return NT_STATUS_NO_MEMORY;
3983 rc = smbldap_search(ldap_state->smbldap_state, ldap_state->domain_dn,
3984 LDAP_SCOPE_BASE, filter, attrs, 0,
3986 TALLOC_FREE(filter);
3987 if (rc != LDAP_SUCCESS) {
3991 count = ldap_count_entries(priv2ld(ldap_state), result);
3996 entry = ldap_first_entry(priv2ld(ldap_state), result);
3997 if (entry == NULL) {
4001 vals = ldap_get_values(priv2ld(ldap_state), entry, policy_attr);
4006 *value = (uint32_t)atol(vals[0]);
4008 ntstatus = NT_STATUS_OK;
4012 ldap_value_free(vals);
4013 ldap_msgfree(result);
4018 /* wrapper around ldapsam_get_account_policy_from_ldap(), handles tdb as cache
4020 - if user hasn't decided to use account policies inside LDAP just reuse the
4023 - if there is a valid cache entry, return that
4024 - if there is an LDAP entry, update cache and return
4025 - otherwise set to default, update cache and return
4029 static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
4030 enum pdb_policy_type type,
4033 NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
4035 if (cache_account_policy_get(type, value)) {
4036 DEBUG(11,("ldapsam_get_account_policy: got valid value from "
4038 return NT_STATUS_OK;
4041 ntstatus = ldapsam_get_account_policy_from_ldap(methods, type,
4043 if (NT_STATUS_IS_OK(ntstatus)) {
4047 DEBUG(10,("ldapsam_get_account_policy: failed to retrieve from "
4051 /* should we automagically migrate old tdb value here ? */
4052 if (account_policy_get(type, value))
4055 DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying "
4056 "default\n", type));
4059 if (!account_policy_get_default(type, value)) {
4065 ntstatus = ldapsam_set_account_policy(methods, type, *value);
4066 if (!NT_STATUS_IS_OK(ntstatus)) {
4072 if (!cache_account_policy_set(type, *value)) {
4073 DEBUG(0,("ldapsam_get_account_policy: failed to update local "
4074 "tdb as a cache\n"));
4075 return NT_STATUS_UNSUCCESSFUL;
4078 return NT_STATUS_OK;
4081 static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
4082 const struct dom_sid *domain_sid,
4086 enum lsa_SidType *attrs)
4088 struct ldapsam_privates *ldap_state =
4089 (struct ldapsam_privates *)methods->private_data;
4090 LDAPMessage *msg = NULL;
4092 char *allsids = NULL;
4093 int i, rc, num_mapped;
4094 NTSTATUS result = NT_STATUS_NO_MEMORY;
4095 TALLOC_CTX *mem_ctx;
4099 mem_ctx = talloc_new(NULL);
4100 if (mem_ctx == NULL) {
4101 DEBUG(0, ("talloc_new failed\n"));
4105 if (!sid_check_is_builtin(domain_sid) &&
4106 !sid_check_is_domain(domain_sid)) {
4107 result = NT_STATUS_INVALID_PARAMETER;
4111 if (num_rids == 0) {
4112 result = NT_STATUS_NONE_MAPPED;
4116 for (i=0; i<num_rids; i++)
4117 attrs[i] = SID_NAME_UNKNOWN;
4119 allsids = talloc_strdup(mem_ctx, "");
4120 if (allsids == NULL) {
4124 for (i=0; i<num_rids; i++) {
4126 sid_compose(&sid, domain_sid, rids[i]);
4127 allsids = talloc_asprintf_append_buffer(
4128 allsids, "(sambaSid=%s)",
4129 sid_string_talloc(mem_ctx, &sid));
4130 if (allsids == NULL) {
4135 /* First look for users */
4139 const char *ldap_attrs[] = { "uid", "sambaSid", NULL };
4141 filter = talloc_asprintf(
4142 mem_ctx, ("(&(objectClass=%s)(|%s))"),
4143 LDAP_OBJ_SAMBASAMACCOUNT, allsids);
4145 if (filter == NULL) {
4149 rc = smbldap_search(ldap_state->smbldap_state,
4150 lp_ldap_user_suffix(),
4151 LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
4153 talloc_autofree_ldapmsg(mem_ctx, msg);
4156 if (rc != LDAP_SUCCESS)
4159 ld = ldap_state->smbldap_state->ldap_struct;
4162 for (entry = ldap_first_entry(ld, msg);
4164 entry = ldap_next_entry(ld, entry)) {
4169 if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
4171 DEBUG(2, ("Could not find sid from ldap entry\n"));
4175 name = smbldap_talloc_single_attribute(ld, entry, "uid",
4178 DEBUG(2, ("Could not retrieve uid attribute\n"));
4182 for (rid_index = 0; rid_index < num_rids; rid_index++) {
4183 if (rid == rids[rid_index])
4187 if (rid_index == num_rids) {
4188 DEBUG(2, ("Got a RID not asked for: %d\n", rid));
4192 attrs[rid_index] = SID_NAME_USER;
4193 names[rid_index] = name;
4197 if (num_mapped == num_rids) {
4198 /* No need to look for groups anymore -- we're done */
4199 result = NT_STATUS_OK;
4203 /* Same game for groups */
4207 const char *ldap_attrs[] = { "cn", "displayName", "sambaSid",
4208 "sambaGroupType", NULL };
4210 filter = talloc_asprintf(
4211 mem_ctx, "(&(objectClass=%s)(|%s))",
4212 LDAP_OBJ_GROUPMAP, allsids);
4213 if (filter == NULL) {
4217 rc = smbldap_search(ldap_state->smbldap_state,
4219 LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
4221 talloc_autofree_ldapmsg(mem_ctx, msg);
4224 if (rc != LDAP_SUCCESS)
4227 /* ldap_struct might have changed due to a reconnect */
4229 ld = ldap_state->smbldap_state->ldap_struct;
4231 /* For consistency checks, we already checked we're only domain or builtin */
4233 is_builtin = sid_check_is_builtin(domain_sid);
4235 for (entry = ldap_first_entry(ld, msg);
4237 entry = ldap_next_entry(ld, entry))
4242 enum lsa_SidType type;
4243 const char *dn = smbldap_talloc_dn(mem_ctx, ld, entry);
4245 attr = smbldap_talloc_single_attribute(ld, entry, "sambaGroupType",
4248 DEBUG(2, ("Could not extract type from ldap entry %s\n",
4253 type = (enum lsa_SidType)atol(attr);
4255 /* Consistency checks */
4256 if ((is_builtin && (type != SID_NAME_ALIAS)) ||
4257 (!is_builtin && ((type != SID_NAME_ALIAS) &&
4258 (type != SID_NAME_DOM_GRP)))) {
4259 DEBUG(2, ("Rejecting invalid group mapping entry %s\n", dn));
4262 if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
4264 DEBUG(2, ("Could not find sid from ldap entry %s\n", dn));
4268 attr = smbldap_talloc_single_attribute(ld, entry, "displayName", names);
4271 DEBUG(10, ("Could not retrieve 'displayName' attribute from %s\n",
4273 attr = smbldap_talloc_single_attribute(ld, entry, "cn", names);
4277 DEBUG(2, ("Could not retrieve naming attribute from %s\n",
4282 for (rid_index = 0; rid_index < num_rids; rid_index++) {
4283 if (rid == rids[rid_index])
4287 if (rid_index == num_rids) {
4288 DEBUG(2, ("Got a RID not asked for: %d\n", rid));
4292 attrs[rid_index] = type;
4293 names[rid_index] = attr;
4297 result = NT_STATUS_NONE_MAPPED;
4300 result = (num_mapped == num_rids) ?
4301 NT_STATUS_OK : STATUS_SOME_UNMAPPED;
4303 TALLOC_FREE(mem_ctx);
4307 static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
4309 char *filter = NULL;
4310 char *escaped = NULL;
4311 char *result = NULL;
4313 if (asprintf(&filter, "(&%s(objectclass=%s))",
4314 "(uid=%u)", LDAP_OBJ_SAMBASAMACCOUNT) < 0) {
4318 escaped = escape_ldap_string(talloc_tos(), username);
4319 if (escaped == NULL) goto done;
4321 result = talloc_string_sub(mem_ctx, filter, "%u", username);
4325 TALLOC_FREE(escaped);
4330 static const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
4334 const char **result;
4336 va_start(ap, mem_ctx);
4337 while (va_arg(ap, const char *) != NULL)
4341 if ((result = TALLOC_ARRAY(mem_ctx, const char *, num+1)) == NULL) {
4345 va_start(ap, mem_ctx);
4346 for (i=0; i<num; i++) {
4347 result[i] = talloc_strdup(result, va_arg(ap, const char*));
4348 if (result[i] == NULL) {
4349 talloc_free(result);
4360 struct ldap_search_state {
4361 struct smbldap_state *connection;
4363 uint32_t acct_flags;
4364 uint16_t group_type;
4371 void *pagedresults_cookie;
4373 LDAPMessage *entries, *current_entry;
4374 bool (*ldap2displayentry)(struct ldap_search_state *state,
4375 TALLOC_CTX *mem_ctx,
4376 LDAP *ld, LDAPMessage *entry,
4377 struct samr_displayentry *result);
4380 static bool ldapsam_search_firstpage(struct pdb_search *search)
4382 struct ldap_search_state *state =
4383 (struct ldap_search_state *)search->private_data;
4385 int rc = LDAP_OPERATIONS_ERROR;
4387 state->entries = NULL;
4389 if (state->connection->paged_results) {
4390 rc = smbldap_search_paged(state->connection, state->base,
4391 state->scope, state->filter,
4392 state->attrs, state->attrsonly,
4393 lp_ldap_page_size(), &state->entries,
4394 &state->pagedresults_cookie);
4397 if ((rc != LDAP_SUCCESS) || (state->entries == NULL)) {
4399 if (state->entries != NULL) {
4400 /* Left over from unsuccessful paged attempt */
4401 ldap_msgfree(state->entries);
4402 state->entries = NULL;
4405 rc = smbldap_search(state->connection, state->base,
4406 state->scope, state->filter, state->attrs,
4407 state->attrsonly, &state->entries);
4409 if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
4412 /* Ok, the server was lying. It told us it could do paged
4413 * searches when it could not. */
4414 state->connection->paged_results = False;
4417 ld = state->connection->ldap_struct;
4419 DEBUG(5, ("Don't have an LDAP connection right after a "
4423 state->current_entry = ldap_first_entry(ld, state->entries);
4428 static bool ldapsam_search_nextpage(struct pdb_search *search)
4430 struct ldap_search_state *state =
4431 (struct ldap_search_state *)search->private_data;
4434 if (!state->connection->paged_results) {
4435 /* There is no next page when there are no paged results */
4439 rc = smbldap_search_paged(state->connection, state->base,
4440 state->scope, state->filter, state->attrs,
4441 state->attrsonly, lp_ldap_page_size(),
4443 &state->pagedresults_cookie);
4445 if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
4448 state->current_entry = ldap_first_entry(state->connection->ldap_struct, state->entries);
4450 if (state->current_entry == NULL) {
4451 ldap_msgfree(state->entries);
4452 state->entries = NULL;
4459 static bool ldapsam_search_next_entry(struct pdb_search *search,
4460 struct samr_displayentry *entry)
4462 struct ldap_search_state *state =
4463 (struct ldap_search_state *)search->private_data;
4467 if ((state->entries == NULL) && (state->pagedresults_cookie == NULL))
4470 if ((state->entries == NULL) &&
4471 !ldapsam_search_nextpage(search))
4474 if (state->current_entry == NULL) {
4478 result = state->ldap2displayentry(state, search,
4479 state->connection->ldap_struct,
4480 state->current_entry, entry);
4484 dn = ldap_get_dn(state->connection->ldap_struct, state->current_entry);
4485 DEBUG(5, ("Skipping entry %s\n", dn != NULL ? dn : "<NULL>"));
4486 if (dn != NULL) ldap_memfree(dn);
4489 state->current_entry = ldap_next_entry(state->connection->ldap_struct, state->current_entry);
4491 if (state->current_entry == NULL) {
4492 ldap_msgfree(state->entries);
4493 state->entries = NULL;
4496 if (!result) goto retry;
4501 static void ldapsam_search_end(struct pdb_search *search)
4503 struct ldap_search_state *state =
4504 (struct ldap_search_state *)search->private_data;
4507 if (state->pagedresults_cookie == NULL)
4510 if (state->entries != NULL)
4511 ldap_msgfree(state->entries);
4513 state->entries = NULL;
4514 state->current_entry = NULL;
4516 if (!state->connection->paged_results)
4519 /* Tell the LDAP server we're not interested in the rest anymore. */
4521 rc = smbldap_search_paged(state->connection, state->base, state->scope,
4522 state->filter, state->attrs,
4523 state->attrsonly, 0, &state->entries,
4524 &state->pagedresults_cookie);
4526 if (rc != LDAP_SUCCESS)
4527 DEBUG(5, ("Could not end search properly\n"));
4532 static bool ldapuser2displayentry(struct ldap_search_state *state,
4533 TALLOC_CTX *mem_ctx,
4534 LDAP *ld, LDAPMessage *entry,
4535 struct samr_displayentry *result)
4538 size_t converted_size;
4540 uint32_t acct_flags;
4542 vals = ldap_get_values(ld, entry, "sambaAcctFlags");
4543 if ((vals == NULL) || (vals[0] == NULL)) {
4544 DEBUG(5, ("\"sambaAcctFlags\" not found\n"));
4547 acct_flags = pdb_decode_acct_ctrl(vals[0]);
4548 ldap_value_free(vals);
4550 if ((state->acct_flags != 0) &&
4551 ((state->acct_flags & acct_flags) == 0))
4554 result->acct_flags = acct_flags;
4555 result->account_name = "";
4556 result->fullname = "";
4557 result->description = "";
4559 vals = ldap_get_values(ld, entry, "uid");
4560 if ((vals == NULL) || (vals[0] == NULL)) {
4561 DEBUG(5, ("\"uid\" not found\n"));
4564 if (!pull_utf8_talloc(mem_ctx,
4565 CONST_DISCARD(char **, &result->account_name),
4566 vals[0], &converted_size))
4568 DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s",
4572 ldap_value_free(vals);
4574 vals = ldap_get_values(ld, entry, "displayName");
4575 if ((vals == NULL) || (vals[0] == NULL))
4576 DEBUG(8, ("\"displayName\" not found\n"));
4577 else if (!pull_utf8_talloc(mem_ctx,
4578 CONST_DISCARD(char **, &result->fullname),
4579 vals[0], &converted_size))
4581 DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s",
4585 ldap_value_free(vals);
4587 vals = ldap_get_values(ld, entry, "description");
4588 if ((vals == NULL) || (vals[0] == NULL))
4589 DEBUG(8, ("\"description\" not found\n"));
4590 else if (!pull_utf8_talloc(mem_ctx,
4591 CONST_DISCARD(char **, &result->description),
4592 vals[0], &converted_size))
4594 DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s",
4598 ldap_value_free(vals);
4600 if ((result->account_name == NULL) ||
4601 (result->fullname == NULL) ||
4602 (result->description == NULL)) {
4603 DEBUG(0, ("talloc failed\n"));
4607 vals = ldap_get_values(ld, entry, "sambaSid");
4608 if ((vals == NULL) || (vals[0] == NULL)) {
4609 DEBUG(0, ("\"objectSid\" not found\n"));
4613 if (!string_to_sid(&sid, vals[0])) {
4614 DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
4615 ldap_value_free(vals);
4618 ldap_value_free(vals);
4620 if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
4621 DEBUG(0, ("sid %s does not belong to our domain\n",
4622 sid_string_dbg(&sid)));
4630 static bool ldapsam_search_users(struct pdb_methods *methods,
4631 struct pdb_search *search,
4632 uint32_t acct_flags)
4634 struct ldapsam_privates *ldap_state =
4635 (struct ldapsam_privates *)methods->private_data;
4636 struct ldap_search_state *state;
4638 state = talloc(search, struct ldap_search_state);
4639 if (state == NULL) {
4640 DEBUG(0, ("talloc failed\n"));
4644 state->connection = ldap_state->smbldap_state;
4646 if ((acct_flags != 0) && ((acct_flags & ACB_NORMAL) != 0))
4647 state->base = lp_ldap_user_suffix();
4648 else if ((acct_flags != 0) &&
4649 ((acct_flags & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) != 0))
4650 state->base = lp_ldap_machine_suffix();
4652 state->base = lp_ldap_suffix();
4654 state->acct_flags = acct_flags;
4655 state->base = talloc_strdup(search, state->base);
4656 state->scope = LDAP_SCOPE_SUBTREE;
4657 state->filter = get_ldap_filter(search, "*");
4658 state->attrs = talloc_attrs(search, "uid", "sambaSid",
4659 "displayName", "description",
4660 "sambaAcctFlags", NULL);
4661 state->attrsonly = 0;
4662 state->pagedresults_cookie = NULL;
4663 state->entries = NULL;
4664 state->ldap2displayentry = ldapuser2displayentry;
4666 if ((state->filter == NULL) || (state->attrs == NULL)) {
4667 DEBUG(0, ("talloc failed\n"));
4671 search->private_data = state;
4672 search->next_entry = ldapsam_search_next_entry;
4673 search->search_end = ldapsam_search_end;
4675 return ldapsam_search_firstpage(search);
4678 static bool ldapgroup2displayentry(struct ldap_search_state *state,
4679 TALLOC_CTX *mem_ctx,
4680 LDAP *ld, LDAPMessage *entry,
4681 struct samr_displayentry *result)
4684 size_t converted_size;
4686 uint16_t group_type;
4688 result->account_name = "";
4689 result->fullname = "";
4690 result->description = "";
4693 vals = ldap_get_values(ld, entry, "sambaGroupType");
4694 if ((vals == NULL) || (vals[0] == NULL)) {
4695 DEBUG(5, ("\"sambaGroupType\" not found\n"));
4697 ldap_value_free(vals);
4702 group_type = atoi(vals[0]);
4704 if ((state->group_type != 0) &&
4705 ((state->group_type != group_type))) {
4706 ldap_value_free(vals);
4710 ldap_value_free(vals);
4712 /* display name is the NT group name */
4714 vals = ldap_get_values(ld, entry, "displayName");
4715 if ((vals == NULL) || (vals[0] == NULL)) {
4716 DEBUG(8, ("\"displayName\" not found\n"));
4718 /* fallback to the 'cn' attribute */
4719 vals = ldap_get_values(ld, entry, "cn");
4720 if ((vals == NULL) || (vals[0] == NULL)) {
4721 DEBUG(5, ("\"cn\" not found\n"));
4724 if (!pull_utf8_talloc(mem_ctx,
4725 CONST_DISCARD(char **,
4726 &result->account_name),
4727 vals[0], &converted_size))
4729 DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc "
4730 "failed: %s", strerror(errno)));
4733 else if (!pull_utf8_talloc(mem_ctx,
4734 CONST_DISCARD(char **,
4735 &result->account_name),
4736 vals[0], &converted_size))
4738 DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s",
4742 ldap_value_free(vals);
4744 vals = ldap_get_values(ld, entry, "description");
4745 if ((vals == NULL) || (vals[0] == NULL))
4746 DEBUG(8, ("\"description\" not found\n"));
4747 else if (!pull_utf8_talloc(mem_ctx,
4748 CONST_DISCARD(char **, &result->description),
4749 vals[0], &converted_size))
4751 DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s",
4754 ldap_value_free(vals);
4756 if ((result->account_name == NULL) ||
4757 (result->fullname == NULL) ||
4758 (result->description == NULL)) {
4759 DEBUG(0, ("talloc failed\n"));
4763 vals = ldap_get_values(ld, entry, "sambaSid");
4764 if ((vals == NULL) || (vals[0] == NULL)) {
4765 DEBUG(0, ("\"objectSid\" not found\n"));
4767 ldap_value_free(vals);
4772 if (!string_to_sid(&sid, vals[0])) {
4773 DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
4777 ldap_value_free(vals);
4779 switch (group_type) {
4780 case SID_NAME_DOM_GRP:
4781 case SID_NAME_ALIAS:
4783 if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)
4784 && !sid_peek_check_rid(&global_sid_Builtin, &sid, &result->rid))
4786 DEBUG(0, ("%s is not in our domain\n",
4787 sid_string_dbg(&sid)));
4793 DEBUG(0,("unknown group type: %d\n", group_type));
4797 result->acct_flags = 0;
4802 static bool ldapsam_search_grouptype(struct pdb_methods *methods,
4803 struct pdb_search *search,
4804 const struct dom_sid *sid,
4805 enum lsa_SidType type)
4807 struct ldapsam_privates *ldap_state =
4808 (struct ldapsam_privates *)methods->private_data;
4809 struct ldap_search_state *state;
4812 state = talloc(search, struct ldap_search_state);
4813 if (state == NULL) {
4814 DEBUG(0, ("talloc failed\n"));
4818 state->connection = ldap_state->smbldap_state;
4820 state->base = talloc_strdup(search, lp_ldap_suffix());
4821 state->connection = ldap_state->smbldap_state;
4822 state->scope = LDAP_SCOPE_SUBTREE;
4823 state->filter = talloc_asprintf(search, "(&(objectclass=%s)"
4824 "(sambaGroupType=%d)(sambaSID=%s*))",
4826 type, sid_to_fstring(tmp, sid));
4827 state->attrs = talloc_attrs(search, "cn", "sambaSid",
4828 "displayName", "description",
4829 "sambaGroupType", NULL);
4830 state->attrsonly = 0;
4831 state->pagedresults_cookie = NULL;
4832 state->entries = NULL;
4833 state->group_type = type;
4834 state->ldap2displayentry = ldapgroup2displayentry;
4836 if ((state->filter == NULL) || (state->attrs == NULL)) {
4837 DEBUG(0, ("talloc failed\n"));
4841 search->private_data = state;
4842 search->next_entry = ldapsam_search_next_entry;
4843 search->search_end = ldapsam_search_end;
4845 return ldapsam_search_firstpage(search);
4848 static bool ldapsam_search_groups(struct pdb_methods *methods,
4849 struct pdb_search *search)
4851 return ldapsam_search_grouptype(methods, search, get_global_sam_sid(), SID_NAME_DOM_GRP);
4854 static bool ldapsam_search_aliases(struct pdb_methods *methods,
4855 struct pdb_search *search,
4856 const struct dom_sid *sid)
4858 return ldapsam_search_grouptype(methods, search, sid, SID_NAME_ALIAS);
4861 static uint32_t ldapsam_capabilities(struct pdb_methods *methods)
4863 return PDB_CAP_STORE_RIDS;
4866 static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
4869 struct smbldap_state *smbldap_state = priv->smbldap_state;
4871 LDAPMessage *result = NULL;
4872 LDAPMessage *entry = NULL;
4873 LDAPMod **mods = NULL;
4877 uint32_t nextRid = 0;
4880 TALLOC_CTX *mem_ctx;
4882 mem_ctx = talloc_new(NULL);
4883 if (mem_ctx == NULL) {
4884 DEBUG(0, ("talloc_new failed\n"));
4885 return NT_STATUS_NO_MEMORY;
4888 status = smbldap_search_domain_info(smbldap_state, &result,
4889 get_global_sam_name(), False);
4890 if (!NT_STATUS_IS_OK(status)) {
4891 DEBUG(3, ("Could not get domain info: %s\n",
4892 nt_errstr(status)));
4896 talloc_autofree_ldapmsg(mem_ctx, result);
4898 entry = ldap_first_entry(priv2ld(priv), result);
4899 if (entry == NULL) {
4900 DEBUG(0, ("Could not get domain info entry\n"));
4901 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
4905 /* Find the largest of the three attributes "sambaNextRid",
4906 "sambaNextGroupRid" and "sambaNextUserRid". I gave up on the
4907 concept of differentiating between user and group rids, and will
4908 use only "sambaNextRid" in the future. But for compatibility
4909 reasons I look if others have chosen different strategies -- VL */
4911 value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
4912 "sambaNextRid", mem_ctx);
4913 if (value != NULL) {
4914 uint32_t tmp = (uint32_t)strtoul(value, NULL, 10);
4915 nextRid = MAX(nextRid, tmp);
4918 value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
4919 "sambaNextUserRid", mem_ctx);
4920 if (value != NULL) {
4921 uint32_t tmp = (uint32_t)strtoul(value, NULL, 10);
4922 nextRid = MAX(nextRid, tmp);
4925 value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
4926 "sambaNextGroupRid", mem_ctx);
4927 if (value != NULL) {
4928 uint32_t tmp = (uint32_t)strtoul(value, NULL, 10);
4929 nextRid = MAX(nextRid, tmp);
4933 nextRid = BASE_RID-1;
4938 smbldap_make_mod(priv2ld(priv), entry, &mods, "sambaNextRid",
4939 talloc_asprintf(mem_ctx, "%d", nextRid));
4940 talloc_autofree_ldapmod(mem_ctx, mods);
4942 if ((dn = smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)) == NULL) {
4943 status = NT_STATUS_NO_MEMORY;
4947 rc = smbldap_modify(smbldap_state, dn, mods);
4949 /* ACCESS_DENIED is used as a placeholder for "the modify failed,
4952 status = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
4955 if (NT_STATUS_IS_OK(status)) {
4959 TALLOC_FREE(mem_ctx);
4963 static NTSTATUS ldapsam_new_rid_internal(struct pdb_methods *methods, uint32_t *rid)
4967 for (i=0; i<10; i++) {
4968 NTSTATUS result = ldapsam_get_new_rid(
4969 (struct ldapsam_privates *)methods->private_data, rid);
4970 if (NT_STATUS_IS_OK(result)) {
4974 if (!NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
4978 /* The ldap update failed (maybe a race condition), retry */
4981 /* Tried 10 times, fail. */
4982 return NT_STATUS_ACCESS_DENIED;
4985 static bool ldapsam_new_rid(struct pdb_methods *methods, uint32_t *rid)
4987 NTSTATUS result = ldapsam_new_rid_internal(methods, rid);
4988 return NT_STATUS_IS_OK(result) ? True : False;
4991 static bool ldapsam_sid_to_id(struct pdb_methods *methods,
4992 const struct dom_sid *sid,
4993 union unid_t *id, enum lsa_SidType *type)
4995 struct ldapsam_privates *priv =
4996 (struct ldapsam_privates *)methods->private_data;
4998 const char *attrs[] = { "sambaGroupType", "gidNumber", "uidNumber",
5000 LDAPMessage *result = NULL;
5001 LDAPMessage *entry = NULL;
5006 TALLOC_CTX *mem_ctx;
5008 mem_ctx = talloc_new(NULL);
5009 if (mem_ctx == NULL) {
5010 DEBUG(0, ("talloc_new failed\n"));
5014 filter = talloc_asprintf(mem_ctx,
5016 "(|(objectClass=%s)(objectClass=%s)))",
5017 sid_string_talloc(mem_ctx, sid),
5018 LDAP_OBJ_GROUPMAP, LDAP_OBJ_SAMBASAMACCOUNT);
5019 if (filter == NULL) {
5020 DEBUG(5, ("talloc_asprintf failed\n"));
5024 rc = smbldap_search_suffix(priv->smbldap_state, filter,
5026 if (rc != LDAP_SUCCESS) {
5029 talloc_autofree_ldapmsg(mem_ctx, result);
5031 if (ldap_count_entries(priv2ld(priv), result) != 1) {
5032 DEBUG(10, ("Got %d entries, expected one\n",
5033 ldap_count_entries(priv2ld(priv), result)));
5037 entry = ldap_first_entry(priv2ld(priv), result);
5039 value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5040 "sambaGroupType", mem_ctx);
5042 if (value != NULL) {
5043 const char *gid_str;
5046 gid_str = smbldap_talloc_single_attribute(
5047 priv2ld(priv), entry, "gidNumber", mem_ctx);
5048 if (gid_str == NULL) {
5049 DEBUG(1, ("%s has sambaGroupType but no gidNumber\n",
5050 smbldap_talloc_dn(mem_ctx, priv2ld(priv),
5055 id->gid = strtoul(gid_str, NULL, 10);
5056 *type = (enum lsa_SidType)strtoul(value, NULL, 10);
5057 store_gid_sid_cache(sid, id->gid);
5058 idmap_cache_set_sid2gid(sid, id->gid);
5063 /* It must be a user */
5065 value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5066 "uidNumber", mem_ctx);
5067 if (value == NULL) {
5068 DEBUG(1, ("Could not find uidNumber in %s\n",
5069 smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)));
5073 id->uid = strtoul(value, NULL, 10);
5074 *type = SID_NAME_USER;
5075 store_uid_sid_cache(sid, id->uid);
5076 idmap_cache_set_sid2uid(sid, id->uid);
5080 TALLOC_FREE(mem_ctx);
5085 * Find the SID for a uid.
5086 * This is shortcut is only used if ldapsam:trusted is set to true.
5088 static bool ldapsam_uid_to_sid(struct pdb_methods *methods, uid_t uid,
5089 struct dom_sid *sid)
5091 struct ldapsam_privates *priv =
5092 (struct ldapsam_privates *)methods->private_data;
5094 const char *attrs[] = { "sambaSID", NULL };
5095 LDAPMessage *result = NULL;
5096 LDAPMessage *entry = NULL;
5098 char *user_sid_string;
5099 struct dom_sid user_sid;
5101 TALLOC_CTX *tmp_ctx = talloc_stackframe();
5103 filter = talloc_asprintf(tmp_ctx,
5106 "(objectClass=%s))",
5108 LDAP_OBJ_POSIXACCOUNT,
5109 LDAP_OBJ_SAMBASAMACCOUNT);
5110 if (filter == NULL) {
5111 DEBUG(3, ("talloc_asprintf failed\n"));
5115 rc = smbldap_search_suffix(priv->smbldap_state, filter, attrs, &result);
5116 if (rc != LDAP_SUCCESS) {
5119 talloc_autofree_ldapmsg(tmp_ctx, result);
5121 if (ldap_count_entries(priv2ld(priv), result) != 1) {
5122 DEBUG(3, ("ERROR: Got %d entries for uid %u, expected one\n",
5123 ldap_count_entries(priv2ld(priv), result),
5124 (unsigned int)uid));
5128 entry = ldap_first_entry(priv2ld(priv), result);
5130 user_sid_string = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5131 "sambaSID", tmp_ctx);
5132 if (user_sid_string == NULL) {
5133 DEBUG(1, ("Could not find sambaSID in object '%s'\n",
5134 smbldap_talloc_dn(tmp_ctx, priv2ld(priv), entry)));
5138 if (!string_to_sid(&user_sid, user_sid_string)) {
5139 DEBUG(3, ("Error calling sid_string_talloc for sid '%s'\n",
5144 sid_copy(sid, &user_sid);
5146 store_uid_sid_cache(sid, uid);
5147 idmap_cache_set_sid2uid(sid, uid);
5152 TALLOC_FREE(tmp_ctx);
5157 * Find the SID for a gid.
5158 * This is shortcut is only used if ldapsam:trusted is set to true.
5160 static bool ldapsam_gid_to_sid(struct pdb_methods *methods, gid_t gid,
5161 struct dom_sid *sid)
5163 struct ldapsam_privates *priv =
5164 (struct ldapsam_privates *)methods->private_data;
5166 const char *attrs[] = { "sambaSID", NULL };
5167 LDAPMessage *result = NULL;
5168 LDAPMessage *entry = NULL;
5170 char *group_sid_string;
5171 struct dom_sid group_sid;
5173 TALLOC_CTX *tmp_ctx = talloc_stackframe();
5175 filter = talloc_asprintf(tmp_ctx,
5177 "(objectClass=%s))",
5180 if (filter == NULL) {
5181 DEBUG(3, ("talloc_asprintf failed\n"));
5185 rc = smbldap_search_suffix(priv->smbldap_state, filter, attrs, &result);
5186 if (rc != LDAP_SUCCESS) {
5189 talloc_autofree_ldapmsg(tmp_ctx, result);
5191 if (ldap_count_entries(priv2ld(priv), result) != 1) {
5192 DEBUG(3, ("ERROR: Got %d entries for gid %u, expected one\n",
5193 ldap_count_entries(priv2ld(priv), result),
5194 (unsigned int)gid));
5198 entry = ldap_first_entry(priv2ld(priv), result);
5200 group_sid_string = smbldap_talloc_single_attribute(priv2ld(priv), entry,
5201 "sambaSID", tmp_ctx);
5202 if (group_sid_string == NULL) {
5203 DEBUG(1, ("Could not find sambaSID in object '%s'\n",
5204 smbldap_talloc_dn(tmp_ctx, priv2ld(priv), entry)));
5208 if (!string_to_sid(&group_sid, group_sid_string)) {
5209 DEBUG(3, ("Error calling sid_string_talloc for sid '%s'\n",
5214 sid_copy(sid, &group_sid);
5216 store_gid_sid_cache(sid, gid);
5217 idmap_cache_set_sid2gid(sid, gid);
5222 TALLOC_FREE(tmp_ctx);
5228 * The following functions are called only if
5229 * ldapsam:trusted and ldapsam:editposix are
5234 * ldapsam_create_user creates a new
5235 * posixAccount and sambaSamAccount object
5236 * in the ldap users subtree
5238 * The uid is allocated by winbindd.
5241 static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
5242 TALLOC_CTX *tmp_ctx, const char *name,
5243 uint32_t acb_info, uint32_t *rid)
5245 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5246 LDAPMessage *entry = NULL;
5247 LDAPMessage *result = NULL;
5248 uint32_t num_result;
5249 bool is_machine = False;
5250 bool add_posix = False;
5251 LDAPMod **mods = NULL;
5259 const char *dn = NULL;
5260 struct dom_sid group_sid;
5261 struct dom_sid user_sid;
5267 if (((acb_info & ACB_NORMAL) && name[strlen(name)-1] == '$') ||
5268 acb_info & ACB_WSTRUST ||
5269 acb_info & ACB_SVRTRUST ||
5270 acb_info & ACB_DOMTRUST) {
5274 username = escape_ldap_string(talloc_tos(), name);
5275 filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass=%s))",
5276 username, LDAP_OBJ_POSIXACCOUNT);
5277 TALLOC_FREE(username);
5279 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5280 if (rc != LDAP_SUCCESS) {
5281 DEBUG(0,("ldapsam_create_user: ldap search failed!\n"));
5282 return NT_STATUS_ACCESS_DENIED;
5284 talloc_autofree_ldapmsg(tmp_ctx, result);
5286 num_result = ldap_count_entries(priv2ld(ldap_state), result);
5288 if (num_result > 1) {
5289 DEBUG (0, ("ldapsam_create_user: More than one user with name [%s] ?!\n", name));
5290 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5293 if (num_result == 1) {
5295 /* check if it is just a posix account.
5296 * or if there is a sid attached to this entry
5299 entry = ldap_first_entry(priv2ld(ldap_state), result);
5301 return NT_STATUS_UNSUCCESSFUL;
5304 tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
5306 DEBUG (1, ("ldapsam_create_user: The user [%s] already exist!\n", name));
5307 return NT_STATUS_USER_EXISTS;
5310 /* it is just a posix account, retrieve the dn for later use */
5311 dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5313 DEBUG(0,("ldapsam_create_user: Out of memory!\n"));
5314 return NT_STATUS_NO_MEMORY;
5318 if (num_result == 0) {
5322 /* Create the basic samu structure and generate the mods for the ldap commit */
5323 if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
5324 DEBUG(1, ("ldapsam_create_user: Could not allocate a new RID\n"));
5328 sid_compose(&user_sid, get_global_sam_sid(), *rid);
5330 user = samu_new(tmp_ctx);
5332 DEBUG(1,("ldapsam_create_user: Unable to allocate user struct\n"));
5333 return NT_STATUS_NO_MEMORY;
5336 if (!pdb_set_username(user, name, PDB_SET)) {
5337 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5338 return NT_STATUS_UNSUCCESSFUL;
5340 if (!pdb_set_domain(user, get_global_sam_name(), PDB_SET)) {
5341 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5342 return NT_STATUS_UNSUCCESSFUL;
5345 if (acb_info & ACB_NORMAL) {
5346 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_SET)) {
5347 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5348 return NT_STATUS_UNSUCCESSFUL;
5351 if (!pdb_set_acct_ctrl(user, acb_info, PDB_SET)) {
5352 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5353 return NT_STATUS_UNSUCCESSFUL;
5357 if (!pdb_set_acct_ctrl(user, ACB_NORMAL | ACB_DISABLED, PDB_SET)) {
5358 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5359 return NT_STATUS_UNSUCCESSFUL;
5363 if (!pdb_set_user_sid(user, &user_sid, PDB_SET)) {
5364 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5365 return NT_STATUS_UNSUCCESSFUL;
5368 if (!init_ldap_from_sam(ldap_state, entry, &mods, user, element_is_set_or_changed)) {
5369 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
5370 return NT_STATUS_UNSUCCESSFUL;
5373 if (ldap_state->schema_ver != SCHEMAVER_SAMBASAMACCOUNT) {
5374 DEBUG(1,("ldapsam_create_user: Unsupported schema version\n"));
5376 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
5381 DEBUG(3,("ldapsam_create_user: Creating new posix user\n"));
5383 /* retrieve the Domain Users group gid */
5384 if (!sid_compose(&group_sid, get_global_sam_sid(), DOMAIN_RID_USERS) ||
5385 !sid_to_gid(&group_sid, &gid)) {
5386 DEBUG (0, ("ldapsam_create_user: Unable to get the Domain Users gid: bailing out!\n"));
5387 return NT_STATUS_INVALID_PRIMARY_GROUP;
5390 /* lets allocate a new userid for this user */
5391 if (!winbind_allocate_uid(&uid)) {
5392 DEBUG (0, ("ldapsam_create_user: Unable to allocate a new user id: bailing out!\n"));
5393 return NT_STATUS_UNSUCCESSFUL;
5398 /* TODO: choose a more appropriate default for machines */
5399 homedir = talloc_sub_specified(tmp_ctx, lp_template_homedir(), "SMB_workstations_home", ldap_state->domain_name, uid, gid);
5400 shell = talloc_strdup(tmp_ctx, "/bin/false");
5402 homedir = talloc_sub_specified(tmp_ctx, lp_template_homedir(), name, ldap_state->domain_name, uid, gid);
5403 shell = talloc_sub_specified(tmp_ctx, lp_template_shell(), name, ldap_state->domain_name, uid, gid);
5405 uidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)uid);
5406 gidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)gid);
5408 escape_name = escape_rdn_val_string_alloc(name);
5410 DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
5411 return NT_STATUS_NO_MEMORY;
5415 dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_machine_suffix ());
5417 dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_user_suffix ());
5420 SAFE_FREE(escape_name);
5422 if (!homedir || !shell || !uidstr || !gidstr || !dn) {
5423 DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
5424 return NT_STATUS_NO_MEMORY;
5427 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
5428 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
5429 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
5430 smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
5431 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
5432 smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", homedir);
5433 smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", shell);
5436 talloc_autofree_ldapmod(tmp_ctx, mods);
5439 rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5441 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
5444 if (rc != LDAP_SUCCESS) {
5445 DEBUG(0,("ldapsam_create_user: failed to create a new user [%s] (dn = %s)\n", name ,dn));
5446 return NT_STATUS_UNSUCCESSFUL;
5449 DEBUG(2,("ldapsam_create_user: added account [%s] in the LDAP database\n", name));
5451 flush_pwnam_cache();
5453 return NT_STATUS_OK;
5456 static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, struct samu *sam_acct)
5458 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5459 LDAPMessage *result = NULL;
5460 LDAPMessage *entry = NULL;
5466 DEBUG(0,("ldapsam_delete_user: Attempt to delete user [%s]\n", pdb_get_username(sam_acct)));
5468 filter = talloc_asprintf(tmp_ctx,
5471 "(objectClass=%s))",
5472 pdb_get_username(sam_acct),
5473 LDAP_OBJ_POSIXACCOUNT,
5474 LDAP_OBJ_SAMBASAMACCOUNT);
5475 if (filter == NULL) {
5476 return NT_STATUS_NO_MEMORY;
5479 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5480 if (rc != LDAP_SUCCESS) {
5481 DEBUG(0,("ldapsam_delete_user: user search failed!\n"));
5482 return NT_STATUS_UNSUCCESSFUL;
5484 talloc_autofree_ldapmsg(tmp_ctx, result);
5486 num_result = ldap_count_entries(priv2ld(ldap_state), result);
5488 if (num_result == 0) {
5489 DEBUG(0,("ldapsam_delete_user: user not found!\n"));
5490 return NT_STATUS_NO_SUCH_USER;
5493 if (num_result > 1) {
5494 DEBUG (0, ("ldapsam_delete_user: More than one user with name [%s] ?!\n", pdb_get_username(sam_acct)));
5495 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5498 entry = ldap_first_entry(priv2ld(ldap_state), result);
5500 return NT_STATUS_UNSUCCESSFUL;
5503 /* it is just a posix account, retrieve the dn for later use */
5504 dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5506 DEBUG(0,("ldapsam_delete_user: Out of memory!\n"));
5507 return NT_STATUS_NO_MEMORY;
5510 /* try to remove memberships first */
5513 struct dom_sid *sids = NULL;
5515 uint32_t num_groups = 0;
5517 uint32_t user_rid = pdb_get_user_rid(sam_acct);
5519 status = ldapsam_enum_group_memberships(my_methods,
5525 if (!NT_STATUS_IS_OK(status)) {
5529 for (i=0; i < num_groups; i++) {
5533 sid_peek_rid(&sids[i], &group_rid);
5535 ldapsam_del_groupmem(my_methods,
5544 rc = smbldap_delete(ldap_state->smbldap_state, dn);
5545 if (rc != LDAP_SUCCESS) {
5546 return NT_STATUS_UNSUCCESSFUL;
5549 flush_pwnam_cache();
5551 return NT_STATUS_OK;
5555 * ldapsam_create_group creates a new
5556 * posixGroup and sambaGroupMapping object
5557 * in the ldap groups subtree
5559 * The gid is allocated by winbindd.
5562 static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
5563 TALLOC_CTX *tmp_ctx,
5567 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5569 LDAPMessage *entry = NULL;
5570 LDAPMessage *result = NULL;
5571 uint32_t num_result;
5572 bool is_new_entry = False;
5573 LDAPMod **mods = NULL;
5579 const char *dn = NULL;
5580 struct dom_sid group_sid;
5584 groupname = escape_ldap_string(talloc_tos(), name);
5585 filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))",
5586 groupname, LDAP_OBJ_POSIXGROUP);
5587 TALLOC_FREE(groupname);
5589 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5590 if (rc != LDAP_SUCCESS) {
5591 DEBUG(0,("ldapsam_create_group: ldap search failed!\n"));
5592 return NT_STATUS_UNSUCCESSFUL;
5594 talloc_autofree_ldapmsg(tmp_ctx, result);
5596 num_result = ldap_count_entries(priv2ld(ldap_state), result);
5598 if (num_result > 1) {
5599 DEBUG (0, ("ldapsam_create_group: There exists more than one group with name [%s]: bailing out!\n", name));
5600 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5603 if (num_result == 1) {
5605 /* check if it is just a posix group.
5606 * or if there is a sid attached to this entry
5609 entry = ldap_first_entry(priv2ld(ldap_state), result);
5611 return NT_STATUS_UNSUCCESSFUL;
5614 tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
5616 DEBUG (1, ("ldapsam_create_group: The group [%s] already exist!\n", name));
5617 return NT_STATUS_GROUP_EXISTS;
5620 /* it is just a posix group, retrieve the gid and the dn for later use */
5621 tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
5623 DEBUG (1, ("ldapsam_create_group: Couldn't retrieve the gidNumber for [%s]?!?!\n", name));
5624 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5627 gid = strtoul(tmp, NULL, 10);
5629 dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5631 DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
5632 return NT_STATUS_NO_MEMORY;
5636 if (num_result == 0) {
5637 is_new_entry = true;
5640 if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
5641 DEBUG(1, ("ldapsam_create_group: Could not allocate a new RID\n"));
5645 sid_compose(&group_sid, get_global_sam_sid(), *rid);
5647 groupsidstr = talloc_strdup(tmp_ctx, sid_string_talloc(tmp_ctx,
5649 grouptype = talloc_asprintf(tmp_ctx, "%d", SID_NAME_DOM_GRP);
5651 if (!groupsidstr || !grouptype) {
5652 DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
5653 return NT_STATUS_NO_MEMORY;
5656 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
5657 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", groupsidstr);
5658 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", grouptype);
5659 smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
5664 DEBUG(3,("ldapsam_create_user: Creating new posix group\n"));
5666 /* lets allocate a new groupid for this group */
5667 if (!winbind_allocate_gid(&gid)) {
5668 DEBUG (0, ("ldapsam_create_group: Unable to allocate a new group id: bailing out!\n"));
5669 return NT_STATUS_UNSUCCESSFUL;
5672 gidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)gid);
5674 escape_name = escape_rdn_val_string_alloc(name);
5676 DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
5677 return NT_STATUS_NO_MEMORY;
5680 dn = talloc_asprintf(tmp_ctx, "cn=%s,%s", escape_name, lp_ldap_group_suffix());
5682 SAFE_FREE(escape_name);
5684 if (!gidstr || !dn) {
5685 DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
5686 return NT_STATUS_NO_MEMORY;
5689 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_POSIXGROUP);
5690 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
5691 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
5694 talloc_autofree_ldapmod(tmp_ctx, mods);
5697 rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5699 if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
5700 /* This call may fail with rfc2307bis schema */
5701 /* Retry adding a structural class */
5702 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "????");
5703 rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
5707 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
5710 if (rc != LDAP_SUCCESS) {
5711 DEBUG(0,("ldapsam_create_group: failed to create a new group [%s] (dn = %s)\n", name ,dn));
5712 return NT_STATUS_UNSUCCESSFUL;
5715 DEBUG(2,("ldapsam_create_group: added group [%s] in the LDAP database\n", name));
5717 return NT_STATUS_OK;
5720 static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, uint32_t rid)
5722 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5723 LDAPMessage *result = NULL;
5724 LDAPMessage *entry = NULL;
5729 struct dom_sid group_sid;
5732 /* get the group sid */
5733 sid_compose(&group_sid, get_global_sam_sid(), rid);
5735 filter = talloc_asprintf(tmp_ctx,
5738 "(objectClass=%s))",
5739 sid_string_talloc(tmp_ctx, &group_sid),
5740 LDAP_OBJ_POSIXGROUP,
5742 if (filter == NULL) {
5743 return NT_STATUS_NO_MEMORY;
5746 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5747 if (rc != LDAP_SUCCESS) {
5748 DEBUG(1,("ldapsam_delete_dom_group: group search failed!\n"));
5749 return NT_STATUS_UNSUCCESSFUL;
5751 talloc_autofree_ldapmsg(tmp_ctx, result);
5753 num_result = ldap_count_entries(priv2ld(ldap_state), result);
5755 if (num_result == 0) {
5756 DEBUG(1,("ldapsam_delete_dom_group: group not found!\n"));
5757 return NT_STATUS_NO_SUCH_GROUP;
5760 if (num_result > 1) {
5761 DEBUG (0, ("ldapsam_delete_dom_group: More than one group with the same SID ?!\n"));
5762 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5765 entry = ldap_first_entry(priv2ld(ldap_state), result);
5767 return NT_STATUS_UNSUCCESSFUL;
5770 /* here it is, retrieve the dn for later use */
5771 dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5773 DEBUG(0,("ldapsam_delete_dom_group: Out of memory!\n"));
5774 return NT_STATUS_NO_MEMORY;
5777 gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
5779 DEBUG (0, ("ldapsam_delete_dom_group: Unable to find the group's gid!\n"));
5780 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5783 /* check no user have this group marked as primary group */
5784 filter = talloc_asprintf(tmp_ctx,
5787 "(objectClass=%s))",
5789 LDAP_OBJ_POSIXACCOUNT,
5790 LDAP_OBJ_SAMBASAMACCOUNT);
5792 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5793 if (rc != LDAP_SUCCESS) {
5794 DEBUG(1,("ldapsam_delete_dom_group: accounts search failed!\n"));
5795 return NT_STATUS_UNSUCCESSFUL;
5797 talloc_autofree_ldapmsg(tmp_ctx, result);
5799 num_result = ldap_count_entries(priv2ld(ldap_state), result);
5801 if (num_result != 0) {
5802 DEBUG(3,("ldapsam_delete_dom_group: Can't delete group, it is a primary group for %d users\n", num_result));
5803 return NT_STATUS_MEMBERS_PRIMARY_GROUP;
5806 rc = smbldap_delete(ldap_state->smbldap_state, dn);
5807 if (rc != LDAP_SUCCESS) {
5808 return NT_STATUS_UNSUCCESSFUL;
5811 return NT_STATUS_OK;
5814 static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
5815 TALLOC_CTX *tmp_ctx,
5817 uint32_t member_rid,
5820 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5821 LDAPMessage *entry = NULL;
5822 LDAPMessage *result = NULL;
5823 uint32_t num_result;
5824 LDAPMod **mods = NULL;
5827 const char *dn = NULL;
5828 struct dom_sid group_sid;
5829 struct dom_sid member_sid;
5834 DEBUG(1,("ldapsam_change_groupmem: add new member(rid=%d) to a domain group(rid=%d)", member_rid, group_rid));
5836 case LDAP_MOD_DELETE:
5837 DEBUG(1,("ldapsam_change_groupmem: delete member(rid=%d) from a domain group(rid=%d)", member_rid, group_rid));
5840 return NT_STATUS_UNSUCCESSFUL;
5843 /* get member sid */
5844 sid_compose(&member_sid, get_global_sam_sid(), member_rid);
5846 /* get the group sid */
5847 sid_compose(&group_sid, get_global_sam_sid(), group_rid);
5849 filter = talloc_asprintf(tmp_ctx,
5852 "(objectClass=%s))",
5853 sid_string_talloc(tmp_ctx, &member_sid),
5854 LDAP_OBJ_POSIXACCOUNT,
5855 LDAP_OBJ_SAMBASAMACCOUNT);
5856 if (filter == NULL) {
5857 return NT_STATUS_NO_MEMORY;
5860 /* get the member uid */
5861 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5862 if (rc != LDAP_SUCCESS) {
5863 DEBUG(1,("ldapsam_change_groupmem: member search failed!\n"));
5864 return NT_STATUS_UNSUCCESSFUL;
5866 talloc_autofree_ldapmsg(tmp_ctx, result);
5868 num_result = ldap_count_entries(priv2ld(ldap_state), result);
5870 if (num_result == 0) {
5871 DEBUG(1,("ldapsam_change_groupmem: member not found!\n"));
5872 return NT_STATUS_NO_SUCH_MEMBER;
5875 if (num_result > 1) {
5876 DEBUG (0, ("ldapsam_change_groupmem: More than one account with the same SID ?!\n"));
5877 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5880 entry = ldap_first_entry(priv2ld(ldap_state), result);
5882 return NT_STATUS_UNSUCCESSFUL;
5885 if (modop == LDAP_MOD_DELETE) {
5886 /* check if we are trying to remove the member from his primary group */
5888 gid_t user_gid, group_gid;
5890 gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
5892 DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's gid!\n"));
5893 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5896 user_gid = strtoul(gidstr, NULL, 10);
5898 if (!sid_to_gid(&group_sid, &group_gid)) {
5899 DEBUG (0, ("ldapsam_change_groupmem: Unable to get group gid from SID!\n"));
5900 return NT_STATUS_UNSUCCESSFUL;
5903 if (user_gid == group_gid) {
5904 DEBUG (3, ("ldapsam_change_groupmem: can't remove user from its own primary group!\n"));
5905 return NT_STATUS_MEMBERS_PRIMARY_GROUP;
5909 /* here it is, retrieve the uid for later use */
5910 uidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "uid", tmp_ctx);
5912 DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's name!\n"));
5913 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5916 filter = talloc_asprintf(tmp_ctx,
5919 "(objectClass=%s))",
5920 sid_string_talloc(tmp_ctx, &group_sid),
5921 LDAP_OBJ_POSIXGROUP,
5925 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
5926 if (rc != LDAP_SUCCESS) {
5927 DEBUG(1,("ldapsam_change_groupmem: group search failed!\n"));
5928 return NT_STATUS_UNSUCCESSFUL;
5930 talloc_autofree_ldapmsg(tmp_ctx, result);
5932 num_result = ldap_count_entries(priv2ld(ldap_state), result);
5934 if (num_result == 0) {
5935 DEBUG(1,("ldapsam_change_groupmem: group not found!\n"));
5936 return NT_STATUS_NO_SUCH_GROUP;
5939 if (num_result > 1) {
5940 DEBUG (0, ("ldapsam_change_groupmem: More than one group with the same SID ?!\n"));
5941 return NT_STATUS_INTERNAL_DB_CORRUPTION;
5944 entry = ldap_first_entry(priv2ld(ldap_state), result);
5946 return NT_STATUS_UNSUCCESSFUL;
5949 /* here it is, retrieve the dn for later use */
5950 dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
5952 DEBUG(0,("ldapsam_change_groupmem: Out of memory!\n"));
5953 return NT_STATUS_NO_MEMORY;
5956 smbldap_set_mod(&mods, modop, "memberUid", uidstr);
5958 talloc_autofree_ldapmod(tmp_ctx, mods);
5960 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
5961 if (rc != LDAP_SUCCESS) {
5962 if (rc == LDAP_TYPE_OR_VALUE_EXISTS && modop == LDAP_MOD_ADD) {
5963 DEBUG(1,("ldapsam_change_groupmem: member is already in group, add failed!\n"));
5964 return NT_STATUS_MEMBER_IN_GROUP;
5966 if (rc == LDAP_NO_SUCH_ATTRIBUTE && modop == LDAP_MOD_DELETE) {
5967 DEBUG(1,("ldapsam_change_groupmem: member is not in group, delete failed!\n"));
5968 return NT_STATUS_MEMBER_NOT_IN_GROUP;
5970 return NT_STATUS_UNSUCCESSFUL;
5973 return NT_STATUS_OK;
5976 static NTSTATUS ldapsam_add_groupmem(struct pdb_methods *my_methods,
5977 TALLOC_CTX *tmp_ctx,
5979 uint32_t member_rid)
5981 return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_ADD);
5983 static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods,
5984 TALLOC_CTX *tmp_ctx,
5986 uint32_t member_rid)
5988 return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_DELETE);
5991 static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
5992 TALLOC_CTX *mem_ctx,
5993 struct samu *sampass)
5995 struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
5996 LDAPMessage *entry = NULL;
5997 LDAPMessage *result = NULL;
5998 uint32_t num_result;
5999 LDAPMod **mods = NULL;
6001 char *escape_username;
6003 const char *dn = NULL;
6007 DEBUG(0,("ldapsam_set_primary_group: Attempt to set primary group for user [%s]\n", pdb_get_username(sampass)));
6009 if (!sid_to_gid(pdb_get_group_sid(sampass), &gid)) {
6010 DEBUG(0,("ldapsam_set_primary_group: failed to retrieve gid from user's group SID!\n"));
6011 return NT_STATUS_UNSUCCESSFUL;
6013 gidstr = talloc_asprintf(mem_ctx, "%u", (unsigned int)gid);
6015 DEBUG(0,("ldapsam_set_primary_group: Out of Memory!\n"));
6016 return NT_STATUS_NO_MEMORY;
6019 escape_username = escape_ldap_string(talloc_tos(),
6020 pdb_get_username(sampass));
6021 if (escape_username== NULL) {
6022 return NT_STATUS_NO_MEMORY;
6025 filter = talloc_asprintf(mem_ctx,
6028 "(objectClass=%s))",
6030 LDAP_OBJ_POSIXACCOUNT,
6031 LDAP_OBJ_SAMBASAMACCOUNT);
6033 TALLOC_FREE(escape_username);
6035 if (filter == NULL) {
6036 return NT_STATUS_NO_MEMORY;
6039 rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
6040 if (rc != LDAP_SUCCESS) {
6041 DEBUG(0,("ldapsam_set_primary_group: user search failed!\n"));
6042 return NT_STATUS_UNSUCCESSFUL;
6044 talloc_autofree_ldapmsg(mem_ctx, result);
6046 num_result = ldap_count_entries(priv2ld(ldap_state), result);
6048 if (num_result == 0) {
6049 DEBUG(0,("ldapsam_set_primary_group: user not found!\n"));
6050 return NT_STATUS_NO_SUCH_USER;
6053 if (num_result > 1) {
6054 DEBUG (0, ("ldapsam_set_primary_group: More than one user with name [%s] ?!\n", pdb_get_username(sampass)));
6055 return NT_STATUS_INTERNAL_DB_CORRUPTION;
6058 entry = ldap_first_entry(priv2ld(ldap_state), result);
6060 return NT_STATUS_UNSUCCESSFUL;
6063 /* retrieve the dn for later use */
6064 dn = smbldap_talloc_dn(mem_ctx, priv2ld(ldap_state), entry);
6066 DEBUG(0,("ldapsam_set_primary_group: Out of memory!\n"));
6067 return NT_STATUS_NO_MEMORY;
6070 /* remove the old one, and add the new one, this way we do not risk races */
6071 smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "gidNumber", gidstr);
6074 return NT_STATUS_OK;
6077 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
6079 if (rc != LDAP_SUCCESS) {
6080 DEBUG(0,("ldapsam_set_primary_group: failed to modify [%s] primary group to [%s]\n",
6081 pdb_get_username(sampass), gidstr));
6082 return NT_STATUS_UNSUCCESSFUL;
6085 flush_pwnam_cache();
6087 return NT_STATUS_OK;
6091 /**********************************************************************
6092 trusted domains functions
6093 *********************************************************************/
6095 static char *trusteddom_dn(struct ldapsam_privates *ldap_state,
6098 return talloc_asprintf(talloc_tos(), "sambaDomainName=%s,%s", domain,
6099 ldap_state->domain_dn);
6102 static bool get_trusteddom_pw_int(struct ldapsam_privates *ldap_state,
6103 TALLOC_CTX *mem_ctx,
6104 const char *domain, LDAPMessage **entry)
6108 int scope = LDAP_SCOPE_SUBTREE;
6109 const char **attrs = NULL; /* NULL: get all attrs */
6110 int attrsonly = 0; /* 0: return values too */
6111 LDAPMessage *result = NULL;
6113 uint32_t num_result;
6115 filter = talloc_asprintf(talloc_tos(),
6116 "(&(objectClass=%s)(sambaDomainName=%s))",
6117 LDAP_OBJ_TRUSTDOM_PASSWORD, domain);
6119 trusted_dn = trusteddom_dn(ldap_state, domain);
6120 if (trusted_dn == NULL) {
6123 rc = smbldap_search(ldap_state->smbldap_state, trusted_dn, scope,
6124 filter, attrs, attrsonly, &result);
6126 if (result != NULL) {
6127 talloc_autofree_ldapmsg(mem_ctx, result);
6130 if (rc == LDAP_NO_SUCH_OBJECT) {
6135 if (rc != LDAP_SUCCESS) {
6139 num_result = ldap_count_entries(priv2ld(ldap_state), result);
6141 if (num_result > 1) {
6142 DEBUG(1, ("ldapsam_get_trusteddom_pw: more than one "
6143 "%s object for domain '%s'?!\n",
6144 LDAP_OBJ_TRUSTDOM_PASSWORD, domain));
6148 if (num_result == 0) {
6149 DEBUG(1, ("ldapsam_get_trusteddom_pw: no "
6150 "%s object for domain %s.\n",
6151 LDAP_OBJ_TRUSTDOM_PASSWORD, domain));
6154 *entry = ldap_first_entry(priv2ld(ldap_state), result);
6160 static bool ldapsam_get_trusteddom_pw(struct pdb_methods *methods,
6163 struct dom_sid *sid,
6164 time_t *pass_last_set_time)
6166 struct ldapsam_privates *ldap_state =
6167 (struct ldapsam_privates *)methods->private_data;
6168 LDAPMessage *entry = NULL;
6170 DEBUG(10, ("ldapsam_get_trusteddom_pw called for domain %s\n", domain));
6172 if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry) ||
6181 pwd_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6182 entry, "sambaClearTextPassword", talloc_tos());
6183 if (pwd_str == NULL) {
6186 /* trusteddom_pw routines do not use talloc yet... */
6187 *pwd = SMB_STRDUP(pwd_str);
6193 /* last change time */
6194 if (pass_last_set_time != NULL) {
6196 time_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6197 entry, "sambaPwdLastSet", talloc_tos());
6198 if (time_str == NULL) {
6201 *pass_last_set_time = (time_t)atol(time_str);
6207 struct dom_sid dom_sid;
6208 sid_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6211 if (sid_str == NULL) {
6214 if (!string_to_sid(&dom_sid, sid_str)) {
6217 sid_copy(sid, &dom_sid);
6223 static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods,
6226 const struct dom_sid *sid)
6228 struct ldapsam_privates *ldap_state =
6229 (struct ldapsam_privates *)methods->private_data;
6230 LDAPMessage *entry = NULL;
6231 LDAPMod **mods = NULL;
6232 char *prev_pwd = NULL;
6233 char *trusted_dn = NULL;
6236 DEBUG(10, ("ldapsam_set_trusteddom_pw called for domain %s\n", domain));
6239 * get the current entry (if there is one) in order to put the
6240 * current password into the previous password attribute
6242 if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry)) {
6247 smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass",
6248 LDAP_OBJ_TRUSTDOM_PASSWORD);
6249 smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaDomainName",
6251 smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaSID",
6252 sid_string_tos(sid));
6253 smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaPwdLastSet",
6254 talloc_asprintf(talloc_tos(), "%li", (long int)time(NULL)));
6255 smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
6256 "sambaClearTextPassword", pwd);
6258 if (entry != NULL) {
6259 prev_pwd = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6260 entry, "sambaClearTextPassword", talloc_tos());
6261 if (prev_pwd != NULL) {
6262 smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
6263 "sambaPreviousClearTextPassword",
6268 talloc_autofree_ldapmod(talloc_tos(), mods);
6270 trusted_dn = trusteddom_dn(ldap_state, domain);
6271 if (trusted_dn == NULL) {
6274 if (entry == NULL) {
6275 rc = smbldap_add(ldap_state->smbldap_state, trusted_dn, mods);
6277 rc = smbldap_modify(ldap_state->smbldap_state, trusted_dn, mods);
6280 if (rc != LDAP_SUCCESS) {
6281 DEBUG(1, ("error writing trusted domain password!\n"));
6288 static bool ldapsam_del_trusteddom_pw(struct pdb_methods *methods,
6292 struct ldapsam_privates *ldap_state =
6293 (struct ldapsam_privates *)methods->private_data;
6294 LDAPMessage *entry = NULL;
6295 const char *trusted_dn;
6297 if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry)) {
6301 if (entry == NULL) {
6302 DEBUG(5, ("ldapsam_del_trusteddom_pw: no such trusted domain: "
6307 trusted_dn = smbldap_talloc_dn(talloc_tos(), priv2ld(ldap_state),
6309 if (trusted_dn == NULL) {
6310 DEBUG(0,("ldapsam_del_trusteddom_pw: Out of memory!\n"));
6314 rc = smbldap_delete(ldap_state->smbldap_state, trusted_dn);
6315 if (rc != LDAP_SUCCESS) {
6322 static NTSTATUS ldapsam_enum_trusteddoms(struct pdb_methods *methods,
6323 TALLOC_CTX *mem_ctx,
6324 uint32_t *num_domains,
6325 struct trustdom_info ***domains)
6328 struct ldapsam_privates *ldap_state =
6329 (struct ldapsam_privates *)methods->private_data;
6331 int scope = LDAP_SCOPE_SUBTREE;
6332 const char *attrs[] = { "sambaDomainName", "sambaSID", NULL };
6333 int attrsonly = 0; /* 0: return values too */
6334 LDAPMessage *result = NULL;
6335 LDAPMessage *entry = NULL;
6337 filter = talloc_asprintf(talloc_tos(), "(objectClass=%s)",
6338 LDAP_OBJ_TRUSTDOM_PASSWORD);
6340 rc = smbldap_search(ldap_state->smbldap_state,
6341 ldap_state->domain_dn,
6348 if (result != NULL) {
6349 talloc_autofree_ldapmsg(mem_ctx, result);
6352 if (rc != LDAP_SUCCESS) {
6353 return NT_STATUS_UNSUCCESSFUL;
6357 if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *, 1))) {
6358 DEBUG(1, ("talloc failed\n"));
6359 return NT_STATUS_NO_MEMORY;
6362 for (entry = ldap_first_entry(priv2ld(ldap_state), result);
6364 entry = ldap_next_entry(priv2ld(ldap_state), entry))
6366 char *dom_name, *dom_sid_str;
6367 struct trustdom_info *dom_info;
6369 dom_info = TALLOC_P(*domains, struct trustdom_info);
6370 if (dom_info == NULL) {
6371 DEBUG(1, ("talloc failed\n"));
6372 return NT_STATUS_NO_MEMORY;
6375 dom_name = smbldap_talloc_single_attribute(priv2ld(ldap_state),
6379 if (dom_name == NULL) {
6380 DEBUG(1, ("talloc failed\n"));
6381 return NT_STATUS_NO_MEMORY;
6383 dom_info->name = dom_name;
6385 dom_sid_str = smbldap_talloc_single_attribute(
6386 priv2ld(ldap_state), entry, "sambaSID",
6388 if (dom_sid_str == NULL) {
6389 DEBUG(1, ("talloc failed\n"));
6390 return NT_STATUS_NO_MEMORY;
6392 if (!string_to_sid(&dom_info->sid, dom_sid_str)) {
6393 DEBUG(1, ("Error calling string_to_sid on SID %s\n",
6395 return NT_STATUS_UNSUCCESSFUL;
6398 ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
6399 domains, num_domains);
6401 if (*domains == NULL) {
6402 DEBUG(1, ("talloc failed\n"));
6403 return NT_STATUS_NO_MEMORY;
6407 DEBUG(5, ("ldapsam_enum_trusteddoms: got %d domains\n", *num_domains));
6408 return NT_STATUS_OK;
6412 /**********************************************************************
6414 *********************************************************************/
6416 static void free_private_data(void **vp)
6418 struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
6420 smbldap_free_struct(&(*ldap_state)->smbldap_state);
6422 if ((*ldap_state)->result != NULL) {
6423 ldap_msgfree((*ldap_state)->result);
6424 (*ldap_state)->result = NULL;
6426 if ((*ldap_state)->domain_dn != NULL) {
6427 SAFE_FREE((*ldap_state)->domain_dn);
6432 /* No need to free any further, as it is talloc()ed */
6435 /*********************************************************************
6436 Intitalise the parts of the pdb_methods structure that are common to
6438 *********************************************************************/
6440 static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const char *location)
6443 struct ldapsam_privates *ldap_state;
6445 if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) {
6449 (*pdb_method)->name = "ldapsam";
6451 (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
6452 (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
6453 (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
6454 (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
6455 (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
6456 (*pdb_method)->rename_sam_account = ldapsam_rename_sam_account;
6458 (*pdb_method)->getgrsid = ldapsam_getgrsid;
6459 (*pdb_method)->getgrgid = ldapsam_getgrgid;
6460 (*pdb_method)->getgrnam = ldapsam_getgrnam;
6461 (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
6462 (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
6463 (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
6464 (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
6466 (*pdb_method)->get_account_policy = ldapsam_get_account_policy;
6467 (*pdb_method)->set_account_policy = ldapsam_set_account_policy;
6469 (*pdb_method)->get_seq_num = ldapsam_get_seq_num;
6471 (*pdb_method)->capabilities = ldapsam_capabilities;
6472 (*pdb_method)->new_rid = ldapsam_new_rid;
6474 (*pdb_method)->get_trusteddom_pw = ldapsam_get_trusteddom_pw;
6475 (*pdb_method)->set_trusteddom_pw = ldapsam_set_trusteddom_pw;
6476 (*pdb_method)->del_trusteddom_pw = ldapsam_del_trusteddom_pw;
6477 (*pdb_method)->enum_trusteddoms = ldapsam_enum_trusteddoms;
6479 /* TODO: Setup private data and free */
6481 if ( !(ldap_state = TALLOC_ZERO_P(*pdb_method, struct ldapsam_privates)) ) {
6482 DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
6483 return NT_STATUS_NO_MEMORY;
6486 nt_status = smbldap_init(*pdb_method, pdb_get_event_context(),
6487 location, &ldap_state->smbldap_state);
6489 if ( !NT_STATUS_IS_OK(nt_status) ) {
6493 if ( !(ldap_state->domain_name = talloc_strdup(*pdb_method, get_global_sam_name()) ) ) {
6494 return NT_STATUS_NO_MEMORY;
6497 (*pdb_method)->private_data = ldap_state;
6499 (*pdb_method)->free_private_data = free_private_data;
6501 return NT_STATUS_OK;
6504 /**********************************************************************
6505 Initialise the 'compat' mode for pdb_ldap
6506 *********************************************************************/
6508 NTSTATUS pdb_init_ldapsam_compat(struct pdb_methods **pdb_method, const char *location)
6511 struct ldapsam_privates *ldap_state;
6512 char *uri = talloc_strdup( NULL, location );
6514 trim_char( uri, '\"', '\"' );
6515 nt_status = pdb_init_ldapsam_common( pdb_method, uri );
6519 if ( !NT_STATUS_IS_OK(nt_status) ) {
6523 (*pdb_method)->name = "ldapsam_compat";
6525 ldap_state = (struct ldapsam_privates *)((*pdb_method)->private_data);
6526 ldap_state->schema_ver = SCHEMAVER_SAMBAACCOUNT;
6528 sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
6530 return NT_STATUS_OK;
6533 /**********************************************************************
6534 Initialise the normal mode for pdb_ldap
6535 *********************************************************************/
6537 NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
6540 struct ldapsam_privates *ldap_state = NULL;
6541 uint32_t alg_rid_base;
6542 char *alg_rid_base_string = NULL;
6543 LDAPMessage *result = NULL;
6544 LDAPMessage *entry = NULL;
6545 struct dom_sid ldap_domain_sid;
6546 struct dom_sid secrets_domain_sid;
6547 char *domain_sid_string = NULL;
6549 char *uri = talloc_strdup( NULL, location );
6551 trim_char( uri, '\"', '\"' );
6552 nt_status = pdb_init_ldapsam_common(pdb_method, uri);
6556 if (!NT_STATUS_IS_OK(nt_status)) {
6560 (*pdb_method)->name = "ldapsam";
6562 (*pdb_method)->add_aliasmem = ldapsam_add_aliasmem;
6563 (*pdb_method)->del_aliasmem = ldapsam_del_aliasmem;
6564 (*pdb_method)->enum_aliasmem = ldapsam_enum_aliasmem;
6565 (*pdb_method)->enum_alias_memberships = ldapsam_alias_memberships;
6566 (*pdb_method)->search_users = ldapsam_search_users;
6567 (*pdb_method)->search_groups = ldapsam_search_groups;
6568 (*pdb_method)->search_aliases = ldapsam_search_aliases;
6570 if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
6571 (*pdb_method)->enum_group_members = ldapsam_enum_group_members;
6572 (*pdb_method)->enum_group_memberships =
6573 ldapsam_enum_group_memberships;
6574 (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
6575 (*pdb_method)->sid_to_id = ldapsam_sid_to_id;
6576 (*pdb_method)->uid_to_sid = ldapsam_uid_to_sid;
6577 (*pdb_method)->gid_to_sid = ldapsam_gid_to_sid;
6579 if (lp_parm_bool(-1, "ldapsam", "editposix", False)) {
6580 (*pdb_method)->create_user = ldapsam_create_user;
6581 (*pdb_method)->delete_user = ldapsam_delete_user;
6582 (*pdb_method)->create_dom_group = ldapsam_create_dom_group;
6583 (*pdb_method)->delete_dom_group = ldapsam_delete_dom_group;
6584 (*pdb_method)->add_groupmem = ldapsam_add_groupmem;
6585 (*pdb_method)->del_groupmem = ldapsam_del_groupmem;
6586 (*pdb_method)->set_unix_primary_group = ldapsam_set_primary_group;
6590 ldap_state = (struct ldapsam_privates *)((*pdb_method)->private_data);
6591 ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
6593 /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
6595 nt_status = smbldap_search_domain_info(ldap_state->smbldap_state,
6597 ldap_state->domain_name, True);
6599 if ( !NT_STATUS_IS_OK(nt_status) ) {
6600 DEBUG(2, ("pdb_init_ldapsam: WARNING: Could not get domain "
6601 "info, nor add one to the domain\n"));
6602 DEBUGADD(2, ("pdb_init_ldapsam: Continuing on regardless, "
6603 "will be unable to allocate new users/groups, "
6604 "and will risk BDCs having inconsistent SIDs\n"));
6605 sid_copy(&ldap_state->domain_sid, get_global_sam_sid());
6606 return NT_STATUS_OK;
6609 /* Given that the above might fail, everything below this must be
6612 entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
6615 DEBUG(0, ("pdb_init_ldapsam: Could not get domain info "
6617 ldap_msgfree(result);
6618 return NT_STATUS_UNSUCCESSFUL;
6621 dn = smbldap_talloc_dn(talloc_tos(), ldap_state->smbldap_state->ldap_struct, entry);
6623 ldap_msgfree(result);
6624 return NT_STATUS_UNSUCCESSFUL;
6627 ldap_state->domain_dn = smb_xstrdup(dn);
6630 domain_sid_string = smbldap_talloc_single_attribute(
6631 ldap_state->smbldap_state->ldap_struct,
6633 get_userattr_key2string(ldap_state->schema_ver,
6634 LDAP_ATTR_USER_SID),
6637 if (domain_sid_string) {
6639 if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) {
6640 DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be "
6641 "read as a valid SID\n", domain_sid_string));
6642 ldap_msgfree(result);
6643 TALLOC_FREE(domain_sid_string);
6644 return NT_STATUS_INVALID_PARAMETER;
6646 found_sid = secrets_fetch_domain_sid(ldap_state->domain_name,
6647 &secrets_domain_sid);
6648 if (!found_sid || !dom_sid_equal(&secrets_domain_sid,
6649 &ldap_domain_sid)) {
6650 DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain "
6651 "%s based on pdb_ldap results %s -> %s\n",
6652 ldap_state->domain_name,
6653 sid_string_dbg(&secrets_domain_sid),
6654 sid_string_dbg(&ldap_domain_sid)));
6656 /* reset secrets.tdb sid */
6657 secrets_store_domain_sid(ldap_state->domain_name,
6659 DEBUG(1, ("New global sam SID: %s\n",
6660 sid_string_dbg(get_global_sam_sid())));
6662 sid_copy(&ldap_state->domain_sid, &ldap_domain_sid);
6663 TALLOC_FREE(domain_sid_string);
6666 alg_rid_base_string = smbldap_talloc_single_attribute(
6667 ldap_state->smbldap_state->ldap_struct,
6669 get_attr_key2string( dominfo_attr_list,
6670 LDAP_ATTR_ALGORITHMIC_RID_BASE ),
6672 if (alg_rid_base_string) {
6673 alg_rid_base = (uint32_t)atol(alg_rid_base_string);
6674 if (alg_rid_base != algorithmic_rid_base()) {
6675 DEBUG(0, ("The value of 'algorithmic RID base' has "
6676 "changed since the LDAP\n"
6677 "database was initialised. Aborting. \n"));
6678 ldap_msgfree(result);
6679 TALLOC_FREE(alg_rid_base_string);
6680 return NT_STATUS_UNSUCCESSFUL;
6682 TALLOC_FREE(alg_rid_base_string);
6684 ldap_msgfree(result);
6686 return NT_STATUS_OK;
6689 NTSTATUS pdb_ldap_init(void)
6692 if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam", pdb_init_ldapsam)))
6695 if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_compat", pdb_init_ldapsam_compat)))
6698 /* Let pdb_nds register backends */
6703 return NT_STATUS_OK;