From 803a6dbaca408ea424fe6969c31460c3b6c4979c Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 22 Oct 2006 21:18:43 +0000 Subject: r19456: Add an example application for ldb using the tdb backend (This used to be commit 778198f279b374222c737e5eda1c47efc2dce39c) --- source4/lib/ldb/nssldb/ldb-nss.c | 401 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 401 insertions(+) create mode 100644 source4/lib/ldb/nssldb/ldb-nss.c (limited to 'source4/lib/ldb/nssldb/ldb-nss.c') diff --git a/source4/lib/ldb/nssldb/ldb-nss.c b/source4/lib/ldb/nssldb/ldb-nss.c new file mode 100644 index 0000000000..3206f38a10 --- /dev/null +++ b/source4/lib/ldb/nssldb/ldb-nss.c @@ -0,0 +1,401 @@ +/* + LDB nsswitch module + + Copyright (C) Simo Sorce 2006 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "ldb-nss.h" + +struct _ldb_nss_context *_ldb_nss_ctx = NULL; + +NSS_STATUS _ldb_nss_init(void) +{ + int ret; + + pid_t mypid = getpid(); + + if (_ldb_nss_ctx != NULL) { + if (_ldb_nss_ctx->pid == mypid) { + /* already initialized */ + return NSS_STATUS_SUCCESS; + } else { + /* we are in a forked child now, reinitialize */ + talloc_free(_ldb_nss_ctx); + _ldb_nss_ctx = NULL; + } + } + + _ldb_nss_ctx = talloc_named(NULL, 0, "_ldb_nss_ctx(%u)", mypid); + if (_ldb_nss_ctx == NULL) { + return NSS_STATUS_UNAVAIL; + } + + _ldb_nss_ctx->pid = mypid; + + ret = ldb_global_init(); + if (ret != 0) { + goto failed; + } + + _ldb_nss_ctx->ldb = ldb_init(_ldb_nss_ctx); + if (_ldb_nss_ctx->ldb == NULL) { + goto failed; + } + + ret = ldb_connect(_ldb_nss_ctx->ldb, _LDB_NSS_URL, LDB_FLG_RDONLY, NULL); + if (ret != LDB_SUCCESS) { + goto failed; + } + + _ldb_nss_ctx->base = ldb_dn_explode(_ldb_nss_ctx, _LDB_NSS_BASEDN); + if (_ldb_nss_ctx->base == NULL) { + goto failed; + } + + _ldb_nss_ctx->pw_cur = 0; + _ldb_nss_ctx->pw_res = NULL; + _ldb_nss_ctx->gr_cur = 0; + _ldb_nss_ctx->gr_res = NULL; + + return NSS_STATUS_SUCCESS; + +failed: + /* talloc_free(_ldb_nss_ctx); */ + _ldb_nss_ctx = NULL; + return NSS_STATUS_UNAVAIL; +} + +NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result, + char *buffer, + int buflen, + int *errnop, + struct ldb_message *msg) +{ + int len; + int bufpos; + const char *tmp; + + bufpos = 0; + + /* get username */ + tmp = ldb_msg_find_attr_as_string(msg, "uid", NULL); + if (tmp == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_name = &buffer[bufpos]; + bufpos += len; + + /* get userPassword */ + tmp = ldb_msg_find_attr_as_string(msg, "userPassword", NULL); + if (tmp == NULL) { + tmp = "LDB"; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_passwd = &buffer[bufpos]; + bufpos += len; + + /* this backend never serves an uid 0 user */ + result->pw_uid = ldb_msg_find_attr_as_int(msg, "uidNumber", 0); + if (result->pw_uid == 0) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + + result->pw_gid = ldb_msg_find_attr_as_int(msg, "gidNumber", 0); + if (result->pw_gid == 0) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + + /* get gecos */ + tmp = ldb_msg_find_attr_as_string(msg, "gecos", NULL); + if (tmp == NULL) { + tmp = ""; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_gecos = &buffer[bufpos]; + bufpos += len; + + /* get homeDirectory */ + tmp = ldb_msg_find_attr_as_string(msg, "homeDirectory", NULL); + if (tmp == NULL) { + tmp = ""; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_dir = &buffer[bufpos]; + bufpos += len; + + /* get shell */ + tmp = ldb_msg_find_attr_as_string(msg, "loginShell", NULL); + if (tmp == NULL) { + tmp = ""; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_shell = &buffer[bufpos]; + bufpos += len; + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _ldb_nss_fill_group(struct group *result, + char *buffer, + int buflen, + int *errnop, + struct ldb_message *group, + struct ldb_result *members) +{ + const char *tmp; + size_t len; + size_t bufpos; + size_t lsize; + int i; + + bufpos = 0; + + /* get group name */ + tmp = ldb_msg_find_attr_as_string(group, "cn", NULL); + if (tmp == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->gr_name = &buffer[bufpos]; + bufpos += len; + + /* get userPassword */ + tmp = ldb_msg_find_attr_as_string(group, "userPassword", NULL); + if (tmp == NULL) { + tmp = "LDB"; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->gr_passwd = &buffer[bufpos]; + bufpos += len; + + result->gr_gid = ldb_msg_find_attr_as_int(group, "gidNumber", 0); + if (result->gr_gid == 0) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + + /* check if there is enough memory for the list of pointers */ + lsize = (members->count + 1) * sizeof(char *); + + /* align buffer on pointer boundary */ + bufpos += (sizeof(char*) - ((unsigned long)(buffer) % sizeof(char*))); + if ((buflen - bufpos) < lsize) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + + result->gr_mem = (char **)&buffer[bufpos]; + bufpos += lsize; + + for (i = 0; i < members->count; i++) { + tmp = ldb_msg_find_attr_as_string(members->msgs[i], "uid", NULL); + if (tmp == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->gr_mem[i] = &buffer[bufpos]; + bufpos += len; + } + + result->gr_mem[i] = NULL; + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _ldb_nss_fill_initgr(gid_t group, + long int limit, + long int *start, + long int *size, + gid_t **groups, + int *errnop, + struct ldb_result *grlist) +{ + NSS_STATUS ret; + int i; + + for (i = 0; i < grlist->count; i++) { + + if (limit && (*start > limit)) { + /* TODO: warn no all groups were reported */ + *errnop = 0; + ret = NSS_STATUS_SUCCESS; + goto done; + } + + if (*start == *size) { + /* buffer full, enlarge it */ + long int gs; + gid_t *gm; + + gs = (*size) + 32; + if (limit && (gs > limit)) { + gs = limit; + } + + gm = (gid_t *)realloc((*groups), gs * sizeof(gid_t)); + if ( ! gm) { + *errnop = ENOMEM; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + *groups = gm; + *size = gs; + } + + (*groups)[*start] = ldb_msg_find_attr_as_int(grlist->msgs[i], "gidNumber", 0); + if ((*groups)[*start] == 0 || (*groups)[*start] == group) { + /* skip root group or primary group */ + continue; + } + (*start)++; + + } + + *errnop = 0; + ret = NSS_STATUS_SUCCESS; +done: + return ret; +} + +#define _LDB_NSS_ALLOC_CHECK(mem) do { if (!mem) { errno = ENOMEM; return NSS_STATUS_UNAVAIL; } } while(0) + +NSS_STATUS _ldb_nss_group_request(struct ldb_result **res, + struct ldb_dn *group_dn, + const char * const *attrs, + const char *mattr) +{ + struct ldb_control **ctrls; + struct ldb_control *ctrl; + struct ldb_asq_control *asqc; + struct ldb_request *req; + int ret; + + ctrls = talloc_array(*res, struct ldb_control *, 2); + _LDB_NSS_ALLOC_CHECK(ctrls); + + ctrl = talloc(ctrls, struct ldb_control); + _LDB_NSS_ALLOC_CHECK(ctrl); + + asqc = talloc(ctrl, struct ldb_asq_control); + _LDB_NSS_ALLOC_CHECK(asqc); + + asqc->source_attribute = talloc_strdup(asqc, mattr); + _LDB_NSS_ALLOC_CHECK(asqc->source_attribute); + + asqc->request = 1; + asqc->src_attr_len = strlen(asqc->source_attribute); + ctrl->oid = LDB_CONTROL_ASQ_OID; + ctrl->critical = 1; + ctrl->data = asqc; + ctrls[0] = ctrl; + ctrls[1] = NULL; + + ret = ldb_build_search_req( + &req, + _ldb_nss_ctx->ldb, + *res, + group_dn, + LDB_SCOPE_BASE, + "(objectClass=*)", + attrs, + ctrls, + res, + ldb_search_default_callback); + + if (ret != LDB_SUCCESS) { + errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + + ldb_set_timeout(_ldb_nss_ctx->ldb, req, 0); + + ret = ldb_request(_ldb_nss_ctx->ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } else { + talloc_free(req); + return NSS_STATUS_UNAVAIL; + } + + talloc_free(req); + return NSS_STATUS_SUCCESS; +} + -- cgit From c046f2e7a35e2cef2c1482f7d6a3f16be45b49d4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Nov 2006 16:09:36 +0000 Subject: r19720: - don't pass a pointer reference to ldb_search_default_callback() as it's ugly when it free's the callers memory on failure! - only steal the controls on a LDB_REPLY_EXTENDED, LDB_REPLY_DONE and ignore them on LDB_REPLY_ENTRY, LDB_REPLY_REFERRAL as we currently have not way to return them in a ldb_result (we should fix this!) metze (This used to be commit 47da62b15abf48f97ce6fc8dc4627792728349ae) --- source4/lib/ldb/nssldb/ldb-nss.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/lib/ldb/nssldb/ldb-nss.c') diff --git a/source4/lib/ldb/nssldb/ldb-nss.c b/source4/lib/ldb/nssldb/ldb-nss.c index 3206f38a10..614f6e170f 100644 --- a/source4/lib/ldb/nssldb/ldb-nss.c +++ b/source4/lib/ldb/nssldb/ldb-nss.c @@ -336,7 +336,7 @@ done: #define _LDB_NSS_ALLOC_CHECK(mem) do { if (!mem) { errno = ENOMEM; return NSS_STATUS_UNAVAIL; } } while(0) -NSS_STATUS _ldb_nss_group_request(struct ldb_result **res, +NSS_STATUS _ldb_nss_group_request(struct ldb_result **_res, struct ldb_dn *group_dn, const char * const *attrs, const char *mattr) @@ -346,8 +346,9 @@ NSS_STATUS _ldb_nss_group_request(struct ldb_result **res, struct ldb_asq_control *asqc; struct ldb_request *req; int ret; + struct ldb_result *res = *_res; - ctrls = talloc_array(*res, struct ldb_control *, 2); + ctrls = talloc_array(res, struct ldb_control *, 2); _LDB_NSS_ALLOC_CHECK(ctrls); ctrl = talloc(ctrls, struct ldb_control); @@ -370,7 +371,7 @@ NSS_STATUS _ldb_nss_group_request(struct ldb_result **res, ret = ldb_build_search_req( &req, _ldb_nss_ctx->ldb, - *res, + res, group_dn, LDB_SCOPE_BASE, "(objectClass=*)", -- cgit From 4889eb9f7aae9349e426d0f6d2217adff67eaebd Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 22 Nov 2006 00:59:34 +0000 Subject: r19831: Big ldb_dn optimization and interfaces enhancement patch This patch changes a lot of the code in ldb_dn.c, and also removes and add a number of manipulation functions around. The aim is to avoid validating a dn if not necessary as the validation code is necessarily slow. This is mainly to speed up internal operations where input is not user generated and so we can assume the DNs need no validation. The code is designed to keep the data as a string if possible. The code is not yet 100% perfect, but pass all the tests so far. A memleak is certainly present, I'll work on that next. Simo. (This used to be commit a580c871d3784602a9cce32d33419e63c8236e63) --- source4/lib/ldb/nssldb/ldb-nss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/ldb/nssldb/ldb-nss.c') diff --git a/source4/lib/ldb/nssldb/ldb-nss.c b/source4/lib/ldb/nssldb/ldb-nss.c index 614f6e170f..4577cea524 100644 --- a/source4/lib/ldb/nssldb/ldb-nss.c +++ b/source4/lib/ldb/nssldb/ldb-nss.c @@ -62,8 +62,8 @@ NSS_STATUS _ldb_nss_init(void) goto failed; } - _ldb_nss_ctx->base = ldb_dn_explode(_ldb_nss_ctx, _LDB_NSS_BASEDN); - if (_ldb_nss_ctx->base == NULL) { + _ldb_nss_ctx->base = ldb_dn_new(_ldb_nss_ctx, _ldb_nss_ctx->ldb, _LDB_NSS_BASEDN); + if ( ! ldb_dn_validate(_ldb_nss_ctx->base)) { goto failed; } -- cgit From 95f930d8751f1bcdd7ca9ef23c59b182c1315891 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:31:50 +0000 Subject: r23794: convert more code from LGPLv2+ to LGPLv3+ (This used to be commit 9d37f1ec070ddcfd49dfe351e76cc08fa0d9b41c) --- source4/lib/ldb/nssldb/ldb-nss.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'source4/lib/ldb/nssldb/ldb-nss.c') diff --git a/source4/lib/ldb/nssldb/ldb-nss.c b/source4/lib/ldb/nssldb/ldb-nss.c index 4577cea524..4cc15b2dde 100644 --- a/source4/lib/ldb/nssldb/ldb-nss.c +++ b/source4/lib/ldb/nssldb/ldb-nss.c @@ -6,17 +6,15 @@ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + version 3 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + You should have received a copy of the GNU Library General Public License + along with this program. If not, see . */ #include "ldb-nss.h" -- cgit From b8875bee5f0c5385ba02646c7a8b2380fdfabb7a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 04:04:46 +0000 Subject: r23800: LGPL is now called GNU Lesser General Public License not GNU Library General Public License (This used to be commit 01e3fe7533b5670236c026ec3c6cc1e25655fbc3) --- source4/lib/ldb/nssldb/ldb-nss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/lib/ldb/nssldb/ldb-nss.c') diff --git a/source4/lib/ldb/nssldb/ldb-nss.c b/source4/lib/ldb/nssldb/ldb-nss.c index 4cc15b2dde..199212dbbf 100644 --- a/source4/lib/ldb/nssldb/ldb-nss.c +++ b/source4/lib/ldb/nssldb/ldb-nss.c @@ -4,7 +4,7 @@ Copyright (C) Simo Sorce 2006 This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public + modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. @@ -13,7 +13,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. - You should have received a copy of the GNU Library General Public License + You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ -- cgit From 0020793515ade04f3ef5754717490e2eb2ca6bb9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 20 Feb 2008 03:40:44 +0100 Subject: Fix static module list generation for ldb. (This used to be commit 92c1c0e9137f0845cac6cc96bf78711b6aaffe21) --- source4/lib/ldb/nssldb/ldb-nss.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source4/lib/ldb/nssldb/ldb-nss.c') diff --git a/source4/lib/ldb/nssldb/ldb-nss.c b/source4/lib/ldb/nssldb/ldb-nss.c index 199212dbbf..e256f41a4d 100644 --- a/source4/lib/ldb/nssldb/ldb-nss.c +++ b/source4/lib/ldb/nssldb/ldb-nss.c @@ -45,11 +45,6 @@ NSS_STATUS _ldb_nss_init(void) _ldb_nss_ctx->pid = mypid; - ret = ldb_global_init(); - if (ret != 0) { - goto failed; - } - _ldb_nss_ctx->ldb = ldb_init(_ldb_nss_ctx); if (_ldb_nss_ctx->ldb == NULL) { goto failed; -- cgit From 929adc9efa5cf985f0585214d30d18521aa1a821 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 14 Jun 2008 11:24:17 -0400 Subject: Make up the right dependencies now that ldb depends on libevents (This used to be commit 3b8eec7ca334528cad3cdcd5e3fc5ee555d8d0e0) --- source4/lib/ldb/nssldb/ldb-nss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/lib/ldb/nssldb/ldb-nss.c') diff --git a/source4/lib/ldb/nssldb/ldb-nss.c b/source4/lib/ldb/nssldb/ldb-nss.c index e256f41a4d..8f7321031b 100644 --- a/source4/lib/ldb/nssldb/ldb-nss.c +++ b/source4/lib/ldb/nssldb/ldb-nss.c @@ -45,7 +45,7 @@ NSS_STATUS _ldb_nss_init(void) _ldb_nss_ctx->pid = mypid; - _ldb_nss_ctx->ldb = ldb_init(_ldb_nss_ctx); + _ldb_nss_ctx->ldb = ldb_init(_ldb_nss_ctx, NULL); if (_ldb_nss_ctx->ldb == NULL) { goto failed; } -- cgit