diff options
Diffstat (limited to 'server/nss/nsssrv_ldb.c')
-rw-r--r-- | server/nss/nsssrv_ldb.c | 169 |
1 files changed, 159 insertions, 10 deletions
diff --git a/server/nss/nsssrv_ldb.c b/server/nss/nsssrv_ldb.c index a54bc6a5..04225e00 100644 --- a/server/nss/nsssrv_ldb.c +++ b/server/nss/nsssrv_ldb.c @@ -27,6 +27,7 @@ #include "nss/nss_ldb.h" struct nss_ldb_search_ctx { + struct ldb_context *ldb; nss_ldb_callback_t callback; void *ptr; struct ldb_result *res; @@ -49,8 +50,8 @@ static int request_done(struct nss_ldb_search_ctx *sctx) return sctx->callback(sctx->ptr, EOK, sctx->res); } -static int getpw_callback(struct ldb_request *req, - struct ldb_reply *ares) +static int get_gen_callback(struct ldb_request *req, + struct ldb_reply *ares) { struct nss_ldb_search_ctx *sctx; struct ldb_result *res; @@ -109,6 +110,7 @@ static int getpw_callback(struct ldb_request *req, } static struct nss_ldb_search_ctx *init_sctx(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, nss_ldb_callback_t fn, void *ptr) { struct nss_ldb_search_ctx *sctx; @@ -117,6 +119,7 @@ static struct nss_ldb_search_ctx *init_sctx(TALLOC_CTX *mem_ctx, if (!sctx) { return NULL; } + sctx->ldb = ldb; sctx->callback = fn; sctx->ptr = ptr; sctx->res = talloc_zero(sctx, struct ldb_result); @@ -128,7 +131,7 @@ static struct nss_ldb_search_ctx *init_sctx(TALLOC_CTX *mem_ctx, return sctx; } -static int do_search(struct nss_ldb_search_ctx *sctx, +static int pwd_search(struct nss_ldb_search_ctx *sctx, struct ldb_context *ldb, const char *expression) { @@ -140,7 +143,7 @@ static int do_search(struct nss_ldb_search_ctx *sctx, ldb_dn_new(sctx, ldb, NSS_USER_BASE), LDB_SCOPE_SUBTREE, expression, attrs, NULL, - sctx, getpw_callback, + sctx, get_gen_callback, NULL); if (ret != LDB_SUCCESS) { return nss_ldb_error_to_errno(ret); @@ -163,7 +166,7 @@ int nss_ldb_getpwnam(TALLOC_CTX *mem_ctx, struct nss_ldb_search_ctx *sctx; char *expression; - sctx = init_sctx(mem_ctx, fn, ptr); + sctx = init_sctx(mem_ctx, ldb, fn, ptr); if (!sctx) { return ENOMEM; } @@ -174,7 +177,7 @@ int nss_ldb_getpwnam(TALLOC_CTX *mem_ctx, return ENOMEM; } - return do_search(sctx, ldb, expression); + return pwd_search(sctx, ldb, expression); } int nss_ldb_getpwuid(TALLOC_CTX *mem_ctx, @@ -187,7 +190,7 @@ int nss_ldb_getpwuid(TALLOC_CTX *mem_ctx, unsigned long long int filter_uid = uid; char *expression; - sctx = init_sctx(mem_ctx, fn, ptr); + sctx = init_sctx(mem_ctx, ldb, fn, ptr); if (!sctx) { return ENOMEM; } @@ -198,7 +201,7 @@ int nss_ldb_getpwuid(TALLOC_CTX *mem_ctx, return ENOMEM; } - return do_search(sctx, ldb, expression); + return pwd_search(sctx, ldb, expression); } int nss_ldb_enumpwent(TALLOC_CTX *mem_ctx, @@ -208,14 +211,160 @@ int nss_ldb_enumpwent(TALLOC_CTX *mem_ctx, { struct nss_ldb_search_ctx *sctx; - sctx = init_sctx(mem_ctx, fn, ptr); + sctx = init_sctx(mem_ctx, ldb, fn, ptr); + if (!sctx) { + return ENOMEM; + } + + return pwd_search(sctx, ldb, NSS_PWENT_FILTER); +} + + + +static int get_grp_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct nss_ldb_search_ctx *sctx; + struct ldb_result *res; + int n; + + sctx = talloc_get_type(req->context, struct nss_ldb_search_ctx); + res = sctx->res; + + if (!ares) { + return request_error(sctx, LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return request_error(sctx, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + res->msgs = talloc_realloc(res, res->msgs, + struct ldb_message *, + res->count + 2); + if (!res->msgs) { + return request_error(sctx, LDB_ERR_OPERATIONS_ERROR); + } + + res->msgs[res->count + 1] = NULL; + + res->msgs[res->count] = talloc_steal(res->msgs, ares->message); + res->count++; + break; + + case LDB_REPLY_REFERRAL: + if (res->refs) { + for (n = 0; res->refs[n]; n++) /*noop*/ ; + } else { + n = 0; + } + + res->refs = talloc_realloc(res, res->refs, char *, n + 2); + if (! res->refs) { + return request_error(sctx, LDB_ERR_OPERATIONS_ERROR); + } + + res->refs[n] = talloc_steal(res->refs, ares->referral); + res->refs[n + 1] = NULL; + break; + + case LDB_REPLY_DONE: + res->controls = talloc_steal(res, ares->controls); + + /* no results, return */ + if (res->count == 0) { + return request_done(sctx); + } + /* 1 result, let's search for members now and append results */ + if (res->count == 1) { + static const char *attrs[] = NSS_GRPW_ATTRS; + struct ldb_request *ureq; + const char *expression; + int ret; + + expression = talloc_asprintf(sctx, NSS_GRNA2_FILTER, + ldb_dn_get_linearized(res->msgs[0]->dn)); + if (!expression) { + return request_error(sctx, LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_build_search_req(&ureq, sctx->ldb, sctx, + ldb_dn_new(sctx, sctx->ldb, NSS_USER_BASE), + LDB_SCOPE_SUBTREE, + expression, attrs, NULL, + sctx, get_gen_callback, + NULL); + if (ret != LDB_SUCCESS) { + return request_error(sctx, ret); + } + + ret = ldb_request(sctx->ldb, ureq); + if (ret != LDB_SUCCESS) { + return request_error(sctx, ret); + } + + return LDB_SUCCESS; + } + + /* anything else is an error */ + return request_error(sctx, LDB_ERR_OPERATIONS_ERROR); + } + + talloc_free(ares); + return LDB_SUCCESS; +} + +static int grp_search(struct nss_ldb_search_ctx *sctx, + struct ldb_context *ldb, + const char *expression) +{ + static const char *attrs[] = NSS_GRNAM_ATTRS; + struct ldb_request *req; + int ret; + + ret = ldb_build_search_req(&req, ldb, sctx, + ldb_dn_new(sctx, ldb, NSS_GROUP_BASE), + LDB_SCOPE_SUBTREE, + expression, attrs, NULL, + sctx, get_grp_callback, + NULL); + if (ret != LDB_SUCCESS) { + return nss_ldb_error_to_errno(ret); + } + + ret = ldb_request(ldb, req); + if (ret != LDB_SUCCESS) { + return nss_ldb_error_to_errno(ret); + } + + return EOK; +} + +int nss_ldb_getgrnam(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct ldb_context *ldb, + const char *name, + nss_ldb_callback_t fn, void *ptr) +{ + struct nss_ldb_search_ctx *sctx; + char *expression; + + sctx = init_sctx(mem_ctx, ldb, fn, ptr); if (!sctx) { return ENOMEM; } - return do_search(sctx, ldb, NSS_PWENT_FILTER); + expression = talloc_asprintf(sctx, NSS_GRNAM_FILTER, name); + if (!expression) { + talloc_free(sctx); + return ENOMEM; + } + + return grp_search(sctx, ldb, expression); } + int nss_ldb_init(TALLOC_CTX *mem_ctx, struct event_context *ev, struct ldb_context **ldbp) |