diff options
Diffstat (limited to 'src/responder')
-rw-r--r-- | src/responder/nss/nsssrv_cmd.c | 83 | ||||
-rw-r--r-- | src/responder/pac/pacsrv_cmd.c | 18 | ||||
-rw-r--r-- | src/responder/pam/pam_LOCAL_domain.c | 39 | ||||
-rw-r--r-- | src/responder/pam/pamsrv_cmd.c | 71 |
4 files changed, 142 insertions, 69 deletions
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index d6ac9dc28..b1d4345a2 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -350,7 +350,7 @@ static int fill_pwent(struct sss_packet *packet, size_t rsize, rp, blen; int fq_len = 0; int i, ret, num; - bool add_domain = (!IS_SUBDOMAIN(dom) && dom->fqnames); + bool add_domain = dom->fqnames; const char *domain = dom->name; bool packet_initialized = false; int ncret; @@ -2734,6 +2734,8 @@ void nss_update_gr_memcache(struct nss_ctx *nctx) #define MNUM_ROFFSET sizeof(uint32_t) #define STRS_ROFFSET 2*sizeof(uint32_t) +/* member can be from memberuid or ghost attribute. Both are stored + * in the internal fqname format (name@domain) */ static int parse_member(TALLOC_CTX *mem_ctx, struct sss_domain_info *group_dom, const char *member, struct sss_domain_info **_member_dom, struct sized_string *_name, bool *_add_domain) @@ -2744,40 +2746,51 @@ static int parse_member(TALLOC_CTX *mem_ctx, struct sss_domain_info *group_dom, const char *use_member; struct sss_domain_info *member_dom; bool add_domain; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } - ret = sss_parse_name(mem_ctx, group_dom->names, member, &domname, &username); + ret = sss_parse_internal_fqname(tmp_ctx, member, &username, &domname); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not parse [%s] into " - "name-value components.\n", member); - return ret; + "shortname and domain name components.\n", member); + goto done; } - add_domain = (!IS_SUBDOMAIN(group_dom) && group_dom->fqnames); - use_member = member; - member_dom = group_dom; + add_domain = group_dom->fqnames; + use_member = username; + member_dom = find_domain_by_name(group_dom, domname, true); + if (member_dom == NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, "Could not find domain '%s'\n", domname); + ret = ERR_DOMAIN_NOT_FOUND; + goto done; + } - if (IS_SUBDOMAIN(group_dom) == false && domname != NULL) { + if (IS_SUBDOMAIN(group_dom) == false && IS_SUBDOMAIN(member_dom) == true) { /* The group is stored in the parent domain, but the member comes from. - * a subdomain. No need to add the domain component, it's already - * present in the memberuid/ghost attribute - */ - add_domain = false; + * a subdomain. */ + add_domain = true; } - if (IS_SUBDOMAIN(group_dom) == true && domname == NULL) { + if (IS_SUBDOMAIN(group_dom) == true && IS_SUBDOMAIN(member_dom) == false) { /* The group is stored in a subdomain, but the member comes * from the parent domain. Need to add the domain component * of the parent domain */ add_domain = true; - use_member = username; - member_dom = group_dom->parent; } to_sized_string(_name, use_member); *_add_domain = add_domain; *_member_dom = member_dom; - return EOK; + + ret = EOK; +done: + talloc_free(tmp_ctx); + return ret; } static int fill_members(struct sss_packet *packet, @@ -2842,7 +2855,8 @@ static int fill_members(struct sss_packet *packet, } } - ret = parse_member(tmp_ctx, dom, tmpstr, &member_dom, &name, &add_domain); + ret = parse_member(tmp_ctx, dom, tmpstr, &member_dom, &name, + &add_domain); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not process member %s, skipping\n", tmpstr); @@ -2923,7 +2937,7 @@ static int fill_grent(struct sss_packet *packet, int i = 0; int ret, num, memnum; size_t rzero, rsize; - bool add_domain = (!IS_SUBDOMAIN(dom) && dom->fqnames); + bool add_domain = dom->fqnames; const char *domain = dom->name; TALLOC_CTX *tmp_ctx = NULL; @@ -4594,26 +4608,21 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx) goto done; } - /* For subdomains a fully qualified name is needed for - * sysdb_search_user_by_name and sysdb_search_group_by_name. */ - if (IS_SUBDOMAIN(dom)) { - sysdb_name = sss_tc_fqname(cmdctx, dom->names, dom, name); - if (sysdb_name == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); - ret = ENOMEM; - goto done; - } + sysdb_name = sss_ioname2internal(cmdctx, dom, name); + if (sysdb_name == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "failed to parse name '%s'.\n", name); + ret = ENOMEM; + goto done; } - /* verify this name has not yet been negatively cached, as user * and groupm, or has been permanently filtered */ ret = sss_ncache_check_user(nctx->ncache, nctx->neg_timeout, - dom, name); + dom, sysdb_name); if (ret == EEXIST) { ret = sss_ncache_check_group(nctx->ncache, nctx->neg_timeout, - dom, name); + dom, sysdb_name); if (ret == EEXIST) { /* if neg cached, return we didn't find it */ DEBUG(SSSDBG_TRACE_FUNC, @@ -4685,9 +4694,8 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx) } } } else { - ret = sysdb_search_user_by_name(cmdctx, dom, - sysdb_name ? sysdb_name : name, - attrs, &msg); + ret = sysdb_search_user_by_name(cmdctx, dom, sysdb_name, attrs, + &msg); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); @@ -4699,8 +4707,7 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx) user_found = true; } else { talloc_free(msg); - ret = sysdb_search_group_by_name(cmdctx, dom, - sysdb_name ? sysdb_name : name, + ret = sysdb_search_group_by_name(cmdctx, dom, sysdb_name, attrs, &msg); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -4736,13 +4743,13 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx) if (dctx->res->count == 0 && !dctx->check_provider) { if (cmdctx->cmd == SSS_NSS_GETSIDBYNAME || cmdctx->cmd == SSS_NSS_GETORIGBYNAME) { - ret = sss_ncache_set_user(nctx->ncache, false, dom, name); + ret = sss_ncache_set_user(nctx->ncache, false, dom, sysdb_name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for %s@%s\n", name, dom->name); } - ret = sss_ncache_set_group(nctx->ncache, false, dom, name); + ret = sss_ncache_set_group(nctx->ncache, false, dom, sysdb_name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for %s@%s\n", name, dom->name); @@ -4766,7 +4773,7 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx) req_name = NULL; req_id = cmdctx->id; } else { - req_name = name; + req_name = sysdb_name; req_id = 0; } if (user_found) { diff --git a/src/responder/pac/pacsrv_cmd.c b/src/responder/pac/pacsrv_cmd.c index 64c02e81c..e5b45a72f 100644 --- a/src/responder/pac/pacsrv_cmd.c +++ b/src/responder/pac/pacsrv_cmd.c @@ -583,6 +583,8 @@ static errno_t save_pac_user(struct pac_req_ctx *pr_ctx) ret = sysdb_search_user_by_uid(tmp_ctx, pr_ctx->dom, pwd->pw_uid, attrs, &msg); if (ret == ENOENT) { + char *name; + if (pwd->pw_gid == 0 && !pr_ctx->dom->mpg) { DEBUG(SSSDBG_CRIT_FAILURE, "Primary group RID from the PAC " "cannot be translated into a GID for " @@ -598,6 +600,12 @@ static errno_t save_pac_user(struct pac_req_ctx *pr_ctx) goto done; } + name = sss_ioname2internal(tmp_ctx, pr_ctx->dom, pwd->pw_name); + if (name == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "failed to format name for '%s'.\n", + pwd->pw_name); + goto done; + } ret = sysdb_store_user(pr_ctx->dom, pwd->pw_name, NULL, pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir, @@ -636,7 +644,7 @@ struct tevent_req *pac_save_memberships_send(struct pac_req_ctx *pr_ctx) struct sss_domain_info *dom = pr_ctx->dom; struct tevent_req *req; errno_t ret; - char *dom_name = NULL; + char *sysdb_name = NULL; struct ldb_message *msg; req = tevent_req_create(pr_ctx, &state, struct pac_save_memberships_state); @@ -646,14 +654,14 @@ struct tevent_req *pac_save_memberships_send(struct pac_req_ctx *pr_ctx) state->sid_iter = 0; - dom_name = sss_get_domain_name(state, pr_ctx->user_name, dom); - if (dom_name == NULL) { + sysdb_name = sss_ioname2internal(state, dom, pr_ctx->user_name); + if (sysdb_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_sprintf failed.\n"); ret = ENOMEM; goto done; } - ret = sysdb_search_user_by_name(state, dom, dom_name, NULL, &msg); + ret = sysdb_search_user_by_name(state, dom, sysdb_name, NULL, &msg); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_name failed " \ "[%d][%s].\n", ret, strerror(ret)); @@ -676,7 +684,7 @@ struct tevent_req *pac_save_memberships_send(struct pac_req_ctx *pr_ctx) } done: - talloc_free(dom_name); + talloc_free(sysdb_name); if (ret != EOK && ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, pr_ctx->cctx->ev); diff --git a/src/responder/pam/pam_LOCAL_domain.c b/src/responder/pam/pam_LOCAL_domain.c index 4b076146c..0966bcb0c 100644 --- a/src/responder/pam/pam_LOCAL_domain.c +++ b/src/responder/pam/pam_LOCAL_domain.c @@ -73,6 +73,12 @@ static void prepare_reply(struct LOCAL_request *lreq) static void do_successful_login(struct LOCAL_request *lreq) { int ret; + char *name; + TALLOC_CTX *tmpctx; + + tmpctx = talloc_new(NULL); + NULL_CHECK_OR_JUMP(tmpctx, ("talloc_new failed.\n"), + lreq->error, ENOMEM, done); lreq->mod_attrs = sysdb_new_attrs(lreq); NULL_CHECK_OR_JUMP(lreq->mod_attrs, ("sysdb_new_attrs failed.\n"), @@ -87,13 +93,16 @@ static void do_successful_login(struct LOCAL_request *lreq) NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); - ret = sysdb_set_user_attr(lreq->domain, - lreq->preq->pd->user, + name = sss_ioname2internal(tmpctx, lreq->domain, lreq->preq->pd->user); + NULL_CHECK_OR_JUMP(name, ("sss_ioname2internal failed.\n"), + lreq->error, ENOMEM, done); + ret = sysdb_set_user_attr(lreq->domain, name, lreq->mod_attrs, SYSDB_MOD_REP); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_set_user_attr failed.\n"), lreq->error, ret, done); done: + talloc_free(tmpctx); return; } @@ -102,6 +111,12 @@ static void do_failed_login(struct LOCAL_request *lreq) int ret; int failedLoginAttempts; struct pam_data *pd; + char *name; + TALLOC_CTX *tmpctx; + + tmpctx = talloc_new(NULL); + NULL_CHECK_OR_JUMP(tmpctx, ("talloc_new failed.\n"), + lreq->error, ENOMEM, done); pd = lreq->preq->pd; pd->pam_status = PAM_AUTH_ERR; @@ -128,13 +143,16 @@ static void do_failed_login(struct LOCAL_request *lreq) NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); - ret = sysdb_set_user_attr(lreq->domain, - lreq->preq->pd->user, + name = sss_ioname2internal(tmpctx, lreq->domain, lreq->preq->pd->user); + NULL_CHECK_OR_JUMP(name, ("sss_ioname2internal failed.\n"), + lreq->error, ENOMEM, done); + ret = sysdb_set_user_attr(lreq->domain, name, lreq->mod_attrs, SYSDB_MOD_REP); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_set_user_attr failed.\n"), lreq->error, ret, done); done: + talloc_free(tmpctx); return; } @@ -161,9 +179,15 @@ static void do_pam_chauthtok(struct LOCAL_request *lreq) char *salt; char *new_hash; struct pam_data *pd; + char *name; + TALLOC_CTX *tmpctx; pd = lreq->preq->pd; + tmpctx = talloc_new(NULL); + NULL_CHECK_OR_JUMP(tmpctx, ("talloc_new failed.\n"), + lreq->error, ENOMEM, done); + ret = sss_authtok_get_password(pd->newauthtok, &password, NULL); if (ret) { /* TODO: should we allow null passwords via a config option ? */ @@ -197,13 +221,16 @@ static void do_pam_chauthtok(struct LOCAL_request *lreq) NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); - ret = sysdb_set_user_attr(lreq->domain, - lreq->preq->pd->user, + name = sss_ioname2internal(tmpctx, lreq->domain, lreq->preq->pd->user); + NULL_CHECK_OR_JUMP(name, ("sss_ioname2internal failed.\n"), + lreq->error, ENOMEM, done); + ret = sysdb_set_user_attr(lreq->domain, name, lreq->mod_attrs, SYSDB_MOD_REP); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_set_user_attr failed.\n"), lreq->error, ret, done); done: + talloc_free(tmpctx); sss_authtok_set_empty(pd->newauthtok); } diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c index b9fd35325..b497b8247 100644 --- a/src/responder/pam/pamsrv_cmd.c +++ b/src/responder/pam/pamsrv_cmd.c @@ -45,10 +45,10 @@ enum pam_verbosity { static errno_t pam_null_last_online_auth_with_curr_token(struct sss_domain_info *domain, - const char *username); + const char *pd_username); static errno_t pam_get_last_online_auth_with_curr_token(struct sss_domain_info *domain, - const char *name, + const char *pd_name, uint64_t *_value); static void pam_reply(struct pam_auth_req *preq); @@ -430,44 +430,61 @@ static errno_t set_last_login(struct pam_auth_req *preq) { struct sysdb_attrs *attrs; errno_t ret; + char *name; + TALLOC_CTX *tmpctx; + + tmpctx = talloc_new(NULL); + if (tmpctx == NULL) { + ret = ENOMEM; + goto done; + } attrs = sysdb_new_attrs(preq); if (!attrs) { ret = ENOMEM; - goto fail; + goto done; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_ONLINE_AUTH, time(NULL)); if (ret != EOK) { - goto fail; + goto done; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_ONLINE_AUTH_WITH_CURR_TOKEN, time(NULL)); if (ret != EOK) { - goto fail; + goto done; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_LOGIN, time(NULL)); if (ret != EOK) { - goto fail; + goto done; + } + + name = sss_ioname2internal(tmpctx, preq->domain, preq->pd->user); + if (name == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "failed to parse name '%s'.\n", + preq->pd->user); + ret = ENOMEM; + goto done; } - ret = sysdb_set_user_attr(preq->domain, preq->pd->user, attrs, + ret = sysdb_set_user_attr(preq->domain, name, attrs, SYSDB_MOD_REP); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "set_last_login failed.\n"); preq->pd->pam_status = PAM_SYSTEM_ERR; - goto fail; + goto done; } else { preq->pd->last_auth_saved = true; } preq->callback(preq); - return EOK; + ret = EOK; -fail: +done: + talloc_free(tmpctx); return ret; } @@ -1678,7 +1695,7 @@ static void pam_check_user_dp_callback(uint16_t err_maj, uint32_t err_min, } static errno_t pam_is_last_online_login_fresh(struct sss_domain_info *domain, - const char* user, + const char* pd_user, int cached_auth_timeout, bool *_result) { @@ -1686,7 +1703,7 @@ static errno_t pam_is_last_online_login_fresh(struct sss_domain_info *domain, bool result; uint64_t last_login; - ret = pam_get_last_online_auth_with_curr_token(domain, user, &last_login); + ret = pam_get_last_online_auth_with_curr_token(domain, pd_user, &last_login); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_get_last_online_auth_with_curr_token failed: %s:[%d]\n", @@ -1737,7 +1754,7 @@ static bool pam_is_authtok_cachable(struct sss_auth_token *authtok) static bool pam_can_user_cache_auth(struct sss_domain_info *domain, int pam_cmd, struct sss_auth_token *authtok, - const char* user, + const char* pd_user, bool cached_auth_failed) { errno_t ret; @@ -1749,7 +1766,7 @@ static bool pam_can_user_cache_auth(struct sss_domain_info *domain, && pam_is_authtok_cachable(authtok) && pam_is_cmd_cachable(pam_cmd)) { - ret = pam_is_last_online_login_fresh(domain, user, + ret = pam_is_last_online_login_fresh(domain, pd_user, domain->cached_auth_timeout, &result); if (ret != EOK) { @@ -1939,12 +1956,13 @@ struct sss_cmd_table *get_pam_cmds(void) errno_t pam_set_last_online_auth_with_curr_token(struct sss_domain_info *domain, - const char *username, + const char *pd_username, uint64_t value) { TALLOC_CTX *tmp_ctx; struct sysdb_attrs *attrs; int ret; + char *name; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { @@ -1963,7 +1981,13 @@ pam_set_last_online_auth_with_curr_token(struct sss_domain_info *domain, value); if (ret != EOK) { goto done; } - ret = sysdb_set_user_attr(domain, username, attrs, SYSDB_MOD_REP); + name = sss_ioname2internal(tmp_ctx, domain, pd_username); + if (name == NULL) { + ret = ENOMEM; + goto done; + } + + ret = sysdb_set_user_attr(domain, name, attrs, SYSDB_MOD_REP); if (ret != EOK) { goto done; } done: @@ -1977,14 +2001,14 @@ done: static errno_t pam_null_last_online_auth_with_curr_token(struct sss_domain_info *domain, - const char *username) + const char *pd_username) { - return pam_set_last_online_auth_with_curr_token(domain, username, 0); + return pam_set_last_online_auth_with_curr_token(domain, pd_username, 0); } static errno_t pam_get_last_online_auth_with_curr_token(struct sss_domain_info *domain, - const char *name, + const char *pd_name, uint64_t *_value) { TALLOC_CTX *tmp_ctx = NULL; @@ -1992,8 +2016,9 @@ pam_get_last_online_auth_with_curr_token(struct sss_domain_info *domain, struct ldb_message *ldb_msg; uint64_t value; errno_t ret; + char *name; - if (name == NULL || *name == '\0') { + if (pd_name == NULL || *pd_name == '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Missing user name.\n"); ret = EINVAL; goto done; @@ -2011,6 +2036,12 @@ pam_get_last_online_auth_with_curr_token(struct sss_domain_info *domain, goto done; } + name = sss_ioname2internal(tmp_ctx, domain, pd_name); + if (name == NULL) { + ret = ENOMEM; + goto done; + } + ret = sysdb_search_user_by_name(tmp_ctx, domain, name, attrs, &ldb_msg); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, |