summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/db/sysdb.c20
-rw-r--r--server/db/sysdb.h27
-rw-r--r--server/db/sysdb_ops.c113
-rw-r--r--server/providers/ldap/ldap_auth.c48
-rw-r--r--server/providers/ldap/sdap_async.c97
-rw-r--r--server/providers/ldap/sdap_async.h9
-rw-r--r--server/providers/proxy.c155
7 files changed, 178 insertions, 291 deletions
diff --git a/server/db/sysdb.c b/server/db/sysdb.c
index 1951a9b3b..0cac339ed 100644
--- a/server/db/sysdb.c
+++ b/server/db/sysdb.c
@@ -443,6 +443,26 @@ int sysdb_transaction_commit_recv(struct tevent_req *req)
return EOK;
}
+/* default transaction commit receive function.
+ * This function does not use the request state so it is safe to use
+ * from any caller */
+void sysdb_transaction_complete(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ int ret;
+
+ ret = sysdb_transaction_commit_recv(subreq);
+ talloc_zfree(subreq);
+ if (ret) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ tevent_req_done(req);
+}
+
+
/* =Operations============================================================ */
struct sysdb_operation_state {
diff --git a/server/db/sysdb.h b/server/db/sysdb.h
index aa1aaf4cd..a81f46301 100644
--- a/server/db/sysdb.h
+++ b/server/db/sysdb.h
@@ -195,6 +195,13 @@ struct tevent_req *sysdb_transaction_commit_send(TALLOC_CTX *mem_ctx,
struct sysdb_handle *handle);
int sysdb_transaction_commit_recv(struct tevent_req *req);
+
+/* default transaction commit receive function.
+ * This function does not use the request state so it is safe to use
+ * from any caller */
+void sysdb_transaction_complete(struct tevent_req *subreq);
+
+
/* Sysdb initialization.
* call this function *only* once to initialize the database and get
* the sysdb ctx */
@@ -457,13 +464,19 @@ struct tevent_req *sysdb_remove_group_member_send(TALLOC_CTX *mem_ctx,
const char *member);
int sysdb_remove_group_member_recv(struct tevent_req *req);
-struct tevent_req *sysdb_set_cached_password_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sss_domain_info *domain,
- const char *user,
- const char *password);
-int sysdb_set_cached_password_recv(struct tevent_req *req);
+/* Password caching function.
+ * If you are in a transaction ignore sysdb and pass in the handle.
+ * If you are not in a transaction pass NULL in handle and provide sysdb,
+ * in this case a transaction will be automatically started and the
+ * function will be completely wrapped in it's own sysdb transaction */
+struct tevent_req *sysdb_cache_password_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sysdb_ctx *sysdb,
+ struct sysdb_handle *handle,
+ struct sss_domain_info *domain,
+ const char *username,
+ const char *password);
+int sysdb_cache_password_recv(struct tevent_req *req);
/* TODO: remove later
* These functions are available in the latest tevent and are the ones that
diff --git a/server/db/sysdb_ops.c b/server/db/sysdb_ops.c
index 24d90b129..c53d6720c 100644
--- a/server/db/sysdb_ops.c
+++ b/server/db/sysdb_ops.c
@@ -2919,20 +2919,32 @@ int sysdb_remove_group_member_recv(struct tevent_req *req)
}
-/* ======================================================================= */
+/* =Password-Caching====================================================== */
-static void sysdb_set_cached_password_done(struct tevent_req *subreq);
+struct sysdb_cache_pw_state {
+ struct tevent_context *ev;
+ struct sss_domain_info *domain;
-struct tevent_req *sysdb_set_cached_password_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sss_domain_info *domain,
- const char *user,
- const char *password)
+ const char *username;
+ struct sysdb_attrs *attrs;
+
+ struct sysdb_handle *handle;
+ bool commit;
+};
+
+static void sysdb_cache_password_trans(struct tevent_req *subreq);
+static void sysdb_cache_password_done(struct tevent_req *subreq);
+
+struct tevent_req *sysdb_cache_password_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sysdb_ctx *sysdb,
+ struct sysdb_handle *handle,
+ struct sss_domain_info *domain,
+ const char *username,
+ const char *password)
{
struct tevent_req *req, *subreq;
- struct sysdb_op_state *state;
- struct sysdb_attrs *attrs;
+ struct sysdb_cache_pw_state *state;
char *hash = NULL;
char *salt;
int ret;
@@ -2941,9 +2953,8 @@ struct tevent_req *sysdb_set_cached_password_send(TALLOC_CTX *mem_ctx,
if (!req) return NULL;
state->ev = ev;
- state->handle = handle;
- state->ignore_not_found = false;
- state->ldbreply = NULL;
+ state->domain = domain;
+ state->username = username;
ret = s3crypt_gen_salt(state, &salt);
if (ret) {
@@ -2957,25 +2968,42 @@ struct tevent_req *sysdb_set_cached_password_send(TALLOC_CTX *mem_ctx,
goto fail;
}
- attrs = sysdb_new_attrs(state);
- if (!attrs) {
+ state->attrs = sysdb_new_attrs(state);
+ if (!state->attrs) {
ERROR_OUT(ret, ENOMEM, fail);
}
- ret = sysdb_attrs_add_string(attrs, SYSDB_CACHEDPWD, hash);
+ ret = sysdb_attrs_add_string(state->attrs, SYSDB_CACHEDPWD, hash);
if (ret) goto fail;
/* FIXME: should we use a different attribute for chache passwords ?? */
- ret = sysdb_attrs_add_long(attrs, "lastCachedPasswordChange",
+ ret = sysdb_attrs_add_long(state->attrs, "lastCachedPasswordChange",
(long)time(NULL));
if (ret) goto fail;
- subreq = sysdb_set_user_attr_send(state, ev, handle, domain,
- user, attrs, SYSDB_MOD_REP);
- if (!subreq) {
- ERROR_OUT(ret, ENOMEM, fail);
+ state->handle = NULL;
+
+ if (handle) {
+ state->handle = handle;
+ state->commit = false;
+
+ subreq = sysdb_set_user_attr_send(state, state->ev, state->handle,
+ state->domain, state->username,
+ state->attrs, SYSDB_MOD_REP);
+ if (!subreq) {
+ ERROR_OUT(ret, ENOMEM, fail);
+ }
+ tevent_req_set_callback(subreq, sysdb_cache_password_done, req);
+ } else {
+ state->commit = true;
+
+ subreq = sysdb_transaction_send(state, state->ev, sysdb);
+ if (!subreq) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ tevent_req_set_callback(subreq, sysdb_cache_password_trans, req);
}
- tevent_req_set_callback(subreq, sysdb_set_cached_password_done, req);
return req;
@@ -2985,10 +3013,36 @@ fail:
return req;
}
-static void sysdb_set_cached_password_done(struct tevent_req *subreq)
+static void sysdb_cache_password_trans(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct sysdb_cache_pw_state *state = tevent_req_data(req,
+ struct sysdb_cache_pw_state);
+ int ret;
+
+ ret = sysdb_transaction_recv(req, state, &state->handle);
+ if (ret) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ subreq = sysdb_set_user_attr_send(state, state->ev, state->handle,
+ state->domain, state->username,
+ state->attrs, SYSDB_MOD_REP);
+ if (!subreq) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+ tevent_req_set_callback(subreq, sysdb_cache_password_done, req);
+}
+
+static void sysdb_cache_password_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
+ struct sysdb_cache_pw_state *state = tevent_req_data(req,
+ struct sysdb_cache_pw_state);
int ret;
ret = sysdb_set_user_attr_recv(subreq);
@@ -2998,10 +3052,21 @@ static void sysdb_set_cached_password_done(struct tevent_req *subreq)
return;
}
+ if (state->commit) {
+ subreq = sysdb_transaction_commit_send(state, state->ev,
+ state->handle);
+ if (!subreq) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+ tevent_req_set_callback(subreq, sysdb_transaction_complete, req);
+ return;
+ }
+
tevent_req_done(req);
}
-int sysdb_set_cached_password_recv(struct tevent_req *req)
+int sysdb_cache_password_recv(struct tevent_req *req)
{
return sysdb_op_default_recv(req);
}
diff --git a/server/providers/ldap/ldap_auth.c b/server/providers/ldap/ldap_auth.c
index c176cb4ee..e36338577 100644
--- a/server/providers/ldap/ldap_auth.c
+++ b/server/providers/ldap/ldap_auth.c
@@ -312,7 +312,7 @@ struct sdap_pam_auth_state {
static void sdap_pam_auth_done(struct tevent_req *req);
static void sdap_password_cache_done(struct tevent_req *req);
-static void sdap_pam_auth_reply(struct be_req *breq, int result, const char *err);
+static void sdap_pam_auth_reply(struct be_req *breq, int result);
/* FIXME: convert caller to tevent_req too ?*/
static void sdap_pam_auth_send(struct be_req *breq)
@@ -356,22 +356,16 @@ static void sdap_pam_auth_send(struct be_req *breq)
default:
pd->pam_status = PAM_SUCCESS;
}
- tevent_req_set_callback(req, sdap_cache_pw_done, data);
-
- return;
-
-fail:
- DEBUG(2, ("Failed to cache password (%d)[%s]!?\n", ret, strerror(ret)));
done:
- sdap_pam_auth_reply(breq, pd->pam_status, NULL);
+ sdap_pam_auth_reply(breq, pd->pam_status);
}
static void sdap_pam_auth_done(struct tevent_req *req)
{
struct sdap_pam_auth_state *state =
tevent_req_callback_data(req, struct sdap_pam_auth_state);
- struct tevent_req *preq;
+ struct tevent_req *subreq;
enum sdap_result result;
int ret;
@@ -399,34 +393,35 @@ static void sdap_pam_auth_done(struct tevent_req *req)
if (result == SDAP_AUTH_SUCCESS &&
state->breq->be_ctx->domain->cache_credentials) {
- preq = sdap_cache_pw_send(state,
- state->breq->be_ctx->ev,
- state->breq->be_ctx->sysdb,
- state->breq->be_ctx->domain,
- state->username,
- state->password);
+ subreq = sysdb_cache_password_send(state,
+ state->breq->be_ctx->ev,
+ state->breq->be_ctx->sysdb,
+ NULL,
+ state->breq->be_ctx->domain,
+ state->username, state->password);
/* password caching failures are not fatal errors */
- if (!preq) {
+ if (!subreq) {
DEBUG(2, ("Failed to cache password for %s\n", state->username));
goto done;
}
- tevent_req_set_callback(preq, sdap_password_cache_done, state);
+ tevent_req_set_callback(subreq, sdap_password_cache_done, state);
return;
}
done:
- sdap_pam_auth_reply(state->breq, state->pd->pam_status, NULL);
+ sdap_pam_auth_reply(state->breq, state->pd->pam_status);
}
-static void sdap_password_cache_done(struct tevent_req *req)
+static void sdap_password_cache_done(struct tevent_req *subreq)
{
- struct sdap_pam_auth_state *state =
- tevent_req_callback_data(req, struct sdap_pam_auth_state);
+ struct sdap_pam_auth_state *state = tevent_req_callback_data(subreq,
+ struct sdap_pam_auth_state);
int ret;
- ret = sdap_cache_pw_recv(req);
+ ret = sysdb_cache_password_recv(subreq);
+ talloc_zfree(subreq);
if (ret) {
/* password caching failures are not fatal errors */
DEBUG(2, ("Failed to cache password for %s\n", state->username));
@@ -434,13 +429,14 @@ static void sdap_password_cache_done(struct tevent_req *req)
DEBUG(4, ("Password successfully cached for %s\n", state->username));
}
- talloc_zfree(req);
- sdap_pam_auth_reply(state->breq, state->pd->pam_status, NULL);
+ sdap_pam_auth_reply(state->breq, state->pd->pam_status);
}
-static void sdap_pam_auth_reply(struct be_req *req, int result, const char *err)
+static void sdap_pam_auth_reply(struct be_req *req, int result)
{
- req->fn(req, result, err);
+ const char *errstr = NULL;
+ if (result) errstr = "Operation failed";
+ req->fn(req, result, errstr);
}
/* ==Module-Initialization-and-Dispose==================================== */
diff --git a/server/providers/ldap/sdap_async.c b/server/providers/ldap/sdap_async.c
index e618824de..2aba33c19 100644
--- a/server/providers/ldap/sdap_async.c
+++ b/server/providers/ldap/sdap_async.c
@@ -520,103 +520,6 @@ int sdap_auth_recv(struct tevent_req *req, enum sdap_result *result)
return EOK;
}
-/* ==Password=Caching===================================================== */
-
-struct sdap_cache_pw_state {
- struct sss_domain_info *domain;
- const char *username;
- const char *password;
-
- struct sysdb_req *sysreq;
-
- int result;
-};
-
-static void sdap_cache_pw_op(struct sysdb_req *req, void *pvt);
-static void sdap_cache_pw_callback(void *pvt, int error, struct ldb_result *r);
-
-struct tevent_req *sdap_cache_pw_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sss_domain_info *domain,
- const char *username,
- const char *password)
-{
- struct tevent_req *req;
- struct sdap_cache_pw_state *state;
- int ret;
-
- req = tevent_req_create(memctx, &state, struct sdap_cache_pw_state);
- if (!req) return NULL;
-
- state->domain = domain;
- state->username = username;
- state->password = password;
-
- ret = sysdb_transaction(state, sysdb, sdap_cache_pw_op, req);
-
- if (ret != EOK) {
- DEBUG(1, ("Failed to start sysydb transaction (%d)[%s]!?\n",
- ret, strerror(ret)));
- goto fail;
- }
-
- return req;
-
-fail:
- tevent_req_error(req, EIO);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void sdap_cache_pw_op(struct sysdb_req *sysreq, void *pvt)
-{
- struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
- struct sdap_cache_pw_state *state = tevent_req_data(req,
- struct sdap_cache_pw_state);
- int ret;
-
- state->sysreq = sysreq;
-
- ret = sysdb_set_cached_password(sysreq,
- state->domain,
- state->username,
- state->password,
- sdap_cache_pw_callback, req);
- if (ret != EOK) {
- state->result = ret;
- tevent_req_done(req);
- }
-}
-
-static void sdap_cache_pw_callback(void *pvt, int e, struct ldb_result *r)
-{
- struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
- struct sdap_cache_pw_state *state = tevent_req_data(req,
- struct sdap_cache_pw_state);
- sysdb_transaction_done(state->sysreq, e);
-
- if (e != EOK) {
- DEBUG(2, ("Failed to cache password (%d)[%s]!?\n", e, strerror(e)));
- state->result = e;
- }
-
- state->result = EOK;
- tevent_req_done(req);
-}
-
-int sdap_cache_pw_recv(struct tevent_req *req)
-{
- struct sdap_cache_pw_state *state = tevent_req_data(req,
- struct sdap_cache_pw_state);
- enum tevent_req_state tstate;
- uint64_t err;
-
- if (tevent_req_is_error(req, &tstate, &err)) {
- return err;
- }
- return state->result;
-}
/* ==Save-User-Entry====================================================== */
diff --git a/server/providers/ldap/sdap_async.h b/server/providers/ldap/sdap_async.h
index 6b72ac04d..37c307a0e 100644
--- a/server/providers/ldap/sdap_async.h
+++ b/server/providers/ldap/sdap_async.h
@@ -79,12 +79,3 @@ struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
const char *password);
int sdap_auth_recv(struct tevent_req *req, enum sdap_result *result);
-
-struct tevent_req *sdap_cache_pw_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sss_domain_info *domain,
- const char *username,
- const char *password);
-
-int sdap_cache_pw_recv(struct tevent_req *req);
diff --git a/server/providers/proxy.c b/server/providers/proxy.c
index 58d52d540..23360945b 100644
--- a/server/providers/proxy.c
+++ b/server/providers/proxy.c
@@ -158,12 +158,6 @@ failed:
}
static void proxy_pam_handler_cache_done(struct tevent_req *treq);
-static struct tevent_req *cache_password_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sss_domain_info *domain,
- const char *username,
- struct authtok_conv *ac);
static void proxy_reply(struct be_req *req,
int error, const char *errstr);
@@ -257,32 +251,46 @@ static void proxy_pam_handler(struct be_req *req) {
pd->pam_status = pam_status;
if (cache_auth_data) {
- struct tevent_req *treq;
+ struct tevent_req *subreq;
+ char *password;
- treq = cache_password_send(req, req->be_ctx->ev,
- req->be_ctx->sysdb,
- req->be_ctx->domain,
- pd->user, auth_data);
- if (!treq) {
+ password = talloc_size(req, auth_data->authtok_size + 1);
+ if (!password) {
/* password caching failures are not fatal errors */
return proxy_reply(req, EOK, NULL);
}
- tevent_req_set_callback(treq, proxy_pam_handler_cache_done, req);
-
- return;
+ memcpy(password, auth_data->authtok, auth_data->authtok_size);
+ password[auth_data->authtok_size] = '\0';
+ talloc_set_destructor((TALLOC_CTX *)password, password_destructor);
+
+ subreq = sysdb_cache_password_send(req, req->be_ctx->ev,
+ req->be_ctx->sysdb, NULL,
+ req->be_ctx->domain,
+ pd->user, password);
+ if (!subreq) {
+ /* password caching failures are not fatal errors */
+ return proxy_reply(req, EOK, NULL);
+ }
+ tevent_req_set_callback(subreq, proxy_pam_handler_cache_done, req);
}
proxy_reply(req, EOK, NULL);
}
-static void proxy_pam_handler_cache_done(struct tevent_req *treq)
+static void proxy_pam_handler_cache_done(struct tevent_req *subreq)
{
- struct be_req *req = tevent_req_callback_data(treq, struct be_req);
+ struct be_req *req = tevent_req_callback_data(subreq, struct be_req);
+ int ret;
/* password caching failures are not fatal errors */
+ ret = sysdb_cache_password_recv(subreq);
+ talloc_zfree(subreq);
- /* so we just ignore any return */
- talloc_zfree(treq);
+ /* so we just log it any return */
+ if (ret) {
+ DEBUG(2, ("Failed to cache password (%d)[%s]!?\n",
+ ret, strerror(ret)));
+ }
return proxy_reply(req, EOK, NULL);
}
@@ -342,115 +350,6 @@ static int proxy_default_recv(struct tevent_req *req)
}
-/* =Password-Caching======================================================*/
-
-struct cache_pw_state {
- struct tevent_context *ev;
- struct sss_domain_info *domain;
- const char *name;
- char *passwd;
-
- struct sysdb_handle *handle;
-};
-
-static void cache_password_process(struct tevent_req *subreq);
-static void cache_password_done(struct tevent_req *subreq);
-
-static struct tevent_req *cache_password_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sss_domain_info *domain,
- const char *username,
- struct authtok_conv *ac)
-{
- struct tevent_req *req, *subreq;
- struct cache_pw_state *state;
- int ret;
-
- req = tevent_req_create(mem_ctx, &state, struct cache_pw_state);
- if (!req) {
- ret = ENOMEM;
- goto fail;
- }
-
- state->ev = ev;
- state->handle = NULL;
- state->name = username;
-
- state->passwd = talloc_size(state, ac->authtok_size + 1);
- if (!state->passwd) {
- ret = ENOMEM;
- goto fail;
- }
- memcpy(state->passwd, ac->authtok, ac->authtok_size);
- state->passwd[ac->authtok_size] = '\0';
- talloc_set_destructor((TALLOC_CTX *)state->passwd,
- password_destructor);
-
- subreq = sysdb_transaction_send(state, state->ev, sysdb);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, cache_password_process, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void cache_password_process(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct cache_pw_state *state = tevent_req_data(req,
- struct cache_pw_state);
- int ret;
-
- ret = sysdb_transaction_recv(subreq, state, &state->handle);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sysdb_set_cached_password_send(state, state->ev, state->handle,
- state->domain,
- state->name,
- state->passwd);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, cache_password_done, req);
-}
-
-static void cache_password_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct cache_pw_state *state = tevent_req_data(req,
- struct cache_pw_state);
- int ret;
-
- ret = sysdb_set_cached_password_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sysdb_transaction_commit_send(state, state->ev, state->handle);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, proxy_default_done, req);
-}
-
-
/* =Getpwnam-wrapper======================================================*/
static void get_pw_name_process(struct tevent_req *subreq);