mirror of
https://github.com/samba-team/samba.git
synced 2025-12-24 04:23:53 +03:00
r19725: sync samba3's ldb with samba4
metze
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
d8f9c20055
commit
207643e9c9
@@ -18,7 +18,7 @@ SLAPD = @SLAPD@
|
||||
EXTRA_OBJ=@EXTRA_OBJ@
|
||||
TESTS=test-tdb.sh @TESTS@
|
||||
|
||||
CFLAGS=-I$(srcdir)/include -Iinclude -I$(srcdir) -I$(srcdir)/.. \
|
||||
CFLAGS=-g -I$(srcdir)/include -Iinclude -I$(srcdir) -I$(srcdir)/.. \
|
||||
@POPT_CFLAGS@ -I@tallocdir@ -I@tdbdir@/include -I@libreplacedir@ \
|
||||
-DLIBDIR=\"$(libdir)\" -DSHLIBEXT=\"@SHLIBEXT@\" -DUSE_MMAP=1 @CFLAGS@
|
||||
|
||||
@@ -41,6 +41,10 @@ MODULES_OBJ=$(MODDIR)/operational.o $(MODDIR)/rdn_name.o \
|
||||
$(MODDIR)/objectclass.o \
|
||||
$(MODDIR)/paged_results.o $(MODDIR)/sort.o $(MODDIR)/asq.o
|
||||
|
||||
NSSDIR=nssldb
|
||||
NSS_OBJ= $(NSSDIR)/ldb-nss.o $(NSSDIR)/ldb-pwd.o $(NSSDIR)/ldb-grp.o
|
||||
NSS_LIB = lib/libnss_ldb.so.2
|
||||
|
||||
OBJS = $(MODULES_OBJ) $(COMMON_OBJ) $(LDB_TDB_OBJ) @TDBOBJ@ @TALLOCOBJ@ @POPTOBJ@ @LIBREPLACEOBJ@ $(EXTRA_OBJ)
|
||||
|
||||
LDB_LIB = lib/libldb.a
|
||||
@@ -53,6 +57,13 @@ EXAMPLES = examples/ldbreader examples/ldifreader
|
||||
|
||||
DIRS = lib bin common ldb_tdb ldb_ldap ldb_sqlite3 modules tools examples
|
||||
|
||||
default: all
|
||||
|
||||
nss: nssdir all $(NSS_LIB)
|
||||
|
||||
nssdir:
|
||||
@mkdir -p $(NSSDIR)
|
||||
|
||||
all: showflags dirs $(OBJS) $(LDB_LIB) $(BINS) $(EXAMPLES) manpages
|
||||
|
||||
showflags:
|
||||
@@ -72,6 +83,9 @@ lib/libldb.a: $(OBJS)
|
||||
ar -rv $@ $(OBJS)
|
||||
@-ranlib $@
|
||||
|
||||
lib/libnss_ldb.so.2: $(NSS_OBJ) $(LIBS)
|
||||
$(CC) -shared -Wl,-soname,libnss_ldb.so.2 -o lib/libnss_ldb.so.2 $(NSS_OBJ) $(OBJS) $(LIB_FLAGS)
|
||||
|
||||
bin/ldbadd: tools/ldbadd.o tools/cmdline.o $(LIBS)
|
||||
$(CC) -o bin/ldbadd tools/ldbadd.o tools/cmdline.o $(LIB_FLAGS)
|
||||
|
||||
@@ -112,7 +126,7 @@ doxygen:
|
||||
|
||||
clean:
|
||||
rm -f *.o */*.o *.gcov */*.gc?? tdbtest.ldb*
|
||||
rm -f $(BINS) $(TDB_OBJ) $(TALLOC_OBJ) $(LDB_LIB)
|
||||
rm -f $(BINS) $(TDB_OBJ) $(TALLOC_OBJ) $(LDB_LIB) $(NSS_LIB)
|
||||
rm -f man/*.1 man/*.3 man/*.html
|
||||
rm -f $(EXAMPLES)
|
||||
rm -rf apidocs/
|
||||
|
||||
@@ -522,7 +522,7 @@ int ldb_request(struct ldb_context *ldb, struct ldb_request *req)
|
||||
Use talloc_free to free the ldb_message returned in 'res', if successful
|
||||
|
||||
*/
|
||||
static int ldb_search_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares)
|
||||
int ldb_search_default_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares)
|
||||
{
|
||||
struct ldb_result *res;
|
||||
int n;
|
||||
@@ -532,9 +532,10 @@ static int ldb_search_callback(struct ldb_context *ldb, void *context, struct ld
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
res = *((struct ldb_result **)context);
|
||||
res = talloc_get_type(context, struct ldb_result);
|
||||
|
||||
if (!res || !ares) {
|
||||
ldb_set_errstring(ldb, "NULL res or ares in callback");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -564,19 +565,17 @@ static int ldb_search_callback(struct ldb_context *ldb, void *context, struct ld
|
||||
|
||||
res->refs[n] = talloc_move(res->refs, &ares->referral);
|
||||
res->refs[n + 1] = NULL;
|
||||
case LDB_REPLY_EXTENDED:
|
||||
case LDB_REPLY_DONE:
|
||||
/* Should do something here to detect if this never
|
||||
* happens */
|
||||
/* TODO: we should really support controls on entries and referrals too! */
|
||||
res->controls = talloc_move(res, &ares->controls);
|
||||
break;
|
||||
}
|
||||
talloc_steal(res, ares->controls);
|
||||
talloc_free(ares);
|
||||
return LDB_SUCCESS;
|
||||
|
||||
error:
|
||||
talloc_free(ares);
|
||||
talloc_free(res);
|
||||
*((struct ldb_result **)context) = NULL;
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
@@ -752,13 +751,16 @@ int ldb_search(struct ldb_context *ldb,
|
||||
enum ldb_scope scope,
|
||||
const char *expression,
|
||||
const char * const *attrs,
|
||||
struct ldb_result **res)
|
||||
struct ldb_result **_res)
|
||||
{
|
||||
struct ldb_request *req;
|
||||
int ret;
|
||||
struct ldb_result *res;
|
||||
|
||||
*res = talloc_zero(ldb, struct ldb_result);
|
||||
if (! *res) {
|
||||
*_res = NULL;
|
||||
|
||||
res = talloc_zero(ldb, struct ldb_result);
|
||||
if (!res) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
@@ -769,7 +771,7 @@ int ldb_search(struct ldb_context *ldb,
|
||||
attrs,
|
||||
NULL,
|
||||
res,
|
||||
ldb_search_callback);
|
||||
ldb_search_default_callback);
|
||||
|
||||
if (ret != LDB_SUCCESS) goto done;
|
||||
|
||||
@@ -785,10 +787,10 @@ int ldb_search(struct ldb_context *ldb,
|
||||
|
||||
done:
|
||||
if (ret != LDB_SUCCESS) {
|
||||
talloc_free(*res);
|
||||
*res = NULL;
|
||||
talloc_free(res);
|
||||
}
|
||||
|
||||
*_res = res;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,19 @@
|
||||
|
||||
#define LDB_SPECIAL "@SPECIAL"
|
||||
|
||||
/**
|
||||
internal ldb exploded dn structures
|
||||
*/
|
||||
struct ldb_dn_component {
|
||||
char *name;
|
||||
struct ldb_val value;
|
||||
};
|
||||
|
||||
struct ldb_dn {
|
||||
int comp_num;
|
||||
struct ldb_dn_component *components;
|
||||
};
|
||||
|
||||
int ldb_dn_is_special(const struct ldb_dn *dn)
|
||||
{
|
||||
if (dn == NULL || dn->comp_num != 1) return 0;
|
||||
@@ -688,6 +701,26 @@ static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_d
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* Copy a DN but replace the old with the new base DN. */
|
||||
struct ldb_dn *ldb_dn_copy_rebase(void *mem_ctx, const struct ldb_dn *old, const struct ldb_dn *old_base, const struct ldb_dn *new_base)
|
||||
{
|
||||
struct ldb_dn *new_dn;
|
||||
int i, offset;
|
||||
|
||||
/* Perhaps we don't need to rebase at all? */
|
||||
if (!old_base || !new_base) {
|
||||
return ldb_dn_copy(mem_ctx, old);
|
||||
}
|
||||
|
||||
offset = old->comp_num - old_base->comp_num;
|
||||
new_dn = ldb_dn_copy_partial(mem_ctx, new_base, offset + new_base->comp_num);
|
||||
for (i = 0; i < offset; i++) {
|
||||
new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &(old->components[i]));
|
||||
}
|
||||
|
||||
return new_dn;
|
||||
}
|
||||
|
||||
/* copy specified number of elements of a dn into a new one
|
||||
element are copied from top level up to the unique rdn
|
||||
num_el may be greater than dn->comp_num (see ldb_dn_make_child)
|
||||
@@ -799,15 +832,6 @@ failed:
|
||||
|
||||
}
|
||||
|
||||
struct ldb_dn *ldb_dn_make_child(void *mem_ctx, const struct ldb_dn_component *component,
|
||||
const struct ldb_dn *base)
|
||||
{
|
||||
if (component == NULL) return NULL;
|
||||
|
||||
return ldb_dn_build_child(mem_ctx, component->name,
|
||||
(char *)component->value.data, base);
|
||||
}
|
||||
|
||||
struct ldb_dn *ldb_dn_compose(void *mem_ctx, const struct ldb_dn *dn1, const struct ldb_dn *dn2)
|
||||
{
|
||||
int i;
|
||||
@@ -872,28 +896,6 @@ struct ldb_dn *ldb_dn_string_compose(void *mem_ctx, const struct ldb_dn *base, c
|
||||
return dn;
|
||||
}
|
||||
|
||||
struct ldb_dn_component *ldb_dn_get_rdn(void *mem_ctx, const struct ldb_dn *dn)
|
||||
{
|
||||
struct ldb_dn_component *rdn;
|
||||
|
||||
if (dn == NULL) return NULL;
|
||||
|
||||
if (dn->comp_num < 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rdn = talloc(mem_ctx, struct ldb_dn_component);
|
||||
if (rdn == NULL) return NULL;
|
||||
|
||||
*rdn = ldb_dn_copy_component(mem_ctx, &dn->components[0]);
|
||||
if (rdn->name == NULL) {
|
||||
talloc_free(rdn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rdn;
|
||||
}
|
||||
|
||||
/* Create a 'canonical name' string from a DN:
|
||||
|
||||
ie dc=samba,dc=org -> samba.org/
|
||||
@@ -962,3 +964,58 @@ char *ldb_dn_canonical_string(void *mem_ctx, const struct ldb_dn *dn) {
|
||||
char *ldb_dn_canonical_ex_string(void *mem_ctx, const struct ldb_dn *dn) {
|
||||
return ldb_dn_canonical(mem_ctx, dn, 1);
|
||||
}
|
||||
|
||||
int ldb_dn_get_comp_num(const struct ldb_dn *dn)
|
||||
{
|
||||
return dn->comp_num;
|
||||
}
|
||||
|
||||
const char *ldb_dn_get_component_name(const struct ldb_dn *dn, unsigned int num)
|
||||
{
|
||||
if (num >= dn->comp_num) return NULL;
|
||||
return dn->components[num].name;
|
||||
}
|
||||
|
||||
const struct ldb_val *ldb_dn_get_component_val(const struct ldb_dn *dn, unsigned int num)
|
||||
{
|
||||
if (num >= dn->comp_num) return NULL;
|
||||
return &dn->components[num].value;
|
||||
}
|
||||
|
||||
const char *ldb_dn_get_rdn_name(const struct ldb_dn *dn) {
|
||||
if (dn->comp_num == 0) return NULL;
|
||||
return dn->components[0].name;
|
||||
}
|
||||
|
||||
const struct ldb_val *ldb_dn_get_rdn_val(const struct ldb_dn *dn) {
|
||||
if (dn->comp_num == 0) return NULL;
|
||||
return &dn->components[0].value;
|
||||
}
|
||||
|
||||
int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val)
|
||||
{
|
||||
char *n;
|
||||
struct ldb_val v;
|
||||
|
||||
if (num >= dn->comp_num) {
|
||||
return LDB_ERR_OTHER;
|
||||
}
|
||||
|
||||
n = talloc_strdup(dn, name);
|
||||
if ( ! n) {
|
||||
return LDB_ERR_OTHER;
|
||||
}
|
||||
|
||||
v.length = val.length;
|
||||
v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
|
||||
if ( ! v.data) {
|
||||
return LDB_ERR_OTHER;
|
||||
}
|
||||
|
||||
talloc_free(dn->components[num].name);
|
||||
talloc_free(dn->components[num].value.data);
|
||||
dn->components[num].name = n;
|
||||
dn->components[num].value = v;
|
||||
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ static int ldb_match_scope(struct ldb_context *ldb,
|
||||
break;
|
||||
|
||||
case LDB_SCOPE_ONELEVEL:
|
||||
if (dn->comp_num == (base->comp_num + 1)) {
|
||||
if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) {
|
||||
if (ldb_dn_compare_base(ldb, base, dn) == 0) {
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
@@ -159,6 +159,7 @@ static const struct ldb_module_ops *ldb_find_module_ops(const char *name)
|
||||
ldb_objectclass_init, \
|
||||
ldb_paged_results_init, \
|
||||
ldb_sort_init, \
|
||||
ldb_asq_init, \
|
||||
NULL \
|
||||
}
|
||||
#endif
|
||||
@@ -205,17 +206,26 @@ int ldb_try_load_dso(struct ldb_context *ldb, const char *name)
|
||||
char *path;
|
||||
void *handle;
|
||||
int (*init_fn) (void);
|
||||
char *modulesdir;
|
||||
|
||||
#ifdef HAVE_DLOPEN
|
||||
if (getenv("LD_LDB_MODULE_PATH") != NULL) {
|
||||
modulesdir = talloc_strdup(ldb, getenv("LD_LDB_MODULE_PATH"));
|
||||
} else {
|
||||
#ifdef _SAMBA_BUILD_
|
||||
path = talloc_asprintf(ldb, "%s/ldb/%s.%s", dyn_MODULESDIR, name, dyn_SHLIBEXT);
|
||||
modulesdir = talloc_asprintf(ldb, "%s/ldb", dyn_MODULESDIR);
|
||||
#else
|
||||
path = talloc_asprintf(ldb, "%s/%s.%s", MODULESDIR, name, SHLIBEXT);
|
||||
modulesdir = talloc_strdup(ldb, MODULESDIR);
|
||||
#endif
|
||||
}
|
||||
|
||||
path = talloc_asprintf(ldb, "%s/%s.%s", modulesdir, name, SHLIBEXT);
|
||||
|
||||
talloc_free(modulesdir);
|
||||
|
||||
ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s\n", name, path);
|
||||
|
||||
handle = dlopen(path, 0);
|
||||
handle = dlopen(path, RTLD_NOW);
|
||||
if (handle == NULL) {
|
||||
ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s\n", name, path, dlerror());
|
||||
return -1;
|
||||
|
||||
@@ -119,10 +119,10 @@ struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v)
|
||||
/*
|
||||
add an empty element to a message
|
||||
*/
|
||||
int ldb_msg_add_empty(struct ldb_message *msg,
|
||||
const char *attr_name,
|
||||
int flags,
|
||||
struct ldb_message_element **return_el)
|
||||
int ldb_msg_add_empty( struct ldb_message *msg,
|
||||
const char *attr_name,
|
||||
int flags,
|
||||
struct ldb_message_element **return_el)
|
||||
{
|
||||
struct ldb_message_element *els;
|
||||
|
||||
|
||||
@@ -167,7 +167,9 @@ OBJ_FILES = \
|
||||
common/ldb_controls.o \
|
||||
common/qsort.o
|
||||
PUBLIC_DEPENDENCIES = \
|
||||
LIBTALLOC
|
||||
LIBTALLOC \
|
||||
DYNCONFIG \
|
||||
SOCKET_WRAPPER
|
||||
MANPAGE = man/ldb.3
|
||||
PUBLIC_HEADERS = include/ldb.h include/ldb_errors.h
|
||||
#
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Copyright (C) Andrew Tridgell 2004
|
||||
Copyright (C) Stefan Metzmacher 2004
|
||||
Copyright (C) Simo Sorce 2005
|
||||
Copyright (C) Simo Sorce 2005-2006
|
||||
|
||||
** NOTE! The following LGPL license applies to the ldb
|
||||
** library. This does NOT imply that all of Samba is released
|
||||
@@ -86,18 +86,9 @@ struct ldb_val {
|
||||
#endif
|
||||
/*! \endcond */
|
||||
|
||||
/**
|
||||
internal ldb exploded dn structures
|
||||
*/
|
||||
struct ldb_dn_component {
|
||||
char *name;
|
||||
struct ldb_val value;
|
||||
};
|
||||
|
||||
struct ldb_dn {
|
||||
int comp_num;
|
||||
struct ldb_dn_component *components;
|
||||
};
|
||||
/* opaque ldb_dn structures, see ldb_dn.c for internals */
|
||||
struct ldb_dn_component;
|
||||
struct ldb_dn;
|
||||
|
||||
/**
|
||||
There are a number of flags that are used with ldap_modify() in
|
||||
@@ -193,12 +184,6 @@ enum ldb_scope {LDB_SCOPE_DEFAULT=-1,
|
||||
|
||||
struct ldb_context;
|
||||
|
||||
/*
|
||||
the fuction type for the callback used in traversing the database
|
||||
*/
|
||||
typedef int (*ldb_traverse_fn)(struct ldb_context *, const struct ldb_message *);
|
||||
|
||||
|
||||
/* debugging uses one of the following levels */
|
||||
enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR,
|
||||
LDB_DEBUG_WARNING, LDB_DEBUG_TRACE};
|
||||
@@ -333,22 +318,25 @@ char *ldb_binary_encode_string(void *mem_ctx, const char *string);
|
||||
typedef int (*ldb_attr_handler_t)(struct ldb_context *, void *mem_ctx, const struct ldb_val *, struct ldb_val *);
|
||||
typedef int (*ldb_attr_comparison_t)(struct ldb_context *, void *mem_ctx, const struct ldb_val *, const struct ldb_val *);
|
||||
|
||||
struct ldb_attrib_handler {
|
||||
const char *attr;
|
||||
/*
|
||||
attribute handler structure
|
||||
|
||||
/* LDB_ATTR_FLAG_* */
|
||||
attr -> The attribute name
|
||||
flags -> LDB_ATTR_FLAG_*
|
||||
ldif_read_fn -> convert from ldif to binary format
|
||||
ldif_write_fn -> convert from binary to ldif format
|
||||
canonicalise_fn -> canonicalise a value, for use by indexing and dn construction
|
||||
comparison_fn -> compare two values
|
||||
*/
|
||||
|
||||
struct ldb_attrib_handler {
|
||||
|
||||
const char *attr;
|
||||
unsigned flags;
|
||||
|
||||
/* convert from ldif to binary format */
|
||||
ldb_attr_handler_t ldif_read_fn;
|
||||
|
||||
/* convert from binary to ldif format */
|
||||
ldb_attr_handler_t ldif_write_fn;
|
||||
|
||||
/* canonicalise a value, for use by indexing and dn construction */
|
||||
ldb_attr_handler_t canonicalise_fn;
|
||||
|
||||
/* compare two values */
|
||||
ldb_attr_comparison_t comparison_fn;
|
||||
};
|
||||
|
||||
@@ -839,6 +827,145 @@ int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, co
|
||||
*/
|
||||
const struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb);
|
||||
|
||||
|
||||
/**
|
||||
The Default iasync search callback function
|
||||
|
||||
\param ldb the context associated with the database (from ldb_init())
|
||||
\param context the callback context
|
||||
\param ares a single reply from the async core
|
||||
|
||||
\return result code (LDB_SUCCESS on success, or a failure code)
|
||||
|
||||
\note this function expects the context to always be an struct ldb_result pointer
|
||||
AND a talloc context, this function will steal on the context each message
|
||||
from the ares reply passed on by the async core so that in the end all the
|
||||
messages will be in the context (ldb_result) memory tree.
|
||||
Freeing the passed context (ldb_result tree) will free all the resources
|
||||
(the request need to be freed separately and the result doe not depend on the
|
||||
request that can be freed as sson as the search request is finished)
|
||||
*/
|
||||
|
||||
int ldb_search_default_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares);
|
||||
|
||||
/**
|
||||
Helper function to build a search request
|
||||
|
||||
\param ret_req the request structure is returned here (talloced on mem_ctx)
|
||||
\param ldb the context associated with the database (from ldb_init())
|
||||
\param mem_ctx a talloc emmory context (used as parent of ret_req)
|
||||
\param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one)
|
||||
\param scope the search scope for the query
|
||||
\param expression the search expression to use for this query
|
||||
\param attrs the search attributes for the query (pass NULL if none required)
|
||||
\param controls an array of controls
|
||||
\param context the callback function context
|
||||
\param the callback function to handle the async replies
|
||||
|
||||
\return result code (LDB_SUCCESS on success, or a failure code)
|
||||
*/
|
||||
|
||||
int ldb_build_search_req(struct ldb_request **ret_req,
|
||||
struct ldb_context *ldb,
|
||||
void *mem_ctx,
|
||||
const struct ldb_dn *base,
|
||||
enum ldb_scope scope,
|
||||
const char *expression,
|
||||
const char * const *attrs,
|
||||
struct ldb_control **controls,
|
||||
void *context,
|
||||
ldb_request_callback_t callback);
|
||||
|
||||
/**
|
||||
Helper function to build an add request
|
||||
|
||||
\param ret_req the request structure is returned here (talloced on mem_ctx)
|
||||
\param ldb the context associated with the database (from ldb_init())
|
||||
\param mem_ctx a talloc emmory context (used as parent of ret_req)
|
||||
\param message contains the entry to be added
|
||||
\param controls an array of controls
|
||||
\param context the callback function context
|
||||
\param the callback function to handle the async replies
|
||||
|
||||
\return result code (LDB_SUCCESS on success, or a failure code)
|
||||
*/
|
||||
|
||||
int ldb_build_add_req(struct ldb_request **ret_req,
|
||||
struct ldb_context *ldb,
|
||||
void *mem_ctx,
|
||||
const struct ldb_message *message,
|
||||
struct ldb_control **controls,
|
||||
void *context,
|
||||
ldb_request_callback_t callback);
|
||||
|
||||
/**
|
||||
Helper function to build a modify request
|
||||
|
||||
\param ret_req the request structure is returned here (talloced on mem_ctx)
|
||||
\param ldb the context associated with the database (from ldb_init())
|
||||
\param mem_ctx a talloc emmory context (used as parent of ret_req)
|
||||
\param message contains the entry to be modified
|
||||
\param controls an array of controls
|
||||
\param context the callback function context
|
||||
\param the callback function to handle the async replies
|
||||
|
||||
\return result code (LDB_SUCCESS on success, or a failure code)
|
||||
*/
|
||||
|
||||
int ldb_build_mod_req(struct ldb_request **ret_req,
|
||||
struct ldb_context *ldb,
|
||||
void *mem_ctx,
|
||||
const struct ldb_message *message,
|
||||
struct ldb_control **controls,
|
||||
void *context,
|
||||
ldb_request_callback_t callback);
|
||||
|
||||
/**
|
||||
Helper function to build a delete request
|
||||
|
||||
\param ret_req the request structure is returned here (talloced on mem_ctx)
|
||||
\param ldb the context associated with the database (from ldb_init())
|
||||
\param mem_ctx a talloc emmory context (used as parent of ret_req)
|
||||
\param dn the DN to be deleted
|
||||
\param controls an array of controls
|
||||
\param context the callback function context
|
||||
\param the callback function to handle the async replies
|
||||
|
||||
\return result code (LDB_SUCCESS on success, or a failure code)
|
||||
*/
|
||||
|
||||
int ldb_build_del_req(struct ldb_request **ret_req,
|
||||
struct ldb_context *ldb,
|
||||
void *mem_ctx,
|
||||
const struct ldb_dn *dn,
|
||||
struct ldb_control **controls,
|
||||
void *context,
|
||||
ldb_request_callback_t callback);
|
||||
|
||||
/**
|
||||
Helper function to build a rename request
|
||||
|
||||
\param ret_req the request structure is returned here (talloced on mem_ctx)
|
||||
\param ldb the context associated with the database (from ldb_init())
|
||||
\param mem_ctx a talloc emmory context (used as parent of ret_req)
|
||||
\param olddn the old DN
|
||||
\param newdn the new DN
|
||||
\param controls an array of controls
|
||||
\param context the callback function context
|
||||
\param the callback function to handle the async replies
|
||||
|
||||
\return result code (LDB_SUCCESS on success, or a failure code)
|
||||
*/
|
||||
|
||||
int ldb_build_rename_req(struct ldb_request **ret_req,
|
||||
struct ldb_context *ldb,
|
||||
void *mem_ctx,
|
||||
const struct ldb_dn *olddn,
|
||||
const struct ldb_dn *newdn,
|
||||
struct ldb_control **controls,
|
||||
void *context,
|
||||
ldb_request_callback_t callback);
|
||||
|
||||
/**
|
||||
Search the database
|
||||
|
||||
@@ -846,7 +973,7 @@ const struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb);
|
||||
records that match an LDAP-like search expression
|
||||
|
||||
\param ldb the context associated with the database (from ldb_init())
|
||||
\param base the Base Distinguished Name for the query (pass NULL for root DN)
|
||||
\param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one)
|
||||
\param scope the search scope for the query
|
||||
\param expression the search expression to use for this query
|
||||
\param attrs the search attributes for the query (pass NULL if none required)
|
||||
@@ -1156,18 +1283,25 @@ struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, void *mem_ctx, const str
|
||||
struct ldb_dn *ldb_dn_explode_casefold(struct ldb_context *ldb, void *mem_ctx, const char *dn);
|
||||
struct ldb_dn *ldb_dn_copy_partial(void *mem_ctx, const struct ldb_dn *dn, int num_el);
|
||||
struct ldb_dn *ldb_dn_copy(void *mem_ctx, const struct ldb_dn *dn);
|
||||
struct ldb_dn *ldb_dn_copy_rebase(void *mem_ctx, const struct ldb_dn *old, const struct ldb_dn *old_base, const struct ldb_dn *new_base);
|
||||
struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, const struct ldb_dn *dn);
|
||||
struct ldb_dn_component *ldb_dn_build_component(void *mem_ctx, const char *attr,
|
||||
const char *val);
|
||||
struct ldb_dn *ldb_dn_build_child(void *mem_ctx, const char *attr,
|
||||
const char * value,
|
||||
const struct ldb_dn *base);
|
||||
struct ldb_dn *ldb_dn_make_child(void *mem_ctx,
|
||||
const struct ldb_dn_component *component,
|
||||
const struct ldb_dn *base);
|
||||
struct ldb_dn *ldb_dn_compose(void *mem_ctx, const struct ldb_dn *dn1, const struct ldb_dn *dn2);
|
||||
struct ldb_dn *ldb_dn_string_compose(void *mem_ctx, const struct ldb_dn *base, const char *child_fmt, ...) PRINTF_ATTRIBUTE(3,4);
|
||||
struct ldb_dn_component *ldb_dn_get_rdn(void *mem_ctx, const struct ldb_dn *dn);
|
||||
char *ldb_dn_canonical_string(void *mem_ctx, const struct ldb_dn *dn);
|
||||
char *ldb_dn_canonical_ex_string(void *mem_ctx, const struct ldb_dn *dn);
|
||||
int ldb_dn_get_comp_num(const struct ldb_dn *dn);
|
||||
const char *ldb_dn_get_component_name(const struct ldb_dn *dn, unsigned int num);
|
||||
const struct ldb_val *ldb_dn_get_component_val(const struct ldb_dn *dn, unsigned int num);
|
||||
const char *ldb_dn_get_rdn_name(const struct ldb_dn *dn);
|
||||
const struct ldb_val *ldb_dn_get_rdn_val(const struct ldb_dn *dn);
|
||||
int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val);
|
||||
|
||||
|
||||
|
||||
/* useful functions for ldb_message structure manipulation */
|
||||
int ldb_dn_cmp(struct ldb_context *ldb, const char *dn1, const char *dn2);
|
||||
@@ -1228,9 +1362,9 @@ struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el,
|
||||
add a new empty element to a ldb_message
|
||||
*/
|
||||
int ldb_msg_add_empty(struct ldb_message *msg,
|
||||
const char *attr_name,
|
||||
int flags,
|
||||
struct ldb_message_element **return_el);
|
||||
const char *attr_name,
|
||||
int flags,
|
||||
struct ldb_message_element **return_el);
|
||||
|
||||
/**
|
||||
add a element to a ldb_message
|
||||
@@ -1239,9 +1373,9 @@ int ldb_msg_add(struct ldb_message *msg,
|
||||
const struct ldb_message_element *el,
|
||||
int flags);
|
||||
int ldb_msg_add_value(struct ldb_message *msg,
|
||||
const char *attr_name,
|
||||
const struct ldb_val *val,
|
||||
struct ldb_message_element **return_el);
|
||||
const char *attr_name,
|
||||
const struct ldb_val *val,
|
||||
struct ldb_message_element **return_el);
|
||||
int ldb_msg_add_steal_value(struct ldb_message *msg,
|
||||
const char *attr_name,
|
||||
struct ldb_val *val);
|
||||
@@ -1407,9 +1541,6 @@ char *ldb_timestring(void *mem_ctx, time_t t);
|
||||
*/
|
||||
time_t ldb_string_to_time(const char *s);
|
||||
|
||||
char *ldb_dn_canonical_string(void *mem_ctx, const struct ldb_dn *dn);
|
||||
char *ldb_dn_canonical_ex_string(void *mem_ctx, const struct ldb_dn *dn);
|
||||
|
||||
|
||||
void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque, ldb_qsort_cmp_fn_t cmp);
|
||||
#endif
|
||||
|
||||
@@ -170,6 +170,7 @@ int ldb_operational_init(void);
|
||||
int ldb_paged_results_init(void);
|
||||
int ldb_rdn_name_init(void);
|
||||
int ldb_schema_init(void);
|
||||
int ldb_asq_init(void);
|
||||
int ldb_sort_init(void);
|
||||
int ldb_ldap_init(void);
|
||||
int ldb_ildap_init(void);
|
||||
|
||||
@@ -7,6 +7,9 @@ modulesdir=@modulesdir@
|
||||
Name: ldb
|
||||
Description: An LDAP-like embedded database
|
||||
Version: 4.0
|
||||
Libs: @LIBS@ -L${libdir} -lldb
|
||||
Requires.private: tdb
|
||||
Requires: talloc
|
||||
Libs: -L${libdir} -lldb
|
||||
Cflags: -I${includedir} @CFLAGS@
|
||||
Modulesdir: ${modulesdir}
|
||||
URL: http://ldb.samba.org/
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "libcli/ldap/ldap.h"
|
||||
#include "libcli/ldap/ldap_client.h"
|
||||
#include "auth/auth.h"
|
||||
#include "auth/credentials/credentials.h"
|
||||
|
||||
struct ildb_private {
|
||||
struct ldap_connection *ldap;
|
||||
@@ -639,8 +640,8 @@ static int ildb_rename(struct ldb_module *module, struct ldb_request *req)
|
||||
|
||||
msg->r.ModifyDNRequest.newrdn =
|
||||
talloc_asprintf(msg, "%s=%s",
|
||||
req->op.rename.newdn->components[0].name,
|
||||
ldb_dn_escape_value(msg, req->op.rename.newdn->components[0].value));
|
||||
ldb_dn_get_rdn_name(req->op.rename.newdn),
|
||||
ldb_dn_escape_value(msg, *ldb_dn_get_rdn_val(req->op.rename.newdn)));
|
||||
if (msg->r.ModifyDNRequest.newrdn == NULL) {
|
||||
talloc_free(msg);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
|
||||
@@ -463,8 +463,8 @@ static int lldb_rename(struct ldb_module *module, struct ldb_request *req)
|
||||
}
|
||||
|
||||
newrdn = talloc_asprintf(lldb_ac, "%s=%s",
|
||||
req->op.rename.newdn->components[0].name,
|
||||
ldb_dn_escape_value(lldb, req->op.rename.newdn->components[0].value));
|
||||
ldb_dn_get_rdn_name(req->op.rename.newdn),
|
||||
ldb_dn_escape_value(lldb, *(ldb_dn_get_rdn_val(req->op.rename.newdn))));
|
||||
if (!newrdn) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
ldb database library
|
||||
|
||||
Copyright (C) Derrell Lipman 2005
|
||||
Copyright (C) Simo Sorce 2005
|
||||
Copyright (C) Simo Sorce 2005-2006
|
||||
|
||||
** NOTE! The following LGPL license applies to the ldb
|
||||
** library. This does NOT imply that all of Samba is released
|
||||
@@ -57,9 +57,9 @@ struct lsql_context {
|
||||
int (*callback)(struct ldb_context *, void *, struct ldb_reply *);
|
||||
};
|
||||
|
||||
static struct ldb_handle *init_handle(struct lsqlite3_private *lsqlite3, struct ldb_module *module,
|
||||
void *context,
|
||||
int (*callback)(struct ldb_context *, void *, struct ldb_reply *))
|
||||
static struct ldb_handle *init_handle(struct lsqlite3_private *lsqlite3,
|
||||
struct ldb_module *module,
|
||||
struct ldb_request *req)
|
||||
{
|
||||
struct lsql_context *ac;
|
||||
struct ldb_handle *h;
|
||||
@@ -85,8 +85,8 @@ static struct ldb_handle *init_handle(struct lsqlite3_private *lsqlite3, struct
|
||||
h->status = LDB_SUCCESS;
|
||||
|
||||
ac->module = module;
|
||||
ac->context = context;
|
||||
ac->callback = callback;
|
||||
ac->context = req->context;
|
||||
ac->callback = req->callback;
|
||||
|
||||
return h;
|
||||
}
|
||||
@@ -370,6 +370,7 @@ static char *parsetree_to_sql(struct ldb_module *module,
|
||||
} else if (strcasecmp(t->u.equality.attr, "dn") == 0) {
|
||||
/* DN query is a special ldb case */
|
||||
char *cdn = ldb_dn_linearize_casefold(module->ldb,
|
||||
mem_ctx,
|
||||
ldb_dn_explode(module->ldb,
|
||||
(const char *)value.data));
|
||||
|
||||
@@ -828,7 +829,7 @@ static long long lsqlite3_get_eid(struct ldb_module *module, const struct ldb_dn
|
||||
return -1;
|
||||
}
|
||||
|
||||
cdn = ldb_dn_linearize(local_ctx, ldb_dn_casefold(module->ldb, dn));
|
||||
cdn = ldb_dn_linearize(local_ctx, ldb_dn_casefold(module->ldb, local_ctx, dn));
|
||||
if (!cdn) goto done;
|
||||
|
||||
eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, local_ctx, cdn);
|
||||
@@ -842,53 +843,8 @@ done:
|
||||
* Interface functions referenced by lsqlite3_ops
|
||||
*/
|
||||
|
||||
static int lsql_search_sync_callback(struct ldb_context *ldb, void *context, struct ldb_reply *ares)
|
||||
{
|
||||
struct ldb_result *res = NULL;
|
||||
|
||||
if (!context) {
|
||||
ldb_set_errstring(ldb, "NULL Context in callback");
|
||||
goto error;
|
||||
}
|
||||
|
||||
res = *((struct ldb_result **)context);
|
||||
|
||||
if (!res || !ares) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ares->type == LDB_REPLY_ENTRY) {
|
||||
res->msgs = talloc_realloc(res, res->msgs, struct ldb_message *, res->count + 2);
|
||||
if (! res->msgs) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
res->msgs[res->count + 1] = NULL;
|
||||
|
||||
res->msgs[res->count] = talloc_move(res->msgs, &ares->message);
|
||||
res->count++;
|
||||
} else {
|
||||
ldb_debug(ldb, LDB_DEBUG_ERROR, "unrecognized async reply in ltdb_search_sync_callback!\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
talloc_free(ares);
|
||||
return LDB_SUCCESS;
|
||||
|
||||
error:
|
||||
if (ares) talloc_free(ares);
|
||||
if (res) talloc_free(res);
|
||||
if (context) *((struct ldb_result **)context) = NULL;
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
/* search for matching records, by tree */
|
||||
int lsql_search_async(struct ldb_module *module, const struct ldb_dn *base,
|
||||
enum ldb_scope scope, struct ldb_parse_tree *tree,
|
||||
const char * const *attrs,
|
||||
void *context,
|
||||
int (*callback)(struct ldb_context *, void *, struct ldb_reply *),
|
||||
struct ldb_handle **handle)
|
||||
int lsql_search(struct ldb_module *module, struct ldb_request *req)
|
||||
{
|
||||
struct lsqlite3_private *lsqlite3 = talloc_get_type(module->private_data, struct lsqlite3_private);
|
||||
struct lsql_context *lsql_ac;
|
||||
@@ -898,32 +854,29 @@ int lsql_search_async(struct ldb_module *module, const struct ldb_dn *base,
|
||||
char *query = NULL;
|
||||
int ret;
|
||||
|
||||
*handle = init_handle(lsqlite3, module, context, callback);
|
||||
if (*handle == NULL) {
|
||||
talloc_free(*handle);
|
||||
req->handle = init_handle(lsqlite3, module, req);
|
||||
if (req->handle == NULL) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
lsql_ac = talloc_get_type((*handle)->private_data, struct lsql_context);
|
||||
lsql_ac = talloc_get_type(req->handle->private_data, struct lsql_context);
|
||||
|
||||
if (base) {
|
||||
norm_basedn = ldb_dn_linearize(lsql_ac, ldb_dn_casefold(module->ldb, base));
|
||||
if ((req->op.search.base == NULL || req->op.search.base->comp_num == 0) &&
|
||||
(req->op.search.scope == LDB_SCOPE_BASE || req->op.search.scope == LDB_SCOPE_ONELEVEL))
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
|
||||
if (req->op.search.base) {
|
||||
norm_basedn = ldb_dn_linearize(lsql_ac, ldb_dn_casefold(module->ldb, lsql_ac, req->op.search.base));
|
||||
if (norm_basedn == NULL) {
|
||||
ret = LDB_ERR_INVALID_DN_SYNTAX;
|
||||
goto failed;
|
||||
}
|
||||
} else norm_basedn = talloc_strdup(lsql_ac, "");
|
||||
|
||||
if (*norm_basedn == '\0' &&
|
||||
(scope == LDB_SCOPE_BASE || scope == LDB_SCOPE_ONELEVEL)) {
|
||||
ret = LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Convert filter into a series of SQL conditions (constraints) */
|
||||
sqlfilter = parsetree_to_sql(module, lsql_ac, tree);
|
||||
sqlfilter = parsetree_to_sql(module, lsql_ac, req->op.search.tree);
|
||||
|
||||
switch(scope) {
|
||||
switch(req->op.search.scope) {
|
||||
case LDB_SCOPE_DEFAULT:
|
||||
case LDB_SCOPE_SUBTREE:
|
||||
if (*norm_basedn != '\0') {
|
||||
@@ -1033,12 +986,12 @@ int lsql_search_async(struct ldb_module *module, const struct ldb_dn *base,
|
||||
/ * */
|
||||
|
||||
lsql_ac->current_eid = 0;
|
||||
lsql_ac->attrs = attrs;
|
||||
lsql_ac->attrs = req->op.search.attrs;
|
||||
lsql_ac->ares = NULL;
|
||||
|
||||
(*handle)->state = LDB_ASYNC_PENDING;
|
||||
req->handle->state = LDB_ASYNC_PENDING;
|
||||
|
||||
ret = sqlite3_exec(lsqlite3->sqlite, query, lsqlite3_search_callback, *handle, &errmsg);
|
||||
ret = sqlite3_exec(lsqlite3->sqlite, query, lsqlite3_search_callback, req->handle, &errmsg);
|
||||
if (ret != SQLITE_OK) {
|
||||
if (errmsg) {
|
||||
ldb_set_errstring(module->ldb, errmsg);
|
||||
@@ -1053,70 +1006,39 @@ int lsql_search_async(struct ldb_module *module, const struct ldb_dn *base,
|
||||
if (lsql_ac->ares->message == NULL)
|
||||
goto failed;
|
||||
|
||||
(*handle)->status = lsql_ac->callback(module->ldb, lsql_ac->context, lsql_ac->ares);
|
||||
if ((*handle)->status != LDB_SUCCESS)
|
||||
req->handle->status = lsql_ac->callback(module->ldb, lsql_ac->context, lsql_ac->ares);
|
||||
if (req->handle->status != LDB_SUCCESS)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
(*handle)->state = LDB_ASYNC_DONE;
|
||||
req->handle->state = LDB_ASYNC_DONE;
|
||||
|
||||
return LDB_SUCCESS;
|
||||
|
||||
failed:
|
||||
talloc_free(*handle);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
static int lsql_search_bytree(struct ldb_module * module, const struct ldb_dn* base,
|
||||
enum ldb_scope scope, struct ldb_parse_tree * tree,
|
||||
const char * const * attrs, struct ldb_result ** res)
|
||||
{
|
||||
struct ldb_handle *handle;
|
||||
int ret;
|
||||
|
||||
*res = talloc_zero(module, struct ldb_result);
|
||||
if (! *res) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
ret = lsql_search_async(module, base, scope, tree, attrs,
|
||||
res, &lsql_search_sync_callback,
|
||||
&handle);
|
||||
|
||||
if (ret == LDB_SUCCESS) {
|
||||
ret = ldb_wait(handle, LDB_WAIT_ALL);
|
||||
talloc_free(handle);
|
||||
}
|
||||
|
||||
if (ret != LDB_SUCCESS) {
|
||||
talloc_free(*res);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* add a record */
|
||||
static int lsql_add_async(struct ldb_module *module, struct ldb_message *msg,
|
||||
void *context,
|
||||
int (*callback)(struct ldb_context *, void *, struct ldb_reply *),
|
||||
struct ldb_handle **handle)
|
||||
static int lsql_add(struct ldb_module *module, struct ldb_request *req)
|
||||
{
|
||||
struct lsqlite3_private *lsqlite3 = talloc_get_type(module->private_data, struct lsqlite3_private);
|
||||
struct lsql_context *lsql_ac;
|
||||
struct ldb_message *msg = req->op.add.message;
|
||||
long long eid;
|
||||
char *dn, *ndn;
|
||||
char *errmsg;
|
||||
char *query;
|
||||
int i;
|
||||
int ret = LDB_ERR_OPERATIONS_ERROR;
|
||||
int ret = LDB_SUCCESS;
|
||||
|
||||
*handle = init_handle(lsqlite3, module, context, callback);
|
||||
if (*handle == NULL) {
|
||||
goto failed;
|
||||
req->handle = init_handle(lsqlite3, module, req);
|
||||
if (req->handle == NULL) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
lsql_ac = talloc_get_type((*handle)->private_data, struct lsql_context);
|
||||
(*handle)->state = LDB_ASYNC_DONE;
|
||||
(*handle)->status = LDB_SUCCESS;
|
||||
lsql_ac = talloc_get_type(req->handle->private_data, struct lsql_context);
|
||||
req->handle->state = LDB_ASYNC_DONE;
|
||||
req->handle->status = LDB_SUCCESS;
|
||||
|
||||
/* See if this is an ltdb special */
|
||||
if (ldb_dn_is_special(msg->dn)) {
|
||||
@@ -1126,26 +1048,28 @@ static int lsql_add_async(struct ldb_module *module, struct ldb_message *msg,
|
||||
if (ldb_dn_compare(module->ldb, msg->dn, c) == 0) {
|
||||
#warning "insert subclasses into object class tree"
|
||||
ret = LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
c = ldb_dn_explode(local_ctx, "@INDEXLIST");
|
||||
if (ldb_dn_compare(module->ldb, msg->dn, c) == 0) {
|
||||
#warning "should we handle indexes somehow ?"
|
||||
goto failed;
|
||||
ret = LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
goto done;
|
||||
}
|
||||
*/
|
||||
/* Others are implicitly ignored */
|
||||
return LDB_SUCCESS;
|
||||
/* Others return an error */
|
||||
ret = LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* create linearized and normalized dns */
|
||||
dn = ldb_dn_linearize(lsql_ac, msg->dn);
|
||||
ndn = ldb_dn_linearize(lsql_ac, ldb_dn_casefold(module->ldb, msg->dn));
|
||||
ndn = ldb_dn_linearize(lsql_ac, ldb_dn_casefold(module->ldb, lsql_ac, msg->dn));
|
||||
if (dn == NULL || ndn == NULL) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
query = lsqlite3_tprintf(lsql_ac,
|
||||
@@ -1156,7 +1080,7 @@ static int lsql_add_async(struct ldb_module *module, struct ldb_message *msg,
|
||||
dn, ndn);
|
||||
if (query == NULL) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg);
|
||||
@@ -1166,13 +1090,13 @@ static int lsql_add_async(struct ldb_module *module, struct ldb_message *msg,
|
||||
free(errmsg);
|
||||
}
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, lsql_ac, ndn);
|
||||
if (eid == -1) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < msg->num_elements; i++) {
|
||||
@@ -1185,7 +1109,7 @@ static int lsql_add_async(struct ldb_module *module, struct ldb_message *msg,
|
||||
attr = ldb_attr_casefold(lsql_ac, el->name);
|
||||
if (attr == NULL) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
h = ldb_attrib_handler(module->ldb, el->name);
|
||||
@@ -1199,7 +1123,7 @@ static int lsql_add_async(struct ldb_module *module, struct ldb_message *msg,
|
||||
h->canonicalise_fn(module->ldb, lsql_ac, &(el->values[j]), &value);
|
||||
if (value.data == NULL) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
insert = lsqlite3_tprintf(lsql_ac,
|
||||
@@ -1211,7 +1135,7 @@ static int lsql_add_async(struct ldb_module *module, struct ldb_message *msg,
|
||||
el->values[j].data, value.data);
|
||||
if (insert == NULL) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = sqlite3_exec(lsqlite3->sqlite, insert, NULL, NULL, &errmsg);
|
||||
@@ -1221,58 +1145,38 @@ static int lsql_add_async(struct ldb_module *module, struct ldb_message *msg,
|
||||
free(errmsg);
|
||||
}
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lsql_ac->callback)
|
||||
(*handle)->status = lsql_ac->callback(module->ldb, lsql_ac->context, NULL);
|
||||
if (lsql_ac->callback) {
|
||||
req->handle->status = lsql_ac->callback(module->ldb, lsql_ac->context, NULL);
|
||||
}
|
||||
|
||||
return LDB_SUCCESS;
|
||||
|
||||
failed:
|
||||
talloc_free(*handle);
|
||||
done:
|
||||
req->handle->state = LDB_ASYNC_DONE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lsql_add(struct ldb_module *module, const struct ldb_message *msg)
|
||||
{
|
||||
struct ldb_handle *handle;
|
||||
int ret;
|
||||
|
||||
ret = lsql_add_async(module, msg, NULL, NULL, &handle);
|
||||
|
||||
if (ret != LDB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
ret = ldb_wait(handle, LDB_WAIT_ALL);
|
||||
|
||||
talloc_free(handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* modify a record */
|
||||
static int lsql_modify_async(struct ldb_module *module, const struct ldb_message *msg,
|
||||
void *context,
|
||||
int (*callback)(struct ldb_context *, void *, struct ldb_reply *),
|
||||
struct ldb_handle **handle)
|
||||
static int lsql_modify(struct ldb_module *module, struct ldb_request *req)
|
||||
{
|
||||
struct lsqlite3_private *lsqlite3 = talloc_get_type(module->private_data, struct lsqlite3_private);
|
||||
struct lsql_context *lsql_ac;
|
||||
struct ldb_message *msg = req->op.mod.message;
|
||||
long long eid;
|
||||
char *errmsg;
|
||||
int i;
|
||||
int ret = LDB_ERR_OPERATIONS_ERROR;
|
||||
int ret = LDB_SUCCESS;
|
||||
|
||||
*handle = init_handle(lsqlite3, module, context, callback);
|
||||
if (*handle == NULL) {
|
||||
goto failed;
|
||||
req->handle = init_handle(lsqlite3, module, req);
|
||||
if (req->handle == NULL) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
lsql_ac = talloc_get_type((*handle)->private_data, struct lsql_context);
|
||||
(*handle)->state = LDB_ASYNC_DONE;
|
||||
(*handle)->status = LDB_SUCCESS;
|
||||
lsql_ac = talloc_get_type(req->handle->private_data, struct lsql_context);
|
||||
req->handle->state = LDB_ASYNC_DONE;
|
||||
req->handle->status = LDB_SUCCESS;
|
||||
|
||||
/* See if this is an ltdb special */
|
||||
if (ldb_dn_is_special(msg->dn)) {
|
||||
@@ -1282,17 +1186,18 @@ static int lsql_modify_async(struct ldb_module *module, const struct ldb_message
|
||||
if (ldb_dn_compare(module->ldb, msg->dn, c) == 0) {
|
||||
#warning "modify subclasses into object class tree"
|
||||
ret = LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Others are implicitly ignored */
|
||||
return LDB_SUCCESS;
|
||||
/* Others return an error */
|
||||
ret = LDB_ERR_UNWILLING_TO_PERFORM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
eid = lsqlite3_get_eid(module, msg->dn);
|
||||
if (eid == -1) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < msg->num_elements; i++) {
|
||||
@@ -1307,7 +1212,7 @@ static int lsql_modify_async(struct ldb_module *module, const struct ldb_message
|
||||
attr = ldb_attr_casefold(lsql_ac, el->name);
|
||||
if (attr == NULL) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
h = ldb_attrib_handler(module->ldb, el->name);
|
||||
@@ -1324,7 +1229,7 @@ static int lsql_modify_async(struct ldb_module *module, const struct ldb_message
|
||||
eid, attr);
|
||||
if (mod == NULL) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg);
|
||||
@@ -1334,7 +1239,7 @@ static int lsql_modify_async(struct ldb_module *module, const struct ldb_message
|
||||
free(errmsg);
|
||||
}
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* MISSING break is INTENTIONAL */
|
||||
@@ -1349,7 +1254,7 @@ static int lsql_modify_async(struct ldb_module *module, const struct ldb_message
|
||||
h->canonicalise_fn(module->ldb, lsql_ac, &(el->values[j]), &value);
|
||||
if (value.data == NULL) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
mod = lsqlite3_tprintf(lsql_ac,
|
||||
@@ -1362,7 +1267,7 @@ static int lsql_modify_async(struct ldb_module *module, const struct ldb_message
|
||||
|
||||
if (mod == NULL) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg);
|
||||
@@ -1372,7 +1277,7 @@ static int lsql_modify_async(struct ldb_module *module, const struct ldb_message
|
||||
free(errmsg);
|
||||
}
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1388,7 +1293,7 @@ static int lsql_modify_async(struct ldb_module *module, const struct ldb_message
|
||||
eid, attr);
|
||||
if (mod == NULL) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg);
|
||||
@@ -1398,7 +1303,7 @@ static int lsql_modify_async(struct ldb_module *module, const struct ldb_message
|
||||
free(errmsg);
|
||||
}
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1410,7 +1315,7 @@ static int lsql_modify_async(struct ldb_module *module, const struct ldb_message
|
||||
h->canonicalise_fn(module->ldb, lsql_ac, &(el->values[j]), &value);
|
||||
if (value.data == NULL) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
mod = lsqlite3_tprintf(lsql_ac,
|
||||
@@ -1422,7 +1327,7 @@ static int lsql_modify_async(struct ldb_module *module, const struct ldb_message
|
||||
|
||||
if (mod == NULL) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg);
|
||||
@@ -1432,7 +1337,7 @@ static int lsql_modify_async(struct ldb_module *module, const struct ldb_message
|
||||
free(errmsg);
|
||||
}
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1440,57 +1345,37 @@ static int lsql_modify_async(struct ldb_module *module, const struct ldb_message
|
||||
}
|
||||
}
|
||||
|
||||
if (lsql_ac->callback)
|
||||
(*handle)->status = lsql_ac->callback(module->ldb, lsql_ac->context, NULL);
|
||||
if (lsql_ac->callback) {
|
||||
req->handle->status = lsql_ac->callback(module->ldb, lsql_ac->context, NULL);
|
||||
}
|
||||
|
||||
return LDB_SUCCESS;
|
||||
|
||||
failed:
|
||||
talloc_free(*handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lsql_modify(struct ldb_module *module, const struct ldb_message *msg)
|
||||
{
|
||||
struct ldb_handle *handle;
|
||||
int ret;
|
||||
|
||||
ret = lsql_modify_async(module, msg, NULL, NULL, &handle);
|
||||
|
||||
if (ret != LDB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
ret = ldb_wait(handle, LDB_WAIT_ALL);
|
||||
|
||||
talloc_free(handle);
|
||||
done:
|
||||
req->handle->state = LDB_ASYNC_DONE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* delete a record */
|
||||
static int lsql_delete_async(struct ldb_module *module, const struct ldb_dn *dn,
|
||||
void *context,
|
||||
int (*callback)(struct ldb_context *, void *, struct ldb_reply *),
|
||||
struct ldb_handle **handle)
|
||||
static int lsql_delete(struct ldb_module *module, struct ldb_request *req)
|
||||
{
|
||||
struct lsqlite3_private *lsqlite3 = talloc_get_type(module->private_data, struct lsqlite3_private);
|
||||
struct lsql_context *lsql_ac;
|
||||
long long eid;
|
||||
char *errmsg;
|
||||
char *query;
|
||||
int ret = LDB_ERR_OPERATIONS_ERROR;
|
||||
int ret = LDB_SUCCESS;
|
||||
|
||||
|
||||
*handle = init_handle(lsqlite3, module, context, callback);
|
||||
if (*handle == NULL) {
|
||||
goto failed;
|
||||
req->handle = init_handle(lsqlite3, module, req);
|
||||
if (req->handle == NULL) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
lsql_ac = talloc_get_type((*handle)->private_data, struct lsql_context);
|
||||
(*handle)->state = LDB_ASYNC_DONE;
|
||||
(*handle)->status = LDB_SUCCESS;
|
||||
lsql_ac = talloc_get_type(req->handle->private_data, struct lsql_context);
|
||||
req->handle->state = LDB_ASYNC_DONE;
|
||||
req->handle->status = LDB_SUCCESS;
|
||||
|
||||
eid = lsqlite3_get_eid(module, dn);
|
||||
eid = lsqlite3_get_eid(module, req->op.del.dn);
|
||||
if (eid == -1) {
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
query = lsqlite3_tprintf(lsql_ac,
|
||||
@@ -1501,7 +1386,7 @@ static int lsql_delete_async(struct ldb_module *module, const struct ldb_dn *dn,
|
||||
eid, eid);
|
||||
if (query == NULL) {
|
||||
ret = LDB_ERR_OTHER;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg);
|
||||
@@ -1510,68 +1395,43 @@ static int lsql_delete_async(struct ldb_module *module, const struct ldb_dn *dn,
|
||||
ldb_set_errstring(module->ldb, errmsg);
|
||||
free(errmsg);
|
||||
}
|
||||
ret = LDB_ERR_OPERATIONS_ERROR;
|
||||
goto failed;
|
||||
req->handle->status = LDB_ERR_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (lsql_ac->callback)
|
||||
(*handle)->status = lsql_ac->callback(module->ldb, lsql_ac->context, NULL);
|
||||
|
||||
return LDB_SUCCESS;
|
||||
|
||||
failed:
|
||||
talloc_free(*handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lsql_delete(struct ldb_module *module, const struct ldb_dn *dn)
|
||||
{
|
||||
struct ldb_handle *handle;
|
||||
int ret;
|
||||
|
||||
/* ignore ltdb specials */
|
||||
if (ldb_dn_is_special(dn)) {
|
||||
return LDB_SUCCESS;
|
||||
if (lsql_ac->callback) {
|
||||
ret = lsql_ac->callback(module->ldb, lsql_ac->context, NULL);
|
||||
}
|
||||
|
||||
ret = lsql_delete_async(module, dn, NULL, NULL, &handle);
|
||||
|
||||
if (ret != LDB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
ret = ldb_wait(handle, LDB_WAIT_ALL);
|
||||
|
||||
talloc_free(handle);
|
||||
done:
|
||||
req->handle->state = LDB_ASYNC_DONE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* rename a record */
|
||||
static int lsql_rename_async(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn,
|
||||
void *context,
|
||||
int (*callback)(struct ldb_context *, void *, struct ldb_reply *),
|
||||
struct ldb_handle **handle)
|
||||
static int lsql_rename(struct ldb_module *module, struct ldb_request *req)
|
||||
{
|
||||
struct lsqlite3_private *lsqlite3 = talloc_get_type(module->private_data, struct lsqlite3_private);
|
||||
struct lsql_context *lsql_ac;
|
||||
char *new_dn, *new_cdn, *old_cdn;
|
||||
char *errmsg;
|
||||
char *query;
|
||||
int ret = LDB_ERR_OPERATIONS_ERROR;
|
||||
int ret = LDB_SUCCESS;
|
||||
|
||||
*handle = init_handle(lsqlite3, module, context, callback);
|
||||
if (*handle == NULL) {
|
||||
goto failed;
|
||||
req->handle = init_handle(lsqlite3, module, req);
|
||||
if (req->handle == NULL) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
lsql_ac = talloc_get_type((*handle)->private_data, struct lsql_context);
|
||||
(*handle)->state = LDB_ASYNC_DONE;
|
||||
(*handle)->status = LDB_SUCCESS;
|
||||
lsql_ac = talloc_get_type(req->handle->private_data, struct lsql_context);
|
||||
req->handle->state = LDB_ASYNC_DONE;
|
||||
req->handle->status = LDB_SUCCESS;
|
||||
|
||||
/* create linearized and normalized dns */
|
||||
old_cdn = ldb_dn_linearize(lsql_ac, ldb_dn_casefold(module->ldb, olddn));
|
||||
new_cdn = ldb_dn_linearize(lsql_ac, ldb_dn_casefold(module->ldb, newdn));
|
||||
new_dn = ldb_dn_linearize(lsql_ac, newdn);
|
||||
old_cdn = ldb_dn_linearize(lsql_ac, ldb_dn_casefold(module->ldb, lsql_ac, req->op.rename.olddn));
|
||||
new_cdn = ldb_dn_linearize(lsql_ac, ldb_dn_casefold(module->ldb, lsql_ac, req->op.rename.newdn));
|
||||
new_dn = ldb_dn_linearize(lsql_ac, req->op.rename.newdn);
|
||||
if (old_cdn == NULL || new_cdn == NULL || new_dn == NULL) {
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* build the SQL query */
|
||||
@@ -1580,7 +1440,7 @@ static int lsql_rename_async(struct ldb_module *module, const struct ldb_dn *old
|
||||
"WHERE norm_dn = '%q';",
|
||||
new_dn, new_cdn, old_cdn);
|
||||
if (query == NULL) {
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* execute */
|
||||
@@ -1591,38 +1451,15 @@ static int lsql_rename_async(struct ldb_module *module, const struct ldb_dn *old
|
||||
free(errmsg);
|
||||
}
|
||||
ret = LDB_ERR_OPERATIONS_ERROR;
|
||||
goto failed;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (lsql_ac->callback)
|
||||
(*handle)->status = lsql_ac->callback(module->ldb, lsql_ac->context, NULL);
|
||||
|
||||
return LDB_SUCCESS;
|
||||
|
||||
failed:
|
||||
talloc_free(*handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lsql_rename(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
|
||||
{
|
||||
struct ldb_handle *handle;
|
||||
int ret;
|
||||
|
||||
/* ignore ltdb specials */
|
||||
if (ldb_dn_is_special(olddn) || ldb_dn_is_special(newdn)) {
|
||||
return LDB_SUCCESS;
|
||||
if (lsql_ac->callback) {
|
||||
ret = lsql_ac->callback(module->ldb, lsql_ac->context, NULL);
|
||||
}
|
||||
|
||||
|
||||
ret = lsql_rename_async(module, olddn, newdn, NULL, NULL, &handle);
|
||||
|
||||
if (ret != LDB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
ret = ldb_wait(handle, LDB_WAIT_ALL);
|
||||
|
||||
talloc_free(handle);
|
||||
done:
|
||||
req->handle->state = LDB_ASYNC_DONE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1687,6 +1524,41 @@ static int lsql_del_trans(struct ldb_module *module)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int destructor(struct lsqlite3_private *lsqlite3)
|
||||
{
|
||||
if (lsqlite3->sqlite) {
|
||||
sqlite3_close(lsqlite3->sqlite);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lsql_request(struct ldb_module *module, struct ldb_request *req)
|
||||
{
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
static int lsql_wait(struct ldb_handle *handle, enum ldb_wait_type type)
|
||||
{
|
||||
return handle->status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Table of operations for the sqlite3 backend
|
||||
*/
|
||||
static const struct ldb_module_ops lsqlite3_ops = {
|
||||
.name = "sqlite",
|
||||
.search = lsql_search,
|
||||
.add = lsql_add,
|
||||
.modify = lsql_modify,
|
||||
.del = lsql_delete,
|
||||
.rename = lsql_rename,
|
||||
.request = lsql_request,
|
||||
.start_transaction = lsql_start_trans,
|
||||
.end_transaction = lsql_end_trans,
|
||||
.del_transaction = lsql_del_trans,
|
||||
.wait = lsql_wait,
|
||||
};
|
||||
|
||||
/*
|
||||
* Static functions
|
||||
*/
|
||||
@@ -1796,12 +1668,12 @@ static int initialize(struct lsqlite3_private *lsqlite3,
|
||||
" ('TOP', '0001');");
|
||||
|
||||
/* Skip protocol indicator of url */
|
||||
if (strncmp(url, "sqlite://", 9) != 0) {
|
||||
if (strncmp(url, "sqlite3://", 10) != 0) {
|
||||
return SQLITE_MISUSE;
|
||||
}
|
||||
|
||||
/* Update pointer to just after the protocol indicator */
|
||||
url += 9;
|
||||
url += 10;
|
||||
|
||||
/* Try to open the (possibly empty/non-existent) database */
|
||||
if ((ret = sqlite3_open(url, &lsqlite3->sqlite)) != SQLITE_OK) {
|
||||
@@ -1959,112 +1831,6 @@ failed:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int destructor(struct lsqlite3_private *lsqlite3)
|
||||
{
|
||||
if (lsqlite3->sqlite) {
|
||||
sqlite3_close(lsqlite3->sqlite);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lsql_wait(struct ldb_handle *handle, enum ldb_wait_type type)
|
||||
{
|
||||
return handle->status;
|
||||
}
|
||||
|
||||
static int lsql_request(struct ldb_module *module, struct ldb_request *req)
|
||||
{
|
||||
/* check for oustanding critical controls and return an error if found */
|
||||
|
||||
if (req->controls != NULL) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_WARNING, "Controls should not reach the ldb_sqlite3 backend!\n");
|
||||
}
|
||||
|
||||
if (check_critical_controls(req->controls)) {
|
||||
return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
|
||||
}
|
||||
|
||||
switch (req->operation) {
|
||||
|
||||
case LDB_SEARCH:
|
||||
return lsql_search_bytree(module,
|
||||
req->op.search.base,
|
||||
req->op.search.scope,
|
||||
req->op.search.tree,
|
||||
req->op.search.attrs,
|
||||
&req->op.search.res);
|
||||
|
||||
case LDB_ADD:
|
||||
return lsql_add(module, req->op.add.message);
|
||||
|
||||
case LDB_MODIFY:
|
||||
return lsql_modify(module, req->op.mod.message);
|
||||
|
||||
case LDB_DELETE:
|
||||
return lsql_delete(module, req->op.del.dn);
|
||||
|
||||
case LDB_RENAME:
|
||||
return lsql_rename(module,
|
||||
req->op.rename.olddn,
|
||||
req->op.rename.newdn);
|
||||
|
||||
case LDB_SEARCH:
|
||||
return lsql_search_async(module,
|
||||
req->op.search.base,
|
||||
req->op.search.scope,
|
||||
req->op.search.tree,
|
||||
req->op.search.attrs,
|
||||
req->context,
|
||||
req->callback,
|
||||
&req->handle);
|
||||
/*
|
||||
case LDB_ADD:
|
||||
return lsql_add_async(module,
|
||||
req->op.add.message,
|
||||
req->context,
|
||||
req->callback,
|
||||
&req->handle);
|
||||
|
||||
case LDB_MODIFY:
|
||||
return lsql_modify_async(module,
|
||||
req->op.mod.message,
|
||||
req->context,
|
||||
req->callback,
|
||||
&req->handle);
|
||||
*/
|
||||
case LDB_DELETE:
|
||||
return lsql_delete_async(module,
|
||||
req->op.del.dn,
|
||||
req->context,
|
||||
req->callback,
|
||||
&req->handle);
|
||||
|
||||
case LDB_RENAME:
|
||||
return lsql_rename_async(module,
|
||||
req->op.rename.olddn,
|
||||
req->op.rename.newdn,
|
||||
req->context,
|
||||
req->callback,
|
||||
&req->handle);
|
||||
|
||||
default:
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Table of operations for the sqlite3 backend
|
||||
*/
|
||||
static const struct ldb_module_ops lsqlite3_ops = {
|
||||
.name = "sqlite",
|
||||
.request = lsql_request,
|
||||
.start_transaction = lsql_start_trans,
|
||||
.end_transaction = lsql_end_trans,
|
||||
.del_transaction = lsql_del_trans,
|
||||
.wait = lsql_wait,
|
||||
};
|
||||
|
||||
/*
|
||||
* connect to the database
|
||||
*/
|
||||
|
||||
@@ -464,7 +464,7 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req)
|
||||
struct ldb_reply *ares;
|
||||
int ret;
|
||||
|
||||
if ((req->op.search.base == NULL || req->op.search.base->comp_num == 0) &&
|
||||
if ((req->op.search.base == NULL || ldb_dn_get_comp_num(req->op.search.base) == 0) &&
|
||||
(req->op.search.scope == LDB_SCOPE_BASE || req->op.search.scope == LDB_SCOPE_ONELEVEL))
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
|
||||
|
||||
@@ -454,8 +454,7 @@ static int asq_init(struct ldb_module *module)
|
||||
|
||||
ret = ldb_request(module->ldb, req);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_ERROR, "asq: Unable to register control with rootdse!\n");
|
||||
return LDB_ERR_OTHER;
|
||||
ldb_debug(module->ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!\n");
|
||||
}
|
||||
|
||||
return ldb_next_init(module);
|
||||
|
||||
@@ -181,60 +181,16 @@ BOOL map_check_local_db(struct ldb_module *module)
|
||||
return True;
|
||||
}
|
||||
|
||||
/* WARK: verbatim copy from ldb_dn.c */
|
||||
static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src)
|
||||
{
|
||||
struct ldb_dn_component dst;
|
||||
|
||||
memset(&dst, 0, sizeof(dst));
|
||||
|
||||
if (src == NULL) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
dst.value = ldb_val_dup(mem_ctx, &(src->value));
|
||||
if (dst.value.data == NULL) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
dst.name = talloc_strdup(mem_ctx, src->name);
|
||||
if (dst.name == NULL) {
|
||||
talloc_free(dst.value.data);
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* Copy a DN but replace the old with the new base DN. */
|
||||
static struct ldb_dn *ldb_dn_rebase(void *mem_ctx, const struct ldb_dn *old, const struct ldb_dn *old_base, const struct ldb_dn *new_base)
|
||||
{
|
||||
struct ldb_dn *new;
|
||||
int i, offset;
|
||||
|
||||
/* Perhaps we don't need to rebase at all? */
|
||||
if (!old_base || !new_base) {
|
||||
return ldb_dn_copy(mem_ctx, old);
|
||||
}
|
||||
|
||||
offset = old->comp_num - old_base->comp_num;
|
||||
new = ldb_dn_copy_partial(mem_ctx, new_base, offset + new_base->comp_num);
|
||||
for (i = 0; i < offset; i++) {
|
||||
new->components[i] = ldb_dn_copy_component(new->components, &(old->components[i]));
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/* Copy a DN with the base DN of the local partition. */
|
||||
static struct ldb_dn *ldb_dn_rebase_local(void *mem_ctx, const struct ldb_map_context *data, const struct ldb_dn *dn)
|
||||
{
|
||||
return ldb_dn_rebase(mem_ctx, dn, data->remote_base_dn, data->local_base_dn);
|
||||
return ldb_dn_copy_rebase(mem_ctx, dn, data->remote_base_dn, data->local_base_dn);
|
||||
}
|
||||
|
||||
/* Copy a DN with the base DN of the remote partition. */
|
||||
static struct ldb_dn *ldb_dn_rebase_remote(void *mem_ctx, const struct ldb_map_context *data, const struct ldb_dn *dn)
|
||||
{
|
||||
return ldb_dn_rebase(mem_ctx, dn, data->local_base_dn, data->remote_base_dn);
|
||||
return ldb_dn_copy_rebase(mem_ctx, dn, data->local_base_dn, data->remote_base_dn);
|
||||
}
|
||||
|
||||
/* Run a request and make sure it targets the remote partition. */
|
||||
@@ -460,23 +416,23 @@ int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attr
|
||||
* ================== */
|
||||
|
||||
/* Map an ldb value into the remote partition. */
|
||||
struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, struct ldb_val val)
|
||||
struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val)
|
||||
{
|
||||
if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_local)) {
|
||||
return map->u.convert.convert_local(module, mem_ctx, &val);
|
||||
return map->u.convert.convert_local(module, mem_ctx, val);
|
||||
}
|
||||
|
||||
return ldb_val_dup(mem_ctx, &val);
|
||||
return ldb_val_dup(mem_ctx, val);
|
||||
}
|
||||
|
||||
/* Map an ldb value back into the local partition. */
|
||||
struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, struct ldb_val val)
|
||||
struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val)
|
||||
{
|
||||
if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_remote)) {
|
||||
return map->u.convert.convert_remote(module, mem_ctx, &val);
|
||||
return map->u.convert.convert_remote(module, mem_ctx, val);
|
||||
}
|
||||
|
||||
return ldb_val_dup(mem_ctx, &val);
|
||||
return ldb_val_dup(mem_ctx, val);
|
||||
}
|
||||
|
||||
|
||||
@@ -500,10 +456,11 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, const
|
||||
{
|
||||
const struct ldb_map_context *data = map_get_context(module);
|
||||
struct ldb_dn *newdn;
|
||||
struct ldb_dn_component *old, *new;
|
||||
const struct ldb_map_attribute *map;
|
||||
enum ldb_map_attr_type map_type;
|
||||
int i;
|
||||
const char *name;
|
||||
struct ldb_val value;
|
||||
int i, ret;
|
||||
|
||||
if (dn == NULL) {
|
||||
return NULL;
|
||||
@@ -516,10 +473,8 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, const
|
||||
}
|
||||
|
||||
/* For each RDN, map the component name and possibly the value */
|
||||
for (i = 0; i < newdn->comp_num; i++) {
|
||||
old = &dn->components[i];
|
||||
new = &newdn->components[i];
|
||||
map = map_attr_find_local(data, old->name);
|
||||
for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) {
|
||||
map = map_attr_find_local(data, ldb_dn_get_component_name(dn, i));
|
||||
|
||||
/* Unknown attribute - leave this RDN as is and hope the best... */
|
||||
if (map == NULL) {
|
||||
@@ -533,21 +488,30 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, const
|
||||
case MAP_GENERATE:
|
||||
ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "
|
||||
"MAP_IGNORE/MAP_GENERATE attribute '%s' "
|
||||
"used in DN!\n", old->name);
|
||||
"used in DN!\n", ldb_dn_get_component_name(dn, i));
|
||||
goto failed;
|
||||
|
||||
case MAP_CONVERT:
|
||||
if (map->u.convert.convert_local == NULL) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "
|
||||
"'convert_local' not set for attribute '%s' "
|
||||
"used in DN!\n", old->name);
|
||||
"used in DN!\n", ldb_dn_get_component_name(dn, i));
|
||||
goto failed;
|
||||
}
|
||||
/* fall through */
|
||||
case MAP_KEEP:
|
||||
case MAP_RENAME:
|
||||
new->name = discard_const_p(char, map_attr_map_local(newdn->components, map, old->name));
|
||||
new->value = ldb_val_map_local(module, newdn->components, map, old->value);
|
||||
name = map_attr_map_local(newdn, map, ldb_dn_get_component_name(dn, i));
|
||||
if (name == NULL) goto failed;
|
||||
|
||||
value = ldb_val_map_local(module, newdn, map, ldb_dn_get_component_val(dn, i));
|
||||
if (value.data == NULL) goto failed;
|
||||
|
||||
ret = ldb_dn_set_component(newdn, i, name, value);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -564,10 +528,11 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, const
|
||||
{
|
||||
const struct ldb_map_context *data = map_get_context(module);
|
||||
struct ldb_dn *newdn;
|
||||
struct ldb_dn_component *old, *new;
|
||||
const struct ldb_map_attribute *map;
|
||||
enum ldb_map_attr_type map_type;
|
||||
int i;
|
||||
const char *name;
|
||||
struct ldb_val value;
|
||||
int i, ret;
|
||||
|
||||
if (dn == NULL) {
|
||||
return NULL;
|
||||
@@ -580,10 +545,8 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, const
|
||||
}
|
||||
|
||||
/* For each RDN, map the component name and possibly the value */
|
||||
for (i = 0; i < newdn->comp_num; i++) {
|
||||
old = &dn->components[i];
|
||||
new = &newdn->components[i];
|
||||
map = map_attr_find_remote(data, old->name);
|
||||
for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) {
|
||||
map = map_attr_find_remote(data, ldb_dn_get_component_name(dn, i));
|
||||
|
||||
/* Unknown attribute - leave this RDN as is and hope the best... */
|
||||
if (map == NULL) {
|
||||
@@ -597,21 +560,30 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, const
|
||||
case MAP_GENERATE:
|
||||
ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "
|
||||
"MAP_IGNORE/MAP_GENERATE attribute '%s' "
|
||||
"used in DN!\n", old->name);
|
||||
"used in DN!\n", ldb_dn_get_component_name(dn, i));
|
||||
goto failed;
|
||||
|
||||
case MAP_CONVERT:
|
||||
if (map->u.convert.convert_remote == NULL) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: "
|
||||
"'convert_remote' not set for attribute '%s' "
|
||||
"used in DN!\n", old->name);
|
||||
"used in DN!\n", ldb_dn_get_component_name(dn, i));
|
||||
goto failed;
|
||||
}
|
||||
/* fall through */
|
||||
case MAP_KEEP:
|
||||
case MAP_RENAME:
|
||||
new->name = discard_const_p(char, map_attr_map_remote(newdn->components, map, old->name));
|
||||
new->value = ldb_val_map_remote(module, newdn->components, map, old->value);
|
||||
name = map_attr_map_remote(newdn, map, ldb_dn_get_component_name(dn, i));
|
||||
if (name == NULL) goto failed;
|
||||
|
||||
value = ldb_val_map_remote(module, newdn, map, ldb_dn_get_component_val(dn, i));
|
||||
if (value.data == NULL) goto failed;
|
||||
|
||||
ret = ldb_dn_set_component(newdn, i, name, value);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1296,13 +1268,13 @@ static int map_init_maps(struct ldb_module *module, struct ldb_map_context *data
|
||||
}
|
||||
|
||||
/* Copy the list of provided module operations. */
|
||||
struct ldb_module_ops ldb_map_get_ops(void)
|
||||
_PUBLIC_ struct ldb_module_ops ldb_map_get_ops(void)
|
||||
{
|
||||
return map_ops;
|
||||
}
|
||||
|
||||
/* Initialize global private data. */
|
||||
int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs,
|
||||
_PUBLIC_ int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs,
|
||||
const struct ldb_map_objectclass *ocls,
|
||||
const char * const *wildcard_attributes,
|
||||
const char *name)
|
||||
|
||||
@@ -56,7 +56,7 @@ static struct ldb_message_element *ldb_msg_el_map_local(struct ldb_module *modul
|
||||
el->name = map_attr_map_local(el, map, old->name);
|
||||
|
||||
for (i = 0; i < el->num_values; i++) {
|
||||
el->values[i] = ldb_val_map_local(module, el->values, map, old->values[i]);
|
||||
el->values[i] = ldb_val_map_local(module, el->values, map, &old->values[i]);
|
||||
}
|
||||
|
||||
return el;
|
||||
|
||||
@@ -195,6 +195,7 @@ static int ldb_msg_replace(struct ldb_message *msg, const struct ldb_message_ele
|
||||
if (ldb_msg_add_empty(msg, el->name, 0, &old) != 0) {
|
||||
return -1;
|
||||
}
|
||||
talloc_free(old->name);
|
||||
}
|
||||
|
||||
/* copy new element */
|
||||
@@ -234,7 +235,7 @@ static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *modu
|
||||
el->name = map_attr_map_remote(el, map, old->name);
|
||||
|
||||
for (i = 0; i < el->num_values; i++) {
|
||||
el->values[i] = ldb_val_map_remote(module, el->values, map, old->values[i]);
|
||||
el->values[i] = ldb_val_map_remote(module, el->values, map, &old->values[i]);
|
||||
}
|
||||
|
||||
return el;
|
||||
@@ -728,21 +729,21 @@ int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx,
|
||||
*new = NULL;
|
||||
return 0;
|
||||
}
|
||||
*(*new)->u.substring.chunks[i] = ldb_val_map_local(module, *new, map, *tree->u.substring.chunks[i]);
|
||||
*(*new)->u.substring.chunks[i] = ldb_val_map_local(module, *new, map, tree->u.substring.chunks[i]);
|
||||
(*new)->u.substring.chunks[i+1] = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LDB_OP_EQUALITY:
|
||||
(*new)->u.equality.value = ldb_val_map_local(module, *new, map, tree->u.equality.value);
|
||||
(*new)->u.equality.value = ldb_val_map_local(module, *new, map, &tree->u.equality.value);
|
||||
break;
|
||||
case LDB_OP_LESS:
|
||||
case LDB_OP_GREATER:
|
||||
case LDB_OP_APPROX:
|
||||
(*new)->u.comparison.value = ldb_val_map_local(module, *new, map, tree->u.comparison.value);
|
||||
(*new)->u.comparison.value = ldb_val_map_local(module, *new, map, &tree->u.comparison.value);
|
||||
break;
|
||||
case LDB_OP_EXTENDED:
|
||||
(*new)->u.extended.value = ldb_val_map_local(module, *new, map, tree->u.extended.value);
|
||||
(*new)->u.extended.value = ldb_val_map_local(module, *new, map, &tree->u.extended.value);
|
||||
(*new)->u.extended.rule_id = talloc_strdup(*new, tree->u.extended.rule_id);
|
||||
break;
|
||||
default: /* unknown kind of simple subtree */
|
||||
|
||||
@@ -77,8 +77,8 @@ const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *ma
|
||||
const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr);
|
||||
int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attrs, const char * const *more_attrs);
|
||||
|
||||
struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, struct ldb_val val);
|
||||
struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, struct ldb_val val);
|
||||
struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val);
|
||||
struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val);
|
||||
|
||||
struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn);
|
||||
struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn);
|
||||
|
||||
@@ -544,9 +544,7 @@ static int paged_request_init(struct ldb_module *module)
|
||||
|
||||
ret = ldb_request(module->ldb, req);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_ERROR, "paged_request: Unable to register control with rootdse!\n");
|
||||
talloc_free(req);
|
||||
return LDB_ERR_OTHER;
|
||||
ldb_debug(module->ldb, LDB_DEBUG_WARNING, "paged_request: Unable to register control with rootdse!\n");
|
||||
}
|
||||
|
||||
talloc_free(req);
|
||||
|
||||
@@ -58,7 +58,8 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req)
|
||||
struct ldb_request *down_req;
|
||||
struct ldb_message *msg;
|
||||
struct ldb_message_element *attribute;
|
||||
struct ldb_dn_component *rdn;
|
||||
const char *rdn_name;
|
||||
struct ldb_val rdn_val;
|
||||
int i, ret;
|
||||
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_name_add_record\n");
|
||||
@@ -80,43 +81,45 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req)
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
rdn = ldb_dn_get_rdn(msg, msg->dn);
|
||||
if (rdn == NULL) {
|
||||
rdn_name = ldb_dn_get_rdn_name(msg->dn);
|
||||
if (rdn_name == NULL) {
|
||||
talloc_free(down_req);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(msg->dn));
|
||||
|
||||
/* Perhaps someone above us tried to set this? */
|
||||
if ((attribute = rdn_name_find_attribute(msg, "name")) != NULL ) {
|
||||
attribute->num_values = 0;
|
||||
}
|
||||
|
||||
if (ldb_msg_add_value(msg, "name", &rdn->value, NULL) != 0) {
|
||||
if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) {
|
||||
talloc_free(down_req);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
attribute = rdn_name_find_attribute(msg, rdn->name);
|
||||
attribute = rdn_name_find_attribute(msg, rdn_name);
|
||||
|
||||
if (!attribute) {
|
||||
if (ldb_msg_add_value(msg, rdn->name, &rdn->value, NULL) != 0) {
|
||||
if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) {
|
||||
talloc_free(down_req);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
} else {
|
||||
const struct ldb_attrib_handler *handler = ldb_attrib_handler(module->ldb, rdn->name);
|
||||
const struct ldb_attrib_handler *handler = ldb_attrib_handler(module->ldb, rdn_name);
|
||||
|
||||
for (i = 0; i < attribute->num_values; i++) {
|
||||
if (handler->comparison_fn(module->ldb, msg, &rdn->value, &attribute->values[i]) == 0) {
|
||||
if (handler->comparison_fn(module->ldb, msg, &rdn_val, &attribute->values[i]) == 0) {
|
||||
/* overwrite so it matches in case */
|
||||
attribute->values[i] = rdn->value;
|
||||
attribute->values[i] = rdn_val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == attribute->num_values) {
|
||||
ldb_debug_set(module->ldb, LDB_DEBUG_FATAL,
|
||||
"RDN mismatch on %s: %s",
|
||||
ldb_dn_linearize(msg, msg->dn), rdn->name);
|
||||
"RDN mismatch on %s: %s (%s)",
|
||||
ldb_dn_linearize(msg, msg->dn), rdn_name, rdn_val.data);
|
||||
talloc_free(down_req);
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
@@ -190,16 +193,12 @@ static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req)
|
||||
static int rdn_name_rename_do_mod(struct ldb_handle *h) {
|
||||
|
||||
struct rename_context *ac;
|
||||
struct ldb_dn_component *rdn;
|
||||
const char *rdn_name;
|
||||
struct ldb_val rdn_val;
|
||||
struct ldb_message *msg;
|
||||
|
||||
ac = talloc_get_type(h->private_data, struct rename_context);
|
||||
|
||||
rdn = ldb_dn_get_rdn(ac, ac->orig_req->op.rename.newdn);
|
||||
if (rdn == NULL) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
ac->mod_req = talloc_zero(ac, struct ldb_request);
|
||||
|
||||
ac->mod_req->operation = LDB_MODIFY;
|
||||
@@ -213,16 +212,23 @@ static int rdn_name_rename_do_mod(struct ldb_handle *h) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
if (ldb_msg_add_empty(msg, rdn->name, LDB_FLAG_MOD_REPLACE, NULL) != 0) {
|
||||
rdn_name = ldb_dn_get_rdn_name(ac->orig_req->op.rename.newdn);
|
||||
if (rdn_name == NULL) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
if (ldb_msg_add_value(msg, rdn->name, &rdn->value, NULL) != 0) {
|
||||
|
||||
rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(ac->orig_req->op.rename.newdn));
|
||||
|
||||
if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
if (ldb_msg_add_value(msg, "name", &rdn->value, NULL) != 0) {
|
||||
if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) {
|
||||
return LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -423,9 +423,7 @@ static int server_sort_init(struct ldb_module *module)
|
||||
|
||||
ret = ldb_request(module->ldb, req);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
ldb_debug(module->ldb, LDB_DEBUG_ERROR, "server_sort: Unable to register control with rootdse!\n");
|
||||
talloc_free(req);
|
||||
return LDB_ERR_OTHER;
|
||||
ldb_debug(module->ldb, LDB_DEBUG_WARNING, "server_sort: Unable to register control with rootdse!\n");
|
||||
}
|
||||
|
||||
talloc_free(req);
|
||||
|
||||
34
source/lib/ldb/nssldb/README.txt
Normal file
34
source/lib/ldb/nssldb/README.txt
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
This test code requires a tdb that is configured for to use the asq module.
|
||||
You can do that adding the following record to a tdb:
|
||||
|
||||
dn: @MODULES
|
||||
@LIST: asq
|
||||
|
||||
Other modules can be used as well (like rdn_name for example)
|
||||
|
||||
The uidNumber 0 and the gidNumber 0 are considered invalid.
|
||||
|
||||
The user records should contain the followin attributes:
|
||||
uid (required) the user name
|
||||
userPassword (optional) the user password (if not present "LDB" is
|
||||
returned in the password field)
|
||||
uidNumber (required) the user uid
|
||||
gidNumber (required) the user primary gid
|
||||
gecos (optional) the GECOS
|
||||
homeDirectory (required) the home directory
|
||||
loginShell (required) the login shell
|
||||
memberOf (required) all the groups the user is member of should
|
||||
be reported here using their DNs. The
|
||||
primary group as well.
|
||||
|
||||
The group accounts should contain the following attributes:
|
||||
cn (required) the group name
|
||||
uesrPassword (optional) the group password (if not present "LDB" is
|
||||
returned in the password field)
|
||||
gidNumber (required) the group gid
|
||||
member (optional) the DNs of the member users, also the ones
|
||||
that have this group as primary
|
||||
|
||||
|
||||
SSS
|
||||
427
source/lib/ldb/nssldb/ldb-grp.c
Normal file
427
source/lib/ldb/nssldb/ldb-grp.c
Normal file
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
extern struct _ldb_nss_context *_ldb_nss_ctx;
|
||||
|
||||
const char *_ldb_nss_gr_attrs[] = {
|
||||
"cn",
|
||||
"userPassword",
|
||||
"gidNumber",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char *_ldb_nss_mem_attrs[] = {
|
||||
"uid",
|
||||
NULL
|
||||
};
|
||||
|
||||
#define _NSS_LDB_ENOMEM(amem) \
|
||||
do { \
|
||||
if ( ! amem) { \
|
||||
errno = ENOMEM; \
|
||||
talloc_free(memctx); \
|
||||
return NSS_STATUS_UNAVAIL; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* This setgrent, getgrent, endgrent is not very efficient */
|
||||
|
||||
NSS_STATUS _nss_ldb_setgrent(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _ldb_nss_init();
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
_ldb_nss_ctx->gr_cur = 0;
|
||||
if (_ldb_nss_ctx->gr_res != NULL) {
|
||||
talloc_free(_ldb_nss_ctx->gr_res);
|
||||
_ldb_nss_ctx->gr_res = NULL;
|
||||
}
|
||||
|
||||
ret = ldb_search(_ldb_nss_ctx->ldb,
|
||||
_ldb_nss_ctx->base,
|
||||
LDB_SCOPE_SUBTREE,
|
||||
_LDB_NSS_GRENT_FILTER,
|
||||
_ldb_nss_gr_attrs,
|
||||
&_ldb_nss_ctx->gr_res);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_STATUS _nss_ldb_endgrent(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _ldb_nss_init();
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
_ldb_nss_ctx->gr_cur = 0;
|
||||
if (_ldb_nss_ctx->gr_res) {
|
||||
talloc_free(_ldb_nss_ctx->gr_res);
|
||||
_ldb_nss_ctx->gr_res = NULL;
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_STATUS _nss_ldb_getgrent_r(struct group *result_buf, char *buffer, size_t buflen, int *errnop)
|
||||
{
|
||||
int ret;
|
||||
struct ldb_result *res;
|
||||
|
||||
ret = _ldb_nss_init();
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*errnop = 0;
|
||||
|
||||
if (_ldb_nss_ctx->gr_cur >= _ldb_nss_ctx->gr_res->count) {
|
||||
/* already returned all entries */
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
res = talloc_zero(_ldb_nss_ctx->gr_res, struct ldb_result);
|
||||
if ( ! res) {
|
||||
errno = *errnop = ENOMEM;
|
||||
_ldb_nss_ctx->gr_cur++; /* skip this entry */
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
ret = _ldb_nss_group_request(&res,
|
||||
_ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur]->dn,
|
||||
_ldb_nss_mem_attrs,
|
||||
"member");
|
||||
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
*errnop = errno;
|
||||
talloc_free(res);
|
||||
_ldb_nss_ctx->gr_cur++; /* skip this entry */
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = _ldb_nss_fill_group(result_buf,
|
||||
buffer,
|
||||
buflen,
|
||||
errnop,
|
||||
_ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur],
|
||||
res);
|
||||
|
||||
talloc_free(res);
|
||||
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
if (ret != NSS_STATUS_TRYAGAIN) {
|
||||
_ldb_nss_ctx->gr_cur++; /* skip this entry */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* this entry is ok, increment counter to nex entry */
|
||||
_ldb_nss_ctx->gr_cur++;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_STATUS _nss_ldb_getgrnam_r(const char *name, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
|
||||
{
|
||||
int ret;
|
||||
char *filter;
|
||||
TALLOC_CTX *ctx;
|
||||
struct ldb_result *gr_res;
|
||||
struct ldb_result *mem_res;
|
||||
|
||||
ret = _ldb_nss_init();
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx = talloc_new(_ldb_nss_ctx->ldb);
|
||||
if ( ! ctx) {
|
||||
*errnop = errno = ENOMEM;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
/* build the filter for this uid */
|
||||
filter = talloc_asprintf(ctx, _LDB_NSS_GRNAM_FILTER, name);
|
||||
if (filter == NULL) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOMEM;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* search the entry */
|
||||
ret = ldb_search(_ldb_nss_ctx->ldb,
|
||||
_ldb_nss_ctx->base,
|
||||
LDB_SCOPE_SUBTREE,
|
||||
filter,
|
||||
_ldb_nss_gr_attrs,
|
||||
&gr_res);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
talloc_steal(ctx, gr_res);
|
||||
|
||||
/* if none found return */
|
||||
if (gr_res->count == 0) {
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (gr_res->count != 1) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
mem_res = talloc_zero(ctx, struct ldb_result);
|
||||
if ( ! mem_res) {
|
||||
errno = *errnop = ENOMEM;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = _ldb_nss_group_request(&mem_res,
|
||||
gr_res->msgs[0]->dn,
|
||||
_ldb_nss_mem_attrs,
|
||||
"member");
|
||||
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
*errnop = errno;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = _ldb_nss_fill_group(result_buf,
|
||||
buffer,
|
||||
buflen,
|
||||
errnop,
|
||||
gr_res->msgs[0],
|
||||
mem_res);
|
||||
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = NSS_STATUS_SUCCESS;
|
||||
done:
|
||||
talloc_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
|
||||
{
|
||||
int ret;
|
||||
char *filter;
|
||||
TALLOC_CTX *ctx;
|
||||
struct ldb_result *gr_res;
|
||||
struct ldb_result *mem_res;
|
||||
|
||||
if (gid == 0) { /* we don't serve root gid by policy */
|
||||
*errnop = errno = ENOENT;
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
ret = _ldb_nss_init();
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ctx = talloc_new(_ldb_nss_ctx->ldb);
|
||||
if ( ! ctx) {
|
||||
*errnop = errno = ENOMEM;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
/* build the filter for this uid */
|
||||
filter = talloc_asprintf(ctx, _LDB_NSS_GRGID_FILTER, gid);
|
||||
if (filter == NULL) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOMEM;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* search the entry */
|
||||
ret = ldb_search(_ldb_nss_ctx->ldb,
|
||||
_ldb_nss_ctx->base,
|
||||
LDB_SCOPE_SUBTREE,
|
||||
filter,
|
||||
_ldb_nss_gr_attrs,
|
||||
&gr_res);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
talloc_steal(ctx, gr_res);
|
||||
|
||||
/* if none found return */
|
||||
if (gr_res->count == 0) {
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (gr_res->count != 1) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
mem_res = talloc_zero(ctx, struct ldb_result);
|
||||
if ( ! mem_res) {
|
||||
errno = *errnop = ENOMEM;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = _ldb_nss_group_request(&mem_res,
|
||||
gr_res->msgs[0]->dn,
|
||||
_ldb_nss_mem_attrs,
|
||||
"member");
|
||||
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
*errnop = errno;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = _ldb_nss_fill_group(result_buf,
|
||||
buffer,
|
||||
buflen,
|
||||
errnop,
|
||||
gr_res->msgs[0],
|
||||
mem_res);
|
||||
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = NSS_STATUS_SUCCESS;
|
||||
done:
|
||||
talloc_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
NSS_STATUS _nss_ldb_initgroups_dyn(const char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop)
|
||||
{
|
||||
int ret;
|
||||
char *filter;
|
||||
const char * attrs[] = { "uidNumber", "gidNumber", NULL };
|
||||
struct ldb_result *uid_res;
|
||||
struct ldb_result *mem_res;
|
||||
|
||||
ret = _ldb_nss_init();
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result);
|
||||
if ( ! mem_res) {
|
||||
errno = *errnop = ENOMEM;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
/* build the filter for this name */
|
||||
filter = talloc_asprintf(mem_res, _LDB_NSS_PWNAM_FILTER, user);
|
||||
if (filter == NULL) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* search the entry */
|
||||
ret = ldb_search(_ldb_nss_ctx->ldb,
|
||||
_ldb_nss_ctx->base,
|
||||
LDB_SCOPE_SUBTREE,
|
||||
filter,
|
||||
attrs,
|
||||
&uid_res);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
talloc_steal(mem_res, uid_res);
|
||||
|
||||
/* if none found return */
|
||||
if (uid_res->count == 0) {
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (uid_res->count != 1) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = _ldb_nss_group_request(&mem_res,
|
||||
uid_res->msgs[0]->dn,
|
||||
attrs,
|
||||
"memberOf");
|
||||
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
*errnop = errno;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = _ldb_nss_fill_initgr(group,
|
||||
limit,
|
||||
start,
|
||||
size,
|
||||
groups,
|
||||
errnop,
|
||||
mem_res);
|
||||
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = NSS_STATUS_SUCCESS;
|
||||
|
||||
done:
|
||||
talloc_free(mem_res);
|
||||
return ret;
|
||||
}
|
||||
402
source/lib/ldb/nssldb/ldb-nss.c
Normal file
402
source/lib/ldb/nssldb/ldb-nss.c
Normal file
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
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;
|
||||
struct ldb_result *res = *_res;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
86
source/lib/ldb/nssldb/ldb-nss.h
Normal file
86
source/lib/ldb/nssldb/ldb-nss.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef _LDB_NSS
|
||||
#define _LDB_NSS
|
||||
|
||||
#include "includes.h"
|
||||
#include "ldb/include/includes.h"
|
||||
|
||||
#include <nss.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#define _LDB_NSS_URL "etc/users.ldb"
|
||||
#define _LDB_NSS_BASEDN "CN=Users,CN=System"
|
||||
#define _LDB_NSS_PWENT_FILTER "(&(objectClass=posixAccount)(!(uidNumber=0))(!(gidNumber=0)))"
|
||||
#define _LDB_NSS_PWUID_FILTER "(&(objectClass=posixAccount)(uidNumber=%d)(!(gidNumber=0)))"
|
||||
#define _LDB_NSS_PWNAM_FILTER "(&(objectClass=posixAccount)(uid=%s)(!(uidNumber=0))(!(gidNumber=0)))"
|
||||
|
||||
#define _LDB_NSS_GRENT_FILTER "(&(objectClass=posixGroup)(!(gidNumber=0)))"
|
||||
#define _LDB_NSS_GRGID_FILTER "(&(objectClass=posixGroup)(gidNumber=%d)))"
|
||||
#define _LDB_NSS_GRNAM_FILTER "(&(objectClass=posixGroup)(cn=%s)(!(gidNumber=0)))"
|
||||
|
||||
typedef enum nss_status NSS_STATUS;
|
||||
|
||||
struct _ldb_nss_context {
|
||||
|
||||
pid_t pid;
|
||||
|
||||
struct ldb_context *ldb;
|
||||
const struct ldb_dn *base;
|
||||
|
||||
int pw_cur;
|
||||
struct ldb_result *pw_res;
|
||||
|
||||
int gr_cur;
|
||||
struct ldb_result *gr_res;
|
||||
};
|
||||
|
||||
NSS_STATUS _ldb_nss_init(void);
|
||||
|
||||
NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result,
|
||||
char *buffer,
|
||||
int buflen,
|
||||
int *errnop,
|
||||
struct ldb_message *msg);
|
||||
|
||||
NSS_STATUS _ldb_nss_fill_group(struct group *result,
|
||||
char *buffer,
|
||||
int buflen,
|
||||
int *errnop,
|
||||
struct ldb_message *group,
|
||||
struct ldb_result *members);
|
||||
|
||||
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 _ldb_nss_group_request(struct ldb_result **res,
|
||||
struct ldb_dn *group_dn,
|
||||
const char * const *attrs,
|
||||
const char *mattr);
|
||||
|
||||
#endif /* _LDB_NSS */
|
||||
241
source/lib/ldb/nssldb/ldb-pwd.c
Normal file
241
source/lib/ldb/nssldb/ldb-pwd.c
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
extern struct _ldb_nss_context *_ldb_nss_ctx;
|
||||
|
||||
const char *_ldb_nss_pw_attrs[] = {
|
||||
"uid",
|
||||
"userPassword",
|
||||
"uidNumber",
|
||||
"gidNumber",
|
||||
"gecos",
|
||||
"homeDirectory",
|
||||
"loginShell",
|
||||
NULL
|
||||
};
|
||||
|
||||
NSS_STATUS _nss_ldb_setpwent(void)
|
||||
{
|
||||
int ret;
|
||||
ret = _ldb_nss_init();
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
_ldb_nss_ctx->pw_cur = 0;
|
||||
if (_ldb_nss_ctx->pw_res != NULL) {
|
||||
talloc_free(_ldb_nss_ctx->pw_res);
|
||||
_ldb_nss_ctx->pw_res = NULL;
|
||||
}
|
||||
|
||||
ret = ldb_search(_ldb_nss_ctx->ldb,
|
||||
_ldb_nss_ctx->base,
|
||||
LDB_SCOPE_SUBTREE,
|
||||
_LDB_NSS_PWENT_FILTER,
|
||||
_ldb_nss_pw_attrs,
|
||||
&_ldb_nss_ctx->pw_res);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_STATUS _nss_ldb_endpwent(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _ldb_nss_init();
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
_ldb_nss_ctx->pw_cur = 0;
|
||||
if (_ldb_nss_ctx->pw_res) {
|
||||
talloc_free(_ldb_nss_ctx->pw_res);
|
||||
_ldb_nss_ctx->pw_res = NULL;
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_STATUS _nss_ldb_getpwent_r(struct passwd *result_buf,
|
||||
char *buffer,
|
||||
int buflen,
|
||||
int *errnop)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _ldb_nss_init();
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*errnop = 0;
|
||||
|
||||
if (_ldb_nss_ctx->pw_cur >= _ldb_nss_ctx->pw_res->count) {
|
||||
/* already returned all entries */
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
ret = _ldb_nss_fill_passwd(result_buf,
|
||||
buffer,
|
||||
buflen,
|
||||
errnop,
|
||||
_ldb_nss_ctx->pw_res->msgs[_ldb_nss_ctx->pw_cur]);
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
_ldb_nss_ctx->pw_cur++;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NSS_STATUS _nss_ldb_getpwuid_r(uid_t uid, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop)
|
||||
{
|
||||
int ret;
|
||||
char *filter;
|
||||
struct ldb_result *res;
|
||||
|
||||
if (uid == 0) { /* we don't serve root uid by policy */
|
||||
*errnop = errno = ENOENT;
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
ret = _ldb_nss_init();
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* build the filter for this uid */
|
||||
filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWUID_FILTER, uid);
|
||||
if (filter == NULL) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOMEM;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* search the entry */
|
||||
ret = ldb_search(_ldb_nss_ctx->ldb,
|
||||
_ldb_nss_ctx->base,
|
||||
LDB_SCOPE_SUBTREE,
|
||||
filter,
|
||||
_ldb_nss_pw_attrs,
|
||||
&res);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* if none found return */
|
||||
if (res->count == 0) {
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (res->count != 1) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* fill in the passwd struct */
|
||||
ret = _ldb_nss_fill_passwd(result_buf,
|
||||
buffer,
|
||||
buflen,
|
||||
errnop,
|
||||
res->msgs[0]);
|
||||
|
||||
done:
|
||||
talloc_free(filter);
|
||||
talloc_free(res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
NSS_STATUS _nss_ldb_getpwnam_r(const char *name, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop)
|
||||
{
|
||||
int ret;
|
||||
char *filter;
|
||||
struct ldb_result *res;
|
||||
|
||||
ret = _ldb_nss_init();
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* build the filter for this name */
|
||||
filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWNAM_FILTER, name);
|
||||
if (filter == NULL) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* search the entry */
|
||||
ret = ldb_search(_ldb_nss_ctx->ldb,
|
||||
_ldb_nss_ctx->base,
|
||||
LDB_SCOPE_SUBTREE,
|
||||
filter,
|
||||
_ldb_nss_pw_attrs,
|
||||
&res);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* if none found return */
|
||||
if (res->count == 0) {
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_NOTFOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (res->count != 1) {
|
||||
/* this is a fatal error */
|
||||
*errnop = errno = ENOENT;
|
||||
ret = NSS_STATUS_UNAVAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* fill in the passwd struct */
|
||||
ret = _ldb_nss_fill_passwd(result_buf,
|
||||
buffer,
|
||||
buflen,
|
||||
errnop,
|
||||
res->msgs[0]);
|
||||
|
||||
done:
|
||||
talloc_free(filter);
|
||||
talloc_free(res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -80,10 +80,12 @@ static int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx,
|
||||
|
||||
static BOOL ldb_comparision_objectSid_isString(const struct ldb_val *v)
|
||||
{
|
||||
/* see if the input if null-terninated */
|
||||
if (v->data[v->length] != '\0') return False;
|
||||
if (v->length < 3) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if (strncmp("S-", (const char *)v->data, 2) != 0) return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
@@ -179,11 +181,11 @@ static BOOL ldb_comparision_objectGUID_isString(const struct ldb_val *v)
|
||||
struct GUID guid;
|
||||
NTSTATUS status;
|
||||
|
||||
/* see if the input if null-terninated */
|
||||
if (v->data[v->length] != '\0') return False;
|
||||
|
||||
if (v->length < 33) return False;
|
||||
|
||||
/* see if the input if null-terninated (safety check for the below) */
|
||||
if (v->data[v->length] != '\0') return False;
|
||||
|
||||
status = GUID_from_string((const char *)v->data, &guid);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return False;
|
||||
@@ -301,9 +303,9 @@ static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_c
|
||||
dn1 = ldb_dn_explode(mem_ctx, (char *)in->data);
|
||||
if (dn1 == NULL) {
|
||||
oc1 = talloc_strndup(mem_ctx, (char *)in->data, in->length);
|
||||
} else if (dn1->comp_num >= 1 && strcasecmp(dn1->components[0].name, "cn") == 0) {
|
||||
oc1 = talloc_strndup(mem_ctx, (char *)dn1->components[0].value.data,
|
||||
dn1->components[0].value.length);
|
||||
} else if (ldb_dn_get_comp_num(dn1) >= 1 && strcasecmp(ldb_dn_get_rdn_name(dn1), "cn") == 0) {
|
||||
const struct ldb_val *val = ldb_dn_get_rdn_val(dn1);
|
||||
oc1 = talloc_strndup(mem_ctx, (char *)val->data, val->length);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -326,9 +328,9 @@ static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx
|
||||
dn1 = ldb_dn_explode(mem_ctx, (char *)v1->data);
|
||||
if (dn1 == NULL) {
|
||||
oc1 = talloc_strndup(mem_ctx, (char *)v1->data, v1->length);
|
||||
} else if (dn1->comp_num >= 1 && strcasecmp(dn1->components[0].name, "cn") == 0) {
|
||||
oc1 = talloc_strndup(mem_ctx, (char *)dn1->components[0].value.data,
|
||||
dn1->components[0].value.length);
|
||||
} else if (ldb_dn_get_comp_num(dn1) >= 1 && strcasecmp(ldb_dn_get_rdn_name(dn1), "cn") == 0) {
|
||||
const struct ldb_val *val = ldb_dn_get_rdn_val(dn1);
|
||||
oc1 = talloc_strndup(mem_ctx, (char *)val->data, val->length);
|
||||
} else {
|
||||
oc1 = NULL;
|
||||
}
|
||||
@@ -336,9 +338,9 @@ static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx
|
||||
dn2 = ldb_dn_explode(mem_ctx, (char *)v2->data);
|
||||
if (dn2 == NULL) {
|
||||
oc2 = talloc_strndup(mem_ctx, (char *)v2->data, v2->length);
|
||||
} else if (dn2->comp_num >= 2 && strcasecmp(dn2->components[0].name, "cn") == 0) {
|
||||
oc2 = talloc_strndup(mem_ctx, (char *)dn2->components[0].value.data,
|
||||
dn2->components[0].value.length);
|
||||
} else if (ldb_dn_get_comp_num(dn2) >= 2 && strcasecmp(ldb_dn_get_rdn_name(dn2), "cn") == 0) {
|
||||
const struct ldb_val *val = ldb_dn_get_rdn_val(dn2);
|
||||
oc2 = talloc_strndup(mem_ctx, (char *)val->data, val->length);
|
||||
} else {
|
||||
oc2 = NULL;
|
||||
}
|
||||
|
||||
25
source/lib/ldb/standalone.sh
Executable file
25
source/lib/ldb/standalone.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd ../replace
|
||||
make clean
|
||||
|
||||
cd ../talloc
|
||||
make clean
|
||||
|
||||
cd ../tdb
|
||||
make clean
|
||||
|
||||
cd ../ldb
|
||||
make clean
|
||||
|
||||
./autogen.sh
|
||||
|
||||
rm -fr build
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
../configure $*
|
||||
make dirs
|
||||
make all
|
||||
|
||||
cd ..
|
||||
@@ -1,20 +1,23 @@
|
||||
#!/bin/sh
|
||||
|
||||
|
||||
LDB_URL="sqlite://sqltest.ldb"
|
||||
LDB_URL="sqlite3://sqltest.ldb"
|
||||
export LDB_URL
|
||||
|
||||
PATH=bin:$PATH
|
||||
export PATH
|
||||
|
||||
rm -f sqltest.ldb
|
||||
|
||||
if [ -z "$LDBDIR" ]; then
|
||||
LDBDIR="."
|
||||
LDBDIR=`dirname $0`/..
|
||||
export LDBDIR
|
||||
fi
|
||||
|
||||
. $LDBDIR/tests/test-generic.sh
|
||||
PATH=bin:$PATH
|
||||
export PATH
|
||||
|
||||
LDB_SPECIALS=0
|
||||
export LDB_SPECIALS
|
||||
|
||||
$LDBDIR/tests/test-generic.sh
|
||||
|
||||
#. $LDBDIR/tests/test-extended.sh
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#if (_SAMBA_BUILD_ >= 4)
|
||||
#include "lib/cmdline/popt_common.h"
|
||||
#include "lib/ldb/samba/ldif_handlers.h"
|
||||
#include "auth/gensec/gensec.h"
|
||||
#include "auth/auth.h"
|
||||
#include "db_wrap.h"
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user