diff options
Diffstat (limited to 'src/responder/pac/pacsrv_utils.c')
-rw-r--r-- | src/responder/pac/pacsrv_utils.c | 478 |
1 files changed, 0 insertions, 478 deletions
diff --git a/src/responder/pac/pacsrv_utils.c b/src/responder/pac/pacsrv_utils.c deleted file mode 100644 index 8d7da341c..000000000 --- a/src/responder/pac/pacsrv_utils.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - SSSD - - PAC Responder - utility finctions - - Copyright (C) Sumit Bose <sbose@redhat.com> 2012 - - 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 <sys/types.h> -#include <stdbool.h> -#include <util/data_blob.h> -#include <gen_ndr/security.h> - -#include "util/util.h" -#include "responder/pac/pacsrv.h" - -errno_t get_sids_from_pac(TALLOC_CTX *mem_ctx, - struct pac_ctx *pac_ctx, - struct PAC_LOGON_INFO *logon_info, - char **_user_sid_str, - char **_primary_group_sid_str, - hash_table_t **_sid_table) -{ - int ret; - size_t s; - struct netr_SamInfo3 *info3; - struct sss_domain_info *user_dom; - struct sss_domain_info *group_dom; - char *sid_str = NULL; - char *msid_str = NULL; - char *user_dom_sid_str = NULL; - size_t user_dom_sid_str_len; - enum idmap_error_code err; - hash_table_t *sid_table = NULL; - hash_key_t key; - hash_value_t value; - char *rid_start; - struct ldb_result *msg = NULL; - char *user_sid_str = NULL; - char *primary_group_sid_str = NULL; - - if (pac_ctx == NULL || logon_info == NULL || _sid_table == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "Missing parameter.\n"); - return EINVAL; - } - - info3 = &logon_info->info3; - - ret = sss_hash_create(mem_ctx, - info3->sidcount + info3->base.groups.count + 2, - &sid_table); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n"); - goto done; - } - - key.type = HASH_KEY_STRING; - value.type = HASH_VALUE_ULONG; - - err = sss_idmap_smb_sid_to_sid(pac_ctx->idmap_ctx, info3->base.domain_sid, - &user_dom_sid_str); - if (err != IDMAP_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "sss_idmap_smb_sid_to_sid failed.\n"); - ret = EFAULT; - goto done; - } - - ret = responder_get_domain_by_id(pac_ctx->rctx, user_dom_sid_str, - &user_dom); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "responder_get_domain_by_id failed.\n"); - ret = EINVAL; - goto done; - } - - user_dom_sid_str_len = strlen(user_dom_sid_str); - sid_str = talloc_zero_size(mem_ctx, user_dom_sid_str_len + 12); - if (sid_str == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n"); - ret = ENOMEM; - goto done; - } - rid_start = sid_str + user_dom_sid_str_len; - - memcpy(sid_str, user_dom_sid_str, user_dom_sid_str_len); - - memset(rid_start, '\0', 12); - ret = snprintf(rid_start, 12, "-%lu", - (unsigned long) info3->base.rid); - if (ret < 0 || ret > 12) { - DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); - ret = EIO; - goto done; - } - - user_sid_str = talloc_strdup(mem_ctx, sid_str); - if (user_sid_str == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); - ret = ENOMEM; - goto done; - } - - key.str = sid_str; - value.ul = 0; - - ret = sysdb_search_object_by_sid(mem_ctx, user_dom, sid_str, NULL, &msg); - if (ret == EOK && msg->count == 1) { - value.ul = ldb_msg_find_attr_as_uint64(msg->msgs[0], SYSDB_UIDNUM, 0); - } - talloc_zfree(msg); - - ret = hash_enter(sid_table, &key, &value); - if (ret != HASH_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", - ret, hash_error_string(ret)); - ret = EIO; - goto done; - } - - - memset(rid_start, '\0', 12); - ret = snprintf(rid_start, 12, "-%lu", - (unsigned long) info3->base.primary_gid); - if (ret < 0 || ret > 12) { - DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); - ret = EIO; - goto done; - } - - primary_group_sid_str = talloc_strdup(mem_ctx, sid_str); - if (primary_group_sid_str == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); - ret = ENOMEM; - goto done; - } - - key.str = sid_str; - value.ul = 0; - - ret = sysdb_search_object_by_sid(mem_ctx, user_dom, sid_str, NULL, &msg); - if (ret == EOK && msg->count == 1) { - value.ul = ldb_msg_find_attr_as_uint64(msg->msgs[0], SYSDB_GIDNUM, 0); - } - talloc_zfree(msg); - - ret = hash_enter(sid_table, &key, &value); - if (ret != HASH_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", - ret, hash_error_string(ret)); - ret = EIO; - goto done; - } - - - for (s = 0; s < info3->base.groups.count; s++) { - memset(rid_start, '\0', 12); - ret = snprintf(rid_start, 12, "-%lu", - (unsigned long) info3->base.groups.rids[s].rid); - if (ret < 0 || ret > 12) { - DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); - ret = EIO; - goto done; - } - - key.str = sid_str; - value.ul = 0; - - ret = sysdb_search_object_by_sid(mem_ctx, user_dom, sid_str, - NULL, &msg); - if (ret == EOK && msg->count == 1) { - value.ul = ldb_msg_find_attr_as_uint64(msg->msgs[0], - SYSDB_GIDNUM, 0); - } - talloc_zfree(msg); - - ret = hash_enter(sid_table, &key, &value); - if (ret != HASH_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", - ret, hash_error_string(ret)); - ret = EIO; - goto done; - } - - } - - for(s = 0; s < info3->sidcount; s++) { - err = sss_idmap_smb_sid_to_sid(pac_ctx->idmap_ctx, info3->sids[s].sid, - &msid_str); - if (err != IDMAP_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "sss_idmap_smb_sid_to_sid failed.\n"); - ret = EFAULT; - goto done; - } - - key.str = msid_str; - value.ul = 0; - - ret = responder_get_domain_by_id(pac_ctx->rctx, msid_str, &group_dom); - if (ret == EOK) { - ret = sysdb_search_object_by_sid(mem_ctx, group_dom, msid_str, - NULL, &msg); - if (ret == EOK && msg->count == 1 ) { - value.ul = ldb_msg_find_attr_as_uint64(msg->msgs[0], - SYSDB_GIDNUM, 0); - } - talloc_zfree(msg); - } - - ret = hash_enter(sid_table, &key, &value); - sss_idmap_free_sid(pac_ctx->idmap_ctx, msid_str); - if (ret != HASH_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", - ret, hash_error_string(ret)); - ret = EIO; - goto done; - } - } - - ret = EOK; - -done: - talloc_free(sid_str); - sss_idmap_free_sid(pac_ctx->idmap_ctx, user_dom_sid_str); - - if (ret == EOK) { - *_sid_table = sid_table; - *_user_sid_str = user_sid_str; - *_primary_group_sid_str = primary_group_sid_str; - } else { - hash_destroy(sid_table); - talloc_free(user_sid_str); - talloc_free(primary_group_sid_str); - } - - return ret; -} - -/** - * Extract the PAC logon data from an NDR blob. - */ -errno_t get_data_from_pac(TALLOC_CTX *mem_ctx, - uint8_t *pac_blob, size_t pac_len, - struct PAC_LOGON_INFO **_logon_info) -{ - DATA_BLOB blob; - struct ndr_pull *ndr_pull; - struct PAC_DATA *pac_data; - enum ndr_err_code ndr_err; - size_t c; - int ret; - - blob.data = pac_blob; - blob.length = pac_len; - - ndr_pull = ndr_pull_init_blob(&blob, mem_ctx); - if (ndr_pull == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ndr_pull_init_blob failed.\n"); - return ENOMEM; - } - ndr_pull->flags |= LIBNDR_FLAG_REF_ALLOC; /* FIXME: is this really needed ? */ - - pac_data = talloc_zero(mem_ctx, struct PAC_DATA); - if (pac_data == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); - return ENOMEM; - } - - ndr_err = ndr_pull_PAC_DATA(ndr_pull, NDR_SCALARS|NDR_BUFFERS, pac_data); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DEBUG(SSSDBG_OP_FAILURE, "ndr_pull_PAC_DATA failed [%d]\n", ndr_err); - return EBADMSG; - } - - for(c = 0; c < pac_data->num_buffers; c++) { - if (pac_data->buffers[c].type == PAC_TYPE_LOGON_INFO) { - *_logon_info = pac_data->buffers[c].info->logon_info.info; - - return EOK; - } - } - - ret = EINVAL; - - talloc_free(pac_data); - return ret; -} - -/** - * Fill up the passwd struct with data from the PAC logon info - */ -errno_t get_pwd_from_pac(TALLOC_CTX *mem_ctx, - struct sss_domain_info *dom, - char *user_sid_str, - char *primary_group_sid_str, - hash_table_t *sid_table, - struct PAC_LOGON_INFO *logon_info, - struct passwd **_pwd, - struct sysdb_attrs **_attrs) -{ - struct passwd *pwd = NULL; - struct sysdb_attrs *attrs = NULL; - struct netr_SamBaseInfo *base_info; - int ret; - char *lname; - char *uc_realm; - char *upn; - hash_key_t key; - hash_value_t value; - struct sss_nss_homedir_ctx homedir_ctx; - - pwd = talloc_zero(mem_ctx, struct passwd); - if (pwd == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); - return ENOMEM; - } - - base_info = &logon_info->info3.base; - - if (base_info->account_name.size == 0) { - DEBUG(SSSDBG_OP_FAILURE, "Missing account name in PAC.\n"); - ret = EINVAL; - goto done; - } - if (base_info->rid == 0) { - DEBUG(SSSDBG_OP_FAILURE, "Missing user RID in PAC.\n"); - ret = EINVAL; - goto done; - } - - /* To be compatible with winbind based lookups we have to use lower - * case names only, effectively making the domain case-insenvitive. */ - lname = sss_tc_utf8_str_tolower(pwd, base_info->account_name.string); - if (lname == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "sss_tc_utf8_str_tolower failed.\n"); - ret = ENOMEM; - goto done; - } - - /* Subdomain use fully qualified names */ - pwd->pw_name = sss_get_domain_name(pwd, lname, dom); - if (!pwd->pw_name) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_sprintf failed.\n"); - ret = ENOMEM; - goto done; - } - - key.type = HASH_KEY_STRING; - key.str = user_sid_str; - ret = hash_lookup(sid_table, &key, &value); - if (ret != HASH_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "hash_lookup failed.\n"); - ret = EIO; - goto done; - } - if (value.type != HASH_VALUE_ULONG) { - DEBUG(SSSDBG_OP_FAILURE, "Wrong value type.\n"); - ret = EIO; - goto done; - } - pwd->pw_uid = value.ul; - - if (IS_SUBDOMAIN(dom) || dom->mpg) { - pwd->pw_gid = 0; /* We use MPGs for sub-domains */ - } else { - key.type = HASH_KEY_STRING; - key.str = primary_group_sid_str; - ret = hash_lookup(sid_table, &key, &value); - if (ret != HASH_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "hash_lookup failed.\n"); - ret = EIO; - goto done; - } - if (value.type != HASH_VALUE_ULONG) { - DEBUG(SSSDBG_OP_FAILURE, "Wrong value type.\n"); - ret = EIO; - goto done; - } - pwd->pw_gid = value.ul; - } - - if (base_info->full_name.size != 0) { - pwd->pw_gecos = talloc_strdup(pwd, base_info->full_name.string); - if (pwd->pw_gecos == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); - ret = ENOMEM; - goto done; - } - } else { - DEBUG(SSSDBG_OP_FAILURE, - "Missing full name in PAC, gecos field will by empty.\n"); - } - - /* Check if there is a special homedir template for sub-domains. If not a - * fallback will be added by the NSS responder. */ - if (IS_SUBDOMAIN(dom) && dom->subdomain_homedir) { - ZERO_STRUCT(homedir_ctx); - - homedir_ctx.username = lname; - homedir_ctx.uid = pwd->pw_uid; - homedir_ctx.domain = dom->name; - homedir_ctx.flatname = dom->flat_name; - homedir_ctx.config_homedir_substr = dom->homedir_substr; - - pwd->pw_dir = expand_homedir_template(pwd, dom->subdomain_homedir, - &homedir_ctx); - if (pwd->pw_dir == NULL) { - ret = ENOMEM; - goto done; - } - } - - pwd->pw_shell = NULL; /* Using default */ - - attrs = sysdb_new_attrs(mem_ctx); - if (attrs == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n"); - ret = ENOMEM; - goto done; - } - - uc_realm = get_uppercase_realm(mem_ctx, dom->name); - if (uc_realm == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n"); - ret = ENOMEM; - goto done; - } - - upn = talloc_asprintf(mem_ctx, "%s@%s", lname, uc_realm); - talloc_free(uc_realm); - if (upn == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); - ret = ENOMEM; - goto done; - } - - ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, upn); - talloc_free(upn); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); - goto done; - } - - ret = sysdb_attrs_add_lc_name_alias(attrs, pwd->pw_name); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_lc_name_alias failed.\n"); - goto done; - } - - ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, user_sid_str); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); - goto done; - } - - *_pwd = pwd; - *_attrs = attrs; - - ret = EOK; - -done: - if (ret != EOK) { - talloc_free(pwd); - } - - return ret; -} |