diff options
Diffstat (limited to 'source3/passdb')
-rw-r--r-- | source3/passdb/lookup_sid.c | 25 | ||||
-rw-r--r-- | source3/passdb/passdb.c | 113 | ||||
-rw-r--r-- | source3/passdb/pdb_ads.c | 2363 | ||||
-rw-r--r-- | source3/passdb/pdb_get_set.c | 138 | ||||
-rw-r--r-- | source3/passdb/pdb_interface.c | 169 | ||||
-rw-r--r-- | source3/passdb/pdb_ldap.c | 276 | ||||
-rw-r--r-- | source3/passdb/pdb_smbpasswd.c | 12 | ||||
-rw-r--r-- | source3/passdb/pdb_tdb.c | 17 | ||||
-rw-r--r-- | source3/passdb/pdb_wbc_sam.c | 17 | ||||
-rw-r--r-- | source3/passdb/secrets.c | 494 | ||||
-rw-r--r-- | source3/passdb/secrets_schannel.c | 131 | ||||
-rw-r--r-- | source3/passdb/util_unixsids.c | 10 | ||||
-rw-r--r-- | source3/passdb/util_wellknown.c | 1 |
13 files changed, 850 insertions, 2916 deletions
diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index a197c51ac8..112225d504 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -86,14 +86,6 @@ bool lookup_name(TALLOC_CTX *mem_ctx, if ((flags & LOOKUP_NAME_BUILTIN) && strequal(domain, builtin_domain_name())) { - if (strlen(name) == 0) { - /* Swap domain and name */ - tmp = name; name = domain; domain = tmp; - sid_copy(&sid, &global_sid_Builtin); - type = SID_NAME_DOMAIN; - goto ok; - } - /* Explicit request for a name in BUILTIN */ if (lookup_builtin_name(name, &rid)) { sid_copy(&sid, &global_sid_Builtin); @@ -114,8 +106,7 @@ bool lookup_name(TALLOC_CTX *mem_ctx, goto ok; } - if (((flags & LOOKUP_NAME_NO_NSS) == 0) - && strequal(domain, unix_users_domain_name())) { + if (!(flags & LOOKUP_NAME_EXPLICIT) && strequal(domain, unix_users_domain_name())) { if (lookup_unix_user_name(name, &sid)) { type = SID_NAME_USER; goto ok; @@ -124,8 +115,7 @@ bool lookup_name(TALLOC_CTX *mem_ctx, return false; } - if (((flags & LOOKUP_NAME_NO_NSS) == 0) - && strequal(domain, unix_groups_domain_name())) { + if (!(flags & LOOKUP_NAME_EXPLICIT) && strequal(domain, unix_groups_domain_name())) { if (lookup_unix_group_name(name, &sid)) { type = SID_NAME_DOM_GRP; goto ok; @@ -290,15 +280,13 @@ bool lookup_name(TALLOC_CTX *mem_ctx, /* 11. Ok, windows would end here. Samba has two more options: Unmapped users and unmapped groups */ - if (((flags & LOOKUP_NAME_NO_NSS) == 0) - && lookup_unix_user_name(name, &sid)) { + if (!(flags & LOOKUP_NAME_EXPLICIT) && lookup_unix_user_name(name, &sid)) { domain = talloc_strdup(tmp_ctx, unix_users_domain_name()); type = SID_NAME_USER; goto ok; } - if (((flags & LOOKUP_NAME_NO_NSS) == 0) - && lookup_unix_group_name(name, &sid)) { + if (!(flags & LOOKUP_NAME_EXPLICIT) && lookup_unix_group_name(name, &sid)) { domain = talloc_strdup(tmp_ctx, unix_groups_domain_name()); type = SID_NAME_DOM_GRP; goto ok; @@ -1129,16 +1117,19 @@ void store_gid_sid_cache(const DOM_SID *psid, gid_t gid) static void legacy_uid_to_sid(DOM_SID *psid, uid_t uid) { + uint32 rid; bool ret; ZERO_STRUCTP(psid); become_root(); - ret = pdb_uid_to_sid(uid, psid); + ret = pdb_uid_to_rid(uid, &rid); unbecome_root(); if (ret) { /* This is a mapped user */ + sid_copy(psid, get_global_sam_sid()); + sid_append_rid(psid, rid); goto done; } diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 0255edcd17..6ba67ef9a7 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -23,7 +23,6 @@ */ #include "includes.h" -#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB @@ -207,7 +206,7 @@ static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *p initialized and will fill in these fields later (such as from a netr_SamInfo3 structure) */ - if ( create && (pdb_capabilities() & PDB_CAP_STORE_RIDS)) { + if ( create && !pdb_rid_algorithm() ) { uint32 user_rid; DOM_SID user_sid; @@ -655,6 +654,9 @@ NTSTATUS local_password_change(const char *user_name, *pp_msg_str = NULL; tosctx = talloc_tos(); + if (!tosctx) { + return NT_STATUS_NO_MEMORY; + } sam_pass = samu_new(tosctx); if (!sam_pass) { @@ -1439,7 +1441,7 @@ static bool init_samu_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 bu } /* Change from V1 is addition of password history field. */ - pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); if (pwHistLen) { uint8 *pw_hist = SMB_MALLOC_ARRAY(uint8, pwHistLen * PW_HISTORY_ENTRY_LEN); if (!pw_hist) { @@ -1519,7 +1521,7 @@ static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 bu char *domain = NULL; char *nt_username = NULL; char *dir_drive = NULL; - char *comment = NULL; + char *unknown_str = NULL; char *munged_dial = NULL; char *fullname = NULL; char *homedir = NULL; @@ -1528,7 +1530,7 @@ static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 bu char *acct_desc = NULL; char *workstations = NULL; uint32 username_len, domain_len, nt_username_len, - dir_drive_len, comment_len, munged_dial_len, + dir_drive_len, unknown_str_len, munged_dial_len, fullname_len, homedir_len, logon_script_len, profile_path_len, acct_desc_len, workstations_len; @@ -1570,7 +1572,7 @@ static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 bu &profile_path_len, &profile_path, /* B */ &acct_desc_len, &acct_desc, /* B */ &workstations_len, &workstations, /* B */ - &comment_len, &comment, /* B */ + &unknown_str_len, &unknown_str, /* B */ &munged_dial_len, &munged_dial, /* B */ &user_rid, /* d */ &group_rid, /* d */ @@ -1656,7 +1658,6 @@ static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 bu } pdb_set_acct_desc(sampass, acct_desc, PDB_SET); - pdb_set_comment(sampass, comment, PDB_SET); pdb_set_workstations(sampass, workstations, PDB_SET); pdb_set_munged_dial(sampass, munged_dial, PDB_SET); @@ -1674,7 +1675,7 @@ static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 bu } } - pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); if (pwHistLen) { uint8 *pw_hist = (uint8 *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN); if (!pw_hist) { @@ -1725,7 +1726,7 @@ done: SAFE_FREE(acct_desc); SAFE_FREE(workstations); SAFE_FREE(munged_dial); - SAFE_FREE(comment); + SAFE_FREE(unknown_str); SAFE_FREE(lm_pw_ptr); SAFE_FREE(nt_pw_ptr); SAFE_FREE(nt_pw_hist_ptr); @@ -1758,7 +1759,7 @@ static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool const char *domain; const char *nt_username; const char *dir_drive; - const char *comment; + const char *unknown_str; const char *munged_dial; const char *fullname; const char *homedir; @@ -1767,7 +1768,7 @@ static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool const char *acct_desc; const char *workstations; uint32 username_len, domain_len, nt_username_len, - dir_drive_len, comment_len, munged_dial_len, + dir_drive_len, unknown_str_len, munged_dial_len, fullname_len, homedir_len, logon_script_len, profile_path_len, acct_desc_len, workstations_len; @@ -1879,7 +1880,7 @@ static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool nt_pw_len = 0; } - pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len); if (pwHistLen && nt_pw_hist && nt_pw_hist_len) { nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN; @@ -1901,12 +1902,8 @@ static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool workstations_len = 0; } - comment = pdb_get_comment(sampass); - if (comment) { - comment_len = strlen(comment) +1; - } else { - comment_len = 0; - } + unknown_str = NULL; + unknown_str_len = 0; munged_dial = pdb_get_munged_dial(sampass); if (munged_dial) { @@ -1936,7 +1933,7 @@ static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool profile_path_len, profile_path, /* B */ acct_desc_len, acct_desc, /* B */ workstations_len, workstations, /* B */ - comment_len, comment, /* B */ + unknown_str_len, unknown_str, /* B */ munged_dial_len, munged_dial, /* B */ user_rid, /* d */ group_rid, /* d */ @@ -1980,7 +1977,7 @@ static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool profile_path_len, profile_path, /* B */ acct_desc_len, acct_desc, /* B */ workstations_len, workstations, /* B */ - comment_len, comment, /* B */ + unknown_str_len, unknown_str, /* B */ munged_dial_len, munged_dial, /* B */ user_rid, /* d */ group_rid, /* d */ @@ -2089,7 +2086,7 @@ bool pdb_copy_sam_account(struct samu *dst, struct samu *src ) } /********************************************************************* - Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME + Update the bad password count checking the AP_RESET_COUNT_TIME *********************************************************************/ bool pdb_update_bad_password_count(struct samu *sampass, bool *updated) @@ -2106,7 +2103,7 @@ bool pdb_update_bad_password_count(struct samu *sampass, bool *updated) } become_root(); - res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime); + res = pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime); unbecome_root(); if (!res) { @@ -2135,7 +2132,7 @@ bool pdb_update_bad_password_count(struct samu *sampass, bool *updated) } /********************************************************************* - Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION + Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION *********************************************************************/ bool pdb_update_autolock_flag(struct samu *sampass, bool *updated) @@ -2151,7 +2148,7 @@ bool pdb_update_autolock_flag(struct samu *sampass, bool *updated) } become_root(); - res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration); + res = pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration); unbecome_root(); if (!res) { @@ -2203,7 +2200,7 @@ bool pdb_increment_bad_password_count(struct samu *sampass) /* Retrieve the account lockout policy */ become_root(); - ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout); + ret = pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout); unbecome_root(); if ( !ret ) { DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n")); @@ -2261,8 +2258,7 @@ bool is_dc_trusted_domain_situation(const char *domain_name) *******************************************************************/ bool get_trust_pw_clear(const char *domain, char **ret_pwd, - const char **account_name, - enum netr_SchannelType *channel) + const char **account_name, uint32 *channel) { char *pwd; time_t last_set_time; @@ -2334,8 +2330,7 @@ bool get_trust_pw_clear(const char *domain, char **ret_pwd, *******************************************************************/ bool get_trust_pw_hash(const char *domain, uint8 ret_pwd[16], - const char **account_name, - enum netr_SchannelType *channel) + const char **account_name, uint32 *channel) { char *pwd = NULL; time_t last_set_time; @@ -2388,3 +2383,63 @@ struct samr_LogonHours get_logon_hours_from_pdb(TALLOC_CTX *mem_ctx, return hours; } + +/**************************************************************** +****************************************************************/ + +NTSTATUS smb_create_user(TALLOC_CTX *mem_ctx, + uint32_t acct_flags, + const char *account, + struct passwd **passwd_p) +{ + struct passwd *passwd; + char *add_script = NULL; + + passwd = Get_Pwnam_alloc(mem_ctx, account); + if (passwd) { + *passwd_p = passwd; + return NT_STATUS_OK; + } + + /* Create appropriate user */ + if (acct_flags & ACB_NORMAL) { + add_script = talloc_strdup(mem_ctx, lp_adduser_script()); + } else if ( (acct_flags & ACB_WSTRUST) || + (acct_flags & ACB_SVRTRUST) || + (acct_flags & ACB_DOMTRUST) ) { + add_script = talloc_strdup(mem_ctx, lp_addmachine_script()); + } else { + DEBUG(1, ("Unknown user type: %s\n", + pdb_encode_acct_ctrl(acct_flags, NEW_PW_FORMAT_SPACE_PADDED_LEN))); + return NT_STATUS_UNSUCCESSFUL; + } + + if (!add_script) { + return NT_STATUS_NO_MEMORY; + } + + if (*add_script) { + int add_ret; + add_script = talloc_all_string_sub(mem_ctx, add_script, + "%u", account); + if (!add_script) { + return NT_STATUS_NO_MEMORY; + } + add_ret = smbrun(add_script, NULL); + DEBUG(add_ret ? 0 : 1,("fetch_account: Running the command `%s' " + "gave %d\n", add_script, add_ret)); + if (add_ret == 0) { + smb_nscd_flush_user_cache(); + } + } + + /* try and find the possible unix account again */ + passwd = Get_Pwnam_alloc(mem_ctx, account); + if (!passwd) { + return NT_STATUS_NO_SUCH_USER; + } + + *passwd_p = passwd; + + return NT_STATUS_OK; +} diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c deleted file mode 100644 index 3ddf4f2dc0..0000000000 --- a/source3/passdb/pdb_ads.c +++ /dev/null @@ -1,2363 +0,0 @@ -/* - Unix SMB/CIFS implementation. - pdb_ldap with ads schema - Copyright (C) Volker Lendecke 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" - -struct pdb_ads_state { - struct sockaddr_un socket_address; - struct tldap_context *ld; - struct dom_sid domainsid; - struct GUID domainguid; - char *domaindn; - char *configdn; - char *netbiosname; -}; - -struct pdb_ads_samu_private { - char *dn; - struct tldap_message *ldapmsg; -}; - -static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m, - struct samu *sam_acct, - const DOM_SID *sid); -static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid, - DOM_SID *sid); -static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob, - struct dom_sid *psid); -static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state, - const struct dom_sid *sid, - TALLOC_CTX *mem_ctx, char **pdn); -static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state); -static int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base, - int scope, const char *attrs[], int num_attrs, - int attrsonly, - TALLOC_CTX *mem_ctx, struct tldap_message ***res, - const char *fmt, ...); -static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state, - const char *filter, - TALLOC_CTX *mem_ctx, - struct pdb_ads_samu_private **presult); - -static bool pdb_ads_pull_time(struct tldap_message *msg, const char *attr, - time_t *ptime) -{ - uint64_t tmp; - - if (!tldap_pull_uint64(msg, attr, &tmp)) { - return false; - } - *ptime = uint64s_nt_time_to_unix_abs(&tmp); - return true; -} - -static gid_t pdb_ads_sid2gid(const struct dom_sid *sid) -{ - uint32_t rid; - sid_peek_rid(sid, &rid); - return rid; -} - -static char *pdb_ads_domaindn2dns(TALLOC_CTX *mem_ctx, char *dn) -{ - char *result, *p; - - result = talloc_string_sub2(mem_ctx, dn, "DC=", "", false, false, - true); - if (result == NULL) { - return NULL; - } - - while ((p = strchr_m(result, ',')) != NULL) { - *p = '.'; - } - - return result; -} - -static struct pdb_domain_info *pdb_ads_get_domain_info( - struct pdb_methods *m, TALLOC_CTX *mem_ctx) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct pdb_domain_info *info; - struct tldap_message *rootdse; - char *tmp; - - info = talloc(mem_ctx, struct pdb_domain_info); - if (info == NULL) { - return NULL; - } - info->name = talloc_strdup(info, state->netbiosname); - if (info->name == NULL) { - goto fail; - } - info->dns_domain = pdb_ads_domaindn2dns(info, state->domaindn); - if (info->dns_domain == NULL) { - goto fail; - } - - rootdse = tldap_rootdse(state->ld); - tmp = tldap_talloc_single_attribute(rootdse, "rootDomainNamingContext", - talloc_tos()); - if (tmp == NULL) { - goto fail; - } - info->dns_forest = pdb_ads_domaindn2dns(info, tmp); - TALLOC_FREE(tmp); - if (info->dns_forest == NULL) { - goto fail; - } - info->sid = state->domainsid; - info->guid = state->domainguid; - return info; - -fail: - TALLOC_FREE(info); - return NULL; -} - -static struct pdb_ads_samu_private *pdb_ads_get_samu_private( - struct pdb_methods *m, struct samu *sam) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct pdb_ads_samu_private *result; - char *sidstr, *filter; - NTSTATUS status; - - result = (struct pdb_ads_samu_private *) - pdb_get_backend_private_data(sam, m); - - if (result != NULL) { - return talloc_get_type_abort( - result, struct pdb_ads_samu_private); - } - - sidstr = sid_binstring(talloc_tos(), pdb_get_user_sid(sam)); - if (sidstr == NULL) { - return NULL; - } - - filter = talloc_asprintf( - talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr); - TALLOC_FREE(sidstr); - if (filter == NULL) { - return NULL; - } - - status = pdb_ads_getsamupriv(state, filter, sam, &result); - TALLOC_FREE(filter); - if (!NT_STATUS_IS_OK(status)) { - return NULL; - } - - return result; -} - -static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m, - struct samu *sam, - struct pdb_ads_samu_private *priv) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - TALLOC_CTX *frame = talloc_stackframe(); - NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION; - struct tldap_message *entry = priv->ldapmsg; - char *str; - time_t tmp_time; - struct dom_sid sid; - uint64_t n; - DATA_BLOB blob; - - str = tldap_talloc_single_attribute(entry, "samAccountName", sam); - if (str == NULL) { - DEBUG(10, ("no samAccountName\n")); - goto fail; - } - pdb_set_username(sam, str, PDB_SET); - - if (pdb_ads_pull_time(entry, "lastLogon", &tmp_time)) { - pdb_set_logon_time(sam, tmp_time, PDB_SET); - } - if (pdb_ads_pull_time(entry, "lastLogoff", &tmp_time)) { - pdb_set_logoff_time(sam, tmp_time, PDB_SET); - } - if (pdb_ads_pull_time(entry, "pwdLastSet", &tmp_time)) { - pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET); - } - if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) { - pdb_set_kickoff_time(sam, tmp_time, PDB_SET); - } - - str = tldap_talloc_single_attribute(entry, "displayName", - talloc_tos()); - if (str != NULL) { - pdb_set_fullname(sam, str, PDB_SET); - } - - str = tldap_talloc_single_attribute(entry, "homeDirectory", - talloc_tos()); - if (str != NULL) { - pdb_set_homedir(sam, str, PDB_SET); - } - - str = tldap_talloc_single_attribute(entry, "homeDrive", talloc_tos()); - if (str != NULL) { - pdb_set_dir_drive(sam, str, PDB_SET); - } - - str = tldap_talloc_single_attribute(entry, "scriptPath", talloc_tos()); - if (str != NULL) { - pdb_set_logon_script(sam, str, PDB_SET); - } - - str = tldap_talloc_single_attribute(entry, "profilePath", - talloc_tos()); - if (str != NULL) { - pdb_set_profile_path(sam, str, PDB_SET); - } - - str = tldap_talloc_single_attribute(entry, "profilePath", - talloc_tos()); - if (str != NULL) { - pdb_set_profile_path(sam, str, PDB_SET); - } - - if (!tldap_pull_binsid(entry, "objectSid", &sid)) { - DEBUG(10, ("Could not pull SID\n")); - goto fail; - } - pdb_set_user_sid(sam, &sid, PDB_SET); - - if (!tldap_pull_uint64(entry, "userAccountControl", &n)) { - DEBUG(10, ("Could not pull userAccountControl\n")); - goto fail; - } - pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET); - - if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) { - if (blob.length != NT_HASH_LEN) { - DEBUG(0, ("Got NT hash of length %d, expected %d\n", - (int)blob.length, NT_HASH_LEN)); - goto fail; - } - pdb_set_nt_passwd(sam, blob.data, PDB_SET); - } - - if (tldap_get_single_valueblob(entry, "dBCSPwd", &blob)) { - if (blob.length != LM_HASH_LEN) { - DEBUG(0, ("Got LM hash of length %d, expected %d\n", - (int)blob.length, LM_HASH_LEN)); - goto fail; - } - pdb_set_lanman_passwd(sam, blob.data, PDB_SET); - } - - if (tldap_pull_uint64(entry, "primaryGroupID", &n)) { - sid_compose(&sid, &state->domainsid, n); - pdb_set_group_sid(sam, &sid, PDB_SET); - - } - status = NT_STATUS_OK; -fail: - TALLOC_FREE(frame); - return status; -} - -static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state, - struct tldap_message *existing, - TALLOC_CTX *mem_ctx, - int *pnum_mods, struct tldap_mod **pmods, - struct samu *sam) -{ - bool ret = true; - DATA_BLOB blob; - - /* TODO: All fields :-) */ - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pnum_mods, pmods, "displayName", - "%s", pdb_get_fullname(sam)); - - blob = data_blob_const(pdb_get_nt_passwd(sam), NT_HASH_LEN); - if (blob.data != NULL) { - ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE, - "unicodePwd", 1, &blob); - } - - blob = data_blob_const(pdb_get_lanman_passwd(sam), NT_HASH_LEN); - if (blob.data != NULL) { - ret &= tldap_add_mod_blobs(mem_ctx, pmods, TLDAP_MOD_REPLACE, - "dBCSPwd", 1, &blob); - } - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pnum_mods, pmods, "userAccountControl", - "%d", ds_acb2uf(pdb_get_acct_ctrl(sam))); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pnum_mods, pmods, "homeDirectory", - "%s", pdb_get_homedir(sam)); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pnum_mods, pmods, "homeDrive", - "%s", pdb_get_dir_drive(sam)); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pnum_mods, pmods, "scriptPath", - "%s", pdb_get_logon_script(sam)); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pnum_mods, pmods, "profilePath", - "%s", pdb_get_profile_path(sam)); - - return ret; -} - -static NTSTATUS pdb_ads_getsamupriv(struct pdb_ads_state *state, - const char *filter, - TALLOC_CTX *mem_ctx, - struct pdb_ads_samu_private **presult) -{ - const char * attrs[] = { - "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires", - "sAMAccountName", "displayName", "homeDirectory", - "homeDrive", "scriptPath", "profilePath", "description", - "userWorkstations", "comment", "userParameters", "objectSid", - "primaryGroupID", "userAccountControl", "logonHours", - "badPwdCount", "logonCount", "countryCode", "codePage", - "unicodePwd", "dBCSPwd" }; - struct tldap_message **users; - int rc, count; - struct pdb_ads_samu_private *result; - - result = talloc(mem_ctx, struct pdb_ads_samu_private); - if (result == NULL) { - return NT_STATUS_NO_MEMORY; - } - - rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB, - attrs, ARRAY_SIZE(attrs), 0, result, - &users, "%s", filter); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_search failed %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - TALLOC_FREE(result); - return NT_STATUS_LDAP(rc); - } - - count = talloc_array_length(users); - if (count != 1) { - DEBUG(10, ("Expected 1 user, got %d\n", count)); - TALLOC_FREE(result); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - result->ldapmsg = users[0]; - if (!tldap_entry_dn(result->ldapmsg, &result->dn)) { - DEBUG(10, ("Could not extract dn\n")); - TALLOC_FREE(result); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - *presult = result; - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_getsampwfilter(struct pdb_methods *m, - struct pdb_ads_state *state, - struct samu *sam_acct, - const char *filter) -{ - struct pdb_ads_samu_private *priv; - NTSTATUS status; - - status = pdb_ads_getsamupriv(state, filter, sam_acct, &priv); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("pdb_ads_getsamupriv failed: %s\n", - nt_errstr(status))); - return status; - } - - status = pdb_ads_init_sam_from_priv(m, sam_acct, priv); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("pdb_ads_init_sam_from_priv failed: %s\n", - nt_errstr(status))); - TALLOC_FREE(priv); - return status; - } - - pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET); - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_getsampwnam(struct pdb_methods *m, - struct samu *sam_acct, - const char *username) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - char *filter; - - filter = talloc_asprintf( - talloc_tos(), "(&(samaccountname=%s)(objectclass=user))", - username); - NT_STATUS_HAVE_NO_MEMORY(filter); - - return pdb_ads_getsampwfilter(m, state, sam_acct, filter); -} - -static NTSTATUS pdb_ads_getsampwsid(struct pdb_methods *m, - struct samu *sam_acct, - const DOM_SID *sid) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - char *sidstr, *filter; - - sidstr = sid_binstring(talloc_tos(), sid); - NT_STATUS_HAVE_NO_MEMORY(sidstr); - - filter = talloc_asprintf( - talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr); - TALLOC_FREE(sidstr); - NT_STATUS_HAVE_NO_MEMORY(filter); - - return pdb_ads_getsampwfilter(m, state, sam_acct, filter); -} - -static NTSTATUS pdb_ads_create_user(struct pdb_methods *m, - TALLOC_CTX *tmp_ctx, - const char *name, uint32 acct_flags, - uint32 *rid) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct tldap_context *ld; - const char *attrs[1] = { "objectSid" }; - struct tldap_mod *mods = NULL; - int num_mods = 0; - struct tldap_message **user; - struct dom_sid sid; - char *dn; - int rc; - bool ok; - - dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name, - state->domaindn); - if (dn == NULL) { - return NT_STATUS_NO_MEMORY; - } - - ld = pdb_ads_ld(state); - if (ld == NULL) { - return NT_STATUS_LDAP(TLDAP_SERVER_DOWN); - } - - /* TODO: Create machines etc */ - - ok = true; - ok &= tldap_make_mod_fmt( - NULL, talloc_tos(), &num_mods, &mods, "objectClass", "user"); - ok &= tldap_make_mod_fmt( - NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s", - name); - if (!ok) { - return NT_STATUS_NO_MEMORY; - } - - - rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_add failed %s\n", - tldap_errstr(talloc_tos(), ld, rc))); - TALLOC_FREE(dn); - return NT_STATUS_LDAP(rc); - } - - rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB, - attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), - &user, - "(&(objectclass=user)(samaccountname=%s))", - name); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("Could not find just created user %s: %s\n", - name, tldap_errstr(talloc_tos(), state->ld, rc))); - TALLOC_FREE(dn); - return NT_STATUS_LDAP(rc); - } - - if (talloc_array_length(user) != 1) { - DEBUG(10, ("Got %d users, expected one\n", - (int)talloc_array_length(user))); - TALLOC_FREE(dn); - return NT_STATUS_LDAP(rc); - } - - if (!tldap_pull_binsid(user[0], "objectSid", &sid)) { - DEBUG(10, ("Could not fetch objectSid from user %s\n", - name)); - TALLOC_FREE(dn); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - sid_peek_rid(&sid, rid); - TALLOC_FREE(dn); - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_delete_user(struct pdb_methods *m, - TALLOC_CTX *tmp_ctx, - struct samu *sam) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - NTSTATUS status; - struct tldap_context *ld; - char *dn; - int rc; - - ld = pdb_ads_ld(state); - if (ld == NULL) { - return NT_STATUS_LDAP(TLDAP_SERVER_DOWN); - } - - status = pdb_ads_sid2dn(state, pdb_get_user_sid(sam), talloc_tos(), - &dn); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - rc = tldap_delete(ld, dn, NULL, 0, NULL, 0); - TALLOC_FREE(dn); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_delete for %s failed: %s\n", dn, - tldap_errstr(talloc_tos(), ld, rc))); - return NT_STATUS_LDAP(rc); - } - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_add_sam_account(struct pdb_methods *m, - struct samu *sampass) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_ads_update_sam_account(struct pdb_methods *m, - struct samu *sam) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private(m, sam); - struct tldap_context *ld; - struct tldap_mod *mods = NULL; - int rc, num_mods = 0; - - ld = pdb_ads_ld(state); - if (ld == NULL) { - return NT_STATUS_LDAP(TLDAP_SERVER_DOWN); - } - - if (!pdb_ads_init_ads_from_sam(state, priv->ldapmsg, talloc_tos(), - &num_mods, &mods, sam)) { - return NT_STATUS_NO_MEMORY; - } - - if (num_mods == 0) { - /* Nothing to do, just return success */ - return NT_STATUS_OK; - } - - rc = tldap_modify(ld, priv->dn, num_mods, mods, NULL, 0, - NULL, 0); - TALLOC_FREE(mods); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_modify for %s failed: %s\n", priv->dn, - tldap_errstr(talloc_tos(), ld, rc))); - return NT_STATUS_LDAP(rc); - } - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_delete_sam_account(struct pdb_methods *m, - struct samu *username) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_ads_rename_sam_account(struct pdb_methods *m, - struct samu *oldname, - const char *newname) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_ads_update_login_attempts(struct pdb_methods *m, - struct samu *sam_acct, - bool success) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_ads_getgrfilter(struct pdb_methods *m, GROUP_MAP *map, - const char *filter) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - const char *attrs[4] = { "objectSid", "description", "samAccountName", - "groupType" }; - char *str; - struct tldap_message **group; - uint32_t grouptype; - int rc; - - rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB, - attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), - &group, "%s", filter); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_search failed %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - return NT_STATUS_LDAP(rc); - } - if (talloc_array_length(group) != 1) { - DEBUG(10, ("Expected 1 user, got %d\n", - (int)talloc_array_length(group))); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - if (!tldap_pull_binsid(group[0], "objectSid", &map->sid)) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - map->gid = pdb_ads_sid2gid(&map->sid); - - if (!tldap_pull_uint32(group[0], "groupType", &grouptype)) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - switch (grouptype) { - case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP: - case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP: - map->sid_name_use = SID_NAME_ALIAS; - break; - case GTYPE_SECURITY_GLOBAL_GROUP: - map->sid_name_use = SID_NAME_DOM_GRP; - break; - default: - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - str = tldap_talloc_single_attribute(group[0], "samAccountName", - talloc_tos()); - if (str == NULL) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - fstrcpy(map->nt_name, str); - TALLOC_FREE(str); - - str = tldap_talloc_single_attribute(group[0], "description", - talloc_tos()); - if (str != NULL) { - fstrcpy(map->comment, str); - TALLOC_FREE(str); - } else { - map->comment[0] = '\0'; - } - - TALLOC_FREE(group); - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map, - DOM_SID sid) -{ - char *filter; - NTSTATUS status; - - filter = talloc_asprintf(talloc_tos(), - "(&(objectsid=%s)(objectclass=group))", - sid_string_talloc(talloc_tos(), &sid)); - if (filter == NULL) { - return NT_STATUS_NO_MEMORY; - } - - status = pdb_ads_getgrfilter(m, map, filter); - TALLOC_FREE(filter); - return status; -} - -static NTSTATUS pdb_ads_getgrgid(struct pdb_methods *m, GROUP_MAP *map, - gid_t gid) -{ - struct dom_sid sid; - pdb_ads_gid_to_sid(m, gid, &sid); - return pdb_ads_getgrsid(m, map, sid); -} - -static NTSTATUS pdb_ads_getgrnam(struct pdb_methods *m, GROUP_MAP *map, - const char *name) -{ - char *filter; - NTSTATUS status; - - filter = talloc_asprintf(talloc_tos(), - "(&(samaccountname=%s)(objectclass=group))", - name); - if (filter == NULL) { - return NT_STATUS_NO_MEMORY; - } - - status = pdb_ads_getgrfilter(m, map, filter); - TALLOC_FREE(filter); - return status; -} - -static NTSTATUS pdb_ads_create_dom_group(struct pdb_methods *m, - TALLOC_CTX *mem_ctx, const char *name, - uint32 *rid) -{ - TALLOC_CTX *frame = talloc_stackframe(); - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct tldap_context *ld; - const char *attrs[1] = { "objectSid" }; - int num_mods = 0; - struct tldap_mod *mods = NULL; - struct tldap_message **alias; - struct dom_sid sid; - char *dn; - int rc; - bool ok = true; - - ld = pdb_ads_ld(state); - if (ld == NULL) { - return NT_STATUS_LDAP(TLDAP_SERVER_DOWN); - } - - dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name, - state->domaindn); - if (dn == NULL) { - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; - } - - ok &= tldap_make_mod_fmt( - NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s", - name); - ok &= tldap_make_mod_fmt( - NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group"); - ok &= tldap_make_mod_fmt( - NULL, talloc_tos(), &num_mods, &mods, "groupType", - "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP); - - if (!ok) { - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; - } - - rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_add failed %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - TALLOC_FREE(frame); - return NT_STATUS_LDAP(rc); - } - - rc = pdb_ads_search_fmt( - state, state->domaindn, TLDAP_SCOPE_SUB, - attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias, - "(&(objectclass=group)(samaccountname=%s))", name); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("Could not find just created alias %s: %s\n", - name, tldap_errstr(talloc_tos(), state->ld, rc))); - TALLOC_FREE(frame); - return NT_STATUS_LDAP(rc); - } - - if (talloc_array_length(alias) != 1) { - DEBUG(10, ("Got %d alias, expected one\n", - (int)talloc_array_length(alias))); - TALLOC_FREE(frame); - return NT_STATUS_LDAP(rc); - } - - if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) { - DEBUG(10, ("Could not fetch objectSid from alias %s\n", - name)); - TALLOC_FREE(frame); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - sid_peek_rid(&sid, rid); - TALLOC_FREE(frame); - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_delete_dom_group(struct pdb_methods *m, - TALLOC_CTX *mem_ctx, uint32 rid) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct tldap_context *ld; - struct dom_sid sid; - char *sidstr; - struct tldap_message **msg; - char *dn; - int rc; - - sid_compose(&sid, &state->domainsid, rid); - - sidstr = sid_binstring(talloc_tos(), &sid); - NT_STATUS_HAVE_NO_MEMORY(sidstr); - - rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB, - NULL, 0, 0, talloc_tos(), &msg, - ("(&(objectSid=%s)(objectClass=group))"), - sidstr); - TALLOC_FREE(sidstr); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_search failed %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - return NT_STATUS_LDAP(rc); - } - - switch talloc_array_length(msg) { - case 0: - return NT_STATUS_NO_SUCH_GROUP; - case 1: - break; - default: - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - if (!tldap_entry_dn(msg[0], &dn)) { - TALLOC_FREE(msg); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - ld = pdb_ads_ld(state); - if (ld == NULL) { - TALLOC_FREE(msg); - return NT_STATUS_LDAP(TLDAP_SERVER_DOWN); - } - - rc = tldap_delete(ld, dn, NULL, 0, NULL, 0); - TALLOC_FREE(msg); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_delete failed: %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - return NT_STATUS_LDAP(rc); - } - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_add_group_mapping_entry(struct pdb_methods *m, - GROUP_MAP *map) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_ads_update_group_mapping_entry(struct pdb_methods *m, - GROUP_MAP *map) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m, - DOM_SID sid) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m, - const DOM_SID *sid, - enum lsa_SidType sid_name_use, - GROUP_MAP **pp_rmap, - size_t *p_num_entries, - bool unix_only) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_ads_enum_group_members(struct pdb_methods *m, - TALLOC_CTX *mem_ctx, - const DOM_SID *group, - uint32 **pmembers, - size_t *pnum_members) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - const char *attrs[1] = { "member" }; - char *sidstr; - struct tldap_message **msg; - int i, rc, num_members; - DATA_BLOB *blobs; - uint32_t *members; - - sidstr = sid_binstring(talloc_tos(), group); - NT_STATUS_HAVE_NO_MEMORY(sidstr); - - rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB, - attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), - &msg, "(objectsid=%s)", sidstr); - TALLOC_FREE(sidstr); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_search failed %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - return NT_STATUS_LDAP(rc); - } - switch talloc_array_length(msg) { - case 0: - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - break; - case 1: - break; - default: - return NT_STATUS_INTERNAL_DB_CORRUPTION; - break; - } - - if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - members = talloc_array(mem_ctx, uint32_t, num_members); - if (members == NULL) { - return NT_STATUS_NO_MEMORY; - } - - for (i=0; i<num_members; i++) { - struct dom_sid sid; - if (!pdb_ads_dnblob2sid(state, &blobs[i], &sid) - || !sid_peek_rid(&sid, &members[i])) { - TALLOC_FREE(members); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - } - - *pmembers = members; - *pnum_members = num_members; - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_enum_group_memberships(struct pdb_methods *m, - TALLOC_CTX *mem_ctx, - struct samu *user, - DOM_SID **pp_sids, - gid_t **pp_gids, - size_t *p_num_groups) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct pdb_ads_samu_private *priv = pdb_ads_get_samu_private( - m, user); - const char *attrs[1] = { "objectSid" }; - struct tldap_message **groups; - int i, rc, count; - size_t num_groups; - struct dom_sid *group_sids; - gid_t *gids; - - rc = pdb_ads_search_fmt( - state, state->domaindn, TLDAP_SCOPE_SUB, - attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &groups, - "(&(member=%s)(grouptype=%d)(objectclass=group))", - priv->dn, GTYPE_SECURITY_GLOBAL_GROUP); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_search failed %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - return NT_STATUS_LDAP(rc); - } - - count = talloc_array_length(groups); - - group_sids = talloc_array(mem_ctx, struct dom_sid, count); - if (group_sids == NULL) { - return NT_STATUS_NO_MEMORY; - } - gids = talloc_array(mem_ctx, gid_t, count); - if (gids == NULL) { - TALLOC_FREE(group_sids); - return NT_STATUS_NO_MEMORY; - } - num_groups = 0; - - for (i=0; i<count; i++) { - if (!tldap_pull_binsid(groups[i], "objectSid", - &group_sids[num_groups])) { - continue; - } - gids[num_groups] = pdb_ads_sid2gid(&group_sids[num_groups]); - - num_groups += 1; - if (num_groups == count) { - break; - } - } - - *pp_sids = group_sids; - *pp_gids = gids; - *p_num_groups = num_groups; - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_set_unix_primary_group(struct pdb_methods *m, - TALLOC_CTX *mem_ctx, - struct samu *user) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_ads_mod_groupmem(struct pdb_methods *m, - TALLOC_CTX *mem_ctx, - uint32 grouprid, uint32 memberrid, - int mod_op) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - TALLOC_CTX *frame = talloc_stackframe(); - struct tldap_context *ld; - struct dom_sid groupsid, membersid; - char *groupdn, *memberdn; - struct tldap_mod *mods; - int rc; - NTSTATUS status; - - ld = pdb_ads_ld(state); - if (ld == NULL) { - return NT_STATUS_LDAP(TLDAP_SERVER_DOWN); - } - - sid_compose(&groupsid, &state->domainsid, grouprid); - sid_compose(&membersid, &state->domainsid, memberrid); - - status = pdb_ads_sid2dn(state, &groupsid, talloc_tos(), &groupdn); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(frame); - return NT_STATUS_NO_SUCH_GROUP; - } - status = pdb_ads_sid2dn(state, &membersid, talloc_tos(), &memberdn); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(frame); - return NT_STATUS_NO_SUCH_USER; - } - - mods = NULL; - - if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op, - "member", memberdn)) { - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; - } - - rc = tldap_modify(ld, groupdn, 1, mods, NULL, 0, NULL, 0); - TALLOC_FREE(frame); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_modify failed: %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) { - return NT_STATUS_MEMBER_IN_GROUP; - } - if (rc == TLDAP_NO_SUCH_ATTRIBUTE) { - return NT_STATUS_MEMBER_NOT_IN_GROUP; - } - return NT_STATUS_LDAP(rc); - } - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_add_groupmem(struct pdb_methods *m, - TALLOC_CTX *mem_ctx, - uint32 group_rid, uint32 member_rid) -{ - return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid, - TLDAP_MOD_ADD); -} - -static NTSTATUS pdb_ads_del_groupmem(struct pdb_methods *m, - TALLOC_CTX *mem_ctx, - uint32 group_rid, uint32 member_rid) -{ - return pdb_ads_mod_groupmem(m, mem_ctx, group_rid, member_rid, - TLDAP_MOD_DELETE); -} - -static NTSTATUS pdb_ads_create_alias(struct pdb_methods *m, - const char *name, uint32 *rid) -{ - TALLOC_CTX *frame = talloc_stackframe(); - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct tldap_context *ld; - const char *attrs[1] = { "objectSid" }; - int num_mods = 0; - struct tldap_mod *mods = NULL; - struct tldap_message **alias; - struct dom_sid sid; - char *dn; - int rc; - bool ok = true; - - ld = pdb_ads_ld(state); - if (ld == NULL) { - return NT_STATUS_LDAP(TLDAP_SERVER_DOWN); - } - - dn = talloc_asprintf(talloc_tos(), "cn=%s,cn=users,%s", name, - state->domaindn); - if (dn == NULL) { - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; - } - - ok &= tldap_make_mod_fmt( - NULL, talloc_tos(), &num_mods, &mods, "samAccountName", "%s", - name); - ok &= tldap_make_mod_fmt( - NULL, talloc_tos(), &num_mods, &mods, "objectClass", "group"); - ok &= tldap_make_mod_fmt( - NULL, talloc_tos(), &num_mods, &mods, "groupType", - "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); - - if (!ok) { - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; - } - - rc = tldap_add(ld, dn, num_mods, mods, NULL, 0, NULL, 0); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_add failed %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - TALLOC_FREE(frame); - return NT_STATUS_LDAP(rc); - } - - rc = pdb_ads_search_fmt( - state, state->domaindn, TLDAP_SCOPE_SUB, - attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &alias, - "(&(objectclass=group)(samaccountname=%s))", name); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("Could not find just created alias %s: %s\n", - name, tldap_errstr(talloc_tos(), state->ld, rc))); - TALLOC_FREE(frame); - return NT_STATUS_LDAP(rc); - } - - if (talloc_array_length(alias) != 1) { - DEBUG(10, ("Got %d alias, expected one\n", - (int)talloc_array_length(alias))); - TALLOC_FREE(frame); - return NT_STATUS_LDAP(rc); - } - - if (!tldap_pull_binsid(alias[0], "objectSid", &sid)) { - DEBUG(10, ("Could not fetch objectSid from alias %s\n", - name)); - TALLOC_FREE(frame); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - sid_peek_rid(&sid, rid); - TALLOC_FREE(frame); - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_delete_alias(struct pdb_methods *m, - const DOM_SID *sid) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct tldap_context *ld; - struct tldap_message **alias; - char *sidstr, *dn; - int rc; - - ld = pdb_ads_ld(state); - if (ld == NULL) { - return NT_STATUS_LDAP(TLDAP_SERVER_DOWN); - } - - sidstr = sid_binstring(talloc_tos(), sid); - if (sidstr == NULL) { - return NT_STATUS_NO_MEMORY; - } - - rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB, - NULL, 0, 0, talloc_tos(), &alias, - "(&(objectSid=%s)(objectclass=group)" - "(|(grouptype=%d)(grouptype=%d)))", - sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP, - GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); - TALLOC_FREE(sidstr); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_search failed: %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - TALLOC_FREE(dn); - return NT_STATUS_LDAP(rc); - } - if (talloc_array_length(alias) != 1) { - DEBUG(10, ("Expected 1 alias, got %d\n", - (int)talloc_array_length(alias))); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - if (!tldap_entry_dn(alias[0], &dn)) { - DEBUG(10, ("Could not get DN for alias %s\n", - sid_string_dbg(sid))); - return NT_STATUS_INTERNAL_ERROR; - } - - rc = tldap_delete(ld, dn, NULL, 0, NULL, 0); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_delete failed: %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - TALLOC_FREE(dn); - return NT_STATUS_LDAP(rc); - } - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m, - const DOM_SID *sid, - struct acct_info *info) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct tldap_context *ld; - const char *attrs[3] = { "objectSid", "description", - "samAccountName" }; - struct tldap_message **msg; - char *sidstr, *dn; - int rc; - struct tldap_mod *mods; - int num_mods; - bool ok; - - ld = pdb_ads_ld(state); - if (ld == NULL) { - return NT_STATUS_LDAP(TLDAP_SERVER_DOWN); - } - - sidstr = sid_binstring(talloc_tos(), sid); - NT_STATUS_HAVE_NO_MEMORY(sidstr); - - rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB, - attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), - &msg, "(&(objectSid=%s)(objectclass=group)" - "(|(grouptype=%d)(grouptype=%d)))", - sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP, - GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); - TALLOC_FREE(sidstr); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_search failed %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - return NT_STATUS_LDAP(rc); - } - switch talloc_array_length(msg) { - case 0: - return NT_STATUS_NO_SUCH_ALIAS; - case 1: - break; - default: - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - if (!tldap_entry_dn(msg[0], &dn)) { - TALLOC_FREE(msg); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - mods = NULL; - num_mods = 0; - ok = true; - - ok &= tldap_make_mod_fmt( - msg[0], msg, &num_mods, &mods, "description", - "%s", info->acct_desc); - ok &= tldap_make_mod_fmt( - msg[0], msg, &num_mods, &mods, "samAccountName", - "%s", info->acct_name); - if (!ok) { - TALLOC_FREE(msg); - return NT_STATUS_NO_MEMORY; - } - if (num_mods == 0) { - /* no change */ - TALLOC_FREE(msg); - return NT_STATUS_OK; - } - - rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0); - TALLOC_FREE(msg); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_modify failed: %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - return NT_STATUS_LDAP(rc); - } - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_sid2dn(struct pdb_ads_state *state, - const struct dom_sid *sid, - TALLOC_CTX *mem_ctx, char **pdn) -{ - struct tldap_message **msg; - char *sidstr, *dn; - int rc; - - sidstr = sid_binstring(talloc_tos(), sid); - NT_STATUS_HAVE_NO_MEMORY(sidstr); - - rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB, - NULL, 0, 0, talloc_tos(), &msg, - "(objectsid=%s)", sidstr); - TALLOC_FREE(sidstr); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_search failed %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - return NT_STATUS_LDAP(rc); - } - - switch talloc_array_length(msg) { - case 0: - return NT_STATUS_NOT_FOUND; - case 1: - break; - default: - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - if (!tldap_entry_dn(msg[0], &dn)) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - dn = talloc_strdup(mem_ctx, dn); - if (dn == NULL) { - return NT_STATUS_NO_MEMORY; - } - TALLOC_FREE(msg); - - *pdn = dn; - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_mod_aliasmem(struct pdb_methods *m, - const DOM_SID *alias, - const DOM_SID *member, - int mod_op) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct tldap_context *ld; - TALLOC_CTX *frame = talloc_stackframe(); - struct tldap_mod *mods; - int rc; - char *aliasdn, *memberdn; - NTSTATUS status; - - ld = pdb_ads_ld(state); - if (ld == NULL) { - return NT_STATUS_LDAP(TLDAP_SERVER_DOWN); - } - - status = pdb_ads_sid2dn(state, alias, talloc_tos(), &aliasdn); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n", - sid_string_dbg(alias), nt_errstr(status))); - TALLOC_FREE(frame); - return NT_STATUS_NO_SUCH_ALIAS; - } - status = pdb_ads_sid2dn(state, member, talloc_tos(), &memberdn); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("pdb_ads_sid2dn (%s) failed: %s\n", - sid_string_dbg(member), nt_errstr(status))); - TALLOC_FREE(frame); - return status; - } - - mods = NULL; - - if (!tldap_add_mod_str(talloc_tos(), &mods, mod_op, - "member", memberdn)) { - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; - } - - rc = tldap_modify(ld, aliasdn, 1, mods, NULL, 0, NULL, 0); - TALLOC_FREE(frame); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_modify failed: %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - if (rc == TLDAP_TYPE_OR_VALUE_EXISTS) { - return NT_STATUS_MEMBER_IN_ALIAS; - } - if (rc == TLDAP_NO_SUCH_ATTRIBUTE) { - return NT_STATUS_MEMBER_NOT_IN_ALIAS; - } - return NT_STATUS_LDAP(rc); - } - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_add_aliasmem(struct pdb_methods *m, - const DOM_SID *alias, - const DOM_SID *member) -{ - return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_ADD); -} - -static NTSTATUS pdb_ads_del_aliasmem(struct pdb_methods *m, - const DOM_SID *alias, - const DOM_SID *member) -{ - return pdb_ads_mod_aliasmem(m, alias, member, TLDAP_MOD_DELETE); -} - -static bool pdb_ads_dnblob2sid(struct pdb_ads_state *state, DATA_BLOB *dnblob, - struct dom_sid *psid) -{ - const char *attrs[1] = { "objectSid" }; - struct tldap_message **msg; - char *dn; - size_t len; - int rc; - bool ret; - - if (!convert_string_talloc(talloc_tos(), CH_UTF8, CH_UNIX, - dnblob->data, dnblob->length, &dn, &len, - false)) { - return false; - } - rc = pdb_ads_search_fmt(state, dn, TLDAP_SCOPE_BASE, - attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), - &msg, "(objectclass=*)"); - TALLOC_FREE(dn); - if (talloc_array_length(msg) != 1) { - DEBUG(10, ("Got %d objects, expected one\n", - (int)talloc_array_length(msg))); - TALLOC_FREE(msg); - return false; - } - - ret = tldap_pull_binsid(msg[0], "objectSid", psid); - TALLOC_FREE(msg); - return ret; -} - -static NTSTATUS pdb_ads_enum_aliasmem(struct pdb_methods *m, - const DOM_SID *alias, - TALLOC_CTX *mem_ctx, - DOM_SID **pmembers, - size_t *pnum_members) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - const char *attrs[1] = { "member" }; - char *sidstr; - struct tldap_message **msg; - int i, rc, num_members; - DATA_BLOB *blobs; - struct dom_sid *members; - - sidstr = sid_binstring(talloc_tos(), alias); - NT_STATUS_HAVE_NO_MEMORY(sidstr); - - rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB, - attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), - &msg, "(objectsid=%s)", sidstr); - TALLOC_FREE(sidstr); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_search failed %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - return NT_STATUS_LDAP(rc); - } - switch talloc_array_length(msg) { - case 0: - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - break; - case 1: - break; - default: - return NT_STATUS_INTERNAL_DB_CORRUPTION; - break; - } - - if (!tldap_entry_values(msg[0], "member", &num_members, &blobs)) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - members = talloc_array(mem_ctx, struct dom_sid, num_members); - if (members == NULL) { - return NT_STATUS_NO_MEMORY; - } - - for (i=0; i<num_members; i++) { - if (!pdb_ads_dnblob2sid(state, &blobs[i], &members[i])) { - TALLOC_FREE(members); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - } - - *pmembers = members; - *pnum_members = num_members; - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_enum_alias_memberships(struct pdb_methods *m, - TALLOC_CTX *mem_ctx, - const DOM_SID *domain_sid, - const DOM_SID *members, - size_t num_members, - uint32_t **palias_rids, - size_t *pnum_alias_rids) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - const char *attrs[1] = { "objectSid" }; - struct tldap_message **msg; - uint32_t *alias_rids = NULL; - size_t num_alias_rids = 0; - int i, rc, count; - bool got_members = false; - char *filter; - NTSTATUS status; - - /* - * TODO: Get the filter right so that we only get the aliases from - * either the SAM or BUILTIN - */ - - filter = talloc_asprintf(talloc_tos(), - "(&(|(grouptype=%d)(grouptype=%d))" - "(objectclass=group)(|", - GTYPE_SECURITY_BUILTIN_LOCAL_GROUP, - GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); - if (filter == NULL) { - return NT_STATUS_NO_MEMORY; - } - - for (i=0; i<num_members; i++) { - char *dn; - - status = pdb_ads_sid2dn(state, &members[i], talloc_tos(), &dn); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("pdb_ads_sid2dn failed for %s: %s\n", - sid_string_dbg(&members[i]), - nt_errstr(status))); - continue; - } - filter = talloc_asprintf_append_buffer( - filter, "(member=%s)", dn); - TALLOC_FREE(dn); - if (filter == NULL) { - return NT_STATUS_NO_MEMORY; - } - got_members = true; - } - - if (!got_members) { - goto done; - } - - rc = pdb_ads_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB, - attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), - &msg, "%s))", filter); - TALLOC_FREE(filter); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("tldap_search failed %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - return NT_STATUS_LDAP(rc); - } - - count = talloc_array_length(msg); - if (count == 0) { - goto done; - } - - alias_rids = talloc_array(mem_ctx, uint32_t, count); - if (alias_rids == NULL) { - TALLOC_FREE(msg); - return NT_STATUS_NO_MEMORY; - } - - for (i=0; i<count; i++) { - struct dom_sid sid; - - if (!tldap_pull_binsid(msg[i], "objectSid", &sid)) { - DEBUG(10, ("Could not pull SID for member %d\n", i)); - continue; - } - if (sid_peek_check_rid(domain_sid, &sid, - &alias_rids[num_alias_rids])) { - num_alias_rids += 1; - } - } -done: - TALLOC_FREE(msg); - *palias_rids = alias_rids; - *pnum_alias_rids = 0; - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m, - const DOM_SID *domain_sid, - int num_rids, - uint32 *rids, - const char **names, - enum lsa_SidType *lsa_attrs) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - const char *attrs[2] = { "sAMAccountType", "sAMAccountName" }; - int i, num_mapped; - - if (num_rids == 0) { - return NT_STATUS_NONE_MAPPED; - } - - num_mapped = 0; - - for (i=0; i<num_rids; i++) { - struct dom_sid sid; - struct tldap_message **msg; - char *sidstr; - uint32_t attr; - int rc; - - lsa_attrs[i] = SID_NAME_UNKNOWN; - - sid_compose(&sid, domain_sid, rids[i]); - - sidstr = sid_binstring(talloc_tos(), &sid); - NT_STATUS_HAVE_NO_MEMORY(sidstr); - - rc = pdb_ads_search_fmt(state, state->domaindn, - TLDAP_SCOPE_SUB, attrs, - ARRAY_SIZE(attrs), 0, talloc_tos(), - &msg, "(objectsid=%s)", sidstr); - TALLOC_FREE(sidstr); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_search failed %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - continue; - } - - switch talloc_array_length(msg) { - case 0: - DEBUG(10, ("rid %d not found\n", (int)rids[i])); - continue; - case 1: - break; - default: - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - names[i] = tldap_talloc_single_attribute( - msg[0], "samAccountName", talloc_tos()); - if (names[i] == NULL) { - DEBUG(10, ("no samAccountName\n")); - continue; - } - if (!tldap_pull_uint32(msg[0], "samAccountType", &attr)) { - DEBUG(10, ("no samAccountType")); - continue; - } - lsa_attrs[i] = ds_atype_map(attr); - num_mapped += 1; - } - - if (num_mapped == 0) { - return NT_STATUS_NONE_MAPPED; - } - if (num_mapped < num_rids) { - return STATUS_SOME_UNMAPPED; - } - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m, - const DOM_SID *domain_sid, - int num_names, - const char **pp_names, - uint32 *rids, - enum lsa_SidType *attrs) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m, - enum pdb_policy_type type, - uint32_t *value) -{ - return account_policy_get(type, value) - ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; -} - -static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m, - enum pdb_policy_type type, - uint32_t value) -{ - return account_policy_set(type, value) - ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; -} - -static NTSTATUS pdb_ads_get_seq_num(struct pdb_methods *m, - time_t *seq_num) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -struct pdb_ads_search_state { - uint32_t acct_flags; - struct samr_displayentry *entries; - uint32_t num_entries; - ssize_t array_size; - uint32_t current; -}; - -static bool pdb_ads_next_entry(struct pdb_search *search, - struct samr_displayentry *entry) -{ - struct pdb_ads_search_state *state = talloc_get_type_abort( - search->private_data, struct pdb_ads_search_state); - - if (state->current == state->num_entries) { - return false; - } - - entry->idx = state->entries[state->current].idx; - entry->rid = state->entries[state->current].rid; - entry->acct_flags = state->entries[state->current].acct_flags; - - entry->account_name = talloc_strdup( - search, state->entries[state->current].account_name); - entry->fullname = talloc_strdup( - search, state->entries[state->current].fullname); - entry->description = talloc_strdup( - search, state->entries[state->current].description); - - if ((entry->account_name == NULL) || (entry->fullname == NULL) - || (entry->description == NULL)) { - DEBUG(0, ("talloc_strdup failed\n")); - return false; - } - - state->current += 1; - return true; -} - -static void pdb_ads_search_end(struct pdb_search *search) -{ - struct pdb_ads_search_state *state = talloc_get_type_abort( - search->private_data, struct pdb_ads_search_state); - TALLOC_FREE(state); -} - -static bool pdb_ads_search_filter(struct pdb_methods *m, - struct pdb_search *search, - const char *filter, - struct pdb_ads_search_state **pstate) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct pdb_ads_search_state *sstate; - const char * attrs[] = { "objectSid", "sAMAccountName", "displayName", - "userAccountControl", "description" }; - struct tldap_message **users; - int i, rc, num_users; - - sstate = talloc_zero(search, struct pdb_ads_search_state); - if (sstate == NULL) { - return false; - } - - rc = pdb_ads_search_fmt( - state, state->domaindn, TLDAP_SCOPE_SUB, - attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &users, - "%s", filter); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_search_ext_s failed: %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - return false; - } - - num_users = talloc_array_length(users); - - sstate->entries = talloc_array(sstate, struct samr_displayentry, - num_users); - if (sstate->entries == NULL) { - DEBUG(10, ("talloc failed\n")); - return false; - } - - sstate->num_entries = 0; - - for (i=0; i<num_users; i++) { - struct samr_displayentry *e; - struct dom_sid sid; - - e = &sstate->entries[sstate->num_entries]; - - e->idx = sstate->num_entries; - if (!tldap_pull_binsid(users[i], "objectSid", &sid)) { - DEBUG(10, ("Could not pull sid\n")); - continue; - } - sid_peek_rid(&sid, &e->rid); - e->acct_flags = ACB_NORMAL; - e->account_name = tldap_talloc_single_attribute( - users[i], "samAccountName", sstate->entries); - if (e->account_name == NULL) { - return false; - } - e->fullname = tldap_talloc_single_attribute( - users[i], "displayName", sstate->entries); - if (e->fullname == NULL) { - e->fullname = ""; - } - e->description = tldap_talloc_single_attribute( - users[i], "description", sstate->entries); - if (e->description == NULL) { - e->description = ""; - } - - sstate->num_entries += 1; - if (sstate->num_entries >= num_users) { - break; - } - } - - search->private_data = sstate; - search->next_entry = pdb_ads_next_entry; - search->search_end = pdb_ads_search_end; - *pstate = sstate; - return true; -} - -static bool pdb_ads_search_users(struct pdb_methods *m, - struct pdb_search *search, - uint32 acct_flags) -{ - struct pdb_ads_search_state *sstate; - bool ret; - - ret = pdb_ads_search_filter(m, search, "(objectclass=user)", &sstate); - if (!ret) { - return false; - } - sstate->acct_flags = acct_flags; - return true; -} - -static bool pdb_ads_search_groups(struct pdb_methods *m, - struct pdb_search *search) -{ - struct pdb_ads_search_state *sstate; - char *filter; - bool ret; - - filter = talloc_asprintf(talloc_tos(), - "(&(grouptype=%d)(objectclass=group))", - GTYPE_SECURITY_GLOBAL_GROUP); - if (filter == NULL) { - return false; - } - ret = pdb_ads_search_filter(m, search, filter, &sstate); - TALLOC_FREE(filter); - if (!ret) { - return false; - } - sstate->acct_flags = 0; - return true; -} - -static bool pdb_ads_search_aliases(struct pdb_methods *m, - struct pdb_search *search, - const DOM_SID *sid) -{ - struct pdb_ads_search_state *sstate; - char *filter; - bool ret; - - filter = talloc_asprintf( - talloc_tos(), "(&(grouptype=%d)(objectclass=group))", - sid_check_is_builtin(sid) - ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP - : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); - - if (filter == NULL) { - return false; - } - ret = pdb_ads_search_filter(m, search, filter, &sstate); - TALLOC_FREE(filter); - if (!ret) { - return false; - } - sstate->acct_flags = 0; - return true; -} - -static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid, - DOM_SID *sid) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - sid_compose(sid, &state->domainsid, uid); - return true; -} - -static bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid, - DOM_SID *sid) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - sid_compose(sid, &state->domainsid, gid); - return true; -} - -static bool pdb_ads_sid_to_id(struct pdb_methods *m, const DOM_SID *sid, - union unid_t *id, enum lsa_SidType *type) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct tldap_message **msg; - char *sidstr; - uint32_t rid; - int rc; - - /* - * This is a big, big hack: Just hard-code the rid as uid/gid. - */ - - sid_peek_rid(sid, &rid); - - sidstr = sid_binstring(talloc_tos(), sid); - if (sidstr == NULL) { - return false; - } - - rc = pdb_ads_search_fmt( - state, state->domaindn, TLDAP_SCOPE_SUB, - NULL, 0, 0, talloc_tos(), &msg, - "(&(objectsid=%s)(objectclass=user))", sidstr); - if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) { - id->uid = rid; - *type = SID_NAME_USER; - TALLOC_FREE(sidstr); - return true; - } - - rc = pdb_ads_search_fmt( - state, state->domaindn, TLDAP_SCOPE_SUB, - NULL, 0, 0, talloc_tos(), &msg, - "(&(objectsid=%s)(objectclass=group))", sidstr); - if ((rc == TLDAP_SUCCESS) && (talloc_array_length(msg) > 0)) { - id->gid = rid; - *type = SID_NAME_DOM_GRP; - TALLOC_FREE(sidstr); - return true; - } - - TALLOC_FREE(sidstr); - return false; -} - -static uint32_t pdb_ads_capabilities(struct pdb_methods *m) -{ - return PDB_CAP_STORE_RIDS | PDB_CAP_ADS; -} - -static bool pdb_ads_new_rid(struct pdb_methods *m, uint32 *rid) -{ - return false; -} - -static bool pdb_ads_get_trusteddom_pw(struct pdb_methods *m, - const char *domain, char** pwd, - DOM_SID *sid, - time_t *pass_last_set_time) -{ - return false; -} - -static bool pdb_ads_set_trusteddom_pw(struct pdb_methods *m, - const char* domain, const char* pwd, - const DOM_SID *sid) -{ - return false; -} - -static bool pdb_ads_del_trusteddom_pw(struct pdb_methods *m, - const char *domain) -{ - return false; -} - -static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m, - TALLOC_CTX *mem_ctx, - uint32 *num_domains, - struct trustdom_info ***domains) -{ - *num_domains = 0; - *domains = NULL; - return NT_STATUS_OK; -} - -static void pdb_ads_init_methods(struct pdb_methods *m) -{ - m->name = "ads"; - m->get_domain_info = pdb_ads_get_domain_info; - m->getsampwnam = pdb_ads_getsampwnam; - m->getsampwsid = pdb_ads_getsampwsid; - m->create_user = pdb_ads_create_user; - m->delete_user = pdb_ads_delete_user; - m->add_sam_account = pdb_ads_add_sam_account; - m->update_sam_account = pdb_ads_update_sam_account; - m->delete_sam_account = pdb_ads_delete_sam_account; - m->rename_sam_account = pdb_ads_rename_sam_account; - m->update_login_attempts = pdb_ads_update_login_attempts; - m->getgrsid = pdb_ads_getgrsid; - m->getgrgid = pdb_ads_getgrgid; - m->getgrnam = pdb_ads_getgrnam; - m->create_dom_group = pdb_ads_create_dom_group; - m->delete_dom_group = pdb_ads_delete_dom_group; - m->add_group_mapping_entry = pdb_ads_add_group_mapping_entry; - m->update_group_mapping_entry = pdb_ads_update_group_mapping_entry; - m->delete_group_mapping_entry = pdb_ads_delete_group_mapping_entry; - m->enum_group_mapping = pdb_ads_enum_group_mapping; - m->enum_group_members = pdb_ads_enum_group_members; - m->enum_group_memberships = pdb_ads_enum_group_memberships; - m->set_unix_primary_group = pdb_ads_set_unix_primary_group; - m->add_groupmem = pdb_ads_add_groupmem; - m->del_groupmem = pdb_ads_del_groupmem; - m->create_alias = pdb_ads_create_alias; - m->delete_alias = pdb_ads_delete_alias; - m->get_aliasinfo = pdb_default_get_aliasinfo; - m->set_aliasinfo = pdb_ads_set_aliasinfo; - m->add_aliasmem = pdb_ads_add_aliasmem; - m->del_aliasmem = pdb_ads_del_aliasmem; - m->enum_aliasmem = pdb_ads_enum_aliasmem; - m->enum_alias_memberships = pdb_ads_enum_alias_memberships; - m->lookup_rids = pdb_ads_lookup_rids; - m->lookup_names = pdb_ads_lookup_names; - m->get_account_policy = pdb_ads_get_account_policy; - m->set_account_policy = pdb_ads_set_account_policy; - m->get_seq_num = pdb_ads_get_seq_num; - m->search_users = pdb_ads_search_users; - m->search_groups = pdb_ads_search_groups; - m->search_aliases = pdb_ads_search_aliases; - m->uid_to_sid = pdb_ads_uid_to_sid; - m->gid_to_sid = pdb_ads_gid_to_sid; - m->sid_to_id = pdb_ads_sid_to_id; - m->capabilities = pdb_ads_capabilities; - m->new_rid = pdb_ads_new_rid; - m->get_trusteddom_pw = pdb_ads_get_trusteddom_pw; - m->set_trusteddom_pw = pdb_ads_set_trusteddom_pw; - m->del_trusteddom_pw = pdb_ads_del_trusteddom_pw; - m->enum_trusteddoms = pdb_ads_enum_trusteddoms; -} - -static void free_private_data(void **vp) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - *vp, struct pdb_ads_state); - - TALLOC_FREE(state->ld); - return; -} - -/* - this is used to catch debug messages from events -*/ -static void s3_tldap_debug(void *context, enum tldap_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); - -static void s3_tldap_debug(void *context, enum tldap_debug_level level, - const char *fmt, va_list ap) -{ - int samba_level = -1; - char *s = NULL; - switch (level) { - case TLDAP_DEBUG_FATAL: - samba_level = 0; - break; - case TLDAP_DEBUG_ERROR: - samba_level = 1; - break; - case TLDAP_DEBUG_WARNING: - samba_level = 2; - break; - case TLDAP_DEBUG_TRACE: - samba_level = 11; - break; - - }; - if (vasprintf(&s, fmt, ap) == -1) { - return; - } - DEBUG(samba_level, ("tldap: %s", s)); - free(s); -} - -static struct tldap_context *pdb_ads_ld(struct pdb_ads_state *state) -{ - NTSTATUS status; - int fd; - - if (tldap_connection_ok(state->ld)) { - return state->ld; - } - TALLOC_FREE(state->ld); - - status = open_socket_out( - (struct sockaddr_storage *)(void *)&state->socket_address, - 0, 0, &fd); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("Could not connect to %s: %s\n", - state->socket_address.sun_path, nt_errstr(status))); - return NULL; - } - - set_blocking(fd, false); - - state->ld = tldap_context_create(state, fd); - if (state->ld == NULL) { - close(fd); - return NULL; - } - tldap_set_debug(state->ld, s3_tldap_debug, NULL); - - return state->ld; -} - -int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base, - int scope, const char *attrs[], int num_attrs, - int attrsonly, - TALLOC_CTX *mem_ctx, struct tldap_message ***res, - const char *fmt, ...) -{ - struct tldap_context *ld; - va_list ap; - int ret; - - ld = pdb_ads_ld(state); - if (ld == NULL) { - return TLDAP_SERVER_DOWN; - } - - va_start(ap, fmt); - ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly, - mem_ctx, res, fmt, ap); - va_end(ap); - - if (ret != TLDAP_SERVER_DOWN) { - return ret; - } - - /* retry once */ - ld = pdb_ads_ld(state); - if (ld == NULL) { - return TLDAP_SERVER_DOWN; - } - - va_start(ap, fmt); - ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly, - mem_ctx, res, fmt, ap); - va_end(ap); - return ret; -} - -static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state, - const char *location) -{ - const char *domain_attrs[2] = { "objectSid", "objectGUID" }; - const char *ncname_attrs[1] = { "netbiosname" }; - struct tldap_context *ld; - struct tldap_message *rootdse, **domain, **ncname; - TALLOC_CTX *frame = talloc_stackframe(); - NTSTATUS status; - int num_domains; - int rc; - - ZERO_STRUCT(state->socket_address); - state->socket_address.sun_family = AF_UNIX; - strncpy(state->socket_address.sun_path, location, - sizeof(state->socket_address.sun_path) - 1); - - ld = pdb_ads_ld(state); - if (ld == NULL) { - status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - goto done; - } - - rc = tldap_fetch_rootdse(ld); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("Could not retrieve rootdse: %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - status = NT_STATUS_LDAP(rc); - goto done; - } - rootdse = tldap_rootdse(state->ld); - - state->domaindn = tldap_talloc_single_attribute( - rootdse, "defaultNamingContext", state); - if (state->domaindn == NULL) { - DEBUG(10, ("Could not get defaultNamingContext\n")); - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto done; - } - DEBUG(10, ("defaultNamingContext = %s\n", state->domaindn)); - - state->configdn = tldap_talloc_single_attribute( - rootdse, "configurationNamingContext", state); - if (state->domaindn == NULL) { - DEBUG(10, ("Could not get configurationNamingContext\n")); - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto done; - } - DEBUG(10, ("configurationNamingContext = %s\n", state->configdn)); - - /* - * Figure out our domain's SID - */ - rc = pdb_ads_search_fmt( - state, state->domaindn, TLDAP_SCOPE_BASE, - domain_attrs, ARRAY_SIZE(domain_attrs), 0, - talloc_tos(), &domain, "(objectclass=*)"); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("Could not retrieve domain: %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - status = NT_STATUS_LDAP(rc); - goto done; - } - - num_domains = talloc_array_length(domain); - if (num_domains != 1) { - DEBUG(10, ("Got %d domains, expected one\n", num_domains)); - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto done; - } - if (!tldap_pull_binsid(domain[0], "objectSid", &state->domainsid)) { - DEBUG(10, ("Could not retrieve domain SID\n")); - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto done; - } - if (!tldap_pull_guid(domain[0], "objectGUID", &state->domainguid)) { - DEBUG(10, ("Could not retrieve domain GUID\n")); - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto done; - } - DEBUG(10, ("Domain SID: %s\n", sid_string_dbg(&state->domainsid))); - - /* - * Figure out our domain's short name - */ - rc = pdb_ads_search_fmt( - state, state->configdn, TLDAP_SCOPE_SUB, - ncname_attrs, ARRAY_SIZE(ncname_attrs), 0, - talloc_tos(), &ncname, "(ncname=%s)", state->domaindn); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("Could not retrieve ncname: %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - status = NT_STATUS_LDAP(rc); - goto done; - } - if (talloc_array_length(ncname) != 1) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto done; - } - - state->netbiosname = tldap_talloc_single_attribute( - ncname[0], "netbiosname", state); - if (state->netbiosname == NULL) { - DEBUG(10, ("Could not get netbiosname\n")); - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto done; - } - DEBUG(10, ("netbiosname: %s\n", state->netbiosname)); - - if (!strequal(lp_workgroup(), state->netbiosname)) { - DEBUG(1, ("ADS is different domain (%s) than ours (%s)\n", - state->netbiosname, lp_workgroup())); - status = NT_STATUS_NO_SUCH_DOMAIN; - goto done; - } - - secrets_store_domain_sid(state->netbiosname, &state->domainsid); - - status = NT_STATUS_OK; -done: - TALLOC_FREE(frame); - return status; -} - -static NTSTATUS pdb_init_ads(struct pdb_methods **pdb_method, - const char *location) -{ - struct pdb_methods *m; - struct pdb_ads_state *state; - char *tmp = NULL; - NTSTATUS status; - - m = talloc(talloc_autofree_context(), struct pdb_methods); - if (m == NULL) { - return NT_STATUS_NO_MEMORY; - } - state = talloc_zero(m, struct pdb_ads_state); - if (state == NULL) { - goto nomem; - } - m->private_data = state; - m->free_private_data = free_private_data; - pdb_ads_init_methods(m); - - if (location == NULL) { - tmp = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi", - lp_private_dir()); - location = tmp; - } - if (location == NULL) { - goto nomem; - } - - status = pdb_ads_connect(state, location); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("pdb_ads_connect failed: %s\n", nt_errstr(status))); - goto fail; - } - - *pdb_method = m; - return NT_STATUS_OK; -nomem: - status = NT_STATUS_NO_MEMORY; -fail: - TALLOC_FREE(m); - return status; -} - -NTSTATUS pdb_ads_init(void); -NTSTATUS pdb_ads_init(void) -{ - return smb_register_passdb(PASSDB_INTERFACE_VERSION, "ads", - pdb_init_ads); -} diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index 6126517900..1155050d79 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -22,7 +22,6 @@ */ #include "includes.h" -#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB @@ -88,7 +87,7 @@ time_t pdb_get_pass_can_change_time(const struct samu *sampass) pdb_get_init_flags(sampass, PDB_CANCHANGETIME) == PDB_CHANGED) return sampass->pass_can_change_time; - if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &allow)) + if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &allow)) allow = 0; /* in normal cases, just calculate it from policy */ @@ -112,7 +111,7 @@ time_t pdb_get_pass_must_change_time(const struct samu *sampass) if (sampass->acct_ctrl & ACB_PWNOEXP) return get_time_t_max(); - if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire) + if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire) || expire == (uint32)-1 || expire == 0) return get_time_t_max(); @@ -1015,9 +1014,6 @@ bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext) { uchar new_lanman_p16[LM_HASH_LEN]; uchar new_nt_p16[NT_HASH_LEN]; - uchar *pwhistory; - uint32 pwHistLen; - uint32 current_history_len; if (!plaintext) return False; @@ -1047,80 +1043,68 @@ bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext) if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED)) return False; - if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) == 0) { - /* - * No password history for non-user accounts - */ - return true; - } - - pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); - - if (pwHistLen == 0) { - /* Set the history length to zero. */ - pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED); - return true; - } - - /* - * We need to make sure we don't have a race condition here - - * the account policy history length can change between when - * the pw_history was first loaded into the struct samu struct - * and now.... JRA. - */ - pwhistory = (uchar *)pdb_get_pw_history(sampass, ¤t_history_len); - - if ((current_history_len != 0) && (pwhistory == NULL)) { - DEBUG(1, ("pdb_set_plaintext_passwd: pwhistory == NULL!\n")); - return false; - } - - if (current_history_len < pwHistLen) { - /* - * Ensure we have space for the needed history. This - * also takes care of an account which did not have - * any history at all so far, i.e. pwhistory==NULL - */ - uchar *new_history = talloc_zero_array( - sampass, uchar, - pwHistLen*PW_HISTORY_ENTRY_LEN); - - if (!new_history) { - return False; + /* Store the password history. */ + if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) { + uchar *pwhistory; + uint32 pwHistLen; + pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); + if (pwHistLen != 0){ + uint32 current_history_len; + /* We need to make sure we don't have a race condition here - the + account policy history length can change between when the pw_history + was first loaded into the struct samu struct and now.... JRA. */ + pwhistory = (uchar *)pdb_get_pw_history(sampass, ¤t_history_len); + + if (current_history_len != pwHistLen) { + /* After closing and reopening struct samu the history + values will sync up. We can't do this here. */ + + /* current_history_len > pwHistLen is not a problem - we + have more history than we need. */ + + if (current_history_len < pwHistLen) { + /* Ensure we have space for the needed history. */ + uchar *new_history = (uchar *)TALLOC(sampass, + pwHistLen*PW_HISTORY_ENTRY_LEN); + if (!new_history) { + return False; + } + + /* And copy it into the new buffer. */ + if (current_history_len) { + memcpy(new_history, pwhistory, + current_history_len*PW_HISTORY_ENTRY_LEN); + } + /* Clearing out any extra space. */ + memset(&new_history[current_history_len*PW_HISTORY_ENTRY_LEN], + '\0', (pwHistLen-current_history_len)*PW_HISTORY_ENTRY_LEN); + /* Finally replace it. */ + pwhistory = new_history; + } + } + if (pwhistory && pwHistLen){ + /* Make room for the new password in the history list. */ + if (pwHistLen > 1) { + memmove(&pwhistory[PW_HISTORY_ENTRY_LEN], + pwhistory, (pwHistLen -1)*PW_HISTORY_ENTRY_LEN ); + } + /* Create the new salt as the first part of the history entry. */ + generate_random_buffer(pwhistory, PW_HISTORY_SALT_LEN); + + /* Generate the md5 hash of the salt+new password as the second + part of the history entry. */ + + E_md5hash(pwhistory, new_nt_p16, &pwhistory[PW_HISTORY_SALT_LEN]); + pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED); + } else { + DEBUG (10,("pdb_get_set.c: pdb_set_plaintext_passwd: pwhistory was NULL!\n")); + } + } else { + /* Set the history length to zero. */ + pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED); } - - memcpy(new_history, pwhistory, - current_history_len*PW_HISTORY_ENTRY_LEN); - - pwhistory = new_history; - } - - /* - * Make room for the new password in the history list. - */ - if (pwHistLen > 1) { - memmove(&pwhistory[PW_HISTORY_ENTRY_LEN], pwhistory, - (pwHistLen-1)*PW_HISTORY_ENTRY_LEN ); } - /* - * Fill the salt area with 0-s: this indicates that - * a plain nt hash is stored in the has area. - * The old format was to store a 16 byte salt and - * then an md5hash of the nt_hash concatenated with - * the salt. - */ - memset(pwhistory, 0, PW_HISTORY_SALT_LEN); - - /* - * Store the plain nt hash in the second 16 bytes. - * The old format was to store the md5 hash of - * the salt+newpw. - */ - memcpy(&pwhistory[PW_HISTORY_SALT_LEN], new_nt_p16, SALTED_MD5_HASH_LEN); - - pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED); - return True; } diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index de46254dde..01815c6353 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -133,7 +133,7 @@ NTSTATUS make_pdb_method_name(struct pdb_methods **methods, const char *selected DEBUG(5,("Attempting to find a passdb backend to match %s (%s)\n", selected, module_name)); entry = pdb_find_backend_entry(module_name); - + /* Try to find a module that contains this module */ if (!entry) { DEBUG(2,("No builtin backend found, trying to load plugin\n")); @@ -143,7 +143,7 @@ NTSTATUS make_pdb_method_name(struct pdb_methods **methods, const char *selected return NT_STATUS_UNSUCCESSFUL; } } - + /* No such backend found */ if(!entry) { DEBUG(0,("No builtin nor plugin backend for %s found\n", module_name)); @@ -210,12 +210,6 @@ static struct pdb_methods *pdb_get_methods(void) return pdb_get_methods_reload(False); } -struct pdb_domain_info *pdb_get_domain_info(TALLOC_CTX *mem_ctx) -{ - struct pdb_methods *pdb = pdb_get_methods(); - return pdb->get_domain_info(pdb, mem_ctx); -} - bool pdb_getsampwnam(struct samu *sam_acct, const char *username) { struct pdb_methods *pdb = pdb_get_methods(); @@ -253,13 +247,13 @@ bool guest_user_info( struct samu *user ) struct passwd *pwd; NTSTATUS result; const char *guestname = lp_guestaccount(); - + if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), guestname ) ) ) { DEBUG(0,("guest_user_info: Unable to locate guest account [%s]!\n", guestname)); return False; } - + result = samu_set_unix(user, pwd ); TALLOC_FREE( pwd ); @@ -285,7 +279,7 @@ bool pdb_getsampwsid(struct samu *sam_acct, const DOM_SID *sid) DEBUG(6,("pdb_getsampwsid: Building guest account\n")); return guest_user_info( sam_acct ); } - + /* check the cache first */ cache_data = memcache_lookup_talloc( @@ -459,7 +453,7 @@ static NTSTATUS pdb_default_delete_user(struct pdb_methods *methods, strlower_m( username ); smb_delete_user( username ); - + return status; } @@ -580,16 +574,16 @@ static NTSTATUS pdb_default_create_dom_group(struct pdb_methods *methods, return NT_STATUS_ACCESS_DENIED; } - if (pdb_capabilities() & PDB_CAP_STORE_RIDS) { + if (pdb_rid_algorithm()) { + *rid = algorithmic_pdb_gid_to_group_rid( grp->gr_gid ); + } else { if (!pdb_new_rid(rid)) { return NT_STATUS_ACCESS_DENIED; } - } else { - *rid = algorithmic_pdb_gid_to_group_rid( grp->gr_gid ); } sid_compose(&group_sid, get_global_sam_sid(), *rid); - + return add_initial_entry(grp->gr_gid, sid_to_fstring(tmp, &group_sid), SID_NAME_DOM_GRP, name, NULL); } @@ -646,7 +640,7 @@ static NTSTATUS pdb_default_delete_dom_group(struct pdb_methods *methods, } /* Don't check the result of smb_delete_group */ - + smb_delete_group(grp_name); return NT_STATUS_OK; @@ -694,22 +688,22 @@ NTSTATUS pdb_enum_group_members(TALLOC_CTX *mem_ctx, result = pdb->enum_group_members(pdb, mem_ctx, sid, pp_member_rids, p_num_members); - + /* special check for rid 513 */ - + if ( !NT_STATUS_IS_OK( result ) ) { uint32 rid; - + sid_peek_rid( sid, &rid ); - + if ( rid == DOMAIN_GROUP_RID_USERS ) { *p_num_members = 0; *pp_member_rids = NULL; - + return NT_STATUS_OK; } } - + return result; } @@ -939,12 +933,11 @@ NTSTATUS pdb_del_aliasmem(const DOM_SID *alias, const DOM_SID *member) return pdb->del_aliasmem(pdb, alias, member); } -NTSTATUS pdb_enum_aliasmem(const DOM_SID *alias, TALLOC_CTX *mem_ctx, +NTSTATUS pdb_enum_aliasmem(const DOM_SID *alias, DOM_SID **pp_members, size_t *p_num_members) { struct pdb_methods *pdb = pdb_get_methods(); - return pdb->enum_aliasmem(pdb, alias, mem_ctx, pp_members, - p_num_members); + return pdb->enum_aliasmem(pdb, alias, pp_members, p_num_members); } NTSTATUS pdb_enum_alias_memberships(TALLOC_CTX *mem_ctx, @@ -994,25 +987,25 @@ NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid, } #endif -bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value) +bool pdb_get_account_policy(int policy_index, uint32 *value) { struct pdb_methods *pdb = pdb_get_methods(); NTSTATUS status; - + become_root(); - status = pdb->get_account_policy(pdb, type, value); + status = pdb->get_account_policy(pdb, policy_index, value); unbecome_root(); - + return NT_STATUS_IS_OK(status); } -bool pdb_set_account_policy(enum pdb_policy_type type, uint32_t value) +bool pdb_set_account_policy(int policy_index, uint32 value) { struct pdb_methods *pdb = pdb_get_methods(); NTSTATUS status; become_root(); - status = pdb->set_account_policy(pdb, type, value); + status = pdb->set_account_policy(pdb, policy_index, value); unbecome_root(); return NT_STATUS_IS_OK(status); @@ -1024,6 +1017,12 @@ bool pdb_get_seq_num(time_t *seq_num) return NT_STATUS_IS_OK(pdb->get_seq_num(pdb, seq_num)); } +bool pdb_uid_to_rid(uid_t uid, uint32 *rid) +{ + struct pdb_methods *pdb = pdb_get_methods(); + return pdb->uid_to_rid(pdb, uid, rid); +} + bool pdb_uid_to_sid(uid_t uid, DOM_SID *sid) { struct pdb_methods *pdb = pdb_get_methods(); @@ -1043,10 +1042,10 @@ bool pdb_sid_to_id(const DOM_SID *sid, union unid_t *id, return pdb->sid_to_id(pdb, sid, id, type); } -uint32_t pdb_capabilities(void) +bool pdb_rid_algorithm(void) { struct pdb_methods *pdb = pdb_get_methods(); - return pdb->capabilities(pdb); + return pdb->rid_algorithm(pdb); } /******************************************************************** @@ -1065,7 +1064,7 @@ bool pdb_new_rid(uint32 *rid) int i; TALLOC_CTX *ctx; - if ((pdb_capabilities() & PDB_CAP_STORE_RIDS) == 0) { + if (pdb_rid_algorithm()) { DEBUG(0, ("Trying to allocate a RID when algorithmic RIDs " "are active\n")); return False; @@ -1168,14 +1167,14 @@ static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, return NT_STATUS_OK; } -static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value) +static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value) { - return account_policy_get(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; + return account_policy_get(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } -static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value) +static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value) { - return account_policy_set(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; + return account_policy_set(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } static NTSTATUS pdb_default_get_seq_num(struct pdb_methods *methods, time_t *seq_num) @@ -1190,17 +1189,17 @@ static bool pdb_default_uid_to_sid(struct pdb_methods *methods, uid_t uid, struct samu *sampw = NULL; struct passwd *unix_pw; bool ret; - + unix_pw = sys_getpwuid( uid ); if ( !unix_pw ) { - DEBUG(4,("pdb_default_uid_to_sid: host has no idea of uid " + DEBUG(4,("pdb_default_uid_to_rid: host has no idea of uid " "%lu\n", (unsigned long)uid)); return False; } - + if ( !(sampw = samu_new( NULL )) ) { - DEBUG(0,("pdb_default_uid_to_sid: samu_new() failed!\n")); + DEBUG(0,("pdb_default_uid_to_rid: samu_new() failed!\n")); return False; } @@ -1210,7 +1209,7 @@ static bool pdb_default_uid_to_sid(struct pdb_methods *methods, uid_t uid, unbecome_root(); if (!ret) { - DEBUG(5, ("pdb_default_uid_to_sid: Did not find user " + DEBUG(5, ("pdb_default_uid_to_rid: Did not find user " "%s (%u)\n", unix_pw->pw_name, (unsigned int)uid)); TALLOC_FREE(sampw); return False; @@ -1223,6 +1222,27 @@ static bool pdb_default_uid_to_sid(struct pdb_methods *methods, uid_t uid, return True; } +static bool pdb_default_uid_to_rid(struct pdb_methods *methods, uid_t uid, + uint32 *rid) +{ + DOM_SID sid; + bool ret; + + ret = pdb_default_uid_to_sid(methods, uid, &sid); + if (!ret) { + return ret; + } + + ret = sid_peek_check_rid(get_global_sam_sid(), &sid, rid); + + if (!ret) { + DEBUG(1, ("Could not peek rid out of sid %s\n", + sid_string_dbg(&sid))); + } + + return ret; +} + static bool pdb_default_gid_to_sid(struct pdb_methods *methods, gid_t gid, DOM_SID *sid) { @@ -1266,7 +1286,7 @@ static bool pdb_default_sid_to_id(struct pdb_methods *methods, ret = True; goto done; } - + /* check for "Unix Group" */ if ( sid_peek_check_rid(&global_sid_Unix_Groups, sid, &rid) ) { @@ -1275,7 +1295,7 @@ static bool pdb_default_sid_to_id(struct pdb_methods *methods, ret = True; goto done; } - + /* BUILTIN */ if (sid_check_is_in_builtin(sid) || @@ -1310,6 +1330,26 @@ static bool pdb_default_sid_to_id(struct pdb_methods *methods, return ret; } +static bool add_uid_to_array_unique(TALLOC_CTX *mem_ctx, + uid_t uid, uid_t **pp_uids, size_t *p_num) +{ + size_t i; + + for (i=0; i<*p_num; i++) { + if ((*pp_uids)[i] == uid) + return True; + } + + *pp_uids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_uids, uid_t, *p_num+1); + + if (*pp_uids == NULL) + return False; + + (*pp_uids)[*p_num] = uid; + *p_num += 1; + return True; +} + static bool get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size_t *p_num) { struct group *grp; @@ -1361,7 +1401,7 @@ static bool get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size if (!winbind_env) { (void)winbind_on(); } - + return ret; } @@ -1418,17 +1458,17 @@ static NTSTATUS pdb_default_enum_group_memberships(struct pdb_methods *methods, gid_t gid; struct passwd *pw; const char *username = pdb_get_username(user); - + /* Ignore the primary group SID. Honor the real Unix primary group. The primary group SID is only of real use to Windows clients */ - + if ( !(pw = getpwnam_alloc(mem_ctx, username)) ) { return NT_STATUS_NO_SUCH_USER; } - + gid = pw->pw_gid; - + TALLOC_FREE( pw ); if (!getgroups_unix_user(mem_ctx, username, gid, pp_gids, p_num_groups)) { @@ -1468,13 +1508,13 @@ static bool lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid, DOM_SID sid; *psid_name_use = SID_NAME_UNKNOWN; - + DEBUG(5,("lookup_global_sam_rid: looking up RID %u.\n", (unsigned int)rid)); sid_copy(&sid, get_global_sam_sid()); sid_append_rid(&sid, rid); - + /* see if the passdb can help us with the name of the user */ if ( !(sam_account = samu_new( NULL )) ) { @@ -1510,14 +1550,14 @@ static bool lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid, return True; } TALLOC_FREE(sam_account); - + ret = pdb_getgrsid(&map, sid); unbecome_root(); /* END BECOME_ROOT BLOCK */ - + /* do not resolve SIDs to a name unless there is a valid gid associated with it */ - + if ( ret && (map.gid != (gid_t)-1) ) { *name = talloc_strdup(mem_ctx, map.nt_name); *psid_name_use = map.sid_name_use; @@ -1528,7 +1568,7 @@ static bool lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid, return True; } - + /* Windows will always map RID 513 to something. On a non-domain controller, this gets mapped to SERVER\None. */ @@ -1536,11 +1576,11 @@ static bool lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid, DEBUG(5, ("Can't find a unix id for an unmapped group\n")); return False; } - + if ( rid == DOMAIN_GROUP_RID_USERS ) { *name = talloc_strdup(mem_ctx, "None" ); *psid_name_use = SID_NAME_DOM_GRP; - + return True; } @@ -1971,12 +2011,6 @@ static NTSTATUS pdb_default_enum_trusteddoms(struct pdb_methods *methods, return secrets_trusted_domains(mem_ctx, num_domains, domains); } -static struct pdb_domain_info *pdb_default_get_domain_info( - struct pdb_methods *m, TALLOC_CTX *mem_ctx) -{ - return NULL; -} - /******************************************************************* Create a pdb_methods structure and initialize it with the default operations. In this way a passdb module can simply implement @@ -1988,12 +2022,10 @@ NTSTATUS make_pdb_method( struct pdb_methods **methods ) { /* allocate memory for the structure as its own talloc CTX */ - *methods = talloc_zero(talloc_autofree_context(), struct pdb_methods); - if (*methods == NULL) { + if ( !(*methods = TALLOC_ZERO_P(talloc_autofree_context(), struct pdb_methods) ) ) { return NT_STATUS_NO_MEMORY; } - (*methods)->get_domain_info = pdb_default_get_domain_info; (*methods)->getsampwnam = pdb_default_getsampwnam; (*methods)->getsampwsid = pdb_default_getsampwsid; (*methods)->create_user = pdb_default_create_user; @@ -2030,6 +2062,7 @@ NTSTATUS make_pdb_method( struct pdb_methods **methods ) (*methods)->get_account_policy = pdb_default_get_account_policy; (*methods)->set_account_policy = pdb_default_set_account_policy; (*methods)->get_seq_num = pdb_default_get_seq_num; + (*methods)->uid_to_rid = pdb_default_uid_to_rid; (*methods)->uid_to_sid = pdb_default_uid_to_sid; (*methods)->gid_to_sid = pdb_default_gid_to_sid; (*methods)->sid_to_id = pdb_default_sid_to_id; diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index ab041feba0..f95f91284b 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -7,20 +7,20 @@ Copyright (C) Andrew Bartlett 2002-2003 Copyright (C) Stefan (metze) Metzmacher 2002-2003 Copyright (C) Simo Sorce 2006 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. - + */ /* TODO: @@ -44,7 +44,6 @@ */ #include "includes.h" -#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB @@ -98,10 +97,10 @@ static const char* get_userattr_key2string( int schema_ver, int key ) switch ( schema_ver ) { case SCHEMAVER_SAMBAACCOUNT: return get_attr_key2string( attrib_map_v22, key ); - + case SCHEMAVER_SAMBASAMACCOUNT: return get_attr_key2string( attrib_map_v30, key ); - + default: DEBUG(0,("get_userattr_key2string: unknown schema version specified\n")); break; @@ -118,14 +117,14 @@ const char** get_userattr_list( TALLOC_CTX *mem_ctx, int schema_ver ) switch ( schema_ver ) { case SCHEMAVER_SAMBAACCOUNT: return get_attr_list( mem_ctx, attrib_map_v22 ); - + case SCHEMAVER_SAMBASAMACCOUNT: return get_attr_list( mem_ctx, attrib_map_v30 ); default: DEBUG(0,("get_userattr_list: unknown schema version specified!\n")); break; } - + return NULL; } @@ -140,7 +139,7 @@ static const char** get_userattr_delete_list( TALLOC_CTX *mem_ctx, case SCHEMAVER_SAMBAACCOUNT: return get_attr_list( mem_ctx, attrib_map_to_delete_v22 ); - + case SCHEMAVER_SAMBASAMACCOUNT: return get_attr_list( mem_ctx, attrib_map_to_delete_v30 ); @@ -148,7 +147,7 @@ static const char** get_userattr_delete_list( TALLOC_CTX *mem_ctx, DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n")); break; } - + return NULL; } @@ -162,7 +161,7 @@ static const char* get_objclass_filter( int schema_ver ) { fstring objclass_filter; char *result; - + switch( schema_ver ) { case SCHEMAVER_SAMBAACCOUNT: fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT ); @@ -175,7 +174,7 @@ static const char* get_objclass_filter( int schema_ver ) objclass_filter[0] = '\0'; break; } - + result = talloc_strdup(talloc_tos(), objclass_filter); SMB_ASSERT(result != NULL); return result; @@ -336,7 +335,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, const char **attr) { char *filter = NULL; - char *escape_user = escape_ldap_string(talloc_tos(), user); + char *escape_user = escape_ldap_string_alloc(user); int ret = -1; if (!escape_user) { @@ -350,7 +349,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, filter = talloc_asprintf(talloc_tos(), "(&%s%s)", "(uid=%u)", get_objclass_filter(ldap_state->schema_ver)); if (!filter) { - TALLOC_FREE(escape_user); + SAFE_FREE(escape_user); return LDAP_NO_MEMORY; } /* @@ -360,7 +359,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, filter = talloc_all_string_sub(talloc_tos(), filter, "%u", escape_user); - TALLOC_FREE(escape_user); + SAFE_FREE(escape_user); if (!filter) { return LDAP_NO_MEMORY; } @@ -448,7 +447,7 @@ static int ldapsam_delete_entry(struct ldapsam_privates *priv, } /* Ok, delete only the SAM attributes */ - + for (name = ldap_first_attribute(priv2ld(priv), entry, &ptr); name != NULL; name = ldap_next_attribute(priv2ld(priv), entry, ptr)) { @@ -902,7 +901,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state, pwHistLen = 0; - pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); if (pwHistLen > 0){ uint8 *pwhist = NULL; int i; @@ -1398,7 +1397,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state, if (need_update(sampass, PDB_PWHISTORY)) { char *pwstr = NULL; uint32 pwHistLen = 0; - pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen); + pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen); pwstr = SMB_MALLOC_ARRAY(char, 1024); if (!pwstr) { @@ -1475,7 +1474,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state, uint16 badcount = pdb_get_bad_password_count(sampass); time_t badtime = pdb_get_bad_password_time(sampass); uint32 pol; - pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &pol); + pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &pol); DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n", (unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime)); @@ -1582,7 +1581,7 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu int count; const char ** attr_list; int rc; - + attr_list = get_userattr_list( user, ldap_state->schema_ver ); append_attr(user, &attr_list, get_userattr_key2string(ldap_state->schema_ver, @@ -1594,9 +1593,9 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu if ( rc != LDAP_SUCCESS ) return NT_STATUS_NO_SUCH_USER; - + count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result); - + if (count < 1) { DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname, count)); ldap_msgfree(result); @@ -1653,12 +1652,12 @@ static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state, return rc; break; } - + case SCHEMAVER_SAMBAACCOUNT: if (!sid_peek_check_rid(&ldap_state->domain_sid, sid, &rid)) { return rc; } - + attr_list = get_userattr_list(NULL, ldap_state->schema_ver); rc = ldapsam_search_suffix_by_rid(ldap_state, rid, result, attr_list ); @@ -1689,7 +1688,7 @@ static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu return NT_STATUS_NO_SUCH_USER; count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result); - + if (count < 1) { DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] " "count=%d\n", sid_string_dbg(sid), count)); @@ -1733,11 +1732,11 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; int rc; - + if (!newpwd || !dn) { return NT_STATUS_INVALID_PARAMETER; } - + if (!mods) { DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n")); /* may be password change below however */ @@ -1765,12 +1764,12 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, ldap_op)); return NT_STATUS_INVALID_PARAMETER; } - + if (rc!=LDAP_SUCCESS) { return NT_STATUS_UNSUCCESSFUL; } } - + if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) && (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) && need_update(newpwd, PDB_PLAINTEXT_PW) && @@ -1794,22 +1793,22 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, } } - if (!push_utf8_talloc(talloc_tos(), &utf8_password, + if (!push_utf8_allocate(&utf8_password, pdb_get_plaintext_passwd(newpwd), &converted_size)) { return NT_STATUS_NO_MEMORY; } - if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) { - TALLOC_FREE(utf8_password); + if (!push_utf8_allocate(&utf8_dn, dn, &converted_size)) { + SAFE_FREE(utf8_password); return NT_STATUS_NO_MEMORY; } if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) { DEBUG(0,("ber_alloc_t returns NULL\n")); - TALLOC_FREE(utf8_password); - TALLOC_FREE(utf8_dn); + SAFE_FREE(utf8_password); + SAFE_FREE(utf8_dn); return NT_STATUS_UNSUCCESSFUL; } @@ -1819,8 +1818,8 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, DEBUG(0,("ldapsam_modify_entry: ber_printf returns a " "value <0\n")); ber_free(ber,1); - TALLOC_FREE(utf8_dn); - TALLOC_FREE(utf8_password); + SAFE_FREE(utf8_dn); + SAFE_FREE(utf8_password); return NT_STATUS_UNSUCCESSFUL; } @@ -1836,21 +1835,21 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods, DEBUG(0,("ldapsam_modify_entry: ber_printf returns a " "value <0\n")); ber_free(ber,1); - TALLOC_FREE(utf8_dn); - TALLOC_FREE(utf8_password); + SAFE_FREE(utf8_dn); + SAFE_FREE(utf8_password); return NT_STATUS_UNSUCCESSFUL; } if ((rc = ber_flatten (ber, &bv))<0) { DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n")); ber_free(ber,1); - TALLOC_FREE(utf8_dn); - TALLOC_FREE(utf8_password); + SAFE_FREE(utf8_dn); + SAFE_FREE(utf8_password); return NT_STATUS_UNSUCCESSFUL; } - - TALLOC_FREE(utf8_dn); - TALLOC_FREE(utf8_password); + + SAFE_FREE(utf8_dn); + SAFE_FREE(utf8_password); ber_free(ber, 1); if (!ldap_state->is_nds_ldap) { @@ -1945,7 +1944,7 @@ static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods, result = NT_STATUS_NO_SUCH_USER; goto done; } - + rc = ldapsam_delete_entry( priv, mem_ctx, entry, priv->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ? @@ -2031,7 +2030,7 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struc TALLOC_FREE(dn); return NT_STATUS_OK; } - + ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed); if (mods != NULL) { @@ -2067,18 +2066,6 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struc - The "rename user script" has full responsibility for changing everything ***************************************************************************/ -static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods, - TALLOC_CTX *tmp_ctx, - uint32 group_rid, - uint32 member_rid); - -static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, - TALLOC_CTX *mem_ctx, - struct samu *user, - DOM_SID **pp_sids, - gid_t **pp_gids, - size_t *p_num_groups); - static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods, struct samu *old_acct, const char *newname) @@ -2231,18 +2218,18 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s /* does the entry already exist but without a samba attributes? we need to return the samba attributes here */ - escape_user = escape_ldap_string(talloc_tos(), username); + escape_user = escape_ldap_string_alloc( username ); filter = talloc_strdup(attr_list, "(uid=%u)"); if (!filter) { status = NT_STATUS_NO_MEMORY; goto fn_exit; } filter = talloc_all_string_sub(attr_list, filter, "%u", escape_user); - TALLOC_FREE(escape_user); if (!filter) { status = NT_STATUS_NO_MEMORY; goto fn_exit; } + SAFE_FREE(escape_user); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr_list, &result); @@ -2389,6 +2376,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s fn_exit: TALLOC_FREE(ctx); + SAFE_FREE(escape_user); if (result) { ldap_msgfree(result); } @@ -2639,7 +2627,7 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, const char *name) { char *filter = NULL; - char *escape_name = escape_ldap_string(talloc_tos(), name); + char *escape_name = escape_ldap_string_alloc(name); NTSTATUS status; if (!escape_name) { @@ -2651,11 +2639,11 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name, get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN), escape_name) < 0) { - TALLOC_FREE(escape_name); + SAFE_FREE(escape_name); return NT_STATUS_NO_MEMORY; } - TALLOC_FREE(escape_name); + SAFE_FREE(escape_name); status = ldapsam_getgroup(methods, filter, map); SAFE_FREE(filter); return status; @@ -2776,19 +2764,20 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, for (memberuid = values; *memberuid != NULL; memberuid += 1) { char *escape_memberuid; - escape_memberuid = escape_ldap_string(talloc_tos(), - *memberuid); + escape_memberuid = escape_ldap_string_alloc(*memberuid); if (escape_memberuid == NULL) { ret = NT_STATUS_NO_MEMORY; goto done; } - + filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid); - TALLOC_FREE(escape_memberuid); if (filter == NULL) { + SAFE_FREE(escape_memberuid); ret = NT_STATUS_NO_MEMORY; goto done; } + + SAFE_FREE(escape_memberuid); } filter = talloc_asprintf_append_buffer(filter, "))"); @@ -2885,7 +2874,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, } ret = NT_STATUS_OK; - + done: if (values) @@ -2922,7 +2911,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, return NT_STATUS_INVALID_PARAMETER; } - escape_name = escape_ldap_string(talloc_tos(), pdb_get_username(user)); + escape_name = escape_ldap_string_alloc(pdb_get_username(user)); if (escape_name == NULL) return NT_STATUS_NO_MEMORY; @@ -3064,7 +3053,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, done: - TALLOC_FREE(escape_name); + SAFE_FREE(escape_name); return ret; } @@ -3382,7 +3371,7 @@ static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods, rc = ldapsam_delete_entry(priv, mem_ctx, entry, LDAP_OBJ_GROUPMAP, get_attr_list(mem_ctx, groupmap_attr_list_to_delete)); - + if ((rc == LDAP_NAMING_VIOLATION) || (rc == LDAP_NOT_ALLOWED_ON_RDN) || (rc == LDAP_OBJECT_CLASS_VIOLATION)) { @@ -3490,11 +3479,11 @@ static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods, while (!bret) { if (!ldap_state->entry) return ret; - + ldap_state->index++; bret = init_group_from_ldap(ldap_state, map, ldap_state->entry); - + ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->entry); @@ -3678,7 +3667,6 @@ static NTSTATUS ldapsam_del_aliasmem(struct pdb_methods *methods, static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods, const DOM_SID *alias, - TALLOC_CTX *mem_ctx, DOM_SID **pp_members, size_t *p_num_members) { @@ -3771,7 +3759,7 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods, if (!string_to_sid(&member, values[i])) continue; - status = add_sid_to_array(mem_ctx, &member, pp_members, + status = add_sid_to_array(NULL, &member, pp_members, &num_members); if (!NT_STATUS_IS_OK(status)) { ldap_value_free(values); @@ -3810,9 +3798,6 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods, bool is_builtin = false; bool sid_added = false; - *pp_alias_rids = NULL; - *p_num_alias_rids = 0; - if (sid_check_is_builtin(domain_sid)) { is_builtin = true; type = SID_NAME_ALIAS; @@ -3828,12 +3813,8 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods, return NT_STATUS_UNSUCCESSFUL; } - if (num_members == 0) { - return NT_STATUS_OK; - } - filter = talloc_asprintf(mem_ctx, - "(&(objectclass=%s)(sambaGroupType=%d)(|", + "(&(|(objectclass=%s)(sambaGroupType=%d))(|", LDAP_OBJ_GROUPMAP, type); for (i=0; i<num_members; i++) @@ -3907,7 +3888,7 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods, } static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, - enum pdb_policy_type type, + int policy_index, uint32 value) { NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL; @@ -3925,7 +3906,7 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, return NT_STATUS_INVALID_PARAMETER; } - policy_attr = get_account_policy_attr(type); + policy_attr = get_account_policy_attr(policy_index); if (policy_attr == NULL) { DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid " "policy\n")); @@ -3945,7 +3926,7 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, return ntstatus; } - if (!cache_account_policy_set(type, value)) { + if (!cache_account_policy_set(policy_index, value)) { DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to " "update local tdb cache\n")); return ntstatus; @@ -3955,15 +3936,14 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods, } static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods, - enum pdb_policy_type type, - uint32_t value) + int policy_index, uint32 value) { - return ldapsam_set_account_policy_in_ldap(methods, type, + return ldapsam_set_account_policy_in_ldap(methods, policy_index, value); } static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods, - enum pdb_policy_type type, + int policy_index, uint32 *value) { NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL; @@ -3986,10 +3966,10 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods return NT_STATUS_INVALID_PARAMETER; } - policy_attr = get_account_policy_attr(type); + policy_attr = get_account_policy_attr(policy_index); if (!policy_attr) { DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid " - "policy index: %d\n", type)); + "policy index: %d\n", policy_index)); return ntstatus; } @@ -4024,7 +4004,7 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods } *value = (uint32)atol(vals[0]); - + ntstatus = NT_STATUS_OK; out: @@ -4039,7 +4019,7 @@ out: - if user hasn't decided to use account policies inside LDAP just reuse the old tdb values - + - if there is a valid cache entry, return that - if there is an LDAP entry, update cache and return - otherwise set to default, update cache and return @@ -4047,18 +4027,17 @@ out: Guenther */ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, - enum pdb_policy_type type, - uint32_t *value) + int policy_index, uint32 *value) { NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL; - if (cache_account_policy_get(type, value)) { + if (cache_account_policy_get(policy_index, value)) { DEBUG(11,("ldapsam_get_account_policy: got valid value from " "cache\n")); return NT_STATUS_OK; } - ntstatus = ldapsam_get_account_policy_from_ldap(methods, type, + ntstatus = ldapsam_get_account_policy_from_ldap(methods, policy_index, value); if (NT_STATUS_IS_OK(ntstatus)) { goto update_cache; @@ -4069,27 +4048,27 @@ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, #if 0 /* should we automagically migrate old tdb value here ? */ - if (account_policy_get(type, value)) + if (account_policy_get(policy_index, value)) goto update_ldap; DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying " - "default\n", type)); + "default\n", policy_index)); #endif - if (!account_policy_get_default(type, value)) { + if (!account_policy_get_default(policy_index, value)) { return ntstatus; } - + /* update_ldap: */ - - ntstatus = ldapsam_set_account_policy(methods, type, *value); + + ntstatus = ldapsam_set_account_policy(methods, policy_index, *value); if (!NT_STATUS_IS_OK(ntstatus)) { return ntstatus; } - + update_cache: - - if (!cache_account_policy_set(type, *value)) { + + if (!cache_account_policy_set(policy_index, *value)) { DEBUG(0,("ldapsam_get_account_policy: failed to update local " "tdb as a cache\n")); return NT_STATUS_UNSUCCESSFUL; @@ -4128,11 +4107,6 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods, goto done; } - if (num_rids == 0) { - result = NT_STATUS_NONE_MAPPED; - goto done; - } - for (i=0; i<num_rids; i++) attrs[i] = SID_NAME_UNKNOWN; @@ -4335,14 +4309,14 @@ static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username) goto done; } - escaped = escape_ldap_string(talloc_tos(), username); + escaped = escape_ldap_string_alloc(username); if (escaped == NULL) goto done; result = talloc_string_sub(mem_ctx, filter, "%u", username); done: SAFE_FREE(filter); - TALLOC_FREE(escaped); + SAFE_FREE(escaped); return result; } @@ -4625,7 +4599,7 @@ static bool ldapuser2displayentry(struct ldap_search_state *state, DEBUG(0, ("talloc failed\n")); return False; } - + vals = ldap_get_values(ld, entry, "sambaSid"); if ((vals == NULL) || (vals[0] == NULL)) { DEBUG(0, ("\"objectSid\" not found\n")); @@ -4781,7 +4755,7 @@ static bool ldapgroup2displayentry(struct ldap_search_state *state, DEBUG(0, ("talloc failed\n")); return False; } - + vals = ldap_get_values(ld, entry, "sambaSid"); if ((vals == NULL) || (vals[0] == NULL)) { DEBUG(0, ("\"objectSid\" not found\n")); @@ -4810,7 +4784,7 @@ static bool ldapgroup2displayentry(struct ldap_search_state *state, return False; } break; - + default: DEBUG(0,("unkown group type: %d\n", group_type)); return False; @@ -4880,9 +4854,9 @@ static bool ldapsam_search_aliases(struct pdb_methods *methods, return ldapsam_search_grouptype(methods, search, sid, SID_NAME_ALIAS); } -static uint32_t ldapsam_capabilities(struct pdb_methods *methods) +static bool ldapsam_rid_algorithm(struct pdb_methods *methods) { - return PDB_CAP_STORE_RIDS; + return False; } static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv, @@ -5191,7 +5165,7 @@ static bool ldapsam_gid_to_sid(struct pdb_methods *methods, gid_t gid, LDAPMessage *entry = NULL; bool ret = false; char *group_sid_string; - DOM_SID group_sid; + DOM_SID *group_sid; int rc; TALLOC_CTX *tmp_ctx = talloc_stackframe(); @@ -5228,13 +5202,14 @@ static bool ldapsam_gid_to_sid(struct pdb_methods *methods, gid_t gid, goto done; } - if (!string_to_sid(&group_sid, group_sid_string)) { + group_sid = string_sid_talloc(tmp_ctx, group_sid_string); + if (group_sid == NULL) { DEBUG(3, ("Error calling sid_string_talloc for sid '%s'\n", group_sid_string)); goto done; } - sid_copy(sid, &group_sid); + sid_copy(sid, group_sid); store_gid_sid_cache(sid, gid); idmap_cache_set_sid2gid(sid, gid); @@ -5248,7 +5223,7 @@ static bool ldapsam_gid_to_sid(struct pdb_methods *methods, gid_t gid, /* - * The following functions are called only if + * The following functions is called only if * ldapsam:trusted and ldapsam:editposix are * set to true */ @@ -5286,7 +5261,7 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, uid_t uid = -1; NTSTATUS ret; int rc; - + if (((acb_info & ACB_NORMAL) && name[strlen(name)-1] == '$') || acb_info & ACB_WSTRUST || acb_info & ACB_SVRTRUST || @@ -5294,10 +5269,10 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, is_machine = True; } - username = escape_ldap_string(talloc_tos(), name); + username = escape_ldap_string_alloc(name); filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass=%s))", username, LDAP_OBJ_POSIXACCOUNT); - TALLOC_FREE(username); + SAFE_FREE(username); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); if (rc != LDAP_SUCCESS) { @@ -5312,7 +5287,7 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, DEBUG (0, ("ldapsam_create_user: More than one user with name [%s] ?!\n", name)); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - + if (num_result == 1) { char *tmp; /* check if it is just a posix account. @@ -5341,7 +5316,7 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, if (num_result == 0) { add_posix = True; } - + /* Create the basic samu structure and generate the mods for the ldap commit */ if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) { DEBUG(1, ("ldapsam_create_user: Could not allocate a new RID\n")); @@ -5476,6 +5451,18 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, return NT_STATUS_OK; } +static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods, + TALLOC_CTX *tmp_ctx, + uint32 group_rid, + uint32 member_rid); + +static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, + TALLOC_CTX *mem_ctx, + struct samu *user, + DOM_SID **pp_sids, + gid_t **pp_gids, + size_t *p_num_groups); + static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, struct samu *sam_acct) { struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data; @@ -5487,7 +5474,7 @@ static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX * int rc; DEBUG(0,("ldapsam_delete_user: Attempt to delete user [%s]\n", pdb_get_username(sam_acct))); - + filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)" "(objectClass=%s)" @@ -5603,11 +5590,11 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods, DOM_SID group_sid; gid_t gid = -1; int rc; - - groupname = escape_ldap_string(talloc_tos(), name); + + groupname = escape_ldap_string_alloc(name); filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))", groupname, LDAP_OBJ_POSIXGROUP); - TALLOC_FREE(groupname); + SAFE_FREE(groupname); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); if (rc != LDAP_SUCCESS) { @@ -5622,7 +5609,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods, DEBUG (0, ("ldapsam_create_group: There exists more than one group with name [%s]: bailing out!\n", name)); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - + if (num_result == 1) { char *tmp; /* check if it is just a posix group. @@ -5646,7 +5633,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods, DEBUG (1, ("ldapsam_create_group: Couldn't retrieve the gidNumber for [%s]?!?!\n", name)); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - + gid = strtoul(tmp, NULL, 10); dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry); @@ -5662,7 +5649,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods, DEBUG(3,("ldapsam_create_user: Creating new posix group\n")); is_new_entry = True; - + /* lets allocate a new groupid for this group */ if (!winbind_allocate_gid(&gid)) { DEBUG (0, ("ldapsam_create_group: Unable to allocate a new group id: bailing out!\n")); @@ -5859,7 +5846,7 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods, default: return NT_STATUS_UNSUCCESSFUL; } - + /* get member sid */ sid_compose(&member_sid, get_global_sam_sid(), member_rid); @@ -5906,7 +5893,7 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods, /* check if we are trying to remove the member from his primary group */ char *gidstr; gid_t user_gid, group_gid; - + gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx); if (!gidstr) { DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's gid!\n")); @@ -5914,7 +5901,7 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods, } user_gid = strtoul(gidstr, NULL, 10); - + if (!sid_to_gid(&group_sid, &group_gid)) { DEBUG (0, ("ldapsam_change_groupmem: Unable to get group gid from SID!\n")); return NT_STATUS_UNSUCCESSFUL; @@ -5989,7 +5976,7 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods, } return NT_STATUS_UNSUCCESSFUL; } - + return NT_STATUS_OK; } @@ -6036,8 +6023,7 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods, return NT_STATUS_NO_MEMORY; } - escape_username = escape_ldap_string(talloc_tos(), - pdb_get_username(sampass)); + escape_username = escape_ldap_string_alloc(pdb_get_username(sampass)); if (escape_username== NULL) { return NT_STATUS_NO_MEMORY; } @@ -6050,7 +6036,7 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods, LDAP_OBJ_POSIXACCOUNT, LDAP_OBJ_SAMBASAMACCOUNT); - TALLOC_FREE(escape_username); + SAFE_FREE(escape_username); if (filter == NULL) { return NT_STATUS_NO_MEMORY; @@ -6276,6 +6262,8 @@ static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods, smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaClearTextPassword", pwd); + talloc_autofree_ldapmod(talloc_tos(), mods); + if (entry != NULL) { prev_pwd = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaClearTextPassword", talloc_tos()); @@ -6286,8 +6274,6 @@ static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods, } } - talloc_autofree_ldapmod(talloc_tos(), mods); - trusted_dn = trusteddom_dn(ldap_state, domain); if (trusted_dn == NULL) { return False; @@ -6489,7 +6475,7 @@ static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const c (*pdb_method)->get_seq_num = ldapsam_get_seq_num; - (*pdb_method)->capabilities = ldapsam_capabilities; + (*pdb_method)->rid_algorithm = ldapsam_rid_algorithm; (*pdb_method)->new_rid = ldapsam_new_rid; (*pdb_method)->get_trusteddom_pw = ldapsam_get_trusteddom_pw; diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index f465d34c88..d663c7f0b2 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -276,7 +276,7 @@ Error was %s\n", pfile, strerror(errno) )); * prevent infinate loops. JRA. */ - if (sys_stat(pfile, &sbuf1, false) != 0) { + if (sys_stat(pfile,&sbuf1) != 0) { DEBUG(0, ("startsmbfilepwent_internal: unable to stat file %s. \ Error was %s\n", pfile, strerror(errno))); pw_file_unlock(fileno(fp), lock_depth); @@ -284,7 +284,7 @@ Error was %s\n", pfile, strerror(errno))); return NULL; } - if (sys_fstat(fileno(fp), &sbuf2, false) != 0) { + if (sys_fstat(fileno(fp),&sbuf2) != 0) { DEBUG(0, ("startsmbfilepwent_internal: unable to fstat file %s. \ Error was %s\n", pfile, strerror(errno))); pw_file_unlock(fileno(fp), lock_depth); @@ -292,7 +292,7 @@ Error was %s\n", pfile, strerror(errno))); return NULL; } - if( sbuf1.st_ex_ino == sbuf2.st_ex_ino) { + if( sbuf1.st_ino == sbuf2.st_ino) { /* No race. */ break; } @@ -1520,9 +1520,9 @@ done: return (ret); } -static uint32_t smbpasswd_capabilities(struct pdb_methods *methods) +static bool smbpasswd_rid_algorithm(struct pdb_methods *methods) { - return 0; + return True; } static void free_private_data(void **vp) @@ -1682,7 +1682,7 @@ static NTSTATUS pdb_init_smbpasswd( struct pdb_methods **pdb_method, const char (*pdb_method)->rename_sam_account = smbpasswd_rename_sam_account; (*pdb_method)->search_users = smbpasswd_search_users; - (*pdb_method)->capabilities = smbpasswd_capabilities; + (*pdb_method)->rid_algorithm = smbpasswd_rid_algorithm; /* Setup private data and free function */ diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index ca89bf7926..dd6e678c99 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -1066,15 +1066,14 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods, return NT_STATUS_ACCESS_DENIED; } -static uint32_t tdbsam_capabilities(struct pdb_methods *methods) +static bool tdbsam_rid_algorithm(struct pdb_methods *methods) { - return PDB_CAP_STORE_RIDS; + return False; } static bool tdbsam_new_rid(struct pdb_methods *methods, uint32 *prid) { uint32 rid; - NTSTATUS status; rid = BASE_RID; /* Default if not set */ @@ -1084,11 +1083,9 @@ static bool tdbsam_new_rid(struct pdb_methods *methods, uint32 *prid) return false; } - status = dbwrap_trans_change_uint32_atomic(db_sam, NEXT_RID_STRING, - &rid, 1); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("tdbsam_new_rid: Failed to increase %s: %s\n", - NEXT_RID_STRING, nt_errstr(status))); + if (dbwrap_change_uint32_atomic(db_sam, NEXT_RID_STRING, &rid, 1) != 0) { + DEBUG(3, ("tdbsam_new_rid: Failed to increase %s\n", + NEXT_RID_STRING)); return false; } @@ -1249,13 +1246,13 @@ static NTSTATUS pdb_init_tdbsam(struct pdb_methods **pdb_method, const char *loc (*pdb_method)->rename_sam_account = tdbsam_rename_sam_account; (*pdb_method)->search_users = tdbsam_search_users; - (*pdb_method)->capabilities = tdbsam_capabilities; + (*pdb_method)->rid_algorithm = tdbsam_rid_algorithm; (*pdb_method)->new_rid = tdbsam_new_rid; /* save the path for later */ if (!location) { - if (asprintf(&tdbfile, "%s/%s", get_dyn_STATEDIR(), + if (asprintf(&tdbfile, "%s/%s", lp_private_dir(), PASSDB_FILE_NAME) < 0) { return NT_STATUS_NO_MEMORY; } diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c index df80411a7a..9c31a0d75c 100644 --- a/source3/passdb/pdb_wbc_sam.c +++ b/source3/passdb/pdb_wbc_sam.c @@ -167,12 +167,12 @@ done: return result; } -static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value) +static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value) { return NT_STATUS_UNSUCCESSFUL; } -static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value) +static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value) { return NT_STATUS_UNSUCCESSFUL; } @@ -316,12 +316,13 @@ static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map const char *name) { NTSTATUS result = NT_STATUS_OK; - const char *domain = ""; + char *user_name = NULL; + char *domain = NULL; DOM_SID sid; gid_t gid; enum lsa_SidType name_type; - if (!winbind_lookup_name(domain, name, &sid, &name_type)) { + if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) { result = NT_STATUS_NO_SUCH_GROUP; goto done; } @@ -339,7 +340,7 @@ static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map goto done; } - if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { + if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) { result = NT_STATUS_NO_SUCH_GROUP; goto done; } @@ -365,10 +366,8 @@ static NTSTATUS pdb_wbc_sam_get_aliasinfo(struct pdb_methods *methods, } static NTSTATUS pdb_wbc_sam_enum_aliasmem(struct pdb_methods *methods, - const DOM_SID *alias, - TALLOC_CTX *mem_ctx, - DOM_SID **pp_members, - size_t *p_num_members) + const DOM_SID *alias, DOM_SID **pp_members, + size_t *p_num_members) { return NT_STATUS_NOT_IMPLEMENTED; } diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index 10a156d653..8e64a49e22 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -23,8 +23,6 @@ such as the local SID and machine trust password */ #include "includes.h" -#include "../libcli/auth/libcli_auth.h" -#include "librpc/gen_ndr/ndr_secrets.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB @@ -46,8 +44,8 @@ static void get_rand_seed(void *userdata, int *new_seed) { *new_seed = sys_getpid(); if (db_ctx) { - dbwrap_trans_change_int32_atomic(db_ctx, "INFO/random_seed", - new_seed, 1); + dbwrap_change_int32_atomic(db_ctx, "INFO/random_seed", + new_seed, 1); } } @@ -61,7 +59,7 @@ bool secrets_init(void) return True; fname = talloc_asprintf(talloc_tos(), "%s/secrets.tdb", - get_dyn_STATEDIR()); + lp_private_dir()); if (fname == NULL) { return false; } @@ -393,7 +391,7 @@ void *secrets_get_trust_account_lock(TALLOC_CTX *mem_ctx, const char *domain) Routine to get the default secure channel type for trust accounts ************************************************************************/ -enum netr_SchannelType get_default_sec_channel(void) +uint32 get_default_sec_channel(void) { if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) { @@ -413,7 +411,7 @@ enum netr_SchannelType get_default_sec_channel(void) bool secrets_fetch_trust_account_password_legacy(const char *domain, uint8 ret_pwd[16], time_t *pass_last_set_time, - enum netr_SchannelType *channel) + uint32 *channel) { struct machine_acct_pass *pass; size_t size = 0; @@ -459,7 +457,7 @@ bool secrets_fetch_trust_account_password_legacy(const char *domain, bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16], time_t *pass_last_set_time, - enum netr_SchannelType *channel) + uint32 *channel) { char *plaintext; @@ -477,6 +475,178 @@ bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16], channel); } +/** + * Pack SID passed by pointer + * + * @param pack_buf pointer to buffer which is to be filled with packed data + * @param bufsize size of packing buffer + * @param sid pointer to sid to be packed + * + * @return length of the packed representation of the whole structure + **/ +static size_t tdb_sid_pack(uint8 *pack_buf, int bufsize, DOM_SID* sid) +{ + int idx; + size_t len = 0; + uint8 *p = pack_buf; + int remaining_space = pack_buf ? bufsize : 0; + + if (!sid) { + return -1; + } + + len += tdb_pack(p, remaining_space, "bb", sid->sid_rev_num, + sid->num_auths); + if (pack_buf) { + p = pack_buf + len; + remaining_space = bufsize - len; + } + + for (idx = 0; idx < 6; idx++) { + len += tdb_pack(p, remaining_space, "b", + sid->id_auth[idx]); + if (pack_buf) { + p = pack_buf + len; + remaining_space = bufsize - len; + } + } + + for (idx = 0; idx < MAXSUBAUTHS; idx++) { + len += tdb_pack(p, remaining_space, "d", + sid->sub_auths[idx]); + if (pack_buf) { + p = pack_buf + len; + remaining_space = bufsize - len; + } + } + + return len; +} + +/** + * Unpack SID into a pointer + * + * @param pack_buf pointer to buffer with packed representation + * @param bufsize size of the buffer + * @param sid pointer to sid structure to be filled with unpacked data + * + * @return size of structure unpacked from buffer + **/ +static size_t tdb_sid_unpack(uint8 *pack_buf, int bufsize, DOM_SID* sid) +{ + int idx, len = 0; + + if (!sid || !pack_buf) return -1; + + len += tdb_unpack(pack_buf + len, bufsize - len, "bb", + &sid->sid_rev_num, &sid->num_auths); + + for (idx = 0; idx < 6; idx++) { + len += tdb_unpack(pack_buf + len, bufsize - len, "b", + &sid->id_auth[idx]); + } + + for (idx = 0; idx < MAXSUBAUTHS; idx++) { + len += tdb_unpack(pack_buf + len, bufsize - len, "d", + &sid->sub_auths[idx]); + } + + return len; +} + +/** + * Pack TRUSTED_DOM_PASS passed by pointer + * + * @param pack_buf pointer to buffer which is to be filled with packed data + * @param bufsize size of the buffer + * @param pass pointer to trusted domain password to be packed + * + * @return length of the packed representation of the whole structure + **/ +static size_t tdb_trusted_dom_pass_pack(uint8 *pack_buf, int bufsize, + TRUSTED_DOM_PASS* pass) +{ + int idx, len = 0; + uint8 *p = pack_buf; + int remaining_space = pack_buf ? bufsize : 0; + + if (!pass) { + return -1; + } + + /* packing unicode domain name and password */ + len += tdb_pack(p, remaining_space, "d", + pass->uni_name_len); + if (pack_buf) { + p = pack_buf + len; + remaining_space = bufsize - len; + } + + for (idx = 0; idx < 32; idx++) { + len += tdb_pack(p, remaining_space, "w", + pass->uni_name[idx]); + if (pack_buf) { + p = pack_buf + len; + remaining_space = bufsize - len; + } + } + + len += tdb_pack(p, remaining_space, "dPd", pass->pass_len, + pass->pass, pass->mod_time); + if (pack_buf) { + p = pack_buf + len; + remaining_space = bufsize - len; + } + + /* packing SID structure */ + len += tdb_sid_pack(p, remaining_space, &pass->domain_sid); + if (pack_buf) { + p = pack_buf + len; + remaining_space = bufsize - len; + } + + return len; +} + + +/** + * Unpack TRUSTED_DOM_PASS passed by pointer + * + * @param pack_buf pointer to buffer with packed representation + * @param bufsize size of the buffer + * @param pass pointer to trusted domain password to be filled with unpacked data + * + * @return size of structure unpacked from buffer + **/ +static size_t tdb_trusted_dom_pass_unpack(uint8 *pack_buf, int bufsize, + TRUSTED_DOM_PASS* pass) +{ + int idx, len = 0; + char *passp = NULL; + + if (!pack_buf || !pass) return -1; + + /* unpack unicode domain name and plaintext password */ + len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len); + + for (idx = 0; idx < 32; idx++) + len += tdb_unpack(pack_buf + len, bufsize - len, "w", + &pass->uni_name[idx]); + + len += tdb_unpack(pack_buf + len, bufsize - len, "dPd", + &pass->pass_len, &passp, &pass->mod_time); + if (passp) { + fstrcpy(pass->pass, passp); + } + SAFE_FREE(passp); + + /* unpack domain sid */ + len += tdb_sid_unpack(pack_buf + len, bufsize - len, + &pass->domain_sid); + + return len; +} + /************************************************************************ Routine to get account password to trusted domain ************************************************************************/ @@ -484,27 +654,30 @@ bool secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16], bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd, DOM_SID *sid, time_t *pass_last_set_time) { - struct TRUSTED_DOM_PASS pass; - enum ndr_err_code ndr_err; + struct trusted_dom_pass pass; + size_t size = 0; /* unpacking structures */ - DATA_BLOB blob; + uint8 *pass_buf; + int pass_len = 0; + + ZERO_STRUCT(pass); /* fetching trusted domain password structure */ - if (!(blob.data = (uint8_t *)secrets_fetch(trustdom_keystr(domain), - &blob.length))) { + if (!(pass_buf = (uint8 *)secrets_fetch(trustdom_keystr(domain), + &size))) { DEBUG(5, ("secrets_fetch failed!\n")); return False; } /* unpack trusted domain password */ - ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &pass, - (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return false; - } + pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass); + SAFE_FREE(pass_buf); - SAFE_FREE(blob.data); + if (pass_len != size) { + DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n")); + return False; + } /* the trust's password */ if (pwd) { @@ -536,37 +709,47 @@ bool secrets_fetch_trusted_domain_password(const char *domain, char** pwd, bool secrets_store_trusted_domain_password(const char* domain, const char* pwd, const DOM_SID *sid) { + smb_ucs2_t *uni_dom_name; bool ret; + size_t converted_size; /* packing structures */ - DATA_BLOB blob; - enum ndr_err_code ndr_err; - struct TRUSTED_DOM_PASS pass; + uint8 *pass_buf = NULL; + int pass_len = 0; + + struct trusted_dom_pass pass; ZERO_STRUCT(pass); - pass.uni_name = domain; - pass.uni_name_len = strlen(domain)+1; + if (!push_ucs2_allocate(&uni_dom_name, domain, &converted_size)) { + DEBUG(0, ("Could not convert domain name %s to unicode\n", + domain)); + return False; + } + + strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1); + pass.uni_name_len = strlen_w(uni_dom_name)+1; + SAFE_FREE(uni_dom_name); /* last change time */ pass.mod_time = time(NULL); /* password of the trust */ pass.pass_len = strlen(pwd); - pass.pass = pwd; + fstrcpy(pass.pass, pwd); /* domain sid */ sid_copy(&pass.domain_sid, sid); - ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), NULL, &pass, - (ndr_push_flags_fn_t)ndr_push_TRUSTED_DOM_PASS); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + /* Calculate the length. */ + pass_len = tdb_trusted_dom_pass_pack(NULL, 0, &pass); + pass_buf = SMB_MALLOC_ARRAY(uint8, pass_len); + if (!pass_buf) { return false; } - - ret = secrets_store(trustdom_keystr(domain), blob.data, blob.length); - - data_blob_free(&blob); - + pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_len, &pass); + ret = secrets_store(trustdom_keystr(domain), (void *)pass_buf, + pass_len); + SAFE_FREE(pass_buf); return ret; } @@ -609,8 +792,7 @@ bool secrets_delete_domain_sid(const char *domain) the password is assumed to be a null terminated ascii string ************************************************************************/ -bool secrets_store_machine_password(const char *pass, const char *domain, - enum netr_SchannelType sec_channel) +bool secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel) { bool ret; uint32 last_change_time; @@ -636,7 +818,7 @@ bool secrets_store_machine_password(const char *pass, const char *domain, char *secrets_fetch_machine_password(const char *domain, time_t *pass_last_set_time, - enum netr_SchannelType *channel) + uint32 *channel) { char *ret; ret = (char *)secrets_fetch(machine_password_keystr(domain), NULL); @@ -707,7 +889,6 @@ bool fetch_ldap_pw(char **dn, char** pw) if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) { SAFE_FREE(*dn); DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n")); - return false; } *pw=(char *)secrets_fetch(key, &size); @@ -773,9 +954,8 @@ struct list_trusted_domains_state { static int list_trusted_domain(struct db_record *rec, void *private_data) { const size_t prefix_len = strlen(SECRETS_DOMTRUST_ACCT_PASS); - struct TRUSTED_DOM_PASS pass; - enum ndr_err_code ndr_err; - DATA_BLOB blob; + size_t converted_size, packed_size = 0; + struct trusted_dom_pass pass; struct trustdom_info *dom_info; struct list_trusted_domains_state *state = @@ -787,12 +967,12 @@ static int list_trusted_domain(struct db_record *rec, void *private_data) return 0; } - blob = data_blob_const(rec->value.dptr, rec->value.dsize); + packed_size = tdb_trusted_dom_pass_unpack( + rec->value.dptr, rec->value.dsize, &pass); - ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), NULL, &pass, - (ndr_pull_flags_fn_t)ndr_pull_TRUSTED_DOM_PASS); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return false; + if (rec->value.dsize != packed_size) { + DEBUG(2, ("Secrets record is invalid!\n")); + return 0; } if (pass.domain_sid.num_auths != 4) { @@ -808,8 +988,9 @@ static int list_trusted_domain(struct db_record *rec, void *private_data) return 0; } - dom_info->name = talloc_strdup(dom_info, pass.uni_name); - if (!dom_info->name) { + if (!pull_ucs2_talloc(dom_info, &dom_info->name, pass.uni_name, + &converted_size)) { + DEBUG(2, ("pull_ucs2_talloc failed\n")); TALLOC_FREE(dom_info); return 0; } @@ -948,23 +1129,226 @@ void secrets_fetch_ipc_userpass(char **username, char **domain, char **password) } } -bool secrets_store_generic(const char *owner, const char *key, const char *secret) +/****************************************************************************** + Open or create the schannel session store tdb. +*******************************************************************************/ + +static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx) { - char *tdbkey = NULL; + TDB_DATA vers; + uint32 ver; + TDB_CONTEXT *tdb_sc = NULL; + char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir()); + + if (!fname) { + return NULL; + } + + tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); + + if (!tdb_sc) { + DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname)); + TALLOC_FREE(fname); + return NULL; + } + + vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION"); + if (vers.dptr == NULL) { + /* First opener, no version. */ + SIVAL(&ver,0,1); + vers.dptr = (uint8 *)&ver; + vers.dsize = 4; + tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE); + vers.dptr = NULL; + } else if (vers.dsize == 4) { + ver = IVAL(vers.dptr,0); + if (ver != 1) { + tdb_close(tdb_sc); + tdb_sc = NULL; + DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n", + (int)ver, fname )); + } + } else { + tdb_close(tdb_sc); + tdb_sc = NULL; + DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n", + (int)vers.dsize, fname )); + } + + SAFE_FREE(vers.dptr); + TALLOC_FREE(fname); + + return tdb_sc; +} + +/****************************************************************************** + Store the schannel state after an AUTH2 call. + Note we must be root here. +*******************************************************************************/ + +bool secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx, + const char *remote_machine, + const struct dcinfo *pdc) +{ + TDB_CONTEXT *tdb_sc = NULL; + TDB_DATA value; bool ret; + char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s", + SECRETS_SCHANNEL_STATE, + remote_machine); + if (!keystr) { + return False; + } - if (asprintf(&tdbkey, "SECRETS/GENERIC/%s/%s", owner, key) < 0) { - DEBUG(0, ("asprintf failed!\n")); + /* Work out how large the record is. */ + value.dsize = tdb_pack(NULL, 0, "dBBBBBfff", + pdc->sequence, + 8, pdc->seed_chal.data, + 8, pdc->clnt_chal.data, + 8, pdc->srv_chal.data, + 16, pdc->sess_key, + 16, pdc->mach_pw, + pdc->mach_acct, + pdc->remote_machine, + pdc->domain); + + value.dptr = TALLOC_ARRAY(mem_ctx, uint8, value.dsize); + if (!value.dptr) { + TALLOC_FREE(keystr); return False; } - ret = secrets_store(tdbkey, secret, strlen(secret)+1); + value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff", + pdc->sequence, + 8, pdc->seed_chal.data, + 8, pdc->clnt_chal.data, + 8, pdc->srv_chal.data, + 16, pdc->sess_key, + 16, pdc->mach_pw, + pdc->mach_acct, + pdc->remote_machine, + pdc->domain); + + tdb_sc = open_schannel_session_store(mem_ctx); + if (!tdb_sc) { + TALLOC_FREE(keystr); + TALLOC_FREE(value.dptr); + return False; + } - SAFE_FREE(tdbkey); + ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False); + + DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n", + keystr )); + + tdb_close(tdb_sc); + TALLOC_FREE(keystr); + TALLOC_FREE(value.dptr); return ret; } -bool secrets_delete_generic(const char *owner, const char *key) +/****************************************************************************** + Restore the schannel state on a client reconnect. + Note we must be root here. +*******************************************************************************/ + +bool secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx, + const char *remote_machine, + struct dcinfo **ppdc) +{ + TDB_CONTEXT *tdb_sc = NULL; + TDB_DATA value; + unsigned char *pseed_chal = NULL; + unsigned char *pclnt_chal = NULL; + unsigned char *psrv_chal = NULL; + unsigned char *psess_key = NULL; + unsigned char *pmach_pw = NULL; + uint32 l1, l2, l3, l4, l5; + int ret; + struct dcinfo *pdc = NULL; + char *keystr = talloc_asprintf_strupper_m(mem_ctx, "%s/%s", + SECRETS_SCHANNEL_STATE, + remote_machine); + + *ppdc = NULL; + + if (!keystr) { + return False; + } + + tdb_sc = open_schannel_session_store(mem_ctx); + if (!tdb_sc) { + TALLOC_FREE(keystr); + return False; + } + + value = tdb_fetch_bystring(tdb_sc, keystr); + if (!value.dptr) { + DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n", + keystr )); + tdb_close(tdb_sc); + return False; + } + + pdc = TALLOC_ZERO_P(mem_ctx, struct dcinfo); + + /* Retrieve the record. */ + ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff", + &pdc->sequence, + &l1, &pseed_chal, + &l2, &pclnt_chal, + &l3, &psrv_chal, + &l4, &psess_key, + &l5, &pmach_pw, + &pdc->mach_acct, + &pdc->remote_machine, + &pdc->domain); + + if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 16 || l5 != 16) { + /* Bad record - delete it. */ + tdb_delete_bystring(tdb_sc, keystr); + tdb_close(tdb_sc); + TALLOC_FREE(keystr); + TALLOC_FREE(pdc); + SAFE_FREE(pseed_chal); + SAFE_FREE(pclnt_chal); + SAFE_FREE(psrv_chal); + SAFE_FREE(psess_key); + SAFE_FREE(pmach_pw); + SAFE_FREE(value.dptr); + return False; + } + + tdb_close(tdb_sc); + + memcpy(pdc->seed_chal.data, pseed_chal, 8); + memcpy(pdc->clnt_chal.data, pclnt_chal, 8); + memcpy(pdc->srv_chal.data, psrv_chal, 8); + memcpy(pdc->sess_key, psess_key, 16); + memcpy(pdc->mach_pw, pmach_pw, 16); + + /* We know these are true so didn't bother to store them. */ + pdc->challenge_sent = True; + pdc->authenticated = True; + + DEBUG(3,("secrets_restore_schannel_session_info: restored schannel info key %s\n", + keystr )); + + SAFE_FREE(pseed_chal); + SAFE_FREE(pclnt_chal); + SAFE_FREE(psrv_chal); + SAFE_FREE(psess_key); + SAFE_FREE(pmach_pw); + + TALLOC_FREE(keystr); + SAFE_FREE(value.dptr); + + *ppdc = pdc; + + return True; +} + +bool secrets_store_generic(const char *owner, const char *key, const char *secret) { char *tdbkey = NULL; bool ret; @@ -974,7 +1358,7 @@ bool secrets_delete_generic(const char *owner, const char *key) return False; } - ret = secrets_delete(tdbkey); + ret = secrets_store(tdbkey, secret, strlen(secret)+1); SAFE_FREE(tdbkey); return ret; diff --git a/source3/passdb/secrets_schannel.c b/source3/passdb/secrets_schannel.c deleted file mode 100644 index f4da625fc6..0000000000 --- a/source3/passdb/secrets_schannel.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Copyright (C) Guenther Deschner 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "../libcli/auth/libcli_auth.h" -#include "../libcli/auth/schannel_state.h" - -/****************************************************************************** - Open or create the schannel session store tdb. -*******************************************************************************/ - -#define SCHANNEL_STORE_VERSION_1 1 -#define SCHANNEL_STORE_VERSION_2 2 /* should not be used */ -#define SCHANNEL_STORE_VERSION_CURRENT SCHANNEL_STORE_VERSION_1 - -TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx) -{ - TDB_DATA vers; - uint32 ver; - TDB_CONTEXT *tdb_sc = NULL; - char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir()); - - if (!fname) { - return NULL; - } - - tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); - - if (!tdb_sc) { - DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname)); - TALLOC_FREE(fname); - return NULL; - } - - again: - vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION"); - if (vers.dptr == NULL) { - /* First opener, no version. */ - SIVAL(&ver,0,SCHANNEL_STORE_VERSION_CURRENT); - vers.dptr = (uint8 *)&ver; - vers.dsize = 4; - tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE); - vers.dptr = NULL; - } else if (vers.dsize == 4) { - ver = IVAL(vers.dptr,0); - if (ver == SCHANNEL_STORE_VERSION_2) { - DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n", - (int)ver, fname )); - tdb_wipe_all(tdb_sc); - goto again; - } - if (ver != SCHANNEL_STORE_VERSION_CURRENT) { - DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n", - (int)ver, fname )); - tdb_close(tdb_sc); - tdb_sc = NULL; - } - } else { - tdb_close(tdb_sc); - tdb_sc = NULL; - DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n", - (int)vers.dsize, fname )); - } - - SAFE_FREE(vers.dptr); - TALLOC_FREE(fname); - - return tdb_sc; -} - -/****************************************************************************** - Wrapper around schannel_fetch_session_key_tdb() - Note we must be root here. -*******************************************************************************/ - -NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, - const char *computer_name, - struct netlogon_creds_CredentialState **pcreds) -{ - struct tdb_context *tdb; - NTSTATUS status; - - tdb = open_schannel_session_store(mem_ctx); - if (!tdb) { - return NT_STATUS_ACCESS_DENIED; - } - - status = schannel_fetch_session_key_tdb(tdb, mem_ctx, computer_name, pcreds); - - tdb_close(tdb); - - return status; -} - -/****************************************************************************** - Wrapper around schannel_store_session_key_tdb() - Note we must be root here. -*******************************************************************************/ - -NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, - struct netlogon_creds_CredentialState *creds) -{ - struct tdb_context *tdb; - NTSTATUS status; - - tdb = open_schannel_session_store(mem_ctx); - if (!tdb) { - return NT_STATUS_ACCESS_DENIED; - } - - status = schannel_store_session_key_tdb(tdb, mem_ctx, creds); - - tdb_close(tdb); - - return status; -} diff --git a/source3/passdb/util_unixsids.c b/source3/passdb/util_unixsids.c index ad51253058..ad4e70256d 100644 --- a/source3/passdb/util_unixsids.c +++ b/source3/passdb/util_unixsids.c @@ -2,17 +2,17 @@ Unix SMB/CIFS implementation. Translate unix-defined names to SIDs and vice versa Copyright (C) Volker Lendecke 2005 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -31,7 +31,7 @@ bool sid_check_is_in_unix_users(const DOM_SID *sid) sid_copy(&dom_sid, sid); sid_split_rid(&dom_sid, &rid); - + return sid_check_is_unix_users(&dom_sid); } @@ -80,7 +80,7 @@ bool sid_check_is_in_unix_groups(const DOM_SID *sid) sid_copy(&dom_sid, sid); sid_split_rid(&dom_sid, &rid); - + return sid_check_is_unix_groups(&dom_sid); } diff --git a/source3/passdb/util_wellknown.c b/source3/passdb/util_wellknown.c index 2af68b7e7c..3a30ab0a65 100644 --- a/source3/passdb/util_wellknown.c +++ b/source3/passdb/util_wellknown.c @@ -50,7 +50,6 @@ static const struct rid_name_map nt_authority_users[] = { { 4, "Interactive"}, { 6, "Service"}, { 7, "AnonymousLogon"}, - { 7, "Anonymous Logon"}, { 8, "Proxy"}, { 9, "ServerLogon"}, { 10, "Self"}, |