summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/db/sysdb.h2
-rw-r--r--src/db/sysdb_search.c39
-rw-r--r--src/providers/krb5/krb5_auth.c51
-rw-r--r--src/providers/ldap/ldap_auth.c203
-rw-r--r--src/responder/pam/pam_LOCAL_domain.c96
-rw-r--r--src/tests/sysdb-tests.c62
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);
}