diff options
-rw-r--r-- | server/confdb/confdb.c | 372 | ||||
-rw-r--r-- | server/confdb/confdb.h | 39 | ||||
-rw-r--r-- | server/nss/nss_ldb.h | 49 | ||||
-rw-r--r-- | server/nss/nsssrv.c | 12 | ||||
-rw-r--r-- | server/nss/nsssrv.h | 4 | ||||
-rw-r--r-- | server/nss/nsssrv_cmd.c | 51 | ||||
-rw-r--r-- | server/nss/nsssrv_ldb.c | 307 | ||||
-rw-r--r-- | server/nss/nsssrv_ldb.h | 63 | ||||
-rw-r--r-- | server/server.mk | 2 |
9 files changed, 767 insertions, 132 deletions
diff --git a/server/confdb/confdb.c b/server/confdb/confdb.c new file mode 100644 index 00000000..18b369ca --- /dev/null +++ b/server/confdb/confdb.c @@ -0,0 +1,372 @@ +/* + SSSD + + NSS Configuratoin DB + + Copyright (C) Simo Sorce <ssorce@redhat.com> 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#define _GNU_SOURCE +#include <string.h> +#include <errno.h> +#include "ldb.h" +#include "ldb_errors.h" +#include "util/util.h" +#define CONFDB_VERSION "0.1" +#define CONFDB_FILE "/var/lib/sss/db/config.ldb" + +#define CONFDB_ZERO_CHECK_OR_JUMP(var, ret, err, label) do { \ + if (!var) { \ + ret = err; \ + goto label; \ + } \ +} while(0) + +struct confdb_ctx { + struct ldb_context *ldb; +}; + +static char *prepend_cn(char *str, int *slen, const char *comp, int clen) +{ + char *ret; + + ret = talloc_realloc(NULL, str, char, *slen + 4 + clen + 1); + if (!ret) + return NULL; + + /* move current string to the end */ + memmove(&ret[clen +4], ret, *slen+1); /* includes termination */ + memcpy(ret, "cn=", 3); + memcpy(&ret[3], comp, clen); + ret[clen+3] = ','; + + *slen = *slen + 4 + clen; + + return ret; +} + +static int parse_section(TALLOC_CTX *mem_ctx, const char *section, + char **sec_dn, const char **rdn_name) +{ + TALLOC_CTX *tmp_ctx; + char *dn; + char *p; + const char *s; + int l, ret; + + /* section must be a non null string and must not start with '.' */ + if (!section || !*section || *section == '.') return EINVAL; + + tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) return ENOMEM; + + s = section; + l = 0; + while ((p = strchrnul(s, '.'))) { + if (l == 0) { + dn = talloc_asprintf(tmp_ctx, "cn=%s", s); + l = 3 + (p-s); + dn[l] = '\0'; + } else { + dn = prepend_cn(dn, &l, s, p-s); + } + if (!dn) { + ret = ENOMEM; + goto done; + } + if (*p == '\0') { + if (rdn_name) *rdn_name = s; + break; /* reached end */ + } + s = p+1; + if (*s == '\0') { /* a section cannot end in '.' */ + ret = EINVAL; + goto done; + } + } + + *sec_dn = talloc_steal(mem_ctx, dn); + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +int confdb_add_param(struct confdb_ctx *cdb, + bool replace, + const char *section, + const char *attribute, + const char **values) +{ + TALLOC_CTX *tmp_ctx; + struct ldb_message *msg; + struct ldb_result *res; + struct ldb_dn *dn; + char *secdn; + const char *rdn_name; + int ret, i; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) + return ENOMEM; + + ret = parse_section(tmp_ctx, section, &secdn, &rdn_name); + if (ret != EOK) { + goto done; + } + + dn = ldb_dn_new(tmp_ctx, cdb->ldb, secdn); + CONFDB_ZERO_CHECK_OR_JUMP(dn, ret, EIO, done); + + ret = ldb_search(cdb->ldb, tmp_ctx, &res, + dn, LDB_SCOPE_BASE, NULL, NULL); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + + msg = ldb_msg_new(tmp_ctx); + CONFDB_ZERO_CHECK_OR_JUMP(msg, ret, ENOMEM, done); + + msg->dn = talloc_steal(msg, dn); + CONFDB_ZERO_CHECK_OR_JUMP(msg->dn, ret, ENOMEM, done); + + if (res->count == 0) { /* add a new message */ + errno = 0; + + /* cn first */ + ret = ldb_msg_add_string(msg, "cn", rdn_name); + if (ret != LDB_SUCCESS) { + if (errno) ret = errno; + else ret = EIO; + goto done; + } + + /* now the requested attribute */ + for (i = 0; values[i]; i++) { + ret = ldb_msg_add_string(msg, attribute, values[i]); + if (ret != LDB_SUCCESS) { + if (errno) ret = errno; + else ret = EIO; + goto done; + } + } + + ret = ldb_add(cdb->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + + } else { + int optype; + errno = 0; + + /* mark this as a replacement */ + if (replace) optype = LDB_FLAG_MOD_REPLACE; + else optype = LDB_FLAG_MOD_ADD; + ret = ldb_msg_add_empty(msg, attribute, optype, NULL); + if (ret != LDB_SUCCESS) { + if (errno) ret = errno; + else ret = EIO; + goto done; + } + + /* now the requested attribute */ + for (i = 0; values[i]; i++) { + ret = ldb_msg_add_string(msg, attribute, values[i]); + if (ret != LDB_SUCCESS) { + if (errno) ret = errno; + else ret = EIO; + goto done; + } + } + + ret = ldb_modify(cdb->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + } + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +int confdb_get_param(struct confdb_ctx *cdb, + TALLOC_CTX *mem_ctx, + const char *section, + const char *attribute, + char ***values) +{ + TALLOC_CTX *tmp_ctx; + struct ldb_result *res; + struct ldb_dn *dn; + char *secdn; + const char *attrs[] = { attribute, NULL }; + char **vals; + struct ldb_message_element *el; + int ret, i; + + tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) + return ENOMEM; + + ret = parse_section(tmp_ctx, section, &secdn, NULL); + if (ret != EOK) { + goto done; + } + + dn = ldb_dn_new(tmp_ctx, cdb->ldb, secdn); + if (!dn) { + ret = EIO; + goto done; + } + + ret = ldb_search(cdb->ldb, tmp_ctx, &res, + dn, LDB_SCOPE_BASE, attrs, NULL); + if (ret != LDB_SUCCESS) { + ret = EIO; + goto done; + } + if (res->count > 1) { + ret = EIO; + goto done; + } + + vals = talloc_zero(mem_ctx, char *); + ret = EOK; + + if (res->count > 0) { + el = ldb_msg_find_element(res->msgs[0], attribute); + if (el && el->num_values > 0) { + vals = talloc_realloc(mem_ctx, vals, char *, el->num_values +1); + if (!vals) { + ret = ENOMEM; + goto done; + } + /* should always be strings so this should be safe */ + for (i = 0; i < el->num_values; i++) { + struct ldb_val v = el->values[i]; + vals[i] = talloc_strndup(vals, (char *)v.data, v.length); + if (!vals[i]) { + ret = ENOMEM; + goto done; + } + } + vals[i] = NULL; + } + } + + *values = vals; + +done: + talloc_free(tmp_ctx); + return ret; +} + +static int confdb_test(struct confdb_ctx *cdb) +{ + char **values; + int ret; + + ret = confdb_get_param(cdb, cdb, + "config", + "version", + &values); + if (ret != EOK) { + return ret; + } + + if (values[0] == NULL) { + /* empty database, will need to init */ + talloc_free(values); + return ENOENT; + } + + if (values[1] != NULL) { + /* more than 1 value ?? */ + talloc_free(values); + return EIO; + } + + if (strcmp(values[0], CONFDB_VERSION) != 0) { + /* bad version get out */ + talloc_free(values); + return EIO; + } + + talloc_free(values); + return EOK; +} + +static int confdb_init_db(struct confdb_ctx *cdb) +{ + const char *verval[] = { CONFDB_VERSION, NULL }; + int ret; + + ret = confdb_add_param(cdb, + false, + "config", + "version", + verval); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +int confdb_init(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct confdb_ctx **cdb_ctx) +{ + struct confdb_ctx *cdb; + int ret; + + cdb = talloc_zero(mem_ctx, struct confdb_ctx); + if (!cdb) + return ENOMEM; + + cdb->ldb = ldb_init(cdb, ev); + if (!cdb->ldb) { + talloc_free(cdb); + return EIO; + } + + ret = ldb_connect(cdb->ldb, CONFDB_FILE, 0, NULL); + if (ret != LDB_SUCCESS) { + talloc_free(cdb); + return EIO; + } + + ret = confdb_test(cdb); + if (ret == ENOENT) { + ret = confdb_init_db(cdb); + } + if (ret != EOK) { + talloc_free(cdb); + return ret; + } + + *cdb_ctx = cdb; + + return EOK; +} diff --git a/server/confdb/confdb.h b/server/confdb/confdb.h new file mode 100644 index 00000000..8becdf99 --- /dev/null +++ b/server/confdb/confdb.h @@ -0,0 +1,39 @@ +/* + SSSD + + NSS Configuratoin DB + + Copyright (C) Simo Sorce <ssorce@redhat.com> 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +struct confdb_ctx; + +int confdb_add_param(struct confdb_ctx *cdb, + bool replace, + const char *section, + const char *attribute, + const char **values); + + +int confdb_get_param(struct confdb_ctx *cdb, + TALLOC_CTX *mem_ctx, + const char *section, + const char *attribute, + char ***values); + +int confdb_init(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct confdb_ctx **cdb_ctx); diff --git a/server/nss/nss_ldb.h b/server/nss/nss_ldb.h index aa820168..f8a161dc 100644 --- a/server/nss/nss_ldb.h +++ b/server/nss/nss_ldb.h @@ -1,26 +1,39 @@ /* nss_ldb private header file */ -#define NSS_LDB_PATH "/var/lib/sss/db/sssd.ldb" +#define NSS_DEF_LDB_PATH "/var/lib/sss/db/sssd.ldb" -#define NSS_USER_BASE "cn=users,cn=local" -#define NSS_GROUP_BASE "cn=groups,cn=local" +#define NSS_DEF_USER_BASE "cn=users,cn=local" +#define NSS_DEF_GROUP_BASE "cn=groups,cn=local" -#define NSS_PWNAM_FILTER "(&(objectclass=user)(uid=%s))" -#define NSS_PWUID_FILTER "(&(objectclass=user)(uidNumber=%llu))" -#define NSS_PWENT_FILTER "(objectclass=user)" +#define NSS_DEF_PWNAM_FILTER "(&(objectclass=user)(uid=%s))" +#define NSS_DEF_PWUID_FILTER "(&(objectclass=user)(uidNumber=%llu))" +#define NSS_DEF_PWENT_FILTER "(objectclass=user)" -#define NSS_GRNAM_FILTER "(&(objectclass=group)(cn=%s))" -#define NSS_GRNA2_FILTER "(&(objectclass=user)(memberof=%s))" -#define NSS_GRGID_FILTER "(&(objectclass=group)(gidNumber=%llu))" -#define NSS_GRENT_FILTER "(objectclass=group)" +#define NSS_DEF_GRNAM_FILTER "(&(objectclass=group)(cn=%s))" +#define NSS_DEF_GRNA2_FILTER "(&(objectclass=user)(memberof=%s))" +#define NSS_DEF_GRGID_FILTER "(&(objectclass=group)(gidNumber=%llu))" +#define NSS_DEF_GRENT_FILTER "(objectclass=group)" -#define NSS_INITGR_FILTER "(&(objectclass=group)(gidNumber=*))" +#define NSS_DEF_INITGR_FILTER "(&(objectclass=group)(gidNumber=*))" -#define NSS_PW_ATTRS {NSS_PW_NAME, NSS_PW_UIDNUM, NSS_PW_GIDNUM, \ - NSS_PW_FULLNAME, NSS_PW_HOMEDIR, NSS_PW_SHELL, \ - NULL} -#define NSS_GRNAM_ATTRS {NSS_GR_NAME, NSS_GR_GIDNUM, NULL} -#define NSS_GRPW_ATTRS {NSS_PW_NAME, NULL} +#define NSS_DEF_PW_NAME "uid" +#define NSS_DEF_PW_UIDNUM "uidNumber" +#define NSS_DEF_PW_GIDNUM "gidNumber" +#define NSS_DEF_PW_FULLNAME "fullName" +#define NSS_DEF_PW_HOMEDIR "HomeDirectory" +#define NSS_DEF_PW_SHELL "loginShell" + +#define NSS_DEF_GR_NAME "cn" +#define NSS_DEF_GR_GIDNUM "gidNumber" +#define NSS_DEF_GR_MEMBER "member" + +#define NSS_DEF_PW_ATTRS {NSS_DEF_PW_NAME, NSS_DEF_PW_UIDNUM, \ + NSS_DEF_PW_GIDNUM, NSS_DEF_PW_FULLNAME, \ + NSS_DEF_PW_HOMEDIR, NSS_DEF_PW_SHELL, \ + NULL} +#define NSS_DEF_GRNAM_ATTRS {NSS_DEF_GR_NAME, NSS_DEF_GR_GIDNUM, NULL} +#define NSS_DEF_GRPW_ATTRS {NSS_DEF_PW_NAME, NULL} + +#define NSS_DEF_INITGR_ATTR "memberof" +#define NSS_DEF_INITGR_ATTRS {NSS_DEF_GR_GIDNUM, NULL} -#define NSS_INITGR_SEARCH_ATTR "memberof" -#define NSS_INITGR_ATTRS {NSS_GR_GIDNUM, NULL} diff --git a/server/nss/nsssrv.c b/server/nss/nsssrv.c index e602c322..ae03c579 100644 --- a/server/nss/nsssrv.c +++ b/server/nss/nsssrv.c @@ -33,6 +33,7 @@ #include "service.h" #include "nss/nsssrv.h" #include "nss/nsssrv_ldb.h" +#include "confdb/confdb.h" static void set_nonblocking(int fd) { @@ -182,7 +183,7 @@ static void accept_fd_handler(struct event_context *ev, } cctx->ev = ev; - cctx->ldb = nctx->ldb; + cctx->lctx = nctx->lctx; talloc_set_destructor(cctx, client_destructor); @@ -233,11 +234,18 @@ failed: void nss_task_init(struct task_server *task) { + struct confdb_ctx *cdb; struct nss_ctx *nctx; int ret; task_server_set_title(task, "sssd[nsssrv]"); + ret = confdb_init(task, task->event_ctx, &cdb); + if (ret != EOK) { + task_server_terminate(task, "fatal error initializing confdb\n"); + return; + } + nctx = talloc_zero(task, struct nss_ctx); if (!nctx) { task_server_terminate(task, "fatal error initializing nss_ctx\n"); @@ -247,7 +255,7 @@ void nss_task_init(struct task_server *task) set_unix_socket(task->event_ctx, nctx, SSS_NSS_SOCKET_NAME); - ret = nss_ldb_init(nctx, task->event_ctx, &nctx->ldb); + ret = nss_ldb_init(nctx, task->event_ctx, cdb, &nctx->lctx); if (ret != EOK) { task_server_terminate(task, "fatal error initializing nss_ctx\n"); return; diff --git a/server/nss/nsssrv.h b/server/nss/nsssrv.h index 6302c32c..e00ccced 100644 --- a/server/nss/nsssrv.h +++ b/server/nss/nsssrv.h @@ -36,12 +36,12 @@ struct nss_ctx { struct task_server *task; struct fd_event *lfde; int lfd; - struct ldb_context *ldb; + struct nss_ldb_ctx *lctx; }; struct cli_ctx { struct event_context *ev; - struct ldb_context *ldb; + struct nss_ldb_ctx *lctx; int cfd; struct fd_event *cfde; struct sockaddr_un addr; diff --git a/server/nss/nsssrv_cmd.c b/server/nss/nsssrv_cmd.c index 0e1cd8ce..74fdb227 100644 --- a/server/nss/nsssrv_cmd.c +++ b/server/nss/nsssrv_cmd.c @@ -83,6 +83,7 @@ static int nss_cmd_get_version(struct cli_ctx *cctx) ***************************************************************************/ static int fill_pwent(struct nss_packet *packet, + struct nss_ldb_ctx *lctx, struct ldb_message **msgs, int count) { @@ -106,12 +107,12 @@ static int fill_pwent(struct nss_packet *packet, for (i = 0; i < count; i++) { msg = msgs[i]; - name = ldb_msg_find_attr_as_string(msg, NSS_PW_NAME, NULL); - fullname = ldb_msg_find_attr_as_string(msg, NSS_PW_FULLNAME, NULL); - homedir = ldb_msg_find_attr_as_string(msg, NSS_PW_HOMEDIR, NULL); - shell = ldb_msg_find_attr_as_string(msg, NSS_PW_SHELL, NULL); - uid = ldb_msg_find_attr_as_uint64(msg, NSS_PW_UIDNUM, 0); - gid = ldb_msg_find_attr_as_uint64(msg, NSS_PW_GIDNUM, 0); + name = ldb_msg_find_attr_as_string(msg, lctx->pw_name, NULL); + fullname = ldb_msg_find_attr_as_string(msg, lctx->pw_fullname, NULL); + homedir = ldb_msg_find_attr_as_string(msg, lctx->pw_homedir, NULL); + shell = ldb_msg_find_attr_as_string(msg, lctx->pw_shell, NULL); + uid = ldb_msg_find_attr_as_uint64(msg, lctx->pw_uidnum, 0); + gid = ldb_msg_find_attr_as_uint64(msg, lctx->pw_gidnum, 0); if (!name || !fullname || !homedir || !shell || !uid || !gid) { DEBUG(1, ("Incomplete user object for %s[%llu]! Skipping\n", @@ -198,7 +199,7 @@ static int nss_cmd_getpw_callback(void *ptr, int status, goto done; } - ret = fill_pwent(cctx->creq->out, res->msgs, res->count); + ret = fill_pwent(cctx->creq->out, cctx->lctx, res->msgs, res->count); nss_packet_set_error(cctx->creq->out, ret); done: @@ -228,7 +229,7 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx) } nctx->cctx = cctx; - ret = nss_ldb_getpwnam(nctx, cctx->ev, cctx->ldb, name, + ret = nss_ldb_getpwnam(nctx, cctx->ev, cctx->lctx, name, nss_cmd_getpw_callback, nctx); return ret; @@ -257,7 +258,7 @@ static int nss_cmd_getpwuid(struct cli_ctx *cctx) } nctx->cctx = cctx; - ret = nss_ldb_getpwuid(nctx, cctx->ev, cctx->ldb, uid, + ret = nss_ldb_getpwuid(nctx, cctx->ev, cctx->lctx, uid, nss_cmd_getpw_callback, nctx); return ret; @@ -328,7 +329,7 @@ static int nss_cmd_setpwent(struct cli_ctx *cctx) cctx->gctx->pwd_cur = 0; } - ret = nss_ldb_enumpwent(nctx, cctx->ev, cctx->ldb, + ret = nss_ldb_enumpwent(nctx, cctx->ev, cctx->lctx, nss_cmd_setpwent_callback, nctx); return ret; @@ -342,7 +343,8 @@ static int nss_cmd_retpwent(struct cli_ctx *cctx, int num) n = gctx->pwds->count - gctx->pwd_cur; if (n > num) n = num; - ret = fill_pwent(cctx->creq->out, &(gctx->pwds->msgs[gctx->pwd_cur]), n); + ret = fill_pwent(cctx->creq->out, cctx->lctx, + &(gctx->pwds->msgs[gctx->pwd_cur]), n); gctx->pwd_cur += n; return ret; @@ -424,7 +426,7 @@ static int nss_cmd_getpwent(struct cli_ctx *cctx) cctx->gctx = gctx; } if (cctx->gctx->pwds == NULL) { - ret = nss_ldb_enumpwent(nctx, cctx->ev, cctx->ldb, + ret = nss_ldb_enumpwent(nctx, cctx->ev, cctx->lctx, nss_cmd_getpwent_callback, nctx); return ret; } @@ -478,6 +480,7 @@ done: ***************************************************************************/ static int fill_grent(struct nss_packet *packet, + struct nss_ldb_ctx *lctx, struct ldb_message **msgs, int count) { @@ -500,8 +503,8 @@ static int fill_grent(struct nss_packet *packet, if (get_group) { /* find group name/gid */ - name = ldb_msg_find_attr_as_string(msg, NSS_GR_NAME, NULL); - gid = ldb_msg_find_attr_as_uint64(msg, NSS_GR_GIDNUM, 0); + name = ldb_msg_find_attr_as_string(msg, lctx->gr_name, NULL); + gid = ldb_msg_find_attr_as_uint64(msg, lctx->gr_gidnum, 0); if (!name || !gid) { DEBUG(1, ("Incomplete group object for %s[%llu]! Aborting\n", name?name:"<NULL>", (unsigned long long int)gid)); @@ -529,7 +532,7 @@ static int fill_grent(struct nss_packet *packet, continue; } - name = ldb_msg_find_attr_as_string(msg, NSS_PW_NAME, NULL); + name = ldb_msg_find_attr_as_string(msg, lctx->pw_name, NULL); if (!name) { /* last member of previous group found, or error. @@ -607,7 +610,7 @@ static int nss_cmd_getgr_callback(void *ptr, int status, goto done; } - ret = fill_grent(cctx->creq->out, res->msgs, res->count); + ret = fill_grent(cctx->creq->out, cctx->lctx, res->msgs, res->count); nss_packet_set_error(cctx->creq->out, ret); done: @@ -637,7 +640,7 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx) } nctx->cctx = cctx; - ret = nss_ldb_getgrnam(nctx, cctx->ev, cctx->ldb, name, + ret = nss_ldb_getgrnam(nctx, cctx->ev, cctx->lctx, name, nss_cmd_getgr_callback, nctx); return ret; @@ -666,7 +669,7 @@ static int nss_cmd_getgrgid(struct cli_ctx *cctx) } nctx->cctx = cctx; - ret = nss_ldb_getgrgid(nctx, cctx->ev, cctx->ldb, gid, + ret = nss_ldb_getgrgid(nctx, cctx->ev, cctx->lctx, gid, nss_cmd_getgr_callback, nctx); return ret; @@ -737,7 +740,7 @@ static int nss_cmd_setgrent(struct cli_ctx *cctx) cctx->gctx->grp_cur = 0; } - ret = nss_ldb_enumgrent(nctx, cctx->ev, cctx->ldb, + ret = nss_ldb_enumgrent(nctx, cctx->ev, cctx->lctx, nss_cmd_setgrent_callback, nctx); return ret; @@ -751,7 +754,8 @@ static int nss_cmd_retgrent(struct cli_ctx *cctx, int num) n = gctx->grps->count - gctx->grp_cur; if (n > num) n = num; - ret = fill_grent(cctx->creq->out, &(gctx->grps->msgs[gctx->grp_cur]), n); + ret = fill_grent(cctx->creq->out, cctx->lctx, + &(gctx->grps->msgs[gctx->grp_cur]), n); gctx->grp_cur += n; return ret; @@ -833,7 +837,7 @@ static int nss_cmd_getgrent(struct cli_ctx *cctx) cctx->gctx = gctx; } if (cctx->gctx->grps == NULL) { - ret = nss_ldb_enumgrent(nctx, cctx->ev, cctx->ldb, + ret = nss_ldb_enumgrent(nctx, cctx->ev, cctx->lctx, nss_cmd_getgrent_callback, nctx); return ret; } @@ -887,6 +891,7 @@ static int nss_cmd_initgr_callback(void *ptr, int status, { struct nss_cmd_ctx *nctx = talloc_get_type(ptr, struct nss_cmd_ctx); struct cli_ctx *cctx = nctx->cctx; + struct nss_ldb_ctx *lctx = cctx->lctx; uint8_t *body; size_t blen; uint64_t gid; @@ -917,7 +922,7 @@ static int nss_cmd_initgr_callback(void *ptr, int status, nss_packet_get_body(cctx->creq->out, &body, &blen); for (i = 0; i < num; i++) { - gid = ldb_msg_find_attr_as_uint64(res->msgs[i], NSS_GR_GIDNUM, 0); + gid = ldb_msg_find_attr_as_uint64(res->msgs[i], lctx->gr_gidnum, 0); if (!gid) { DEBUG(1, ("Incomplete group object for initgroups! Aborting\n")); nss_packet_set_error(cctx->creq->out, EIO); @@ -957,7 +962,7 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx) } nctx->cctx = cctx; - ret = nss_ldb_initgroups(nctx, cctx->ev, cctx->ldb, name, + ret = nss_ldb_initgroups(nctx, cctx->ev, cctx->lctx, name, nss_cmd_initgr_callback, nctx); return ret; diff --git a/server/nss/nsssrv_ldb.c b/server/nss/nsssrv_ldb.c index 3e6d877a..56cdb5d7 100644 --- a/server/nss/nsssrv_ldb.c +++ b/server/nss/nsssrv_ldb.c @@ -25,9 +25,10 @@ #include "nss/nsssrv.h" #include "nss/nsssrv_ldb.h" #include "nss/nss_ldb.h" +#include "confdb/confdb.h" struct nss_ldb_search_ctx { - struct ldb_context *ldb; + struct nss_ldb_ctx *nlctx; nss_ldb_callback_t callback; void *ptr; struct ldb_result *res; @@ -109,9 +110,10 @@ static int get_gen_callback(struct ldb_request *req, return LDB_SUCCESS; } -static struct nss_ldb_search_ctx *init_sctx(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, - nss_ldb_callback_t fn, void *ptr) +static struct nss_ldb_search_ctx *init_src_ctx(TALLOC_CTX *mem_ctx, + struct nss_ldb_ctx *ctx, + nss_ldb_callback_t fn, + void *ptr) { struct nss_ldb_search_ctx *sctx; @@ -119,7 +121,7 @@ static struct nss_ldb_search_ctx *init_sctx(TALLOC_CTX *mem_ctx, if (!sctx) { return NULL; } - sctx->ldb = ldb; + sctx->nlctx = ctx; sctx->callback = fn; sctx->ptr = ptr; sctx->res = talloc_zero(sctx, struct ldb_result); @@ -134,24 +136,23 @@ static struct nss_ldb_search_ctx *init_sctx(TALLOC_CTX *mem_ctx, /* users */ static int pwd_search(struct nss_ldb_search_ctx *sctx, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, const char *expression) { - static const char *attrs[] = NSS_PW_ATTRS; struct ldb_request *req; int ret; - ret = ldb_build_search_req(&req, ldb, sctx, - ldb_dn_new(sctx, ldb, NSS_USER_BASE), + ret = ldb_build_search_req(&req, ctx->ldb, sctx, + ldb_dn_new(sctx, ctx->ldb, ctx->user_base), LDB_SCOPE_SUBTREE, - expression, attrs, NULL, + expression, ctx->pw_attrs, NULL, sctx, get_gen_callback, NULL); if (ret != LDB_SUCCESS) { return nss_ldb_error_to_errno(ret); } - ret = ldb_request(ldb, req); + ret = ldb_request(ctx->ldb, req); if (ret != LDB_SUCCESS) { return nss_ldb_error_to_errno(ret); } @@ -161,30 +162,30 @@ static int pwd_search(struct nss_ldb_search_ctx *sctx, int nss_ldb_getpwnam(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, 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); + sctx = init_src_ctx(mem_ctx, ctx, fn, ptr); if (!sctx) { return ENOMEM; } - expression = talloc_asprintf(sctx, NSS_PWNAM_FILTER, name); + expression = talloc_asprintf(sctx, ctx->pwnam_filter, name); if (!expression) { talloc_free(sctx); return ENOMEM; } - return pwd_search(sctx, ldb, expression); + return pwd_search(sctx, ctx, expression); } int nss_ldb_getpwuid(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, uint64_t uid, nss_ldb_callback_t fn, void *ptr) { @@ -192,33 +193,33 @@ int nss_ldb_getpwuid(TALLOC_CTX *mem_ctx, unsigned long long int filter_uid = uid; char *expression; - sctx = init_sctx(mem_ctx, ldb, fn, ptr); + sctx = init_src_ctx(mem_ctx, ctx, fn, ptr); if (!sctx) { return ENOMEM; } - expression = talloc_asprintf(sctx, NSS_PWUID_FILTER, filter_uid); + expression = talloc_asprintf(sctx, ctx->pwuid_filter, filter_uid); if (!expression) { talloc_free(sctx); return ENOMEM; } - return pwd_search(sctx, ldb, expression); + return pwd_search(sctx, ctx, expression); } int nss_ldb_enumpwent(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, nss_ldb_callback_t fn, void *ptr) { struct nss_ldb_search_ctx *sctx; - sctx = init_sctx(mem_ctx, ldb, fn, ptr); + sctx = init_src_ctx(mem_ctx, ctx, fn, ptr); if (!sctx) { return ENOMEM; } - return pwd_search(sctx, ldb, NSS_PWENT_FILTER); + return pwd_search(sctx, ctx, ctx->pwent_filter); } /* groups */ @@ -232,10 +233,10 @@ struct get_mem_ctx { static int get_members(void *ptr, int status, struct ldb_result *res) { + struct nss_ldb_ctx *ctx; struct nss_ldb_search_ctx *sctx; struct get_mem_ctx *gmctx; struct nss_ldb_search_ctx *mem_sctx; - static const char *attrs[] = NSS_GRPW_ATTRS; struct ldb_request *req; struct ldb_message *msg; struct ldb_result *ret_res; @@ -244,6 +245,7 @@ static int get_members(void *ptr, int status, sctx = talloc_get_type(ptr, struct nss_ldb_search_ctx); gmctx = talloc_get_type(sctx->ptr, struct get_mem_ctx); + ctx = sctx->nlctx; if (status != LDB_SUCCESS) { return request_error(gmctx->ret_sctx, status); @@ -267,7 +269,7 @@ static int get_members(void *ptr, int status, return request_done(gmctx->ret_sctx); } - mem_sctx = init_sctx(gmctx, sctx->ldb, get_members, sctx); + mem_sctx = init_src_ctx(gmctx, ctx, get_members, sctx); if (!mem_sctx) { return request_error(gmctx->ret_sctx, LDB_ERR_OPERATIONS_ERROR); } @@ -289,23 +291,23 @@ static int get_members(void *ptr, int status, ret_res->count++; /* search for this group members */ - expression = talloc_asprintf(mem_sctx, NSS_GRNA2_FILTER, + expression = talloc_asprintf(mem_sctx, ctx->grna2_filter, ldb_dn_get_linearized(msg->dn)); if (!expression) { return request_error(gmctx->ret_sctx, LDB_ERR_OPERATIONS_ERROR); } - ret = ldb_build_search_req(&req, mem_sctx->ldb, mem_sctx, - ldb_dn_new(mem_sctx, mem_sctx->ldb, NSS_USER_BASE), + ret = ldb_build_search_req(&req, ctx->ldb, mem_sctx, + ldb_dn_new(mem_sctx, ctx->ldb, ctx->user_base), LDB_SCOPE_SUBTREE, - expression, attrs, NULL, + expression, ctx->grpw_attrs, NULL, mem_sctx, get_gen_callback, NULL); if (ret != LDB_SUCCESS) { return request_error(gmctx->ret_sctx, ret); } - ret = ldb_request(mem_sctx->ldb, req); + ret = ldb_request(ctx->ldb, req); if (ret != LDB_SUCCESS) { return request_error(gmctx->ret_sctx, ret); } @@ -317,10 +319,12 @@ static int get_grp_callback(struct ldb_request *req, struct ldb_reply *ares) { struct nss_ldb_search_ctx *sctx; + struct nss_ldb_ctx *ctx; struct ldb_result *res; int n; sctx = talloc_get_type(req->context, struct nss_ldb_search_ctx); + ctx = sctx->nlctx; res = sctx->res; if (!ares) { @@ -383,7 +387,7 @@ static int get_grp_callback(struct ldb_request *req, /* re-use sctx to create a fake handler for the first call to * get_members() */ - sctx = init_sctx(gmctx, sctx->ldb, get_members, gmctx); + sctx = init_src_ctx(gmctx, ctx, get_members, gmctx); return get_members(sctx, LDB_SUCCESS, NULL); } @@ -397,24 +401,23 @@ static int get_grp_callback(struct ldb_request *req, } static int grp_search(struct nss_ldb_search_ctx *sctx, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, 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), + ret = ldb_build_search_req(&req, ctx->ldb, sctx, + ldb_dn_new(sctx, ctx->ldb, ctx->group_base), LDB_SCOPE_SUBTREE, - expression, attrs, NULL, + expression, ctx->grnam_attrs, NULL, sctx, get_grp_callback, NULL); if (ret != LDB_SUCCESS) { return nss_ldb_error_to_errno(ret); } - ret = ldb_request(ldb, req); + ret = ldb_request(ctx->ldb, req); if (ret != LDB_SUCCESS) { return nss_ldb_error_to_errno(ret); } @@ -424,30 +427,30 @@ static int grp_search(struct nss_ldb_search_ctx *sctx, int nss_ldb_getgrnam(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, 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); + sctx = init_src_ctx(mem_ctx, ctx, fn, ptr); if (!sctx) { return ENOMEM; } - expression = talloc_asprintf(sctx, NSS_GRNAM_FILTER, name); + expression = talloc_asprintf(sctx, ctx->grnam_filter, name); if (!expression) { talloc_free(sctx); return ENOMEM; } - return grp_search(sctx, ldb, expression); + return grp_search(sctx, ctx, expression); } int nss_ldb_getgrgid(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, uint64_t gid, nss_ldb_callback_t fn, void *ptr) { @@ -455,40 +458,40 @@ int nss_ldb_getgrgid(TALLOC_CTX *mem_ctx, unsigned long long int filter_gid = gid; char *expression; - sctx = init_sctx(mem_ctx, ldb, fn, ptr); + sctx = init_src_ctx(mem_ctx, ctx, fn, ptr); if (!sctx) { return ENOMEM; } - expression = talloc_asprintf(sctx, NSS_GRGID_FILTER, filter_gid); + expression = talloc_asprintf(sctx, ctx->grgid_filter, filter_gid); if (!expression) { talloc_free(sctx); return ENOMEM; } - return grp_search(sctx, ldb, expression); + return grp_search(sctx, ctx, expression); } int nss_ldb_enumgrent(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, nss_ldb_callback_t fn, void *ptr) { struct nss_ldb_search_ctx *sctx; - sctx = init_sctx(mem_ctx, ldb, fn, ptr); + sctx = init_src_ctx(mem_ctx, ctx, fn, ptr); if (!sctx) { return ENOMEM; } - return grp_search(sctx, ldb, NSS_GRENT_FILTER); + return grp_search(sctx, ctx, ctx->grent_filter); } static int nss_ldb_initgr_search(void *ptr, int status, struct ldb_result *res) { + struct nss_ldb_ctx *ctx; struct nss_ldb_search_ctx *sctx; - static const char *attrs[] = NSS_INITGR_ATTRS; char *expression; struct ldb_request *req; struct ldb_control **ctrl; @@ -496,6 +499,7 @@ static int nss_ldb_initgr_search(void *ptr, int status, int ret; sctx = talloc_get_type(ptr, struct nss_ldb_search_ctx); + ctx = sctx->nlctx; if (res->count == 0) { return request_done(sctx); @@ -504,7 +508,7 @@ static int nss_ldb_initgr_search(void *ptr, int status, return request_error(sctx, LDB_ERR_OPERATIONS_ERROR); } - expression = talloc_asprintf(sctx, NSS_INITGR_FILTER); + expression = talloc_asprintf(sctx, ctx->initgr_filter); if (!expression) { return request_error(sctx, LDB_ERR_OPERATIONS_ERROR); } @@ -525,24 +529,24 @@ static int nss_ldb_initgr_search(void *ptr, int status, return request_error(sctx, LDB_ERR_OPERATIONS_ERROR); } control->request = 1; - control->source_attribute = talloc_strdup(control, NSS_INITGR_SEARCH_ATTR); + control->source_attribute = talloc_strdup(control, ctx->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, sctx->ldb, sctx, + ret = ldb_build_search_req(&req, ctx->ldb, sctx, res->msgs[0]->dn, LDB_SCOPE_BASE, - expression, attrs, ctrl, + expression, ctx->initgr_attrs, ctrl, sctx, get_gen_callback, NULL); if (ret != LDB_SUCCESS) { return request_error(sctx, ret); } - ret = ldb_request(sctx->ldb, req); + ret = ldb_request(ctx->ldb, req); if (ret != LDB_SUCCESS) { return request_error(sctx, ret); } @@ -552,44 +556,43 @@ static int nss_ldb_initgr_search(void *ptr, int status, int nss_ldb_initgroups(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, const char *name, nss_ldb_callback_t fn, void *ptr) { struct nss_ldb_search_ctx *ret_sctx; struct nss_ldb_search_ctx *sctx; - static const char *attrs[] = NSS_PW_ATTRS; char *expression; struct ldb_request *req; int ret; - ret_sctx = init_sctx(mem_ctx, ldb, fn, ptr); + ret_sctx = init_src_ctx(mem_ctx, ctx, fn, ptr); if (!ret_sctx) { return ENOMEM; } - sctx = init_sctx(ret_sctx, ldb, nss_ldb_initgr_search, ret_sctx); + sctx = init_src_ctx(ret_sctx, ctx, nss_ldb_initgr_search, ret_sctx); if (!sctx) { talloc_free(sctx); return ENOMEM; } - expression = talloc_asprintf(sctx, NSS_PWNAM_FILTER, name); + expression = talloc_asprintf(sctx, ctx->pwnam_filter, name); if (!expression) { talloc_free(sctx); return ENOMEM; } - ret = ldb_build_search_req(&req, ldb, sctx, - ldb_dn_new(sctx, ldb, NSS_USER_BASE), + ret = ldb_build_search_req(&req, ctx->ldb, sctx, + ldb_dn_new(sctx, ctx->ldb, ctx->user_base), LDB_SCOPE_SUBTREE, - expression, attrs, NULL, + expression, ctx->pw_attrs, NULL, sctx, get_gen_callback, NULL); if (ret != LDB_SUCCESS) { return nss_ldb_error_to_errno(ret); } - ret = ldb_request(ldb, req); + ret = ldb_request(ctx->ldb, req); if (ret != LDB_SUCCESS) { return nss_ldb_error_to_errno(ret); } @@ -597,26 +600,192 @@ int nss_ldb_initgroups(TALLOC_CTX *mem_ctx, return LDB_SUCCESS; } +#define NSS_LDB_CONF_SECTION "config.services.nss" + +static int nss_ldb_read_var(TALLOC_CTX *tmp_ctx, + struct confdb_ctx *cdb, + struct nss_ldb_ctx *ctx, + const char *name, + const char *def_value, + const char **target) +{ + int ret; + char *t; + char **values; + + ret = confdb_get_param(cdb, tmp_ctx, + NSS_LDB_CONF_SECTION, + name, &values); + if (ret != EOK) + return ret; + + if (values[0]) + t = talloc_steal(ctx, values[0]); + else + t = talloc_strdup(ctx, def_value); + + *target = t; + return EOK; +} + +static int nss_ldb_read_array(TALLOC_CTX *tmp_ctx, + struct confdb_ctx *cdb, + struct nss_ldb_ctx *ctx, + const char *name, + const char **def_value, + const char ***target) +{ + char **values; + const char **t; + int i, ret; + + ret = confdb_get_param(cdb, tmp_ctx, + NSS_LDB_CONF_SECTION, + name, &values); + if (ret != EOK) + return ret; + + for (i = 0; values[i]; i++) /* count */ ; + if (i == 0) { + for (i = 0; def_value[i]; i++) /*count */ ; + } + if (i == 0) + return EINVAL; + + t = talloc_array(ctx, const char *, i+1); + if (!*target) + return ENOMEM; + + if (values[0]) { + for (i = 0; values[i]; i++) { + t[i] = talloc_steal(ctx, values[i]); + } + } else { + for (i = 0; def_value[i]; i++) { + t[i] = talloc_strdup(ctx, def_value[i]); + } + } + t[i] = NULL; + + *target = t; + return EOK; +} + +static int nss_ldb_read_conf(TALLOC_CTX *mem_ctx, + struct confdb_ctx *cdb, + struct nss_ldb_ctx **nlctx) +{ + struct nss_ldb_ctx *ctx; + TALLOC_CTX *tmp_ctx; + int ret; + + tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) + return ENOMEM; + + ctx = talloc(mem_ctx, struct nss_ldb_ctx); + if (!ctx) { + ret = ENOMEM; + goto done; + } + + nss_ldb_read_var(tmp_ctx, cdb, ctx, "ldbFile", + NSS_DEF_LDB_PATH, &ctx->ldb_file); + + nss_ldb_read_var(tmp_ctx, cdb, ctx, "userBase", + NSS_DEF_USER_BASE, &ctx->user_base); + nss_ldb_read_var(tmp_ctx, cdb, ctx, "groupBase", + NSS_DEF_GROUP_BASE, &ctx->group_base); + + nss_ldb_read_var(tmp_ctx, cdb, ctx, "pwnamFilter", + NSS_DEF_PWNAM_FILTER, &ctx->pwnam_filter); + nss_ldb_read_var(tmp_ctx, cdb, ctx, "pwuidFilter", + NSS_DEF_PWUID_FILTER, &ctx->pwuid_filter); + nss_ldb_read_var(tmp_ctx, cdb, ctx, "pwentFilter", + NSS_DEF_PWENT_FILTER, &ctx->pwent_filter); + + nss_ldb_read_var(tmp_ctx, cdb, ctx, "grnamFilter", + NSS_DEF_GRNAM_FILTER, &ctx->grnam_filter); + nss_ldb_read_var(tmp_ctx, cdb, ctx, "grna2Filter", + NSS_DEF_GRNA2_FILTER, &ctx->grna2_filter); + nss_ldb_read_var(tmp_ctx, cdb, ctx, "grgidFilter", + NSS_DEF_GRGID_FILTER, &ctx->grgid_filter); + nss_ldb_read_var(tmp_ctx, cdb, ctx, "grentFilter", + NSS_DEF_GRENT_FILTER, &ctx->grent_filter); + + nss_ldb_read_var(tmp_ctx, cdb, ctx, "initgrFilter", + NSS_DEF_INITGR_FILTER, &ctx->initgr_filter); + + nss_ldb_read_var(tmp_ctx, cdb, ctx, "pwName", + NSS_DEF_PW_NAME, &ctx->pw_name); + nss_ldb_read_var(tmp_ctx, cdb, ctx, "pwUidnum", + NSS_DEF_PW_UIDNUM, &ctx->pw_uidnum); + nss_ldb_read_var(tmp_ctx, cdb, ctx, "pwGidnum", + NSS_DEF_PW_GIDNUM, &ctx->pw_gidnum); + nss_ldb_read_var(tmp_ctx, cdb, ctx, "pwFullname", + NSS_DEF_PW_FULLNAME, &ctx->pw_fullname); + nss_ldb_read_var(tmp_ctx, cdb, ctx, "pwHomedir", + NSS_DEF_PW_HOMEDIR, &ctx->pw_homedir); + nss_ldb_read_var(tmp_ctx, cdb, ctx, "pwShell", + NSS_DEF_PW_SHELL, &ctx->pw_shell); + + nss_ldb_read_var(tmp_ctx, cdb, ctx, "grName", + NSS_DEF_GR_NAME, &ctx->gr_name); + nss_ldb_read_var(tmp_ctx, cdb, ctx, "grGidnum", + NSS_DEF_GR_GIDNUM, &ctx->gr_gidnum); + nss_ldb_read_var(tmp_ctx, cdb, ctx, "grMember", + NSS_DEF_GR_MEMBER, &ctx->gr_member); + + nss_ldb_read_var(tmp_ctx, cdb, ctx, "initgrAttr", + NSS_DEF_INITGR_ATTR, + &ctx->initgr_attr); + + const char *pwattrs[] = NSS_DEF_PW_ATTRS; + nss_ldb_read_array(tmp_ctx, cdb, ctx, "pwAttrs", + pwattrs, &ctx->pw_attrs); + const char *grnamattrs[] = NSS_DEF_GRNAM_ATTRS; + nss_ldb_read_array(tmp_ctx, cdb, ctx, "grnamAttrs", + grnamattrs, &ctx->grnam_attrs); + const char *grpwattrs[] = NSS_DEF_GRPW_ATTRS; + nss_ldb_read_array(tmp_ctx, cdb, ctx, "grpwAttrs", + grpwattrs, &ctx->grpw_attrs); + const char *initgrattrs[] = NSS_DEF_INITGR_ATTRS; + nss_ldb_read_array(tmp_ctx, cdb, ctx, "initgrAttrs", + initgrattrs, &ctx->initgr_attrs); + + *nlctx = ctx; + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} int nss_ldb_init(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context **ldbp) + struct confdb_ctx *cdb, + struct nss_ldb_ctx **nlctx) { - struct ldb_context *ldb; + struct nss_ldb_ctx *ctx; int ret; - ldb = ldb_init(mem_ctx, ev); - if (!ldb) { + ret = nss_ldb_read_conf(mem_ctx, cdb, &ctx); + if (ret != EOK) + return ret; + + ctx->ldb = ldb_init(mem_ctx, ev); + if (!ctx->ldb) { + talloc_free(ctx); return EIO; } - ret = ldb_connect(ldb, NSS_LDB_PATH, 0, NULL); + ret = ldb_connect(ctx->ldb, ctx->ldb_file, 0, NULL); if (ret != LDB_SUCCESS) { - talloc_free(ldb); + talloc_free(ctx); return EIO; } - *ldbp = ldb; + *nlctx = ctx; return EOK; } diff --git a/server/nss/nsssrv_ldb.h b/server/nss/nsssrv_ldb.h index eb3e8fca..c7a3c4d6 100644 --- a/server/nss/nsssrv_ldb.h +++ b/server/nss/nsssrv_ldb.h @@ -1,58 +1,87 @@ -#define NSS_PW_NAME "uid" -#define NSS_PW_UIDNUM "uidNumber" -#define NSS_PW_GIDNUM "gidNumber" -#define NSS_PW_FULLNAME "fullName" -#define NSS_PW_HOMEDIR "HomeDirectory" -#define NSS_PW_SHELL "loginShell" +struct nss_ldb_ctx { + struct ldb_context *ldb; + const char *ldb_file; -#define NSS_GR_NAME "cn" -#define NSS_GR_GIDNUM "gidNumber" -#define NSS_GR_MEMBER "member" + const char *user_base; + const char *group_base; + + const char *pwnam_filter; + const char *pwuid_filter; + const char *pwent_filter; + + const char *grnam_filter; + const char *grna2_filter; + const char *grgid_filter; + const char *grent_filter; + + const char *initgr_filter; + + const char *pw_name; + const char *pw_uidnum; + const char *pw_gidnum; + const char *pw_fullname; + const char *pw_homedir; + const char *pw_shell; + + const char *gr_name; + const char *gr_gidnum; + const char *gr_member; + + const char *initgr_attr; + + const char **pw_attrs; + const char **grnam_attrs; + const char **grpw_attrs; + const char **initgr_attrs; +}; + +struct confdb_ctx; typedef int (*nss_ldb_callback_t)(void *, int, struct ldb_result *); int nss_ldb_init(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context **ldb); + struct confdb_ctx *cdb, + struct nss_ldb_ctx **nlctx); int nss_ldb_getpwnam(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, const char *name, nss_ldb_callback_t fn, void *ptr); int nss_ldb_getpwuid(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, uint64_t uid, nss_ldb_callback_t fn, void *ptr); int nss_ldb_enumpwent(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, nss_ldb_callback_t fn, void *ptr); int nss_ldb_getgrnam(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, const char *name, nss_ldb_callback_t fn, void *ptr); int nss_ldb_getgrgid(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, uint64_t gid, nss_ldb_callback_t fn, void *ptr); int nss_ldb_enumgrent(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, nss_ldb_callback_t fn, void *ptr); int nss_ldb_initgroups(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct ldb_context *ldb, + struct nss_ldb_ctx *ctx, const char *name, nss_ldb_callback_t fn, void *ptr); diff --git a/server/server.mk b/server/server.mk index 2a423e7e..8558c731 100644 --- a/server/server.mk +++ b/server/server.mk @@ -1,4 +1,4 @@ -SERVER_OBJ = server.o monitor.o process.o service.o service_task.o util/debug.o util/signal.o util/become_daemon.o nss/nsssrv.o nss/nsssrv_packet.o nss/nsssrv_cmd.o nss/nsssrv_ldb.o +SERVER_OBJ = server.o monitor.o process.o service.o service_task.o util/debug.o util/signal.o util/become_daemon.o confdb/confdb.o nss/nsssrv.o nss/nsssrv_packet.o nss/nsssrv_cmd.o nss/nsssrv_ldb.o install:: all ${INSTALLCMD} -d $(DESTDIR)$(sbindir) |