summaryrefslogtreecommitdiff
path: root/server/nss/nsssrv_ldb.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/nss/nsssrv_ldb.c')
-rw-r--r--server/nss/nsssrv_ldb.c169
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)