diff options
-rw-r--r-- | src/db/sysdb.h | 2 | ||||
-rw-r--r-- | src/db/sysdb_search.c | 39 | ||||
-rw-r--r-- | src/providers/krb5/krb5_auth.c | 51 | ||||
-rw-r--r-- | src/providers/ldap/ldap_auth.c | 203 | ||||
-rw-r--r-- | src/responder/pam/pam_LOCAL_domain.c | 96 | ||||
-rw-r--r-- | src/tests/sysdb-tests.c | 62 |
6 files changed, 160 insertions, 293 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 7b5166fe..fa82e579 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -295,7 +295,7 @@ int sysdb_get_user_attr(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attributes, - sysdb_callback_t fn, void *ptr); + struct ldb_result **res); /* functions that modify the databse diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c index cabf19f4..8d8a0e11 100644 --- a/src/db/sysdb_search.c +++ b/src/db/sysdb_search.c @@ -706,35 +706,40 @@ int sysdb_get_user_attr(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attributes, - sysdb_callback_t fn, void *ptr) + struct ldb_result **_res) { - struct sysdb_search_ctx *sctx; - struct tevent_req *req; + TALLOC_CTX *tmpctx; + struct ldb_dn *base_dn; + struct ldb_result *res; + int ret; if (!domain) { return EINVAL; } - sctx = init_src_ctx(mem_ctx, domain, ctx, fn, ptr); - if (!sctx) { + tmpctx = talloc_new(mem_ctx); + if (!tmpctx) { return ENOMEM; } - sctx->expression = talloc_asprintf(sctx, SYSDB_PWNAM_FILTER, name); - if (!sctx->expression) { - talloc_free(sctx); - return ENOMEM; + base_dn = ldb_dn_new_fmt(tmpctx, ctx->ldb, + SYSDB_TMPL_USER_BASE, domain->name); + if (!base_dn) { + ret = ENOMEM; + goto done; } - sctx->attrs = attributes; - - req = sysdb_operation_send(mem_ctx, ctx->ev, ctx); - if (!req) { - talloc_free(sctx); - return ENOMEM; + ret = ldb_search(ctx->ldb, tmpctx, &res, base_dn, + LDB_SCOPE_SUBTREE, attributes, + SYSDB_PWNAM_FILTER, name); + if (ret) { + ret = sysdb_error_to_errno(ret); + goto done; } - tevent_req_set_callback(req, user_search, sctx); + *_res = talloc_steal(mem_ctx, res); - return EOK; +done: + talloc_zfree(tmpctx); + return ret; } diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c index 0d5ea5d2..6a57fe5f 100644 --- a/src/providers/krb5/krb5_auth.c +++ b/src/providers/krb5/krb5_auth.c @@ -610,7 +610,6 @@ static int handle_child_recv(struct tevent_req *req, return EOK; } -static void get_user_attr_done(void *pvt, int err, struct ldb_result *res); static void krb5_resolve_kdc_done(struct tevent_req *req); static void krb5_resolve_kpasswd_done(struct tevent_req *req); static void krb5_find_ccache_step(struct krb5child_req *kr); @@ -623,6 +622,12 @@ void krb5_pam_handler(struct be_req *be_req) const char **attrs; int pam_status = PAM_SYSTEM_ERR; int dp_err = DP_ERR_FATAL; + struct ldb_result *res; + struct krb5child_req *kr = NULL; + const char *ccache_file = NULL; + const char *realm; + krb5_error_code kerr; + struct tevent_req *req; int ret; pd = talloc_get_type(be_req->req_data, struct pam_data); @@ -668,49 +673,20 @@ void krb5_pam_handler(struct be_req *be_req) attrs[5] = NULL; ret = sysdb_get_user_attr(be_req, be_req->be_ctx->sysdb, - be_req->be_ctx->domain, pd->user, attrs, - get_user_attr_done, be_req); - + be_req->be_ctx->domain, pd->user, + attrs, &res); if (ret) { + DEBUG(5, ("sysdb search for upn of user [%s] failed.\n", pd->user)); goto done; } - return; - -done: - pd->pam_status = pam_status; - - krb_reply(be_req, dp_err, pd->pam_status); -} - -static void get_user_attr_done(void *pvt, int err, struct ldb_result *res) -{ - struct be_req *be_req = talloc_get_type(pvt, struct be_req); - struct krb5_ctx *krb5_ctx; - struct krb5child_req *kr = NULL; - struct tevent_req *req; - krb5_error_code kerr; - int ret; - struct pam_data *pd = talloc_get_type(be_req->req_data, struct pam_data); - int pam_status = PAM_SYSTEM_ERR; - int dp_err = DP_ERR_FATAL; - const char *ccache_file = NULL; - const char *realm; - ret = krb5_setup(be_req, &kr); if (ret != EOK) { DEBUG(1, ("krb5_setup failed.\n")); goto failed; } - krb5_ctx = kr->krb5_ctx; - - if (err != LDB_SUCCESS) { - DEBUG(5, ("sysdb search for upn of user [%s] failed.\n", pd->user)); - goto failed; - } - - realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM); + realm = dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_REALM); if (realm == NULL) { DEBUG(1, ("Missing Kerberos realm.\n")); goto failed; @@ -782,8 +758,7 @@ static void get_user_attr_done(void *pvt, int err, struct ldb_result *res) break; default: - DEBUG(1, ("A user search by name (%s) returned > 1 results!\n", - pd->user)); + DEBUG(1, ("User search for (%s) returned > 1 results!\n", pd->user)); goto failed; break; } @@ -791,7 +766,7 @@ static void get_user_attr_done(void *pvt, int err, struct ldb_result *res) kr->srv = NULL; kr->kpasswd_srv = NULL; req = be_resolve_server_send(kr, be_req->be_ctx->ev, be_req->be_ctx, - krb5_ctx->service->name); + kr->krb5_ctx->service->name); if (req == NULL) { DEBUG(1, ("be_resolve_server_send failed.\n")); goto failed; @@ -803,7 +778,7 @@ static void get_user_attr_done(void *pvt, int err, struct ldb_result *res) failed: talloc_free(kr); - +done: pd->pam_status = pam_status; krb_reply(be_req, dp_err, pd->pam_status); } diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c index 7eabd6cf..e0935da3 100644 --- a/src/providers/ldap/ldap_auth.c +++ b/src/providers/ldap/ldap_auth.c @@ -312,152 +312,107 @@ shadow_fail: /* ==Get-User-DN========================================================== */ -struct get_user_dn_state { - struct tevent_context *ev; - struct sdap_auth_ctx *ctx; - struct sdap_handle *sh; - - const char **attrs; - const char *name; - - char *dn; +static int get_user_dn(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + struct sdap_options *opts, + struct sss_domain_info *dom, + const char *username, + char **user_dn, + enum pwexpire *user_pw_expire_type, + void **user_pw_expire_data) +{ + TALLOC_CTX *tmpctx; enum pwexpire pw_expire_type; void *pw_expire_data; -}; - -static void get_user_dn_done(void *pvt, int err, struct ldb_result *res); - -struct tevent_req *get_user_dn_send(TALLOC_CTX *memctx, - struct tevent_context *ev, - struct sdap_auth_ctx *ctx, - struct sdap_handle *sh, - const char *username) -{ - struct tevent_req *req; - struct get_user_dn_state *state; + struct ldb_result *res; + const char **attrs; + const char *dn; int ret; - req = tevent_req_create(memctx, &state, struct get_user_dn_state); - if (!req) return NULL; - - state->ev = ev; - state->ctx = ctx; - state->sh = sh; - state->name = username; - - state->attrs = talloc_array(state, const char *, 11); - if (!state->attrs) { - talloc_zfree(req); - return NULL; - } - state->attrs[0] = SYSDB_ORIG_DN; - state->attrs[1] = SYSDB_SHADOWPW_LASTCHANGE; - state->attrs[2] = SYSDB_SHADOWPW_MIN; - state->attrs[3] = SYSDB_SHADOWPW_MAX; - state->attrs[4] = SYSDB_SHADOWPW_WARNING; - state->attrs[5] = SYSDB_SHADOWPW_INACTIVE; - state->attrs[6] = SYSDB_SHADOWPW_EXPIRE; - state->attrs[7] = SYSDB_KRBPW_LASTCHANGE; - state->attrs[8] = SYSDB_KRBPW_EXPIRATION; - state->attrs[9] = SYSDB_PWD_ATTRIBUTE; - state->attrs[10] = NULL; - - /* this sysdb call uses a sysdn operation, which means it will be - * schedule only after we return, no timer hack needed */ - ret = sysdb_get_user_attr(state, state->ctx->be->sysdb, - state->ctx->be->domain, state->name, - state->attrs, get_user_dn_done, req); - if (ret) { - tevent_req_error(req, ret); - tevent_req_post(req, ev); + tmpctx = talloc_new(memctx); + if (!tmpctx) { + return ENOMEM; } - return req; -} + attrs = talloc_array(tmpctx, const char *, 11); + if (!attrs) { + ret = ENOMEM; + goto done; + } -static void get_user_dn_done(void *pvt, int err, struct ldb_result *res) -{ - struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); - struct get_user_dn_state *state = tevent_req_data(req, - struct get_user_dn_state); - const char *dn; - int ret; + attrs[0] = SYSDB_ORIG_DN; + attrs[1] = SYSDB_SHADOWPW_LASTCHANGE; + attrs[2] = SYSDB_SHADOWPW_MIN; + attrs[3] = SYSDB_SHADOWPW_MAX; + attrs[4] = SYSDB_SHADOWPW_WARNING; + attrs[5] = SYSDB_SHADOWPW_INACTIVE; + attrs[6] = SYSDB_SHADOWPW_EXPIRE; + attrs[7] = SYSDB_KRBPW_LASTCHANGE; + attrs[8] = SYSDB_KRBPW_EXPIRATION; + attrs[9] = SYSDB_PWD_ATTRIBUTE; + attrs[10] = NULL; - if (err != LDB_SUCCESS) { - tevent_req_error(req, EIO); - return; + ret = sysdb_get_user_attr(tmpctx, sysdb, dom, username, attrs, &res); + if (ret) { + goto done; } switch (res->count) { case 0: /* FIXME: not in cache, needs a true search */ - tevent_req_error(req, ENOENT); + ret = ENOENT; break; case 1: dn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_ORIG_DN, NULL); - if (!dn) { + if (dn) { + dn = talloc_strdup(tmpctx, dn); + } else { /* TODO: try to search ldap server ? */ /* FIXME: remove once we store originalDN on every call * NOTE: this is wrong, works only with some DITs */ - dn = talloc_asprintf(state, "%s=%s,%s", - state->ctx->opts->user_map[SDAP_AT_USER_NAME].name, - state->name, - dp_opt_get_string(state->ctx->opts->basic, - SDAP_USER_SEARCH_BASE)); - if (!dn) { - tevent_req_error(req, ENOMEM); - break; - } + dn = talloc_asprintf(tmpctx, "%s=%s,%s", + opts->user_map[SDAP_AT_USER_NAME].name, + username, + dp_opt_get_string(opts->basic, + SDAP_USER_SEARCH_BASE)); } - - state->dn = talloc_strdup(state, dn); - if (!state->dn) { - tevent_req_error(req, ENOMEM); + if (!dn) { + ret = ENOMEM; break; } - ret = find_password_expiration_attributes(state, res->msgs[0], - state->ctx->opts->basic, - &state->pw_expire_type, - &state->pw_expire_data); + ret = find_password_expiration_attributes(tmpctx, + res->msgs[0], + opts->basic, + &pw_expire_type, + &pw_expire_data); if (ret != EOK) { DEBUG(1, ("find_password_expiration_attributes failed.\n")); - tevent_req_error(req, ENOMEM); - break; } - - tevent_req_done(req); break; default: - DEBUG(1, ("A user search by name (%s) returned > 1 results!\n", - state->name)); - tevent_req_error(req, EFAULT); + DEBUG(1, ("User search by name (%s) returned > 1 results!\n", + username)); + ret = EFAULT; break; } -} -static int get_user_dn_recv(struct tevent_req *req, - TALLOC_CTX *memctx, char **dn, - enum pwexpire *pw_expire_type, - void **pw_expire_data) -{ - struct get_user_dn_state *state = tevent_req_data(req, - struct get_user_dn_state); - - TEVENT_REQ_RETURN_ON_ERROR(req); - - *dn = talloc_steal(memctx, state->dn); - if (!*dn) return ENOMEM; - - /* state->pw_expire_data may be NULL */ - *pw_expire_data = talloc_steal(memctx, state->pw_expire_data); - - *pw_expire_type = state->pw_expire_type; +done: + if (ret == EOK) { + *user_dn = talloc_strdup(memctx, dn); + if (!*user_dn) { + ret = ENOMEM; + } + /* pw_expire_data may be NULL */ + *user_pw_expire_data = talloc_steal(memctx, pw_expire_data); + *user_pw_expire_type = pw_expire_type; + } - return EOK; + talloc_zfree(tmpctx); + return ret; } /* ==Authenticate-User==================================================== */ @@ -480,7 +435,6 @@ struct auth_state { static void auth_resolve_done(struct tevent_req *subreq); static void auth_connect_done(struct tevent_req *subreq); -static void auth_get_user_dn_done(struct tevent_req *subreq); static void auth_bind_user_done(struct tevent_req *subreq); static struct tevent_req *auth_send(TALLOC_CTX *memctx, @@ -560,28 +514,9 @@ static void auth_connect_done(struct tevent_req *subreq) fo_set_port_status(state->srv, PORT_WORKING); } - subreq = get_user_dn_send(state, state->ev, - state->ctx, state->sh, - state->username); - if (!subreq) { - tevent_req_error(req, ENOMEM); - return; - } - - tevent_req_set_callback(subreq, auth_get_user_dn_done, req); -} - -static void auth_get_user_dn_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct auth_state *state = tevent_req_data(req, - struct auth_state); - int ret; - - ret = get_user_dn_recv(subreq, state, &state->dn, &state->pw_expire_type, - &state->pw_expire_data); - talloc_zfree(subreq); + ret = get_user_dn(state, state->ctx->be->sysdb, state->ctx->opts, + state->ctx->be->domain, state->username, &state->dn, + &state->pw_expire_type, &state->pw_expire_data); if (ret) { tevent_req_error(req, ret); return; diff --git a/src/responder/pam/pam_LOCAL_domain.c b/src/responder/pam/pam_LOCAL_domain.c index 09229c29..a17934ce 100644 --- a/src/responder/pam/pam_LOCAL_domain.c +++ b/src/responder/pam/pam_LOCAL_domain.c @@ -214,27 +214,56 @@ done: return; } -static void local_handler_callback(void *pvt, int ldb_status, - struct ldb_result *res) +int LOCAL_pam_handler(struct pam_auth_req *preq) { struct LOCAL_request *lreq; + static const char *attrs[] = {SYSDB_NAME, + SYSDB_PWD, + SYSDB_DISABLED, + SYSDB_LAST_LOGIN, + "lastPasswordChange", + "accountExpires", + SYSDB_FAILED_LOGIN_ATTEMPTS, + "passwordHint", + "passwordHistory", + SYSDB_LAST_FAILED_LOGIN, + NULL}; + struct ldb_result *res; const char *username = NULL; const char *password = NULL; char *newauthtok = NULL; char *new_hash = NULL; char *authtok = NULL; - struct pam_data *pd; + struct pam_data *pd = preq->pd; int ret; - lreq = talloc_get_type(pvt, struct LOCAL_request); - pd = lreq->preq->pd; + DEBUG(4, ("LOCAL pam handler.\n")); - DEBUG(4, ("pam_handler_callback called with ldb_status [%d].\n", - ldb_status)); + lreq = talloc_zero(preq, struct LOCAL_request); + if (!lreq) { + return ENOMEM; + } - NEQ_CHECK_OR_JUMP(ldb_status, LDB_SUCCESS, ("ldb search failed.\n"), - lreq->error, sysdb_error_to_errno(ldb_status), done); + ret = sysdb_get_ctx_from_list(preq->cctx->rctx->db_list, + preq->domain, &lreq->dbctx); + if (ret != EOK) { + DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n")); + talloc_free(lreq); + return ret; + } + lreq->ev = preq->cctx->ev; + lreq->preq = preq; + pd->pam_status = PAM_SUCCESS; + + ret = sysdb_get_user_attr(lreq, lreq->dbctx, + preq->domain, preq->pd->user, + attrs, &res); + if (ret != EOK) { + DEBUG(1, ("sysdb_get_user_attr failed.\n")); + talloc_free(lreq); + return ret; + } if (res->count < 1) { DEBUG(4, ("No user found with filter ["SYSDB_PWNAM_FILTER"]\n", @@ -328,53 +357,6 @@ done: memset(newauthtok, 0, pd->newauthtok_size); prepare_reply(lreq); -} - -int LOCAL_pam_handler(struct pam_auth_req *preq) -{ - int ret; - struct LOCAL_request *lreq; - - static const char *attrs[] = {SYSDB_NAME, - SYSDB_PWD, - SYSDB_DISABLED, - SYSDB_LAST_LOGIN, - "lastPasswordChange", - "accountExpires", - SYSDB_FAILED_LOGIN_ATTEMPTS, - "passwordHint", - "passwordHistory", - SYSDB_LAST_FAILED_LOGIN, - NULL}; - - DEBUG(4, ("LOCAL pam handler.\n")); - - lreq = talloc_zero(preq, struct LOCAL_request); - if (!lreq) { - return ENOMEM; - } - - ret = sysdb_get_ctx_from_list(preq->cctx->rctx->db_list, - preq->domain, &lreq->dbctx); - if (ret != EOK) { - DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n")); - talloc_free(lreq); - return ret; - } - lreq->ev = preq->cctx->ev; - lreq->preq = preq; - - preq->pd->pam_status = PAM_SUCCESS; - - ret = sysdb_get_user_attr(lreq, lreq->dbctx, - preq->domain, preq->pd->user, attrs, - local_handler_callback, lreq); - - if (ret != EOK) { - DEBUG(1, ("sysdb_get_user_attr failed.\n")); - talloc_free(lreq); - return ret; - } - return EOK; } + diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index 162d174b..62ad6d16 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -174,7 +174,6 @@ struct test_data { int error; struct sysdb_attrs *attrs; - const char *attrval; /* testing sysdb_get_user_attr */ const char **attrlist; struct ldb_message *msg; @@ -356,31 +355,6 @@ static int test_set_user_attr(struct test_data *data) return ret; } -static void test_get_user_attr(void *pvt, int error, struct ldb_result *res) -{ - struct test_data *data = talloc_get_type(pvt, struct test_data); - data->finished = true; - - if (error != EOK) { - data->error = error; - return; - } - - switch (res->count) { - case 0: - data->error = ENOENT; - break; - - case 1: - data->attrval = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, 0); - break; - - default: - data->error = EFAULT; - break; - } -} - static int test_add_group_member(struct test_data *data) { const char *username; @@ -1044,9 +1018,11 @@ END_TEST START_TEST (test_sysdb_get_user_attr) { struct sysdb_test_ctx *test_ctx; - struct test_data *data; - int ret; const char *attrs[] = { SYSDB_SHELL, NULL }; + struct ldb_result *res; + const char *attrval; + char *username; + int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); @@ -1055,28 +1031,22 @@ START_TEST (test_sysdb_get_user_attr) return; } - data = talloc_zero(test_ctx, struct test_data); - data->ctx = test_ctx; - data->username = talloc_asprintf(data, "testuser%d", _i); - - ret = sysdb_get_user_attr(data, - data->ctx->sysdb, - data->ctx->domain, - data->username, - attrs, - test_get_user_attr, - data); - if (ret == EOK) { - ret = test_loop(data); - } + username = talloc_asprintf(test_ctx, "testuser%d", _i); + ret = sysdb_get_user_attr(test_ctx, test_ctx->sysdb, + test_ctx->domain, username, + attrs, &res); if (ret) { - fail("Could not get attributes for user %s", data->username); + fail("Could not get attributes for user %s", username); goto done; } - fail_if(strcmp(data->attrval, "/bin/ksh"), - "Got bad attribute value for user %s", - data->username); + + fail_if(res->count != 1, + "Invalid number of entries, expected 1, got %d", res->count); + + attrval = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, 0); + fail_if(strcmp(attrval, "/bin/ksh"), + "Got bad attribute value for user %s", username); done: talloc_free(test_ctx); } |