From 71eacad35be73dc30d56d3cffa9785a533d25fc8 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 2 Mar 2009 18:44:44 -0500 Subject: Provide sysdb_set_user_attr() functions. Provide also helper functions to build struct sysdb_attrs. Also fix sysdb_get_user_attr() to have a consistent interface as all other functions. --- server/db/sysdb.c | 75 ++++++++++++++++++++++++++++++++++++++++ server/db/sysdb.h | 22 +++++++++++- server/db/sysdb_ops.c | 56 ++++++++++++++++++++++++++++++ server/db/sysdb_search.c | 5 +-- server/infopipe/infopipe_users.c | 3 +- 5 files changed, 157 insertions(+), 4 deletions(-) diff --git a/server/db/sysdb.c b/server/db/sysdb.c index f4cbd569f..022e33e47 100644 --- a/server/db/sysdb.c +++ b/server/db/sysdb.c @@ -41,6 +41,81 @@ struct ldb_context *sysdb_ctx_get_ldb(struct sysdb_ctx *ctx) return ctx->ldb; } +struct sysdb_attrs *sysdb_new_attrs(TALLOC_CTX *memctx) +{ + return talloc_zero(memctx, struct sysdb_attrs); +} + +static int sysdb_attrs_get_el(struct sysdb_attrs *attrs, const char *name, + struct ldb_message_element **el) +{ + struct ldb_message_element *e = NULL; + int i; + + for (i = 0; i < attrs->num; i++) { + if (strcasecmp(name, attrs->a[i].name) == 0) + e = &(attrs->a[i]); + } + + if (!e) { + e = talloc_realloc(attrs, attrs->a, + struct ldb_message_element, attrs->num+1); + if (!e) return ENOMEM; + attrs->a = e; + + e[attrs->num].name = talloc_strdup(e, name); + if (!e[attrs->num].name) return ENOMEM; + + e[attrs->num].num_values = 0; + e[attrs->num].values = NULL; + e[attrs->num].flags = 0; + + e = &(attrs->a[attrs->num]); + attrs->num++; + } + + *el = e; + + return EOK; +} + +int sysdb_attrs_add_val(struct sysdb_attrs *attrs, + const char *name, const struct ldb_val *val) +{ + struct ldb_message_element *el; + struct ldb_val *vals; + int ret; + + ret = sysdb_attrs_get_el(attrs, name, &el); + + + vals = talloc_realloc(attrs->a, el->values, + struct ldb_val, el->num_values+1); + if (!vals) return ENOMEM; + + vals[el->num_values] = ldb_val_dup(vals, val); + if (vals[el->num_values].data == NULL && + vals[el->num_values].length != 0) { + return ENOMEM; + } + + el->values = vals; + el->num_values++; + + return EOK; +} + +int sysdb_attrs_add_string(struct sysdb_attrs *attrs, + const char *name, const char *str) +{ + struct ldb_val v; + + v.data = (uint8_t *)str; + v.length = strlen(str); + + return sysdb_attrs_add_val(attrs, name, &v); +} + /************************************************ * Initialiazation stuff */ diff --git a/server/db/sysdb.h b/server/db/sysdb.h index 498ad09bf..add922e6b 100644 --- a/server/db/sysdb.h +++ b/server/db/sysdb.h @@ -111,6 +111,11 @@ struct confdb_ctx; struct sysdb_ctx; struct sysdb_req; +struct sysdb_attrs { + int num; + struct ldb_message_element *a; +}; + typedef void (*sysdb_callback_t)(void *, int, struct ldb_result *); typedef void (*sysdb_req_fn_t)(struct sysdb_req *, void *pvt); @@ -166,11 +171,13 @@ int sysdb_initgroups(TALLOC_CTX *mem_ctx, const char *name, bool legacy, sysdb_callback_t fn, void *ptr); + int sysdb_get_user_attr(TALLOC_CTX *mem_ctx, struct sysdb_ctx *ctx, - struct sss_domain_info *domain, + const char *domain, const char *name, const char **attributes, + bool legacy, sysdb_callback_t fn, void *ptr); struct ldb_context *sysdb_ctx_get_ldb(struct sysdb_ctx *ctx); @@ -215,6 +222,19 @@ int sysdb_delete_group_by_gid(struct sysdb_req *sysreq, const char *domain, gid_t gid, sysdb_callback_t fn, void *pvt); +struct sysdb_attrs *sysdb_new_attrs(TALLOC_CTX *memctx); +int sysdb_attrs_add_val(struct sysdb_attrs *attrs, + const char *name, const struct ldb_val *val); +int sysdb_attrs_add_string(struct sysdb_attrs *attrs, + const char *name, const char *str); + +int sysdb_set_user_attr(struct sysdb_req *sysreq, + struct sysdb_ctx *ctx, + const char *domain, + const char *name, + struct sysdb_attrs *attributes, + sysdb_callback_t fn, void *ptr); + /* legacy functions for proxy providers */ int sysdb_legacy_store_user(struct sysdb_req *sysreq, diff --git a/server/db/sysdb_ops.c b/server/db/sysdb_ops.c index ffcf1cd7d..3a51f4351 100644 --- a/server/db/sysdb_ops.c +++ b/server/db/sysdb_ops.c @@ -437,6 +437,62 @@ int sysdb_delete_group_by_gid(struct sysdb_req *sysreq, return EOK; } +int sysdb_set_user_attr(struct sysdb_req *sysreq, + struct sysdb_ctx *ctx, + const char *domain, + const char *name, + struct sysdb_attrs *attrs, + sysdb_callback_t fn, void *pvt) +{ + struct sysdb_cb_ctx *cbctx; + struct ldb_message *msg; + struct ldb_request *req; + int i, ret; + + if (!sysdb_req_check_running(sysreq)) { + DEBUG(2, ("Invalid request! Not running at this time.\n")); + return EINVAL; + } + + if (attrs->num == 0) return EINVAL; + + cbctx = talloc_zero(sysreq, struct sysdb_cb_ctx); + if (!cbctx) return ENOMEM; + + cbctx->fn = fn; + cbctx->pvt = pvt; + + msg = ldb_msg_new(cbctx); + if (!msg) return ENOMEM; + + msg->dn = sysdb_user_dn(ctx, msg, domain, name); + if (!msg->dn) return ENOMEM; + + msg->elements = talloc_array(msg, struct ldb_message_element, attrs->num); + if (!msg->elements) return ENOMEM; + + for (i = 0; i < attrs->num; i++) { + msg->elements[i] = attrs->a[i]; + msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; + } + + msg->num_elements = attrs->num; + + ret = ldb_build_mod_req(&req, ctx->ldb, cbctx, msg, NULL, + cbctx, sysdb_op_callback, NULL); + if (ret == LDB_SUCCESS) { + ret = ldb_request(ctx->ldb, req); + } + if (ret != LDB_SUCCESS) { + return sysdb_error_to_errno(ret); + } + + return EOK; +} + + + + /* "sysdb_legacy_" functions * the set of functions named sysdb_legacy_* are used by modules * that only have access to strictly posix like databases where diff --git a/server/db/sysdb_search.c b/server/db/sysdb_search.c index 7f7eeb11c..c5a85caca 100644 --- a/server/db/sysdb_search.c +++ b/server/db/sysdb_search.c @@ -740,9 +740,10 @@ int sysdb_initgroups(TALLOC_CTX *mem_ctx, int sysdb_get_user_attr(TALLOC_CTX *mem_ctx, struct sysdb_ctx *ctx, - struct sss_domain_info *domain, + const char *domain, const char *name, const char **attributes, + bool legacy, sysdb_callback_t fn, void *ptr) { struct sysdb_search_ctx *sctx; @@ -751,7 +752,7 @@ int sysdb_get_user_attr(TALLOC_CTX *mem_ctx, return EINVAL; } - sctx = init_src_ctx(mem_ctx, domain->name, domain->legacy, ctx, fn, ptr); + sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr); if (!sctx) { return ENOMEM; } diff --git a/server/infopipe/infopipe_users.c b/server/infopipe/infopipe_users.c index 4b9b0255c..4495f09d7 100644 --- a/server/infopipe/infopipe_users.c +++ b/server/infopipe/infopipe_users.c @@ -579,9 +579,10 @@ static int infp_get_attr_lookup(struct infp_getattr_ctx *infp_getattr_req) /* Call into the sysdb for the requested attributes */ ret = sysdb_get_user_attr(infp_getattr_req, infp_getattr_req->infp_req->infp->sysdb, - infp_getattr_req->domain, + infp_getattr_req->domain->name, infp_getattr_req->usernames[infp_getattr_req->index], (const char **)attributes, + infp_getattr_req->domain->legacy, infp_get_attr_lookup_callback, infp_getattr_req); return EOK; -- cgit