diff options
Diffstat (limited to 'source3/passdb')
-rw-r--r-- | source3/passdb/pdb_ads.c | 2693 | ||||
-rw-r--r-- | source3/passdb/wscript_build | 9 |
2 files changed, 0 insertions, 2702 deletions
diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c deleted file mode 100644 index df9b7b3a95..0000000000 --- a/source3/passdb/pdb_ads.c +++ /dev/null @@ -1,2693 +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" -#include "passdb.h" -#include "tldap.h" -#include "tldap_util.h" -#include "../libds/common/flags.h" -#include "secrets.h" -#include "../librpc/gen_ndr/samr.h" -#include "../librpc/gen_ndr/idmap.h" -#include "../libcli/ldap/ldap_ndr.h" -#include "../libcli/security/security.h" -#include "../libds/common/flag_mapping.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 bool pdb_ads_gid_to_sid(struct pdb_methods *m, gid_t gid, - struct 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 = nt_time_to_unix(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 = ldap_encode_ndr_dom_sid(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; - uint32_t i; - 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); - } - - str = tldap_talloc_single_attribute(entry, "comment", - talloc_tos()); - if (str != NULL) { - pdb_set_comment(sam, str, PDB_SET); - } - - str = tldap_talloc_single_attribute(entry, "description", - talloc_tos()); - if (str != NULL) { - pdb_set_acct_desc(sam, str, PDB_SET); - } - - str = tldap_talloc_single_attribute(entry, "userWorkstations", - talloc_tos()); - if (str != NULL) { - pdb_set_workstations(sam, str, PDB_SET); - } - - str = tldap_talloc_single_attribute(entry, "userParameters", - talloc_tos()); - if (str != NULL) { - pdb_set_munged_dial(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); - - } - - if (tldap_pull_uint32(entry, "countryCode", &i)) { - pdb_set_country_code(sam, i, PDB_SET); - } - - if (tldap_pull_uint32(entry, "codePage", &i)) { - pdb_set_code_page(sam, i, PDB_SET); - } - - if (tldap_get_single_valueblob(entry, "logonHours", &blob)) { - - if (blob.length > MAX_HOURS_LEN) { - status = NT_STATUS_INVALID_PARAMETER; - goto fail; - } - pdb_set_logon_divs(sam, blob.length * 8, PDB_SET); - pdb_set_hours_len(sam, blob.length, PDB_SET); - pdb_set_hours(sam, blob.data, blob.length, PDB_SET); - - } else { - uint8_t hours[21]; - pdb_set_logon_divs(sam, sizeof(hours)/8, PDB_SET); - pdb_set_hours_len(sam, sizeof(hours), PDB_SET); - memset(hours, 0xff, sizeof(hours)); - pdb_set_hours(sam, hours, sizeof(hours), PDB_SET); - } - - status = NT_STATUS_OK; -fail: - TALLOC_FREE(frame); - return status; -} - -static bool pdb_ads_make_time_mod(struct tldap_message *existing, - TALLOC_CTX *mem_ctx, - struct tldap_mod **pmods, int *pnum_mods, - const char *attrib, time_t t) -{ - uint64_t nt_time; - - unix_to_nt_time(&nt_time, t); - - return tldap_make_mod_fmt( - existing, mem_ctx, pmods, pnum_mods, attrib, - "%llu", nt_time); -} - -static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state, - struct tldap_message *existing, - TALLOC_CTX *mem_ctx, - struct tldap_mod **pmods, int *pnum_mods, - struct samu *sam) -{ - bool ret = true; - DATA_BLOB blob; - const char *pw; - - /* TODO: All fields :-) */ - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pmods, pnum_mods, "displayName", - "%s", pdb_get_fullname(sam)); - - pw = pdb_get_plaintext_passwd(sam); - - /* - * If we have the plain text pw, this is probably about to be - * set. Is this true always? - */ - if (pw != NULL) { - char *pw_quote; - uint8_t *pw_utf16; - size_t pw_utf16_len; - - pw_quote = talloc_asprintf(talloc_tos(), "\"%s\"", pw); - if (pw_quote == NULL) { - ret = false; - goto fail; - } - - ret &= convert_string_talloc(talloc_tos(), - CH_UNIX, CH_UTF16LE, - pw_quote, strlen(pw_quote), - &pw_utf16, &pw_utf16_len); - if (!ret) { - goto fail; - } - blob = data_blob_const(pw_utf16, pw_utf16_len); - - ret &= tldap_add_mod_blobs(mem_ctx, pmods, pnum_mods, - TLDAP_MOD_REPLACE, - "unicodePwd", &blob, 1); - TALLOC_FREE(pw_utf16); - TALLOC_FREE(pw_quote); - } - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pmods, pnum_mods, "userAccountControl", - "%d", ds_acb2uf(pdb_get_acct_ctrl(sam))); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pmods, pnum_mods, "homeDirectory", - "%s", pdb_get_homedir(sam)); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pmods, pnum_mods, "homeDrive", - "%s", pdb_get_dir_drive(sam)); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pmods, pnum_mods, "scriptPath", - "%s", pdb_get_logon_script(sam)); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pmods, pnum_mods, "profilePath", - "%s", pdb_get_profile_path(sam)); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pmods, pnum_mods, "comment", - "%s", pdb_get_comment(sam)); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pmods, pnum_mods, "description", - "%s", pdb_get_acct_desc(sam)); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pmods, pnum_mods, "userWorkstations", - "%s", pdb_get_workstations(sam)); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pmods, pnum_mods, "userParameters", - "%s", pdb_get_munged_dial(sam)); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pmods, pnum_mods, "countryCode", - "%i", (int)pdb_get_country_code(sam)); - - ret &= tldap_make_mod_fmt( - existing, mem_ctx, pmods, pnum_mods, "codePage", - "%i", (int)pdb_get_code_page(sam)); - - ret &= pdb_ads_make_time_mod( - existing, mem_ctx, pmods, pnum_mods, "accountExpires", - (int)pdb_get_kickoff_time(sam)); - - ret &= tldap_make_mod_blob( - existing, mem_ctx, pmods, pnum_mods, "logonHours", - data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam))); - -fail: - 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_NO_SUCH_USER; - } - - 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 struct dom_sid *sid) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - char *sidstr, *filter; - - sidstr = ldap_encode_ndr_dom_sid(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(), &mods, &num_mods, "objectClass", "user"); - ok &= tldap_make_mod_fmt( - NULL, talloc_tos(), &mods, &num_mods, "samAccountName", "%s", - name); - if (!ok) { - return NT_STATUS_NO_MEMORY; - } - - - rc = tldap_add(ld, dn, mods, num_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(), - &mods, &num_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, mods, num_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, - TALLOC_CTX *mem_ctx, - struct tldap_message **pmsg) -{ - 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 group, 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; - } - map->nt_name = talloc_move(map, &str); - - str = tldap_talloc_single_attribute(group[0], "description", - talloc_tos()); - if (str != NULL) { - map->comment = talloc_move(map, &str); - } else { - map->comment = talloc_strdup(map, ""); - } - - if (pmsg != NULL) { - *pmsg = talloc_move(mem_ctx, &group[0]); - } - TALLOC_FREE(group); - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_getgrsid(struct pdb_methods *m, GROUP_MAP *map, - struct 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, NULL, NULL); - 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, NULL, NULL); - 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(), &mods, &num_mods, "samAccountName", "%s", - name); - ok &= tldap_make_mod_fmt( - NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group"); - ok &= tldap_make_mod_fmt( - NULL, talloc_tos(), &mods, &num_mods, "groupType", - "%d", (int)GTYPE_SECURITY_GLOBAL_GROUP); - - if (!ok) { - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; - } - - rc = tldap_add(ld, dn, mods, num_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 = ldap_encode_ndr_dom_sid(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) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - struct tldap_context *ld; - struct tldap_mod *mods = NULL; - char *filter; - struct tldap_message *existing; - char *dn; - GROUP_MAP *existing_map; - int rc, num_mods = 0; - bool ret; - NTSTATUS status; - - ld = pdb_ads_ld(state); - if (ld == NULL) { - return NT_STATUS_LDAP(TLDAP_SERVER_DOWN); - } - - filter = talloc_asprintf(talloc_tos(), - "(&(objectsid=%s)(objectclass=group))", - sid_string_talloc(talloc_tos(), &map->sid)); - if (filter == NULL) { - return NT_STATUS_NO_MEMORY; - } - - existing_map = talloc_zero(talloc_tos(), GROUP_MAP); - if (!existing_map) { - return NT_STATUS_NO_MEMORY; - } - - status = pdb_ads_getgrfilter(m, existing_map, filter, - talloc_tos(), &existing); - TALLOC_FREE(existing_map); - TALLOC_FREE(filter); - - if (!tldap_entry_dn(existing, &dn)) { - return NT_STATUS_LDAP(TLDAP_DECODING_ERROR); - } - - ret = true; - - ret &= tldap_make_mod_fmt( - existing, talloc_tos(), &mods, &num_mods, "description", - "%s", map->comment); - ret &= tldap_make_mod_fmt( - existing, talloc_tos(), &mods, &num_mods, "samaccountname", - "%s", map->nt_name); - - if (!ret) { - return NT_STATUS_NO_MEMORY; - } - - if (num_mods == 0) { - TALLOC_FREE(existing); - return NT_STATUS_OK; - } - - rc = tldap_modify(ld, dn, mods, num_mods, NULL, 0, NULL, 0); - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("ldap_modify for %s failed: %s\n", dn, - tldap_errstr(talloc_tos(), ld, rc))); - TALLOC_FREE(existing); - return NT_STATUS_LDAP(rc); - } - TALLOC_FREE(existing); - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_delete_group_mapping_entry(struct pdb_methods *m, - struct dom_sid sid) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_ads_enum_group_mapping(struct pdb_methods *m, - const struct 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 struct 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 = ldap_encode_ndr_dom_sid(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", &blobs, &num_members)) { - *pmembers = NULL; - *pnum_members = 0; - return NT_STATUS_OK; - } - - 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, - struct dom_sid **pp_sids, - gid_t **pp_gids, - uint32_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; - 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; - - priv = pdb_ads_get_samu_private(m, user); - if (priv != NULL) { - 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); - } else { - /* - * This happens for artificial samu users - */ - DEBUG(10, ("Could not get pdb_ads_samu_private\n")); - count = 0; - } - - group_sids = talloc_array(mem_ctx, struct dom_sid, count+1); - if (group_sids == NULL) { - return NT_STATUS_NO_MEMORY; - } - gids = talloc_array(mem_ctx, gid_t, count+1); - if (gids == NULL) { - TALLOC_FREE(group_sids); - return NT_STATUS_NO_MEMORY; - } - - sid_copy(&group_sids[0], pdb_get_group_sid(user)); - if (!sid_to_gid(&group_sids[0], &gids[0])) { - TALLOC_FREE(gids); - TALLOC_FREE(group_sids); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - num_groups = 1; - - 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 num_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; - num_mods = 0; - - if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op, - "member", memberdn)) { - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; - } - - rc = tldap_modify(ld, groupdn, mods, num_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 ((mod_op == TLDAP_MOD_ADD) && - (rc == TLDAP_ALREADY_EXISTS)) { - return NT_STATUS_MEMBER_IN_GROUP; - } - if ((mod_op == TLDAP_MOD_DELETE) && - (rc == TLDAP_UNWILLING_TO_PERFORM)) { - 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(), &mods, &num_mods, "samAccountName", "%s", - name); - ok &= tldap_make_mod_fmt( - NULL, talloc_tos(), &mods, &num_mods, "objectClass", "group"); - ok &= tldap_make_mod_fmt( - NULL, talloc_tos(), &mods, &num_mods, "groupType", - "%d", (int)GTYPE_SECURITY_DOMAIN_LOCAL_GROUP); - - if (!ok) { - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; - } - - rc = tldap_add(ld, dn, mods, num_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 struct 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 = NULL; - int rc; - - ld = pdb_ads_ld(state); - if (ld == NULL) { - return NT_STATUS_LDAP(TLDAP_SERVER_DOWN); - } - - sidstr = ldap_encode_ndr_dom_sid(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))); - 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))); - return NT_STATUS_LDAP(rc); - } - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_ads_set_aliasinfo(struct pdb_methods *m, - const struct 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 = ldap_encode_ndr_dom_sid(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, &mods, &num_mods, "description", - "%s", info->acct_desc); - ok &= tldap_make_mod_fmt( - msg[0], msg, &mods, &num_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, mods, num_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 = ldap_encode_ndr_dom_sid(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 struct dom_sid *alias, - const struct 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 num_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; - num_mods = 0; - - if (!tldap_add_mod_str(talloc_tos(), &mods, &num_mods, mod_op, - "member", memberdn)) { - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; - } - - rc = tldap_modify(ld, aliasdn, mods, num_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 struct dom_sid *alias, - const struct 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 struct dom_sid *alias, - const struct 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)) { - 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 struct dom_sid *alias, - TALLOC_CTX *mem_ctx, - struct 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 = ldap_encode_ndr_dom_sid(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", &blobs, &num_members)) { - *pmembers = NULL; - *pnum_members = 0; - return NT_STATUS_OK; - } - - 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 struct dom_sid *domain_sid, - const struct 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 = NULL; - 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 struct 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 = ldap_encode_ndr_dom_sid(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 struct 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, - uint32_t acct_flags, - 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; - } - sstate->acct_flags = acct_flags; - - 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; - uint32_t ctrl; - - 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); - - if (tldap_pull_uint32(users[i], "userAccountControl", &ctrl)) { - - e->acct_flags = ds_uf2acb(ctrl); - - DEBUG(10, ("pdb_ads_search_filter: Found %x, " - "filter %x\n", (int)e->acct_flags, - (int)sstate->acct_flags)); - - - if ((sstate->acct_flags != 0) && - ((sstate->acct_flags & e->acct_flags) == 0)) { - continue; - } - - if (e->acct_flags & (ACB_WSTRUST|ACB_SVRTRUST)) { - e->acct_flags |= ACB_NORMAL; - } - } else { - e->acct_flags = ACB_NORMAL; - } - - if (e->rid == DOMAIN_RID_GUEST) { - /* - * Guest is specially crafted in s3. Make - * QueryDisplayInfo match QueryUserInfo - */ - e->account_name = lp_guestaccount(); - e->fullname = lp_guestaccount(); - e->description = ""; - e->acct_flags = ACB_NORMAL; - } else { - e->account_name = tldap_talloc_single_attribute( - users[i], "samAccountName", sstate->entries); - e->fullname = tldap_talloc_single_attribute( - users[i], "displayName", sstate->entries); - e->description = tldap_talloc_single_attribute( - users[i], "description", sstate->entries); - } - if (e->account_name == NULL) { - return false; - } - if (e->fullname == NULL) { - e->fullname = ""; - } - 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; - char *filter; - bool ret; - - DEBUG(10, ("pdb_ads_search_users got flags %x\n", acct_flags)); - - if (acct_flags & ACB_NORMAL) { - filter = talloc_asprintf( - talloc_tos(), - "(&(objectclass=user)(sAMAccountType=%d))", - ATYPE_NORMAL_ACCOUNT); - } else if (acct_flags & ACB_WSTRUST) { - filter = talloc_asprintf( - talloc_tos(), - "(&(objectclass=user)(sAMAccountType=%d))", - ATYPE_WORKSTATION_TRUST); - } else { - filter = talloc_strdup(talloc_tos(), "(objectclass=user)"); - } - if (filter == NULL) { - return false; - } - - ret = pdb_ads_search_filter(m, search, filter, acct_flags, &sstate); - TALLOC_FREE(filter); - if (!ret) { - return false; - } - 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, 0, &sstate); - TALLOC_FREE(filter); - if (!ret) { - return false; - } - return true; -} - -static bool pdb_ads_search_aliases(struct pdb_methods *m, - struct pdb_search *search, - const struct 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, 0, &sstate); - TALLOC_FREE(filter); - if (!ret) { - return false; - } - return true; -} - -static bool pdb_ads_uid_to_sid(struct pdb_methods *m, uid_t uid, - struct 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, - struct 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 struct dom_sid *sid, - struct unixid *id) -{ - struct pdb_ads_state *state = talloc_get_type_abort( - m->private_data, struct pdb_ads_state); - const char *attrs[4] = { "objectClass", "samAccountType", - "uidNumber", "gidNumber" }; - struct tldap_message **msg; - char *sidstr, *base; - uint32_t atype; - int rc; - bool ret = false; - - id->id = -1; - id->type = ID_TYPE_NOT_SPECIFIED; - - sidstr = sid_binstring_hex(sid); - if (sidstr == NULL) { - return false; - } - base = talloc_asprintf(talloc_tos(), "<SID=%s>", sidstr); - SAFE_FREE(sidstr); - - rc = pdb_ads_search_fmt( - state, base, TLDAP_SCOPE_BASE, - attrs, ARRAY_SIZE(attrs), 0, talloc_tos(), &msg, - "(objectclass=*)"); - TALLOC_FREE(base); - - if (rc != TLDAP_SUCCESS) { - DEBUG(10, ("pdb_ads_search_fmt failed: %s\n", - tldap_errstr(talloc_tos(), state->ld, rc))); - return false; - } - if (talloc_array_length(msg) != 1) { - DEBUG(10, ("Got %d objects, expected 1\n", - (int)talloc_array_length(msg))); - goto fail; - } - if (!tldap_pull_uint32(msg[0], "samAccountType", &atype)) { - DEBUG(10, ("samAccountType not found\n")); - goto fail; - } - if (atype == ATYPE_ACCOUNT) { - uid_t uid; - id->type = ID_TYPE_UID; - if (!tldap_pull_uint32(msg[0], "uidNumber", &uid)) { - DEBUG(10, ("Did not find uidNumber\n")); - goto fail; - } - id->id = uid; - } else { - gid_t gid; - id->type = ID_TYPE_GID; - if (!tldap_pull_uint32(msg[0], "gidNumber", &gid)) { - DEBUG(10, ("Did not find gidNumber\n")); - goto fail; - } - id->id = gid; - } - ret = true; -fail: - TALLOC_FREE(msg); - return ret; -} - -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, - struct 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 struct 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; - strlcpy(state->socket_address.sun_path, location, - sizeof(state->socket_address.sun_path)); - - 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->configdn == 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_ads_init_secrets(struct pdb_methods *m) -{ -#if _SAMBA_BUILD_ == 4 - struct pdb_domain_info *dom_info; - bool ret; - - dom_info = pdb_ads_get_domain_info(m, m); - if (!dom_info) { - return NT_STATUS_UNSUCCESSFUL; - } - - secrets_clear_domain_protection(dom_info->name); - ret = secrets_store_domain_sid(dom_info->name, - &dom_info->sid); - if (!ret) { - goto done; - } - ret = secrets_store_domain_guid(dom_info->name, - &dom_info->guid); - if (!ret) { - goto done; - } - ret = secrets_mark_domain_protected(dom_info->name); - if (!ret) { - goto done; - } - -done: - TALLOC_FREE(dom_info); - if (!ret) { - return NT_STATUS_UNSUCCESSFUL; - } -#endif - return NT_STATUS_OK; -} - -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(NULL, 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; - } - - status = pdb_ads_init_secrets(m); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("pdb_ads_init_secrets failed!\n")); - 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/wscript_build b/source3/passdb/wscript_build index 59a7f80697..2a39b10eea 100644 --- a/source3/passdb/wscript_build +++ b/source3/passdb/wscript_build @@ -2,7 +2,6 @@ PDB_TDBSAM_SRC = 'pdb_tdb.c' PDB_LDAP_SRC = 'pdb_ldap.c pdb_nds.c pdb_ipa.c pdb_ldap_util.c' -PDB_ADS_SRC = 'pdb_ads.c' PDB_SMBPASSWD_SRC = 'pdb_smbpasswd.c' PDB_WBC_SAM_SRC = 'pdb_wbc_sam.c' @@ -22,14 +21,6 @@ bld.SAMBA3_MODULE('pdb_ldap', internal_module=bld.SAMBA3_IS_STATIC_MODULE('pdb_ldap'), enabled=bld.SAMBA3_IS_ENABLED_MODULE('pdb_ldap') and bld.env.HAVE_LDAP) -bld.SAMBA3_MODULE('pdb_ads', - subsystem='pdb', - source=PDB_ADS_SRC, - deps='cli-ldap-common TLDAP', - init_function='', - internal_module=bld.SAMBA3_IS_STATIC_MODULE('pdb_ads'), - enabled=bld.SAMBA3_IS_ENABLED_MODULE('pdb_ads')) - bld.SAMBA3_MODULE('pdb_smbpasswd', subsystem='pdb', source=PDB_SMBPASSWD_SRC, |