END_TEST void setup_talloc_context(void) { int ret; int i; struct pam_data *pd; struct krb5_ctx *krb5_ctx; fail_unless(tmp_ctx == NULL, "Talloc context already initialized."); tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "Cannot create talloc context."); kr = talloc_zero(tmp_ctx, struct krb5child_req); fail_unless(kr != NULL, "Cannot create krb5child_req structure."); pd = create_pam_data(tmp_ctx); fail_unless(pd != NULL, "Cannot create pam_data structure."); krb5_ctx = talloc_zero(tmp_ctx, struct krb5_ctx); fail_unless(pd != NULL, "Cannot create krb5_ctx structure."); pd->user = discard_const(USERNAME); kr->uid = atoi(UID); kr->upn = discard_const(PRINCIPAL_NAME); pd->cli_pid = atoi(PID); krb5_ctx->opts = talloc_zero_array(tmp_ctx, struct dp_option, KRB5_OPTS); fail_unless(krb5_ctx->opts != NULL, "Cannot created options."); for (i = 0; i < KRB5_OPTS; i++) { krb5_ctx->opts[i].opt_name = default_krb5_opts[i].opt_name; krb5_ctx->opts[i].type = default_krb5_opts[i].type; krb5_ctx->opts[i].def_val = default_krb5_opts[i].def_val; } ret = dp_opt_set_string(krb5_ctx->opts, KRB5_REALM, REALM); fail_unless(ret == EOK, "Failed to set Realm"); ret = dp_opt_set_string(krb5_ctx->opts, KRB5_CCACHEDIR, CCACHE_DIR); fail_unless(ret == EOK, "Failed to set Ccache dir"); kr->homedir = HOME_DIRECTORY; kr->pd = pd; kr->krb5_ctx = krb5_ctx; }
static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd) { struct sss_domain_info *dom; struct pam_auth_req *preq; struct pam_data *pd; int ret; errno_t ncret; struct pam_ctx *pctx = talloc_get_type(cctx->rctx->pvt_ctx, struct pam_ctx); struct tevent_req *req; preq = talloc_zero(cctx, struct pam_auth_req); if (!preq) { return ENOMEM; } talloc_set_destructor(preq, pam_auth_req_destructor); preq->cctx = cctx; preq->pd = create_pam_data(preq); if (!preq->pd) { talloc_free(preq); return ENOMEM; } pd = preq->pd; pd->cmd = pam_cmd; pd->priv = cctx->priv; ret = pam_forwarder_parse_data(cctx, pd); if (ret == EAGAIN) { req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, pd->domain); if (req == NULL) { ret = ENOMEM; } else { tevent_req_set_callback(req, pam_forwarder_cb, preq); ret = EAGAIN; } goto done; } else if (ret != EOK) { ret = EINVAL; goto done; } /* now check user is valid */ if (pd->domain) { preq->domain = responder_get_domain(cctx->rctx, pd->domain); if (!preq->domain) { ret = ENOENT; goto done; } ncret = sss_ncache_check_user(pctx->ncache, pctx->neg_timeout, preq->domain, pd->user); if (ncret == EEXIST) { /* User found in the negative cache */ ret = ENOENT; goto done; } } else { for (dom = preq->cctx->rctx->domains; dom; dom = get_next_domain(dom, false)) { if (dom->fqnames) continue; ncret = sss_ncache_check_user(pctx->ncache, pctx->neg_timeout, dom, pd->user); if (ncret == ENOENT) { /* User not found in the negative cache * Proceed with PAM actions */ break; } /* Try the next domain */ DEBUG(SSSDBG_TRACE_FUNC, "User [%s@%s] filtered out (negative cache). " "Trying next domain.\n", pd->user, dom->name); } if (!dom) { ret = ENOENT; goto done; } preq->domain = dom; } if (preq->domain->provider == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Domain [%s] has no auth provider.\n", preq->domain->name); ret = EINVAL; goto done; } preq->check_provider = NEED_CHECK_PROVIDER(preq->domain->provider); ret = pam_check_user_search(preq); if (ret == EOK) { pam_dom_forwarder(preq); } done: return pam_check_user_done(preq, ret); }