summaryrefslogtreecommitdiff
path: root/server/db/sysdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/db/sysdb.c')
-rw-r--r--server/db/sysdb.c745
1 files changed, 9 insertions, 736 deletions
diff --git a/server/db/sysdb.c b/server/db/sysdb.c
index ddd7fbe4..1c91f122 100644
--- a/server/db/sysdb.c
+++ b/server/db/sysdb.c
@@ -20,743 +20,13 @@
*/
#include "util/util.h"
-#include "db/sysdb.h"
-#include "db/sysdb_internal.h"
+#include "db/sysdb_private.h"
#include "confdb/confdb.h"
#include <time.h>
-struct sysdb_search_ctx {
- struct sysdb_ctx *dbctx;
- const char *domain;
- bool legacy;
- sysdb_callback_t callback;
- void *ptr;
- struct ldb_result *res;
-};
-
-static int sysdb_error_to_errno(int lerr)
-{
- /* fake it up for now, requires a mapping table */
- return EIO;
-}
-
-static void request_error(struct sysdb_search_ctx *sctx, int ldb_error)
-{
- sctx->callback(sctx->ptr, sysdb_error_to_errno(ldb_error), sctx->res);
-}
-
-static void request_done(struct sysdb_search_ctx *sctx)
-{
- sctx->callback(sctx->ptr, EOK, sctx->res);
-}
-
-static int get_gen_callback(struct ldb_request *req,
- struct ldb_reply *ares)
-{
- struct sysdb_search_ctx *sctx;
- struct ldb_result *res;
- int n;
-
- sctx = talloc_get_type(req->context, struct sysdb_search_ctx);
- res = sctx->res;
-
- if (!ares) {
- request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- if (ares->error != LDB_SUCCESS) {
- request_error(sctx, ares->error);
- return 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) {
- request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- return 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) {
- request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- return 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);
-
- /* this is the last message, and means the request is done */
- request_done(sctx);
- return LDB_SUCCESS;
- }
-
- talloc_free(ares);
- return LDB_SUCCESS;
-}
-
-static struct sysdb_search_ctx *init_src_ctx(TALLOC_CTX *mem_ctx,
- const char *domain,
- bool legacy,
- struct sysdb_ctx *ctx,
- sysdb_callback_t fn,
- void *ptr)
-{
- struct sysdb_search_ctx *sctx;
-
- sctx = talloc(mem_ctx, struct sysdb_search_ctx);
- if (!sctx) {
- return NULL;
- }
- sctx->dbctx = ctx;
- sctx->callback = fn;
- sctx->ptr = ptr;
- sctx->res = talloc_zero(sctx, struct ldb_result);
- if (!sctx->res) {
- talloc_free(sctx);
- return NULL;
- }
- sctx->domain = talloc_strdup(sctx, domain);
- if (!sctx->domain) {
- talloc_free(sctx);
- return NULL;
- }
- sctx->legacy = legacy;
-
- return sctx;
-}
-
-/* users */
-
-static int pwd_search(struct sysdb_search_ctx *sctx,
- struct sysdb_ctx *ctx,
- const char *expression)
-{
- static const char *attrs[] = SYSDB_PW_ATTRS;
- struct ldb_request *req;
- struct ldb_dn *base_dn;
- int ret;
-
- base_dn = ldb_dn_new_fmt(sctx, ctx->ldb,
- SYSDB_TMPL_USER_BASE, sctx->domain);
- if (!base_dn) {
- return ENOMEM;
- }
-
- ret = ldb_build_search_req(&req, ctx->ldb, sctx,
- base_dn, LDB_SCOPE_SUBTREE,
- expression, attrs, NULL,
- sctx, get_gen_callback,
- NULL);
- if (ret != LDB_SUCCESS) {
- return sysdb_error_to_errno(ret);
- }
-
- ret = ldb_request(ctx->ldb, req);
- if (ret != LDB_SUCCESS) {
- return sysdb_error_to_errno(ret);
- }
-
- return EOK;
-}
-
-int sysdb_getpwnam(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *ctx,
- const char *domain,
- const char *name,
- bool legacy,
- sysdb_callback_t fn, void *ptr)
-{
- struct sysdb_search_ctx *sctx;
- char *expression;
-
- if (!domain) {
- return EINVAL;
- }
-
- sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr);
- if (!sctx) {
- return ENOMEM;
- }
-
- expression = talloc_asprintf(sctx, SYSDB_PWNAM_FILTER, name);
- if (!expression) {
- talloc_free(sctx);
- return ENOMEM;
- }
-
- return pwd_search(sctx, ctx, expression);
-}
-
-int sysdb_getpwuid(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *ctx,
- const char *domain,
- uid_t uid,
- bool legacy,
- sysdb_callback_t fn, void *ptr)
-{
- struct sysdb_search_ctx *sctx;
- unsigned long int filter_uid = uid;
- char *expression;
-
- if (!domain) {
- return EINVAL;
- }
-
- sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr);
- if (!sctx) {
- return ENOMEM;
- }
-
- expression = talloc_asprintf(sctx, SYSDB_PWUID_FILTER, filter_uid);
- if (!expression) {
- talloc_free(sctx);
- return ENOMEM;
- }
-
- return pwd_search(sctx, ctx, expression);
-}
-
-int sysdb_enumpwent(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *ctx,
- const char *domain,
- bool legacy,
- sysdb_callback_t fn, void *ptr)
-{
- struct sysdb_search_ctx *sctx;
-
- if (!domain) {
- return EINVAL;
- }
-
- sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr);
- if (!sctx) {
- return ENOMEM;
- }
-
- return pwd_search(sctx, ctx, SYSDB_PWENT_FILTER);
-}
-
-/* groups */
-
-struct get_mem_ctx {
- struct sysdb_search_ctx *ret_sctx;
- struct ldb_message **grps;
- int num_grps;
-};
-
-static void get_members(void *ptr, int status, struct ldb_result *res)
-{
- struct sysdb_ctx *ctx;
- struct sysdb_search_ctx *sctx;
- struct get_mem_ctx *gmctx;
- struct sysdb_search_ctx *mem_sctx;
- struct ldb_request *req;
- struct ldb_message *msg;
- struct ldb_result *ret_res;
- struct ldb_dn *dn;
- static const char *attrs[] = SYSDB_GRPW_ATTRS;
- const char *expression;
- int ret, i;
-
- sctx = talloc_get_type(ptr, struct sysdb_search_ctx);
- gmctx = talloc_get_type(sctx->ptr, struct get_mem_ctx);
- ctx = sctx->dbctx;
-
- if (status != LDB_SUCCESS) {
- return request_error(gmctx->ret_sctx, status);
- }
-
- ret_res = gmctx->ret_sctx->res;
-
- /* append previous search results to final (if any) */
- if (res && res->count != 0) {
- ret_res->msgs = talloc_realloc(ret_res, ret_res->msgs,
- struct ldb_message *,
- ret_res->count + res->count + 1);
- for(i = 0; i < res->count; i++) {
- ret_res->msgs[ret_res->count] = talloc_steal(ret_res, res->msgs[i]);
- ret_res->count++;
- }
- ret_res->msgs[ret_res->count] = NULL;
- }
-
- if (gmctx->grps[0] == NULL) {
- return request_done(gmctx->ret_sctx);
- }
-
- mem_sctx = init_src_ctx(gmctx, sctx->domain, sctx->legacy,
- ctx, get_members, sctx);
- if (!mem_sctx) {
- return request_error(gmctx->ret_sctx, LDB_ERR_OPERATIONS_ERROR);
- }
-
- /* fetch next group to search for members */
- gmctx->num_grps--;
- msg = gmctx->grps[gmctx->num_grps];
- gmctx->grps[gmctx->num_grps] = NULL;
-
- /* queue the group entry on the final result structure */
- ret_res->msgs = talloc_realloc(ret_res, ret_res->msgs,
- struct ldb_message *,
- ret_res->count + 2);
- if (!ret_res->msgs) {
- return request_error(gmctx->ret_sctx, LDB_ERR_OPERATIONS_ERROR);
- }
- ret_res->msgs[ret_res->count + 1] = NULL;
- ret_res->msgs[ret_res->count] = talloc_steal(ret_res->msgs, msg);
- ret_res->count++;
-
- /* search for this group members */
- expression = talloc_asprintf(mem_sctx, SYSDB_GRNA2_FILTER,
- ldb_dn_get_linearized(msg->dn));
- if (!expression) {
- return request_error(gmctx->ret_sctx, LDB_ERR_OPERATIONS_ERROR);
- }
-
- dn = ldb_dn_new_fmt(mem_sctx, ctx->ldb,
- SYSDB_TMPL_USER_BASE, sctx->domain);
- if (!dn) {
- return request_error(gmctx->ret_sctx, LDB_ERR_OPERATIONS_ERROR);
- }
-
- ret = ldb_build_search_req(&req, ctx->ldb, mem_sctx,
- dn, LDB_SCOPE_SUBTREE,
- expression, attrs, NULL,
- mem_sctx, get_gen_callback,
- NULL);
- if (ret != LDB_SUCCESS) {
- return request_error(gmctx->ret_sctx, ret);
- }
-
- ret = ldb_request(ctx->ldb, req);
- if (ret != LDB_SUCCESS) {
- return request_error(gmctx->ret_sctx, ret);
- }
-}
-
-static int get_grp_callback(struct ldb_request *req,
- struct ldb_reply *ares)
-{
- struct sysdb_search_ctx *sctx;
- struct sysdb_ctx *ctx;
- struct ldb_result *res;
- int n;
-
- sctx = talloc_get_type(req->context, struct sysdb_search_ctx);
- ctx = sctx->dbctx;
- res = sctx->res;
-
- if (!ares) {
- request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- if (ares->error != LDB_SUCCESS) {
- request_error(sctx, ares->error);
- return 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) {
- request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- return 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) {
- request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- return 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) {
- request_done(sctx);
- return LDB_SUCCESS;
- }
- if (res->count > 0) {
- struct get_mem_ctx *gmctx;
-
- gmctx = talloc_zero(req, struct get_mem_ctx);
- if (!gmctx) {
- request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- return LDB_ERR_OPERATIONS_ERROR;
- }
- gmctx->ret_sctx = sctx;
- gmctx->grps = talloc_steal(gmctx, res->msgs);
- gmctx->num_grps = res->count;
- res->msgs = NULL;
- res->count = 0;
-
- /* re-use sctx to create a fake handler for the first call to
- * get_members() */
- sctx = init_src_ctx(gmctx,
- sctx->domain, sctx->legacy,
- ctx, get_members, gmctx);
-
- get_members(sctx, LDB_SUCCESS, NULL);
- return LDB_SUCCESS;
- }
-
- /* anything else is an error */
- request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- talloc_free(ares);
- return LDB_SUCCESS;
-}
-
-static int grp_search(struct sysdb_search_ctx *sctx,
- struct sysdb_ctx *ctx,
- const char *expression)
-{
- ldb_request_callback_t callback;
- static const char *attrs[] = SYSDB_GRNAM_ATTRS;
- struct ldb_request *req;
- struct ldb_dn *base_dn;
- int ret;
-
- if (sctx->legacy) {
- callback = get_gen_callback;
- } else {
- callback = get_grp_callback;
- }
-
- base_dn = ldb_dn_new_fmt(sctx, ctx->ldb,
- SYSDB_TMPL_GROUP_BASE, sctx->domain);
- if (!base_dn) {
- return ENOMEM;
- }
-
- ret = ldb_build_search_req(&req, ctx->ldb, sctx,
- base_dn, LDB_SCOPE_SUBTREE,
- expression, attrs, NULL,
- sctx, callback,
- NULL);
- if (ret != LDB_SUCCESS) {
- return sysdb_error_to_errno(ret);
- }
-
- ret = ldb_request(ctx->ldb, req);
- if (ret != LDB_SUCCESS) {
- return sysdb_error_to_errno(ret);
- }
-
- return EOK;
-}
-
-int sysdb_getgrnam(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *ctx,
- const char *domain,
- const char *name,
- bool legacy,
- sysdb_callback_t fn, void *ptr)
-{
- struct sysdb_search_ctx *sctx;
- char *expression;
-
- if (!domain) {
- return EINVAL;
- }
-
- sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr);
- if (!sctx) {
- return ENOMEM;
- }
-
- expression = talloc_asprintf(sctx, SYSDB_GRNAM_FILTER, name);
- if (!expression) {
- talloc_free(sctx);
- return ENOMEM;
- }
-
- return grp_search(sctx, ctx, expression);
-}
-
-int sysdb_getgrgid(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *ctx,
- const char *domain,
- gid_t gid,
- bool legacy,
- sysdb_callback_t fn, void *ptr)
-{
- struct sysdb_search_ctx *sctx;
- unsigned long int filter_gid = gid;
- char *expression;
-
- if (!domain) {
- return EINVAL;
- }
-
- sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr);
- if (!sctx) {
- return ENOMEM;
- }
-
- expression = talloc_asprintf(sctx, SYSDB_GRGID_FILTER, filter_gid);
- if (!expression) {
- talloc_free(sctx);
- return ENOMEM;
- }
-
- return grp_search(sctx, ctx, expression);
-}
-
-int sysdb_enumgrent(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *ctx,
- const char *domain,
- bool legacy,
- sysdb_callback_t fn, void *ptr)
-{
- struct sysdb_search_ctx *sctx;
-
- if (!domain) {
- return EINVAL;
- }
-
- sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr);
- if (!sctx) {
- return ENOMEM;
- }
-
- return grp_search(sctx, ctx, SYSDB_GRENT_FILTER);
-}
-
-static void sysdb_initgr_legacy(void *ptr, int status,
- struct ldb_result *res)
-{
- struct sysdb_ctx *ctx;
- struct sysdb_search_ctx *sctx;
- char *expression;
- struct ldb_request *req;
- struct ldb_dn *base_dn;
- static const char *attrs[] = SYSDB_INITGR_ATTRS;
- const char *userid;
- int ret;
-
- sctx = talloc_get_type(ptr, struct sysdb_search_ctx);
- ctx = sctx->dbctx;
-
- if (res->count == 0) {
- return request_done(sctx);
- }
- if (res->count > 1) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- }
-
- userid = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_PW_NAME, NULL);
- if (!userid) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- }
-
- expression = talloc_asprintf(sctx, SYSDB_INITGR_LEGACY_FILTER, userid);
- if (!expression) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- }
-
- base_dn = ldb_dn_new_fmt(sctx, ctx->ldb,
- SYSDB_TMPL_GROUP_BASE, sctx->domain);
- if (!base_dn) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- }
-
- ret = ldb_build_search_req(&req, ctx->ldb, sctx,
- base_dn, LDB_SCOPE_SUBTREE,
- expression, attrs, NULL,
- sctx, get_gen_callback,
- NULL);
- if (ret != LDB_SUCCESS) {
- return request_error(sctx, ret);
- }
-
- ret = ldb_request(ctx->ldb, req);
- if (ret != LDB_SUCCESS) {
- return request_error(sctx, ret);
- }
-}
-
-static void sysdb_initgr_search(void *ptr, int status,
- struct ldb_result *res)
-{
- struct sysdb_ctx *ctx;
- struct sysdb_search_ctx *sctx;
- char *expression;
- struct ldb_request *req;
- struct ldb_control **ctrl;
- struct ldb_asq_control *control;
- static const char *attrs[] = SYSDB_INITGR_ATTRS;
- int ret;
-
- sctx = talloc_get_type(ptr, struct sysdb_search_ctx);
- ctx = sctx->dbctx;
-
- if (res->count == 0) {
- return request_done(sctx);
- }
- if (res->count > 1) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- }
-
- expression = talloc_asprintf(sctx, SYSDB_INITGR_FILTER);
- if (!expression) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- }
-
- ctrl = talloc_array(sctx, struct ldb_control *, 2);
- if (!ctrl) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- }
- ctrl[1] = NULL;
- ctrl[0] = talloc(ctrl, struct ldb_control);
- if (!ctrl[0]) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- }
- ctrl[0]->oid = LDB_CONTROL_ASQ_OID;
- ctrl[0]->critical = 1;
- control = talloc(ctrl[0], struct ldb_asq_control);
- if (!control) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- }
- control->request = 1;
- control->source_attribute = talloc_strdup(control, SYSDB_INITGR_ATTR);
- if (!control->source_attribute) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
- }
- control->src_attr_len = strlen(control->source_attribute);
- ctrl[0]->data = control;
-
- ret = ldb_build_search_req(&req, ctx->ldb, sctx,
- res->msgs[0]->dn,
- LDB_SCOPE_BASE,
- expression, attrs, ctrl,
- sctx, get_gen_callback,
- NULL);
- if (ret != LDB_SUCCESS) {
- return request_error(sctx, ret);
- }
-
- ret = ldb_request(ctx->ldb, req);
- if (ret != LDB_SUCCESS) {
- return request_error(sctx, ret);
- }
-}
-
-int sysdb_initgroups(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *ctx,
- const char *domain,
- const char *name,
- bool legacy,
- sysdb_callback_t fn, void *ptr)
-{
- sysdb_callback_t second_callback;
- static const char *attrs[] = SYSDB_PW_ATTRS;
- struct sysdb_search_ctx *ret_sctx;
- struct sysdb_search_ctx *sctx;
- char *expression;
- struct ldb_request *req;
- struct ldb_dn *base_dn;
- int ret;
-
- if (!domain) {
- return EINVAL;
- }
-
- ret_sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr);
- if (!ret_sctx) {
- return ENOMEM;
- }
-
- if (legacy) {
- second_callback = sysdb_initgr_legacy;
- } else {
- second_callback = sysdb_initgr_search;
- }
-
- sctx = init_src_ctx(ret_sctx, domain, legacy,
- ctx, second_callback, ret_sctx);
- if (!sctx) {
- talloc_free(ret_sctx);
- return ENOMEM;
- }
-
- expression = talloc_asprintf(sctx, SYSDB_PWNAM_FILTER, name);
- if (!expression) {
- talloc_free(ret_sctx);
- return ENOMEM;
- }
-
- base_dn = ldb_dn_new_fmt(sctx, ctx->ldb, SYSDB_TMPL_USER_BASE, domain);
- if (!base_dn) {
- talloc_free(ret_sctx);
- return ENOMEM;
- }
-
- ret = ldb_build_search_req(&req, ctx->ldb, sctx,
- base_dn, LDB_SCOPE_SUBTREE,
- expression, attrs, NULL,
- sctx, get_gen_callback,
- NULL);
- if (ret != LDB_SUCCESS) {
- return sysdb_error_to_errno(ret);
- }
-
- ret = ldb_request(ctx->ldb, req);
- if (ret != LDB_SUCCESS) {
- return sysdb_error_to_errno(ret);
- }
-
- return LDB_SUCCESS;
-}
+/************************************************
+ * Initialiazation stuff
+ */
static int sysdb_read_var(TALLOC_CTX *mem_ctx,
struct confdb_ctx *cdb,
@@ -896,15 +166,18 @@ int sysdb_init(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct confdb_ctx *cdb,
const char *alt_db_path,
- struct sysdb_ctx **dbctx)
+ struct sysdb_ctx **_ctx)
{
struct sysdb_ctx *ctx;
int ret;
+ if (!ev) return EINVAL;
+
ctx = talloc_zero(mem_ctx, struct sysdb_ctx);
if (!ctx) {
return ENOMEM;
}
+ ctx->ev = ev;
if (!alt_db_path) {
ret = sysdb_get_db_path(ctx, cdb, &ctx->ldb_file);
@@ -938,7 +211,7 @@ int sysdb_init(TALLOC_CTX *mem_ctx,
return ret;
}
- *dbctx = ctx;
+ *_ctx = ctx;
return EOK;
}