diff options
Diffstat (limited to 'server/db')
-rw-r--r-- | server/db/sysdb.c | 20 | ||||
-rw-r--r-- | server/db/sysdb.h | 27 | ||||
-rw-r--r-- | server/db/sysdb_ops.c | 113 |
3 files changed, 129 insertions, 31 deletions
diff --git a/server/db/sysdb.c b/server/db/sysdb.c index 1951a9b3..0cac339e 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 aa1aaf4c..a81f4630 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 24d90b12..c53d6720 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); } |