*/
/* location of the default slapd config file */
#define SLAPD_DEFAULT_CONFIGFILE LDAP_SYSCONFDIR LDAP_DIRSEP "slapd.conf"
+#define SLAPD_DEFAULT_CONFIGDIR LDAP_SYSCONFDIR LDAP_DIRSEP "slapd.d"
#define SLAPD_DEFAULT_DB_DIR LDAP_RUNDIR LDAP_DIRSEP "openldap-data"
#define SLAPD_DEFAULT_DB_MODE 0600
#define SLAPD_DEFAULT_UCDATA LDAP_DATADIR LDAP_DIRSEP "ucdata"
op2.ors_tlimit = SLAP_NO_LIMIT;
op2.ors_attrs = anlistp;
op2.ors_attrsonly = 0;
+ op2.o_private = cp->op->o_private;
cb.sc_private = &p;
Modifications *modlist = op->ora_modlist;
Modifications **modtail = &modlist;
int rc = 0;
+ BackendDB *op_be;
manageDSAit = get_manageDSAit( op );
goto done;
}
+ /* If we've got a glued backend, check the real backend */
+ op_be = op->o_bd;
+ if ( SLAP_GLUE_INSTANCE( op->o_bd )) {
+ op->o_bd = select_backend( &e->e_nname, manageDSAit, 0 );
+ }
+
/* check restrictions */
if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) {
send_ldap_result( op, rs );
size_t textlen = sizeof( textbuf );
slap_callback cb = { NULL, slap_replog_cb, NULL, NULL };
+ op->o_bd = op_be;
+
if ( !update ) {
rs->sr_err = slap_mods_no_update_check( modlist,
&rs->sr_text,
static int
bdb_cf_oc(ConfigArgs *c)
{
- if ( c->emit ) {
+ if ( c->op == SLAP_CONFIG_EMIT ) {
value_add_one( &c->rvalue_vals, &bdb_oc->soc_cname );
return 0;
}
struct bdb_info *bdb = c->be->be_private;
int rc;
- if ( c->emit ) {
+ if ( c->op == SLAP_CONFIG_EMIT ) {
rc = 0;
switch( c->type ) {
case BDB_CHKPT:
int rc;
bi->bi_cf_table = bdbcfg;
- rc = init_config_attrs( bdbcfg );
+ rc = config_register_schema( bdbcfg, bdbocs );
if ( rc ) return rc;
bdbcfg[0].ad = slap_schema.si_ad_objectClass;
- rc = init_config_ocs( bdbocs );
- return rc;
-}
-
-int bdb_db_config( Backend *be, const char *fname, int lineno, int argc,
- char **argv )
-{
- ConfigArgs c = { 0 };
- int rc;
-
- c.be = be;
- c.fname = fname;
- c.lineno = lineno;
- c.argc = argc;
- c.argv = argv;
- sprintf( c.log, "%s: line %lu", fname, lineno );
-
- rc = parse_config_table( bdbcfg, &c );
- if ( rc == ARG_UNKNOWN )
- rc = SLAP_CONF_UNKNOWN;
- return rc;
+ return 0;
}
bi->bi_destroy = 0;
bi->bi_db_init = bdb_db_init;
- bi->bi_db_config = bdb_db_config;
+ bi->bi_db_config = config_generic_wrapper;
bi->bi_db_open = bdb_db_open;
bi->bi_db_close = bdb_db_close;
bi->bi_db_destroy = bdb_db_destroy;
/* get entry */
rc = bdb_dn2entry( op, NULL, &op->o_req_ndn, &ei, 1, locker, &lock );
- e = ei->bei_e;
+ /* bdb_dn2entry() may legally leave ei == NULL
+ * if rc != 0 and rc != DB_NOTFOUND
+ */
+ if ( ei ) {
+ e = ei->bei_e;
+ }
+
switch(rc) {
case DB_NOTFOUND:
case 0:
#include <ac/unistd.h>
#include "slap.h"
#include "lutil.h"
+#include "config.h"
struct ldif_info {
struct berval li_base_path;
- ID tool_current;
+ ID tool_current;
Entry ** tool_entries;
int tool_put_entry_flag;
int tool_numentries;
#define ENTRY_BUFF_INCREMENT 500
-static char *
-dn2path(struct berval * dn, struct berval * rootdn, struct berval * base_path)
+static ObjectClass *ldif_oc;
+
+static ConfigDriver ldif_cf;
+
+static ConfigTable ldifcfg[] = {
+ { "", "", 0, 0, 0, ARG_MAGIC,
+ ldif_cf, NULL, NULL, NULL },
+ { "directory", "dir", 2, 2, 0, ARG_BERVAL|ARG_OFFSET,
+ (void *)offsetof(struct ldif_info, li_base_path),
+ "( OLcfgAt:1.1 NAME 'dbDirectory' "
+ "DESC 'Directory for database content' "
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString )", NULL, NULL },
+ { NULL, NULL, 0, 0, 0, ARG_IGNORED,
+ NULL, NULL, NULL, NULL }
+};
+
+static ConfigOCs ldifocs[] = {
+ { "( OLcfgOc:2.1 "
+ "NAME 'ldifConfig' "
+ "DESC 'LDIF backend configuration' "
+ "AUXILIARY "
+ "MAY ( dbDirectory ) )",
+ &ldif_oc },
+ { NULL, NULL }
+};
+
+static int
+ldif_cf( ConfigArgs *c )
+{
+ if ( c->op == SLAP_CONFIG_EMIT ) {
+ value_add_one( &c->rvalue_vals, &ldif_oc->soc_cname );
+ return 0;
+ }
+ return 1;
+}
+
+static void
+dn2path(struct berval * dn, struct berval * rootdn, struct berval * base_path,
+ struct berval *res)
{
- char *result = ch_malloc( dn->bv_len + base_path->bv_len + 2 +
- STRLENOF( LDIF ));
char *ptr, *sep, *end;
- ptr = lutil_strcopy( result, base_path->bv_val );
+ res->bv_len = dn->bv_len + base_path->bv_len + 1 + STRLENOF( LDIF );
+ res->bv_val = ch_malloc( res->bv_len + 1 );
+ ptr = lutil_strcopy( res->bv_val, base_path->bv_val );
*ptr++ = LDAP_DIRSEP[0];
ptr = lutil_strcopy( ptr, rootdn->bv_val );
end = dn->bv_val + dn->bv_len - rootdn->bv_len - 1;
end = sep;
}
strcpy(ptr, LDIF);
- return result;
}
-static char * slurp_file(int fd) {
+static char * slurp_file(int fd) {
int entry_buf_size = 40 * ENTRY_BUFF_INCREMENT;
int read_chars_total = 0;
int read_chars = 0;
char * entry_pos = entry;
while(1) {
- if(entry_size - read_chars_total == 0) {
- entry = (char *) realloc(entry, sizeof(char) * 2 * entry_size);
- entry_size = 2 * entry_size;
- }
- read_chars = read(fd, (void *) entry_pos, entry_size - read_chars_total);
- if(read_chars == -1) {
- SLAP_FREE(entry);
- return NULL;
- }
- entry_pos += read_chars;
- if(read_chars == 0) {
- if(entry_size - read_chars_total > 0)
- entry[read_chars_total] = '\0';
- else {
- entry = (char *) realloc(entry, sizeof(char) * entry_size + 1);
- entry_size = entry_size + 1;
- entry[read_chars_total] = '\0';
- }
- break;
- }
- else {
- read_chars_total += read_chars;
- }
+ if(entry_size - read_chars_total == 0) {
+ entry = (char *) realloc(entry, sizeof(char) * 2 * entry_size);
+ entry_size = 2 * entry_size;
+ }
+ read_chars = read(fd, (void *) entry_pos, entry_size - read_chars_total);
+ if(read_chars == -1) {
+ SLAP_FREE(entry);
+ return NULL;
+ }
+ entry_pos += read_chars;
+ if(read_chars == 0) {
+ if(entry_size - read_chars_total > 0)
+ entry[read_chars_total] = '\0';
+ else {
+ entry = (char *) realloc(entry, sizeof(char) * entry_size + 1);
+ entry_size = entry_size + 1;
+ entry[read_chars_total] = '\0';
+ }
+ break;
+ }
+ else {
+ read_chars_total += read_chars;
+ }
}
return entry;
}
char * spewptr = spew;
while(written < len) {
- writeres = write(fd, spewptr, len - written);
- if(writeres == -1) {
- perror("could not spew write");
- return -1;
- }
- else {
- spewptr += writeres;
- written += writeres;
- }
+ writeres = write(fd, spewptr, len - written);
+ if(writeres == -1) {
+ perror("could not spew write");
+ return -1;
+ }
+ else {
+ spewptr += writeres;
+ written += writeres;
+ }
}
return writeres;
}
-static int spew_entry(Entry * e, char * path) {
+static int spew_entry(Entry * e, struct berval * path) {
int rs;
int openres;
int spew_res;
int entry_length;
char * entry_as_string;
- openres = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
+ openres = open(path->bv_val, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
if(openres == -1) {
- if(errno == ENOENT)
- rs = LDAP_NO_SUCH_OBJECT;
- else
- rs = LDAP_UNWILLING_TO_PERFORM;
+ if(errno == ENOENT)
+ rs = LDAP_NO_SUCH_OBJECT;
+ else
+ rs = LDAP_UNWILLING_TO_PERFORM;
}
else {
- entry_as_string = entry2str(e, &entry_length);
- if(entry_as_string == NULL) {
- rs = LDAP_UNWILLING_TO_PERFORM;
- close(openres);
- }
- else {
- spew_res = spew_file(openres, entry_as_string);
- close(openres);
- if(spew_res == -1)
- rs = LDAP_UNWILLING_TO_PERFORM;
- else
- rs = LDAP_SUCCESS;
- }
- }
+ entry_as_string = entry2str(e, &entry_length);
+ if(entry_as_string == NULL) {
+ rs = LDAP_UNWILLING_TO_PERFORM;
+ close(openres);
+ }
+ else {
+ spew_res = spew_file(openres, entry_as_string);
+ close(openres);
+ if(spew_res == -1)
+ rs = LDAP_UNWILLING_TO_PERFORM;
+ else
+ rs = LDAP_SUCCESS;
+ }
+ }
return rs;
}
/* error reading file */
if(entry == NULL) {
- goto return_value;
+ goto return_value;
}
ldentry = str2entry(entry);
return_value:
if(fd != -1) {
- if(close(fd) != 0) {
- /* log error */
- }
+ if(close(fd) != 0) {
+ /* log error */
+ }
}
if(entry != NULL)
- SLAP_FREE(entry);
+ SLAP_FREE(entry);
return ldentry;
}
static Entry * get_entry(struct berval * dn, struct berval * rootdn, struct berval * base_path) {
- char * path = (char *) dn2path(dn, rootdn, base_path);
- int fd = open(path, O_RDONLY);
+ struct berval path;
+ int fd;
+ dn2path(dn, rootdn, base_path, &path);
+ fd = open(path.bv_val, O_RDONLY);
/* error opening file (mebbe should log error) */
if(fd == -1) {
- perror("failed to open file");
- goto return_value;
+ perror("failed to open file");
}
- goto return_value;
- return_value:
- if(path != NULL)
- SLAP_FREE(path);
+ if(path.bv_val != NULL)
+ SLAP_FREE(path.bv_val);
return get_entry_for_fd(fd);
}
-/* takes a base path and a filename and opens that file */
-static int fd_for_path_components(char * base, char * name) {
- char * absolutepath;
- int fd;
- absolutepath = (char *) SLAP_MALLOC(sizeof(char) *
- (strlen(base) +
- strlen(name) + 2));
- absolutepath[0] = '\0';
- strcat(absolutepath, base);
- strcat(absolutepath, LDAP_DIRSEP);
- strcat(absolutepath, name);
- fd = open(absolutepath, O_RDONLY);
- SLAP_FREE(absolutepath);
- return fd;
+static void fullpath(struct berval *base, struct berval *name, struct berval *res) {
+ char *ptr;
+ res->bv_len = name->bv_len + base->bv_len + 1;
+ res->bv_val = ch_malloc( res->bv_len + 1 );
+ strcpy(res->bv_val, base->bv_val);
+ ptr = res->bv_val + base->bv_len;
+ *ptr++ = LDAP_DIRSEP[0];
+ strcpy(ptr, name->bv_val);
}
-static Entry ** r_enum_tree(Entry ** entries, int *elen, int *eind, char * path) {
- DIR * dir_of_path = opendir(path);
- int fd;
- struct dirent * dir;
- char * newpath;
- Entry * e;
+typedef struct bvlist {
+ struct bvlist *next;
+ struct berval bv;
+} bvlist;
+
+static Entry ** r_enum_tree(Entry ** entries, int *elen, int *eind,
+ struct berval * path, int scope) {
if(entries == NULL) {
- entries = (Entry **) SLAP_MALLOC(sizeof(Entry *) * ENTRY_BUFF_INCREMENT);
- *elen = ENTRY_BUFF_INCREMENT;
+ entries = (Entry **) SLAP_MALLOC(sizeof(Entry *) * ENTRY_BUFF_INCREMENT);
+ *elen = ENTRY_BUFF_INCREMENT;
}
- if(dir_of_path == NULL) {/* can't open directory */
- perror("failed to open directory");
- return entries;
+
+ if ( scope == LDAP_SCOPE_BASE || scope == LDAP_SCOPE_SUBTREE ) {
+ int fd;
+ Entry * e;
+ if(! (*eind < *elen)) { /* grow entries if necessary */
+ entries = (Entry **) SLAP_REALLOC(entries, sizeof(Entry *) * (*elen) * 2);
+ *elen = *elen * 2;
+ }
+ fd = open( path->bv_val, O_RDONLY );
+ if ( fd < 0 ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "=> ldif_enum_tree: failed to open %s\n",
+ path->bv_val, 0, 0 );
+ goto leave;
+ }
+
+ e = get_entry_for_fd(fd);
+ if(e != NULL) {
+ entries[*eind] = e;
+ *eind = *eind + 1;
+ }
+ else {
+ Debug( LDAP_DEBUG_ANY,
+ "=> ldif_enum_tree: failed to read entry for %s\n",
+ path->bv_val, 0, 0 );
+ goto leave;
+ }
}
+ if ( scope != LDAP_SCOPE_BASE ) {
+ DIR * dir_of_path;
+ bvlist *list = NULL, *ptr;
+
+ path->bv_len -= STRLENOF( LDIF );
+ path->bv_val[path->bv_len] = '\0';
+
+ dir_of_path = opendir(path->bv_val);
+ if(dir_of_path == NULL) {/* can't open directory */
+ Debug( LDAP_DEBUG_TRACE,
+ "=> ldif_enum_tree: failed to opendir %s\n",
+ path->bv_val, 0, 0 );
+ goto leave;
+ }
- while(1) {
- dir = readdir(dir_of_path);
- if(dir == NULL) break; /* end of the directory */
- if(dir->d_type == DT_REG) { /* regular file, read the entry into memory */
- if(! (*eind < *elen)) { /* grow entries if necessary */
- entries = (Entry **) SLAP_REALLOC(entries, sizeof(Entry *) * (*elen) * 2);
- *elen = *elen * 2;
- }
- fd = fd_for_path_components(path, dir->d_name);
- if(fd != -1) {
- e = get_entry_for_fd(fd);
- if(e != NULL) {
- entries[*eind] = e;
- *eind = *eind + 1;
+ while(1) {
+ struct berval fname;
+ struct dirent * dir;
+ bvlist *bvl, *prev;
+
+ dir = readdir(dir_of_path);
+ if(dir == NULL) break; /* end of the directory */
+ fname.bv_len = strlen( dir->d_name );
+ if ( fname.bv_len <= STRLENOF( LDIF ))
+ continue;
+ if ( strcmp( dir->d_name + (fname.bv_len - STRLENOF(LDIF)), LDIF))
+ continue;
+ fname.bv_val = dir->d_name;
+
+ bvl = ch_malloc( sizeof(bvlist) );
+ ber_dupbv( &bvl->bv, &fname );
+
+ for (ptr = list, prev = (bvlist *)&list; ptr;
+ prev = ptr, ptr = ptr->next) {
+ if ( strcmp( bvl->bv.bv_val, ptr->bv.bv_val ) < 0 )
+ break;
+ }
+ prev->next = bvl;
+ bvl->next = ptr;
+
+ }
+ closedir(dir_of_path);
+
+ for ( ptr = list; ptr; ptr=ptr->next ) {
+ struct berval fpath;
+ fullpath( path, &ptr->bv, &fpath );
+ entries = r_enum_tree(entries, elen, eind, &fpath,
+ scope == LDAP_SCOPE_ONELEVEL ? LDAP_SCOPE_BASE : scope);
+ free(fpath.bv_val);
+ }
}
- else
- perror("failed to read entry");
- }
- else
- perror("failed to open fd");
- }
- else if(dir->d_type == DT_DIR) {
- if(! (strcasecmp(dir->d_name, ".") == 0 || strcasecmp(dir->d_name, "..") == 0)) {
- newpath = (char *) SLAP_MALLOC(sizeof(char) *
- (strlen(path) + strlen(dir->d_name) + 2));
- newpath[0] = '\0';
- strcat(newpath, path);
- strcat(newpath, LDAP_DIRSEP);
- strcat(newpath, dir->d_name);
- entries = r_enum_tree(entries, elen, eind, newpath);
- SLAP_FREE(newpath);
- }
- }
- }
- closedir(dir_of_path);
+leave:
return entries;
}
-static Entry ** enum_tree(struct berval * path, int * length) {
+static Entry ** enum_tree(BackendDB *be, struct berval * ndn, int * length, int scope) {
+ struct ldif_info *ni = (struct ldif_info *) be->be_private;
+ struct berval path;
int index = 0;
- return r_enum_tree(NULL, &index, length, path->bv_val);
+
+ dn2path(ndn, &be->be_nsuffix[0], &ni->li_base_path, &path);
+ return r_enum_tree(NULL, &index, length, &path, scope);
}
-static char * get_parent_path(char * dnpath) {
- int dnpathlen = strlen(dnpath);
- char * result;
+/* Get the parent path plus the LDIF suffix */
+static void get_parent_path(struct berval * dnpath, struct berval *res) {
+ int dnpathlen = dnpath->bv_len;
int i;
for(i = dnpathlen;i>0;i--) /* find the first path seperator */
- if(dnpath[i] == LDAP_DIRSEP[0])
- break;
- result = ch_malloc( i + 1 );
- strncpy(result, dnpath, i);
- result[i] = '\0';
- return result;
+ if(dnpath->bv_val[i] == LDAP_DIRSEP[0])
+ break;
+ res->bv_len = i;
+ res->bv_val = ch_malloc( res->bv_len + 1 + STRLENOF(LDIF) );
+ strncpy(res->bv_val, dnpath->bv_val, i);
+ strcpy(res->bv_val+i, LDIF);
+ res->bv_val[i] = '\0';
}
-static int apply_modify_to_entry(Entry * entry,
- Modifications * modlist,
- Operation * op,
- SlapReply * rs)
+static int apply_modify_to_entry(Entry * entry,
+ Modifications * modlist,
+ Operation * op,
+ SlapReply * rs)
{
char textbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof textbuf;
Attribute *save_attrs;
if (!acl_check_modlist(op, entry, modlist)) {
- return LDAP_INSUFFICIENT_ACCESS;
+ return LDAP_INSUFFICIENT_ACCESS;
}
/* save_attrs = entry->e_attrs; Why?
- entry->e_attrs = attrs_dup(entry->e_attrs); */
+ entry->e_attrs = attrs_dup(entry->e_attrs); */
for (; modlist != NULL; modlist = modlist->sml_next) {
- mods = &modlist->sml_mod;
-
- switch (mods->sm_op) {
- case LDAP_MOD_ADD:
- rc = modify_add_values(entry, mods,
- get_permissiveModify(op),
- &rs->sr_text, textbuf,
- textlen);
- break;
+ mods = &modlist->sml_mod;
+
+ switch (mods->sm_op) {
+ case LDAP_MOD_ADD:
+ rc = modify_add_values(entry, mods,
+ get_permissiveModify(op),
+ &rs->sr_text, textbuf,
+ textlen);
+ break;
- case LDAP_MOD_DELETE:
- rc = modify_delete_values(entry, mods,
- get_permissiveModify(op),
- &rs->sr_text, textbuf,
+ case LDAP_MOD_DELETE:
+ rc = modify_delete_values(entry, mods,
+ get_permissiveModify(op),
+ &rs->sr_text, textbuf,
textlen);
- break;
+ break;
- case LDAP_MOD_REPLACE:
- rc = modify_replace_values(entry, mods,
- get_permissiveModify(op),
- &rs->sr_text, textbuf,
+ case LDAP_MOD_REPLACE:
+ rc = modify_replace_values(entry, mods,
+ get_permissiveModify(op),
+ &rs->sr_text, textbuf,
textlen);
- break;
- case LDAP_MOD_INCREMENT:
- break;
- case SLAP_MOD_SOFTADD:
- mods->sm_op = LDAP_MOD_ADD;
- rc = modify_add_values(entry, mods,
- get_permissiveModify(op),
- &rs->sr_text, textbuf,
- textlen);
- mods->sm_op = SLAP_MOD_SOFTADD;
- if (rc == LDAP_TYPE_OR_VALUE_EXISTS) {
- rc = LDAP_SUCCESS;
- }
- break;
- default:
- break;
- }
- if(rc != LDAP_SUCCESS) break;
+ break;
+ case LDAP_MOD_INCREMENT:
+ break;
+ case SLAP_MOD_SOFTADD:
+ mods->sm_op = LDAP_MOD_ADD;
+ rc = modify_add_values(entry, mods,
+ get_permissiveModify(op),
+ &rs->sr_text, textbuf,
+ textlen);
+ mods->sm_op = SLAP_MOD_SOFTADD;
+ if (rc == LDAP_TYPE_OR_VALUE_EXISTS) {
+ rc = LDAP_SUCCESS;
+ }
+ break;
+ default:
+ break;
+ }
+ if(rc != LDAP_SUCCESS) break;
}
if(rc == LDAP_SUCCESS) {
- if ( mods->sm_desc == slap_schema.si_ad_objectClass ) {
- entry->e_ocflags = 0;
- }
- /* check that the entry still obeys the schema */
- rc = entry_schema_check(op->o_bd, entry,
- save_attrs, &rs->sr_text,
- textbuf, textlen);
+ if ( mods->sm_desc == slap_schema.si_ad_objectClass ) {
+ entry->e_ocflags = 0;
+ }
+ /* check that the entry still obeys the schema */
+ rc = entry_schema_check(op->o_bd, entry,
+ save_attrs, &rs->sr_text,
+ textbuf, textlen);
}
return rc;
}
/* no object is found for them */
if(entry == NULL) {
- if(be_isroot_pw(op)) {
- return_val = LDAP_SUCCESS;
- goto return_result;
- }
- else if(be_root_dn(op->o_bd)) {
- return_val = LDAP_INVALID_CREDENTIALS;
- rs->sr_err = LDAP_INVALID_CREDENTIALS;
- goto return_result;
- }
- else {
- rs->sr_err = LDAP_NO_SUCH_OBJECT;
- return_val = 1;
- goto return_result;
- }
+ if(be_isroot_pw(op)) {
+ return_val = LDAP_SUCCESS;
+ goto return_result;
+ }
+ else if(be_root_dn(op->o_bd)) {
+ return_val = LDAP_INVALID_CREDENTIALS;
+ rs->sr_err = LDAP_INVALID_CREDENTIALS;
+ goto return_result;
+ }
+ else {
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ return_val = 1;
+ goto return_result;
+ }
}
/* they don't have userpassword */
if((a = attr_find(entry->e_attrs, password)) == NULL) {
- rs->sr_err = LDAP_INAPPROPRIATE_AUTH;
- return_val = 1;
- goto return_result;
+ rs->sr_err = LDAP_INAPPROPRIATE_AUTH;
+ return_val = 1;
+ goto return_result;
}
/* authentication actually failed */
if(slap_passwd_check(op, entry, a, &op->oq_bind.rb_cred,
- &rs->sr_text) != 0) {
- rs->sr_err = LDAP_INVALID_CREDENTIALS;
- return_val = 1;
- goto return_result;
+ &rs->sr_text) != 0) {
+ rs->sr_err = LDAP_INVALID_CREDENTIALS;
+ return_val = 1;
+ goto return_result;
}
/* let the front-end send success */
return_result:
ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
if(return_val != 0)
- send_ldap_result( op, rs );
+ send_ldap_result( op, rs );
if(entry != NULL)
- entry_free(entry);
+ entry_free(entry);
return return_val;
}
Entry ** entries = NULL;
ldap_pvt_thread_mutex_lock(&ni->li_mutex);
- entries = (Entry **) enum_tree(&ni->li_base_path, &numentries);
+ entries = (Entry **) enum_tree(op->o_bd, &op->o_req_ndn, &numentries, op->ors_scope);
if(entries != NULL) {
- for(i=0;i<numentries;i++) {
- if(test_filter(op, entries[i], op->ors_filter) == LDAP_COMPARE_TRUE) {
- rs->sr_entry = entries[i];
- rs->sr_attrs = op->ors_attrs;
- rs->sr_flags = REP_ENTRY_MODIFIABLE;
- send_search_entry(op, rs);
- }
- entry_free(entries[i]);
- }
- SLAP_FREE(entries);
- rs->sr_err = LDAP_SUCCESS;
- ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
- send_ldap_result(op, rs);
+ for(i=0;i<numentries;i++) {
+ if(test_filter(op, entries[i], op->ors_filter) == LDAP_COMPARE_TRUE) {
+ rs->sr_entry = entries[i];
+ rs->sr_attrs = op->ors_attrs;
+ rs->sr_flags = REP_ENTRY_MODIFIABLE;
+ send_search_entry(op, rs);
+ }
+ entry_free(entries[i]);
+ }
+ SLAP_FREE(entries);
+ rs->sr_err = LDAP_SUCCESS;
+ ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
+ send_ldap_result(op, rs);
}
else {
- rs->sr_err = LDAP_BUSY;
- ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
- send_ldap_result(op, rs);
+ rs->sr_err = LDAP_BUSY;
+ ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
+ send_ldap_result(op, rs);
}
return 0;
static int ldif_back_add(Operation *op, SlapReply *rs) {
struct ldif_info *ni = (struct ldif_info *) op->o_bd->be_private;
Entry * e = op->ora_e;
- Attribute *save_attrs;
struct berval dn = e->e_nname;
- char * leaf_path = NULL;
- char * base = NULL;
- char * base_ldif = NULL;
+ struct berval leaf_path = BER_BVNULL;
struct stat stats;
int statres;
char textbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof textbuf;
+ rs->sr_err = entry_schema_check(op->o_bd, e,
+ NULL, &rs->sr_text, textbuf, textlen);
+ if ( rs->sr_err != LDAP_SUCCESS ) goto send_res;
+
ldap_pvt_thread_mutex_lock(&ni->li_mutex);
- ldap_pvt_thread_mutex_lock(&entry2str_mutex);
- leaf_path = (char *) dn2path(&dn, &op->o_bd->be_nsuffix[0], &ni->li_base_path);
-
- /* save_attrs = e->e_attrs; why?
- e->e_attrs = attrs_dup(e->e_attrs);*/
-
- if(leaf_path != NULL) {
- char * tmp;
- /* build path to container, and path to ldif of container */
- base = (char *) get_parent_path(leaf_path);
- base_ldif = (char *) SLAP_MALLOC(sizeof(char) * (strlen(base) + 6));
- tmp = (char *) lutil_strcopy(base_ldif, base);
- lutil_strcopy(tmp, LDIF);
-
- rs->sr_err = entry_schema_check(op->o_bd, e,
- save_attrs,
- &rs->sr_text,
- textbuf, textlen);
- if(rs->sr_err == LDAP_SUCCESS) {
- statres = stat(base, &stats); /* check if container exists */
- if(statres == -1 && errno == ENOENT) { /* container missing */
- statres = stat(base_ldif, &stats); /* check for leaf node */
- if(statres == -1 && errno == ENOENT) {
- rs->sr_err = LDAP_NO_SUCH_OBJECT; /* parent doesn't exist */
- }
- else if(statres != -1) { /* create parent */
- int mkdirres = mkdir(base, 0750);
- if(mkdirres == -1) {
- rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
- }
+ dn2path(&dn, &op->o_bd->be_nsuffix[0], &ni->li_base_path, &leaf_path);
+
+ if(leaf_path.bv_val != NULL) {
+ struct berval base = BER_BVNULL;
+ /* build path to container and ldif of container */
+ get_parent_path(&leaf_path, &base);
+
+ statres = stat(base.bv_val, &stats); /* check if container exists */
+ if(statres == -1 && errno == ENOENT) { /* container missing */
+ base.bv_val[base.bv_len] = '.';
+ statres = stat(base.bv_val, &stats); /* check for leaf node */
+ base.bv_val[base.bv_len] = '\0';
+ if(statres == -1 && errno == ENOENT) {
+ rs->sr_err = LDAP_NO_SUCH_OBJECT; /* parent doesn't exist */
+ }
+ else if(statres != -1) { /* create parent */
+ int mkdirres = mkdir(base.bv_val, 0750);
+ if(mkdirres == -1) {
+ rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ }
+ }
+ else
+ rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ }/* container was possibly created, move on to add the entry */
+ if(rs->sr_err == LDAP_SUCCESS) {
+ statres = stat(leaf_path.bv_val, &stats);
+ if(statres == -1 && errno == ENOENT) {
+ ldap_pvt_thread_mutex_lock(&entry2str_mutex);
+ rs->sr_err = (int) spew_entry(e, &leaf_path);
+ ldap_pvt_thread_mutex_unlock(&entry2str_mutex);
+ }
+ else /* it already exists */
+ rs->sr_err = LDAP_ALREADY_EXISTS;
+ }
+ SLAP_FREE(base.bv_val);
+ SLAP_FREE(leaf_path.bv_val);
}
- else
- rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
- }/* container was possibly created, move on to add the entry */
- if(rs->sr_err == LDAP_SUCCESS) {
- statres = stat(leaf_path, &stats);
- if(statres == -1 && errno == ENOENT) {
- rs->sr_err = (int) spew_entry(e, leaf_path);
- }
- else /* it already exists */
- rs->sr_err = LDAP_ALREADY_EXISTS;
- }
- }
- }
ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
- ldap_pvt_thread_mutex_unlock(&entry2str_mutex);
- send_ldap_result(op, rs);
- if(leaf_path != NULL)
- SLAP_FREE(leaf_path);
- if(base != NULL)
- SLAP_FREE(base);
- if(base_ldif != NULL)
- SLAP_FREE(base_ldif);
+send_res:
+ send_ldap_result(op, rs);
return 0;
}
static int ldif_back_modify(Operation *op, SlapReply *rs) {
struct ldif_info *ni = (struct ldif_info *) op->o_bd->be_private;
Modifications * modlst = op->orm_modlist;
- char * path = NULL;
+ struct berval path = BER_BVNULL;
Entry * entry = NULL;
int spew_res;
ldap_pvt_thread_mutex_lock(&ni->li_mutex);
- ldap_pvt_thread_mutex_lock(&entry2str_mutex);
- path = (char *) dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path);
- entry = (Entry *) get_entry(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path);
+ dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path,
+ &path);
+ entry = (Entry *) get_entry(&op->o_req_ndn, &op->o_bd->be_nsuffix[0],
+ &ni->li_base_path);
if(entry != NULL) {
- rs->sr_err = apply_modify_to_entry(entry, modlst, op, rs);
- if(rs->sr_err == LDAP_SUCCESS) {
- spew_res = spew_entry(entry, path);
- if(spew_res == -1) {
- perror("could not output entry");
- rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
- }
- }
+ rs->sr_err = apply_modify_to_entry(entry, modlst, op, rs);
+ if(rs->sr_err == LDAP_SUCCESS) {
+ ldap_pvt_thread_mutex_lock(&entry2str_mutex);
+ spew_res = spew_entry(entry, &path);
+ ldap_pvt_thread_mutex_unlock(&entry2str_mutex);
+ if(spew_res == -1) {
+ perror("could not output entry");
+ rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ }
+ }
}
else {
- rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
}
- if(path != NULL)
- SLAP_FREE(path);
if(entry != NULL)
- entry_free(entry);
- rs->sr_text = "";
+ entry_free(entry);
+ if(path.bv_val != NULL)
+ SLAP_FREE(path.bv_val);
+ rs->sr_text = NULL;
ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
- ldap_pvt_thread_mutex_unlock(&entry2str_mutex);
send_ldap_result(op, rs);
return 0;
}
static int ldif_back_delete(Operation *op, SlapReply *rs) {
struct ldif_info *ni = (struct ldif_info *) op->o_bd->be_private;
- char * path = NULL;
+ struct berval path = BER_BVNULL;
int res = 0;
ldap_pvt_thread_mutex_lock(&ni->li_mutex);
- path = (char *) dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path);
- res = unlink(path);
+ dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path, &path);
+ res = unlink(path.bv_val);
if(res == -1) {
- if(errno == ENOENT)
- rs->sr_err = LDAP_NO_SUCH_OBJECT;
- else
- rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ if(errno == ENOENT)
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ else
+ rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
}
else
- rs->sr_err = LDAP_SUCCESS;
+ rs->sr_err = LDAP_SUCCESS;
- SLAP_FREE(path);
+ SLAP_FREE(path.bv_val);
ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
send_ldap_result(op, rs);
return 0;
}
-static int is_leaf_node(char * path) {
- DIR * nonleafnode;
- int path_len = strlen(path);
- char * nonleafpath = (char *) SLAP_MALLOC(sizeof(char) * path_len + 1);
+static int is_leaf_node(struct berval * path) {
+ DIR * nonleafnode;
+ int path_len = path->bv_len;
int res;
- strncpy(nonleafpath, path, path_len);
- nonleafpath[path_len - 5] = '\0';
- nonleafnode = opendir(nonleafpath);
+ path->bv_val[path->bv_len - STRLENOF(LDIF)] = '\0';
+ nonleafnode = opendir(path->bv_val);
+ path->bv_val[path->bv_len - STRLENOF(LDIF)] = '.';
if(nonleafnode == NULL) {
- res = 1;
+ res = 1;
}
else {
- closedir(nonleafnode);
- res = 0;
+ closedir(nonleafnode);
+ res = 0;
}
- SLAP_FREE(nonleafpath);
return res;
}
-static int move_entry(Entry * entry, struct berval * ndn,
- struct berval * newndn, struct berval * rootdn,
- struct berval * base_path) {
+static int move_entry(Entry * entry, struct berval * ndn,
+ struct berval * newndn, struct berval * rootdn,
+ struct berval * base_path) {
int res;
int exists_res;
- char * path = (char *) dn2path(ndn, rootdn, base_path);
- char * newpath = (char *) dn2path(newndn, rootdn, base_path);
- int path_len = strlen(path);
+ struct berval path;
+ struct berval newpath;
- if((entry == NULL || path == NULL) || newpath == NULL) { /* some object doesn't exist */
- res = LDAP_NO_SUCH_OBJECT;
+ dn2path(ndn, rootdn, base_path, &path);
+ dn2path(newndn, rootdn, base_path, &newpath);
+
+ if((entry == NULL || path.bv_val == NULL) || newpath.bv_val == NULL) {
+ /* some object doesn't exist */
+ res = LDAP_NO_SUCH_OBJECT;
}
- else if(! is_leaf_node(path)) { /* entry is not a leaf node */
- res = LDAP_NOT_ALLOWED_ON_NONLEAF;
+ else if(! is_leaf_node(&path)) { /* entry is not a leaf node */
+ res = LDAP_NOT_ALLOWED_ON_NONLEAF;
}
else { /* do the modrdn */
- exists_res = open(newpath, O_RDONLY);
- if(exists_res == -1 && errno == ENOENT) {
- res = spew_entry(entry, newpath);
- if(res != -1) {
- /* if this fails we should log something bad */
- res = unlink(path);
- res = LDAP_SUCCESS;
- }
- else {
- if(errno == ENOENT)
- res = LDAP_NO_SUCH_OBJECT;
- else
- res = LDAP_UNWILLING_TO_PERFORM;
- unlink(newpath); /* in case file was created */
- }
- }
- else if(exists_res) {
- res = LDAP_ALREADY_EXISTS;
- int close_res = close(exists_res);
- if(close_res == -1) {
- /* log heinous error */
- }
- }
- else {
- res = LDAP_UNWILLING_TO_PERFORM;
- }
- }
-
- if(path != NULL)
- SLAP_FREE(path);
- if(newpath != NULL)
- SLAP_FREE(newpath);
+ exists_res = open(newpath.bv_val, O_RDONLY);
+ if(exists_res == -1 && errno == ENOENT) {
+ res = spew_entry(entry, &newpath);
+ if(res != -1) {
+ /* if this fails we should log something bad */
+ res = unlink(path.bv_val);
+ res = LDAP_SUCCESS;
+ }
+ else {
+ if(errno == ENOENT)
+ res = LDAP_NO_SUCH_OBJECT;
+ else
+ res = LDAP_UNWILLING_TO_PERFORM;
+ unlink(newpath.bv_val); /* in case file was created */
+ }
+ }
+ else if(exists_res) {
+ int close_res = close(exists_res);
+ res = LDAP_ALREADY_EXISTS;
+ if(close_res == -1) {
+ /* log heinous error */
+ }
+ }
+ else {
+ res = LDAP_UNWILLING_TO_PERFORM;
+ }
+ }
+
+ if(newpath.bv_val != NULL)
+ SLAP_FREE(newpath.bv_val);
+ if(path.bv_val != NULL)
+ SLAP_FREE(path.bv_val);
return res;
}
struct ldif_info *ni = (struct ldif_info *) op->o_bd->be_private;
struct berval new_dn = {0, NULL}, new_ndn = {0, NULL};
struct berval * new_parent_dn = NULL;
- struct berval p_dn;
+ struct berval p_dn, bv = {0, NULL};
Entry * entry = NULL;
LDAPRDN new_rdn = NULL;
LDAPRDN old_rdn = NULL;
ldap_pvt_thread_mutex_lock(&ni->li_mutex);
ldap_pvt_thread_mutex_lock(&entry2str_mutex);
- entry = (Entry *) get_entry(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path);
+ entry = (Entry *) get_entry(&op->o_req_ndn, &op->o_bd->be_nsuffix[0],
+ &ni->li_base_path);
/* build the mods to the entry */
if(entry != NULL) {
- if(ldap_bv2rdn(&op->oq_modrdn.rs_newrdn, &new_rdn, (char **)&rs->sr_text,
- LDAP_DN_FORMAT_LDAP)) {
- rs->sr_err = LDAP_INVALID_DN_SYNTAX;
- }
- else if(op->oq_modrdn.rs_deleteoldrdn &&
- ldap_bv2rdn(&op->o_req_dn, &old_rdn, (char **)&rs->sr_text,
+ if(ldap_bv2rdn(&op->oq_modrdn.rs_newrdn, &new_rdn,
+ (char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP)) {
+ rs->sr_err = LDAP_INVALID_DN_SYNTAX;
+ }
+ else if(op->oq_modrdn.rs_deleteoldrdn &&
+ ldap_bv2rdn(&op->o_req_dn, &old_rdn, (char **)&rs->sr_text,
LDAP_DN_FORMAT_LDAP)) {
- rs->sr_err = LDAP_OTHER;
- }
- else { /* got both rdns successfully, ready to build mods */
- if(slap_modrdn2mods(op, rs, entry, old_rdn, new_rdn, &mods) != LDAP_SUCCESS) {
- rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
- }
- else { /* built mods successfully */
-
- /* build new dn, and new ndn for the entry */
- if(op->oq_modrdn.rs_newSup != NULL) /* new superior */
- p_dn = *op->oq_modrdn.rs_newSup;
- else
- p_dn = slap_empty_bv;
- dnParent(&entry->e_name, &p_dn);
- build_new_dn(&new_dn, &p_dn, &op->oq_modrdn.rs_newrdn, NULL);
- struct berval bv = {0, NULL};
- dnNormalize( 0, NULL, NULL, &new_dn, &bv, op->o_tmpmemctx );
- ber_dupbv( &new_ndn, &bv );
- entry->e_name = new_dn;
- entry->e_nname = new_ndn;
-
- /* perform the modifications */
- res = apply_modify_to_entry(entry, mods, op, rs);
- if(res == LDAP_SUCCESS) {
- rs->sr_err = move_entry(entry, &op->o_req_ndn,
- &new_ndn,
- &op->o_bd->be_nsuffix[0],
- &ni->li_base_path);
- }
- else
- rs->sr_err = res;
- }
- }
+ rs->sr_err = LDAP_OTHER;
+ }
+ else { /* got both rdns successfully, ready to build mods */
+ if(slap_modrdn2mods(op, rs, entry, old_rdn, new_rdn, &mods)
+ != LDAP_SUCCESS) {
+ rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ }
+ else { /* built mods successfully */
+
+ /* build new dn, and new ndn for the entry */
+ if(op->oq_modrdn.rs_newSup != NULL) /* new superior */
+ p_dn = *op->oq_modrdn.rs_newSup;
+ else
+ p_dn = slap_empty_bv;
+ dnParent(&entry->e_name, &p_dn);
+ build_new_dn(&new_dn, &p_dn, &op->oq_modrdn.rs_newrdn, NULL);
+ dnNormalize( 0, NULL, NULL, &new_dn, &bv, op->o_tmpmemctx );
+ ber_dupbv( &new_ndn, &bv );
+ entry->e_name = new_dn;
+ entry->e_nname = new_ndn;
+
+ /* perform the modifications */
+ res = apply_modify_to_entry(entry, mods, op, rs);
+ if(res == LDAP_SUCCESS) {
+ rs->sr_err = move_entry(entry, &op->o_req_ndn,
+ &new_ndn,
+ &op->o_bd->be_nsuffix[0],
+ &ni->li_base_path);
+ }
+ else
+ rs->sr_err = res;
+ }
+ }
}
else /* entry was null */
- rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
if(entry != NULL)
- entry_free(entry);
+ entry_free(entry);
rs->sr_text = "";
ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
ldap_pvt_thread_mutex_unlock(&entry2str_mutex);
ldap_pvt_thread_mutex_lock(&ni->li_mutex);
- e = (Entry *) get_entry(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path);
+ e = (Entry *) get_entry(&op->o_req_ndn, &op->o_bd->be_nsuffix[0],
+ &ni->li_base_path);
if(e != NULL) {
- for(a = attrs_find( e->e_attrs, op->oq_compare.rs_ava->aa_desc );
- a != NULL;
- a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc ))
- {
- rs->sr_err = LDAP_COMPARE_FALSE;
-
- if (value_find_ex(op->oq_compare.rs_ava->aa_desc,
- SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
- SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
- a->a_nvals, &op->oq_compare.rs_ava->aa_value,
- op->o_tmpmemctx ) == 0)
- {
- rs->sr_err = LDAP_COMPARE_TRUE;
- break;
- }
- }
+ for(a = attrs_find( e->e_attrs, op->oq_compare.rs_ava->aa_desc );
+ a != NULL;
+ a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc )) {
+ rs->sr_err = LDAP_COMPARE_FALSE;
+
+ if (value_find_ex(op->oq_compare.rs_ava->aa_desc,
+ SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
+ SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
+ a->a_nvals, &op->oq_compare.rs_ava->aa_value,
+ op->o_tmpmemctx ) == 0) {
+ rs->sr_err = LDAP_COMPARE_TRUE;
+ break;
+ }
+ }
}
else {
- rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
}
if(e != NULL)
- entry_free(e);
+ entry_free(e);
ldap_pvt_thread_mutex_unlock(&ni->li_mutex);
send_ldap_result(op, rs);
return 0;
}
static int ldif_tool_entry_open(BackendDB * be, int mode) {
- struct ldif_info *ni = (struct ldif_info *) be->be_private;
+ struct ldif_info *ni = (struct ldif_info *) be->be_private;
ni->tool_entries = NULL;
ni->tool_numentries = 0;
ni->tool_current = 0;
}
static int ldif_tool_entry_close(BackendDB * be) {
- struct ldif_info *ni = (struct ldif_info *) be->be_private;
- int i;
- /*if(ni->tool_entries != NULL) {
- for(i=0;i<ni->tool_numentries;i++) {
- SLAP_FREE(ni->tool_entries[i]);
- }*/
+ struct ldif_info *ni = (struct ldif_info *) be->be_private;
+
SLAP_FREE(ni->tool_entries);
return 0;
}
static ID ldif_tool_entry_first(BackendDB *be) {
- struct ldif_info *ni = (struct ldif_info *) be->be_private;
+ struct ldif_info *ni = (struct ldif_info *) be->be_private;
ID id = 1; /* first entry in the array of entries shifted by one */
+
ni->tool_current = 1;
if(ni->tool_entries == NULL || ni->tool_put_entry_flag) {
- ni->tool_entries = (Entry **) enum_tree(&ni->li_base_path, &ni->tool_numentries);
- ni->tool_put_entry_flag = 0;
+ ni->tool_entries = (Entry **) enum_tree(be, &be->be_nsuffix[0],
+ &ni->tool_numentries, LDAP_SCOPE_SUBTREE);
+ ni->tool_put_entry_flag = 0;
}
return id;
}
static ID ldif_tool_entry_next(BackendDB *be) {
- struct ldif_info *ni = (struct ldif_info *) be->be_private;
+ struct ldif_info *ni = (struct ldif_info *) be->be_private;
ni->tool_current += 1;
if(ni->tool_put_entry_flag) {
- ni->tool_entries = (Entry **) enum_tree(&ni->li_base_path, &ni->tool_numentries);
- ni->tool_put_entry_flag = 0;
+ ni->tool_entries = (Entry **) enum_tree(be, &be->be_nsuffix[0],
+ &ni->tool_numentries, LDAP_SCOPE_SUBTREE);
+ ni->tool_put_entry_flag = 0;
}
if(ni->tool_current > ni->tool_numentries)
- return NOID;
+ return NOID;
else
- return ni->tool_current;
+ return ni->tool_current;
}
static Entry * ldif_tool_entry_get(BackendDB * be, ID id) {
- struct ldif_info *ni = (struct ldif_info *) be->be_private;
+ struct ldif_info *ni = (struct ldif_info *) be->be_private;
Entry * e;
if(id > ni->tool_numentries || id < 1)
- return NULL;
+ return NULL;
else {
- e = ni->tool_entries[id - 1];
- ni->tool_entries[id - 1] = NULL;
- return e;
+ e = ni->tool_entries[id - 1];
+ ni->tool_entries[id - 1] = NULL;
+ return e;
}
}
static ID ldif_tool_entry_put(BackendDB * be, Entry * e, struct berval *text) {
- struct ldif_info *ni = (struct ldif_info *) be->be_private;
- Attribute *save_attrs;
+ struct ldif_info *ni = (struct ldif_info *) be->be_private;
+ Attribute *save_attrs;
struct berval dn = e->e_nname;
- char * leaf_path = NULL;
- char * base = NULL;
- char * base_ldif = NULL;
+ struct berval leaf_path = BER_BVNULL;
struct stat stats;
int statres;
char textbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof textbuf;
int res = LDAP_SUCCESS;
- leaf_path = (char *) dn2path(&dn, &be->be_nsuffix[0], &ni->li_base_path);
-
- /* save_attrs = e->e_attrs; why?
- e->e_attrs = attrs_dup(e->e_attrs);*/
-
- if(leaf_path != NULL) {
- char * tmp;
- /* build path to container, and path to ldif of container */
- base = (char *) get_parent_path(leaf_path);
- base_ldif = (char *) SLAP_MALLOC(sizeof(char) * (strlen(base) + 6));
- tmp = (char *) lutil_strcopy(base_ldif, base);
- lutil_strcopy(tmp, LDIF);
-
- statres = stat(base, &stats); /* check if container exists */
- if(statres == -1 && errno == ENOENT) { /* container missing */
- statres = stat(base_ldif, &stats); /* check for leaf node */
- if(statres == -1 && errno == ENOENT) {
- res = LDAP_NO_SUCH_OBJECT; /* parent doesn't exist */
- }
- else if(statres != -1) { /* create parent */
- int mkdirres = mkdir(base, 0750);
- if(mkdirres == -1) {
- res = LDAP_UNWILLING_TO_PERFORM;
- }
- }
- else
- res = LDAP_UNWILLING_TO_PERFORM;
- }/* container was possibly created, move on to add the entry */
- if(res == LDAP_SUCCESS) {
- statres = stat(leaf_path, &stats);
- if(statres == -1 && errno == ENOENT) {
- res = (int) spew_entry(e, leaf_path);
- }
- else /* it already exists */
- res = LDAP_ALREADY_EXISTS;
- }
- }
-
- if(leaf_path != NULL)
- SLAP_FREE(leaf_path);
- if(base != NULL)
- SLAP_FREE(base);
- if(base_ldif != NULL)
- SLAP_FREE(base_ldif);
- if(res == LDAP_SUCCESS) {
- ni->tool_put_entry_flag = 1;
- return 1;
+ dn2path(&dn, &be->be_nsuffix[0], &ni->li_base_path, &leaf_path);
+
+ if(leaf_path.bv_val != NULL) {
+ struct berval base = BER_BVNULL;
+ /* build path to container, and path to ldif of container */
+ get_parent_path(&leaf_path, &base);
+
+ statres = stat(base.bv_val, &stats); /* check if container exists */
+ if(statres == -1 && errno == ENOENT) { /* container missing */
+ base.bv_val[base.bv_len] = '.';
+ statres = stat(base.bv_val, &stats); /* check for leaf node */
+ base.bv_val[base.bv_len] = '\0';
+ if(statres == -1 && errno == ENOENT) {
+ res = LDAP_NO_SUCH_OBJECT; /* parent doesn't exist */
+ }
+ else if(statres != -1) { /* create parent */
+ int mkdirres = mkdir(base.bv_val, 0750);
+ if(mkdirres == -1) {
+ res = LDAP_UNWILLING_TO_PERFORM;
+ }
+ }
+ else
+ res = LDAP_UNWILLING_TO_PERFORM;
+ }/* container was possibly created, move on to add the entry */
+ if(res == LDAP_SUCCESS) {
+ statres = stat(leaf_path.bv_val, &stats);
+ if(statres == -1 && errno == ENOENT) {
+ res = (int) spew_entry(e, &leaf_path);
+ }
+ else /* it already exists */
+ res = LDAP_ALREADY_EXISTS;
+ }
+ SLAP_FREE(base.bv_val);
+ SLAP_FREE(leaf_path.bv_val);
}
- else
- return NOID;
-}
-static int
-ldif_back_db_config(
- BackendDB *be,
- const char *fname,
- int lineno,
- int argc,
- char **argv )
-{
- struct ldif_info *ni = (struct ldif_info *) be->be_private;
-
- if ( strcasecmp( argv[0], "directory" ) == 0 ) {
- if ( argc < 2 ) {
- fprintf( stderr,
- "%s: line %d: missing <path> in \"directory <path>\" line\n",
- fname, lineno );
- return 1;
- }
- ber_str2bv(argv[1], 0, 1, &ni->li_base_path);
- } else {
- return SLAP_CONF_UNKNOWN;
+ if(res == LDAP_SUCCESS) {
+ ni->tool_put_entry_flag = 1;
+ return 1;
}
- return 0;
+ else
+ return NOID;
}
-
static int
ldif_back_db_init( BackendDB *be )
{
ni = ch_calloc( 1, sizeof(struct ldif_info) );
be->be_private = ni;
+ be->be_cf_table = be->bd_info->bi_cf_table;
ldap_pvt_thread_mutex_init(&ni->li_mutex);
return 0;
}
static int
ldif_back_db_destroy(
- Backend *be
- )
+ Backend *be
+ )
{
struct ldif_info *ni = be->be_private;
ldap_pvt_thread_mutex_destroy(&ni->li_mutex);
static int
ldif_back_db_open(
- Backend *be
- )
+ Backend *be
+ )
{
struct ldif_info *ni = (struct ldif_info *) be->be_private;
if( BER_BVISEMPTY(&ni->li_base_path)) {/* missing base path */
- fprintf(stderr, "missing base path for back-ldif\n");
- return 1;
+ fprintf(stderr, "missing base path for back-ldif\n");
+ return 1;
}
return 0;
}
int
ldif_back_initialize(
- BackendInfo *bi
- )
+ BackendInfo *bi
+ )
{
+ int rc;
+
+ bi->bi_cf_table = ldifcfg;
+
bi->bi_open = 0;
bi->bi_close = 0;
bi->bi_config = 0;
bi->bi_destroy = 0;
bi->bi_db_init = ldif_back_db_init;
- bi->bi_db_config = ldif_back_db_config;
+ bi->bi_db_config = config_generic_wrapper;
bi->bi_db_open = ldif_back_db_open;
bi->bi_db_close = 0;
bi->bi_db_destroy = ldif_back_db_destroy;
bi->bi_tool_id2entry_get = 0;
bi->bi_tool_entry_modify = 0;
+ rc = config_register_schema( ldifcfg, ldifocs );
+ if ( rc ) return rc;
+ ldifcfg[0].ad = slap_schema.si_ad_objectClass;
return 0;
}
/* Any initialization needed? */
if ( on->on_bi.bi_db_init ) {
+ int rc;
be->bd_info = (BackendInfo *)on2;
- on2->on_bi.bi_db_init( be );
+ rc = on2->on_bi.bi_db_init( be );
be->bd_info = (BackendInfo *)oi;
+ if ( rc ) return rc;
}
return 0;
#include "config.h"
static struct berval config_rdn = BER_BVC("cn=config");
-static struct berval access_rdn = BER_BVC("cn=access");
#ifdef SLAPD_MODULES
typedef struct modpath_s {
BerVarray c_dseFiles;
} ConfigFile;
+typedef struct CfOcInfo {
+ struct berval *co_name;
+ ConfigTable *co_table;
+} CfOcInfo;
+
+typedef enum {
+ Cf_Global = 1,
+ Cf_Include,
+ Cf_Backend,
+ Cf_Database,
+ Cf_Overlay
+} CfEtypes;
+
typedef struct CfEntryInfo {
struct CfEntryInfo *ce_sibs;
struct CfEntryInfo *ce_kids;
Entry *ce_entry;
+ CfEtypes ce_type;
BackendInfo *ce_bi;
BackendDB *ce_be;
} CfEntryInfo;
typedef struct {
ConfigFile *cb_config;
CfEntryInfo *cb_root;
+ BackendDB cb_db; /* underlying database */
+ int cb_got_ldif;
} CfBackInfo;
/* These do nothing in slapd, they're kept only to make them
static char *logfileName;
static BerVarray authz_rewrites;
+static struct berval cfdir;
+
+/* Private state */
static AttributeDescription *cfAd_backend, *cfAd_database, *cfAd_overlay,
*cfAd_include;
static ObjectClass *cfOc_global, *cfOc_backend, *cfOc_database,
- *cfOc_include, *cfOc_overlay, *cfOc_access;
+ *cfOc_include, *cfOc_overlay;
static ConfigFile cf_prv, *cfn = &cf_prv;
+static Avlnode *CfOcTree;
+
static int add_syncrepl LDAP_P(( Backend *, char **, int ));
static int parse_syncrepl_line LDAP_P(( char **, int, syncinfo_t *));
static void syncrepl_unparse LDAP_P (( syncinfo_t *, struct berval *));
static ConfigDriver config_fname;
+static ConfigDriver config_cfdir;
static ConfigDriver config_generic;
static ConfigDriver config_search_base;
static ConfigDriver config_passwd_hash;
"DESC 'File for slapd configuration directives' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "", "", 0, 0, 0, ARG_MAGIC,
+ &config_cfdir, "( OLcfgAt:79 NAME 'olcConfigDir' "
+ "DESC 'Directory for slapd configuration backend' "
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "access", NULL, 0, 0, 0, ARG_MAY_DB|ARG_MAGIC|CFG_ACL,
&config_generic, "( OLcfgAt:1 NAME 'olcAccess' "
"DESC 'Access Control List' "
{ "concurrency", "level", 2, 2, 0, ARG_INT|ARG_NONZERO|ARG_MAGIC|CFG_CONCUR,
&config_generic, "( OLcfgAt:10 NAME 'olcConcurrency' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
- { "conn_max_pending", "max", 2, 2, 0, ARG_LONG,
+ { "conn_max_pending", "max", 2, 2, 0, ARG_INT,
&slap_conn_max_pending, "( OLcfgAt:11 NAME 'olcConnMaxPending' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
- { "conn_max_pending_auth", "max", 2, 2, 0, ARG_LONG,
+ { "conn_max_pending_auth", "max", 2, 2, 0, ARG_INT,
&slap_conn_max_pending_auth, "( OLcfgAt:12 NAME 'olcConnMaxPendingAuth' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "database", "type", 2, 2, 0, ARG_MAGIC|CFG_DATABASE,
{ "limits", "limits", 2, 0, 0, ARG_DB|ARG_MAGIC|CFG_LIMITS,
&config_generic, "( OLcfgAt:25 NAME 'olcLimits' "
"SYNTAX OMsDirectoryString )", NULL, NULL },
- { "localSSF", "ssf", 2, 2, 0, ARG_LONG,
+ { "localSSF", "ssf", 2, 2, 0, ARG_INT,
&local_ssf, "( OLcfgAt:26 NAME 'olcLocalSSF' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "logfile", "file", 2, 2, 0, ARG_STRING|ARG_MAGIC|CFG_LOGFILE,
{ "sizelimit", "limit", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC|CFG_SIZE,
&config_sizelimit, "( OLcfgAt:60 NAME 'olcSizeLimit' "
"SYNTAX OMsInteger )", NULL, NULL },
- { "sockbuf_max_incoming", "max", 2, 2, 0, ARG_LONG,
+ { "sockbuf_max_incoming", "max", 2, 2, 0, ARG_BER_LEN_T,
&sockbuf_max_incoming, "( OLcfgAt:61 NAME 'olcSockbufMaxIncoming' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
- { "sockbuf_max_incoming_auth", "max", 2, 2, 0, ARG_LONG,
+ { "sockbuf_max_incoming_auth", "max", 2, 2, 0, ARG_BER_LEN_T,
&sockbuf_max_incoming_auth, "( OLcfgAt:62 NAME 'olcSockbufMaxIncomingAuth' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "srvtab", "file", 2, 2, 0,
"NAME 'olcGlobal' "
"DESC 'OpenLDAP Global configuration options' "
"SUP olcConfig STRUCTURAL "
- "MAY ( olcAllows $ olcArgsFile $ olcAttributeOptions $ "
+ "MAY ( olcConfigDir $ olcAllows $ olcArgsFile $ olcAttributeOptions $ "
"olcAuthIDRewrite $ olcAuthzPolicy $ olcAuthzRegexp $ "
"olcConcurrency $ olcConnMaxPending $ olcConnMaxPendingAuth $ "
"olcDefaultSearchBase $ olcDisallows $ olcGentleHUP $ "
"NAME 'olcDatabaseConfig' "
"DESC 'OpenLDAP Database-specific options' "
"SUP olcConfig STRUCTURAL "
- "MAY ( olcDatabase $ olcLastMod $ olcLimits $ "
+ "MAY ( olcDatabase $ olcAccess $ olcLastMod $ olcLimits $ "
"olcMaxDerefDepth $ olcPlugin $ olcReadOnly $ olcReplica $ "
"olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ "
"olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSuffix $ olcSyncrepl $ "
"DESC 'OpenLDAP Overlay-specific options' "
"SUP olcConfig STRUCTURAL "
"MAY ( olcOverlay ) )", &cfOc_overlay },
- { "( OLcfgOc:8 "
- "NAME 'olcACL' "
- "DESC 'OpenLDAP Access Control List' "
- "SUP olcConfig STRUCTURAL "
- "MUST ( olcAccess ) )", &cfOc_access },
{ NULL, NULL }
};
char *p;
int i;
- if ( c->emit ) {
+ if ( c->op == SLAP_CONFIG_EMIT ) {
int rc = 0;
switch(c->type) {
case CFG_CONCUR:
static int
config_fname(ConfigArgs *c) {
- if(c->emit && c->line) {
+ if(c->op == SLAP_CONFIG_EMIT && c->line) {
ConfigFile *cf = (ConfigFile *)c->line;
value_add_one( &c->rvalue_vals, &cf->c_file );
return 0;
return(1);
}
+static int
+config_cfdir(ConfigArgs *c) {
+ if(c->op == SLAP_CONFIG_EMIT) {
+ value_add_one( &c->rvalue_vals, &cfdir );
+ return 0;
+ }
+ return(1);
+}
+
static int
config_search_base(ConfigArgs *c) {
struct berval dn;
- if(c->emit) {
+ if(c->op == SLAP_CONFIG_EMIT) {
int rc = 1;
if (!BER_BVISEMPTY(&default_search_base)) {
value_add_one(&c->rvalue_vals, &default_search_base);
static int
config_passwd_hash(ConfigArgs *c) {
int i;
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
struct berval bv;
for (i=0; default_passwd_hash && default_passwd_hash[i]; i++) {
ber_str2bv(default_passwd_hash[i], 0, 0, &bv);
static int
config_schema_dn(ConfigArgs *c) {
- struct berval dn;
- int rc;
- if ( c->emit ) {
- value_add_one(&c->rvalue_vals, &c->be->be_schemadn);
- value_add_one(&c->rvalue_nvals, &c->be->be_schemandn);
- return 0;
+ if ( c->op == SLAP_CONFIG_EMIT ) {
+ int rc = 1;
+ if ( !BER_BVISEMPTY( &c->be->be_schemadn )) {
+ value_add_one(&c->rvalue_vals, &c->be->be_schemadn);
+ value_add_one(&c->rvalue_nvals, &c->be->be_schemandn);
+ rc = 0;
+ }
+ return rc;
}
c->be->be_schemadn = c->value_dn;
c->be->be_schemandn = c->value_ndn;
int i, rc = 0;
char *next;
struct slap_limits_set *lim = &c->be->be_def_limit;
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
char buf[8192];
struct berval bv;
bv.bv_val = buf;
int i, rc = 0;
char *next;
struct slap_limits_set *lim = &c->be->be_def_limit;
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
char buf[8192];
struct berval bv;
bv.bv_val = buf;
static int
config_overlay(ConfigArgs *c) {
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
return 1;
}
if(c->argv[1][0] == '-' && overlay_config(c->be, &c->argv[1][1])) {
Backend *tbe;
struct berval pdn, ndn;
int rc;
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
if ( !BER_BVISNULL( &c->be->be_suffix[0] )) {
value_add( &c->rvalue_vals, c->be->be_suffix );
value_add( &c->rvalue_nvals, c->be->be_nsuffix );
static int
config_rootdn(ConfigArgs *c) {
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
if ( !BER_BVISNULL( &c->be->be_rootdn )) {
value_add_one(&c->rvalue_vals, &c->be->be_rootdn);
value_add_one(&c->rvalue_nvals, &c->be->be_rootndn);
static int
config_rootpw(ConfigArgs *c) {
Backend *tbe;
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
if (!BER_BVISEMPTY(&c->be->be_rootpw)) {
c->value_string=ch_strdup("*");
return 0;
{ BER_BVNULL, 0 }
};
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
return mask_to_verbs( restrictable_ops, c->be->be_restrictops,
&c->rvalue_vals );
}
{ BER_BVC("update_anon"), SLAP_ALLOW_UPDATE_ANON },
{ BER_BVNULL, 0 }
};
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
return mask_to_verbs( allowable_ops, global_allows, &c->rvalue_vals );
}
i = verbs_to_mask(c->argc, c->argv, allowable_ops, &allows);
{ BER_BVC("tls_authc"), SLAP_DISALLOW_TLS_AUTHC },
{ BER_BVNULL, 0 }
};
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
return mask_to_verbs( disallowable_ops, global_disallows, &c->rvalue_vals );
}
i = verbs_to_mask(c->argc, c->argv, disallowable_ops, &disallows);
{ BER_BVC("strong"), SLAP_REQUIRE_STRONG },
{ BER_BVNULL, 0 }
};
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
return mask_to_verbs( requires_ops, c->be->be_requires, &c->rvalue_vals );
}
i = verbs_to_mask(c->argc, c->argv, requires_ops, &requires);
{ BER_BVNULL, 0 }
};
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
return mask_to_verbs( loglevel_ops, ldap_syslog, &c->rvalue_vals );
}
static int
config_syncrepl(ConfigArgs *c) {
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
if ( c->be->be_syncinfo ) {
struct berval bv;
syncrepl_unparse( c->be->be_syncinfo, &bv );
static int
config_referral(ConfigArgs *c) {
struct berval vals[2];
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
if ( default_referral ) {
value_add( &c->rvalue_vals, default_referral );
return 0;
slap_ssf_set_t *set = &c->be->be_ssf_set;
char *next;
int i, j;
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
char numbuf[32];
struct berval bv;
slap_ssf_t *tgt;
char *replicahost, *replicauri;
LDAPURLDesc *ludp;
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
if (c->be->be_replica) {
struct berval bv;
for (i=0;c->be->be_replica[i]; i++) {
config_updatedn(ConfigArgs *c) {
struct berval dn;
int rc;
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
if (!BER_BVISEMPTY(&c->be->be_update_ndn)) {
value_add_one(&c->rvalue_vals, &c->be->be_update_ndn);
value_add_one(&c->rvalue_nvals, &c->be->be_update_ndn);
static int
config_updateref(ConfigArgs *c) {
struct berval vals[2];
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
if ( c->be->be_update_refs ) {
value_add( &c->rvalue_vals, c->be->be_update_refs );
return 0;
ConfigFile *cf;
ConfigFile *cfsave = cfn;
ConfigFile *cf2 = NULL;
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
return 1;
}
cf = ch_calloc( 1, sizeof(ConfigFile));
"unknown tls_option <%x>\n",
c->log, c->type, 0);
}
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
return ldap_pvt_tls_get_option( NULL, flag, &c->value_string );
}
ch_free(c->value_string);
"unknown tls_option <%x>\n",
c->log, c->type, 0);
}
- if (c->emit) {
+ if (c->op == SLAP_CONFIG_EMIT) {
ldap_pvt_tls_get_option( NULL, flag, &c->value_int );
for (i=0; !BER_BVISNULL(&keys[i].word); i++) {
if (keys[i].mask == c->value_int) {
ber_dupbv( bv, &bc );
}
-
-int
-read_config(const char *fname, int depth) {
-
- if ( !backend_db_init( "config" ))
- return 1;
-
- ber_str2bv( fname, 0, 1, &cf_prv.c_file );
- return read_config_file(fname, depth, NULL);
-}
-
-static int
-config_back_bind( Operation *op, SlapReply *rs )
-{
- if ( op->orb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op )) {
- ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ));
- /* frontend sends result */
- return LDAP_SUCCESS;
- }
-
- rs->sr_err = LDAP_INVALID_CREDENTIALS;
- send_ldap_result( op, rs );
-
- return rs->sr_err;
-}
-
static CfEntryInfo *
config_find_base( CfEntryInfo *root, struct berval *dn, CfEntryInfo **last )
{
struct berval cdn;
char *c;
+ if ( !root ) {
+ *last = NULL;
+ return NULL;
+ }
+
if ( dn_match( &root->ce_entry->e_nname, dn ))
return root;
return root;
}
+static int
+config_ldif_resp( Operation *op, SlapReply *rs )
+{
+ if ( rs->sr_type == REP_SEARCH ) {
+ CfBackInfo *cfb = op->o_callback->sc_private;
+ CfEntryInfo *ce, *last;
+
+ cfb->cb_got_ldif = 1;
+ config_find_base( cfb->cb_root, &rs->sr_entry->e_nname, &last );
+ ce = ch_calloc( 1, sizeof(CfEntryInfo) );
+ ce->ce_entry = entry_dup( rs->sr_entry );
+ ce->ce_entry->e_private = ce;
+ if ( !last ) {
+ cfb->cb_root = ce;
+ } else if ( last->ce_kids ) {
+ CfEntryInfo *c2;
+
+ for (c2=last->ce_kids; c2 && c2->ce_sibs; c2 = c2->ce_sibs);
+ c2->ce_sibs = ce;
+ } else {
+ last->ce_kids = ce;
+ }
+ }
+ return 0;
+}
+
+/* Configure and read the underlying back-ldif store */
+static int
+config_setup_ldif( BackendDB *be, const char *dir ) {
+ CfBackInfo *cfb = be->be_private;
+ ConfigArgs c = {0};
+ ConfigTable *ct;
+ char *argv[3];
+ int rc;
+ slap_callback cb = { NULL, config_ldif_resp, NULL, NULL };
+ Connection conn = {0};
+ char opbuf[OPERATION_BUFFER_SIZE];
+ Operation *op;
+ SlapReply rs = {REP_RESULT};
+ Filter filter = { LDAP_FILTER_PRESENT };
+ struct berval filterstr = BER_BVC("(objectclass=*)");
+
+ cfb->cb_db.bd_info = backend_info( "ldif" );
+ if ( !cfb->cb_db.bd_info )
+ return 1;
+
+ if ( cfb->cb_db.bd_info->bi_db_init( &cfb->cb_db )) return 1;
+
+ /* Mark that back-ldif type is in use */
+ cfb->cb_db.bd_info->bi_nDB++;
+
+ cfb->cb_db.be_suffix = be->be_suffix;
+ cfb->cb_db.be_nsuffix = be->be_nsuffix;
+ cfb->cb_db.be_rootdn = be->be_rootdn;
+ cfb->cb_db.be_rootndn = be->be_rootndn;
+
+ ber_str2bv( dir, 0, 1, &cfdir );
+
+ c.be = &cfb->cb_db;
+ c.fname = "slapd";
+ c.argc = 2;
+ argv[0] = "directory";
+ argv[1] = (char *)dir;
+ argv[2] = NULL;
+ c.argv = argv;
+
+ ct = config_find_keyword( c.be->be_cf_table, &c );
+ if ( !ct )
+ return 1;
+
+ if ( config_add_vals( ct, &c ))
+ return 1;
+
+ if ( backend_startup_one( &cfb->cb_db ))
+ return 1;
+
+ op = (Operation *)opbuf;
+ connection_fake_init( &conn, op, cfb );
+
+ filter.f_desc = slap_schema.si_ad_objectClass;
+
+ op->o_tag = LDAP_REQ_SEARCH;
+
+ op->ors_filter = &filter;
+ op->ors_filterstr = filterstr;
+ op->ors_scope = LDAP_SCOPE_SUBTREE;
+
+ op->o_dn = be->be_rootdn;
+ op->o_ndn = be->be_rootndn;
+
+ op->o_req_dn = be->be_suffix[0];
+ op->o_req_ndn = be->be_nsuffix[0];
+
+ op->ors_tlimit = SLAP_NO_LIMIT;
+ op->ors_slimit = SLAP_NO_LIMIT;
+
+ op->ors_attrs = slap_anlist_all_attributes;
+ op->ors_attrsonly = 0;
+
+ op->o_callback = &cb;
+ cb.sc_private = cfb;
+
+ op->o_bd = &cfb->cb_db;
+ op->o_bd->be_search( op, &rs );
+
+ return 0;
+}
+
+static int
+CfOcInfo_cmp( const void *c1, const void *c2 ) {
+ const CfOcInfo *co1 = c1;
+ const CfOcInfo *co2 = c2;
+
+ return ber_bvcmp( co1->co_name, co2->co_name );
+}
+
+int
+config_register_schema(ConfigTable *ct, ConfigOCs *ocs) {
+ int i;
+ CfOcInfo *co;
+
+ i = init_config_attrs( ct );
+ if ( i ) return i;
+
+ /* set up the objectclasses */
+ i = init_config_ocs( ocs );
+ if ( i ) return i;
+
+ for (i=0; ocs[i].def; i++) {
+ if ( ocs[i].oc ) {
+ co = ch_malloc( sizeof(CfOcInfo) );
+ co->co_name = &(*ocs[i].oc)->soc_cname;
+ co->co_table = ct;
+ avl_insert( &CfOcTree, co, CfOcInfo_cmp, avl_dup_error );
+ }
+ }
+ return 0;
+}
+
+int
+read_config(const char *fname, const char *dir) {
+ BackendDB *be;
+
+ /* Setup the config backend */
+ be = backend_db_init( "config" );
+ if ( !be )
+ return 1;
+
+ /* Setup the underlying back-ldif backend */
+ if ( config_setup_ldif( be, dir ))
+ return 1;
+
+#if 0 /* not yet
+ /* If we read the config from back-ldif, nothing to do here */
+ if ( cfb->cb_got_ldif )
+ return 0;
+#endif
+ ber_str2bv( fname, 0, 1, &cf_prv.c_file );
+
+ return read_config_file(fname, 0, NULL);
+}
+
+static int
+config_back_bind( Operation *op, SlapReply *rs )
+{
+ if ( op->orb_method == LDAP_AUTH_SIMPLE && be_isroot_pw( op )) {
+ ber_dupbv( &op->orb_edn, be_root_dn( op->o_bd ));
+ /* frontend sends result */
+ return LDAP_SUCCESS;
+ }
+
+ rs->sr_err = LDAP_INVALID_CREDENTIALS;
+ send_ldap_result( op, rs );
+
+ return rs->sr_err;
+}
+
static int
config_send( Operation *op, SlapReply *rs, CfEntryInfo *ce, int depth )
{
goto out;
}
ldap_pvt_thread_pool_pause( &connection_pool );
+
+ /* Strategy:
+ * 1) perform the Modify on the cached Entry.
+ * 2) verify that the Entry still satisfies the schema.
+ * 3) perform the individual config operations.
+ * 4) store Modified entry in underlying LDIF backend.
+ */
ldap_pvt_thread_pool_resume( &connection_pool );
out:
send_ldap_result( op, rs );
vals[0] = oc->soc_cname;
attr_merge(e, slap_schema.si_ad_objectClass, vals, NULL );
+ attr_merge(e, slap_schema.si_ad_structuralObjectClass, vals, NULL );
ptr = strchr(rdn->bv_val, '=');
ad_name.bv_val = rdn->bv_val;
ad_name.bv_len = ptr - rdn->bv_val;
if ((*at)->sat_ad == ad || (*at)->sat_ad == slap_schema.si_ad_cn )
continue;
for (i=0;ct[i].name;i++) {
- if (ct[i].ad == (*at)->sat_ad)
+ if (ct[i].ad == (*at)->sat_ad) {
+ rc = config_get_vals(&ct[i], c);
+ if (rc == LDAP_SUCCESS) {
+ attr_merge(e, ct[i].ad, c->rvalue_vals, c->rvalue_nvals);
+ ber_bvarray_free( c->rvalue_nvals );
+ ber_bvarray_free( c->rvalue_vals );
+ }
break;
- }
- rc = config_get_vals(&ct[i], c);
- if (rc == LDAP_SUCCESS) {
- attr_merge(e, ct[i].ad, c->rvalue_vals, c->rvalue_nvals);
- ber_bvarray_free( c->rvalue_nvals );
- ber_bvarray_free( c->rvalue_vals );
+ }
}
}
if ((*at)->sat_ad == ad || (*at)->sat_ad == slap_schema.si_ad_cn )
continue;
for (i=0;ct[i].name;i++) {
- if (ct[i].ad == (*at)->sat_ad)
+ if (ct[i].ad == (*at)->sat_ad) {
+ rc = config_get_vals(&ct[i], c);
+ if (rc == LDAP_SUCCESS) {
+ attr_merge(e, ct[i].ad, c->rvalue_vals, c->rvalue_nvals);
+ ber_bvarray_free( c->rvalue_nvals );
+ ber_bvarray_free( c->rvalue_vals );
+ }
break;
- }
- rc = config_get_vals(&ct[i], c);
- if (rc == LDAP_SUCCESS) {
- attr_merge(e, ct[i].ad, c->rvalue_vals, c->rvalue_nvals);
- ber_bvarray_free( c->rvalue_nvals );
- ber_bvarray_free( c->rvalue_vals );
+ }
}
}
}
static CfEntryInfo *
-config_build_includes( ConfigArgs *c, Entry *parent )
+config_build_includes( ConfigArgs *c, Entry *parent,
+ Operation *op, SlapReply *rs )
{
Entry *e;
int i;
c->line = (char *)cf;
config_build_entry( c, e, cfOc_include, &c->value_dn,
c->bi->bi_cf_table, NO_TABLE );
+ op->ora_e = e;
+ op->o_bd->be_add( op, rs );
ce = e->e_private;
+ ce->ce_type = Cf_Include;
+ ce->ce_bi = c->bi;
if ( !ceparent->ce_kids ) {
ceparent->ce_kids = ce;
} else {
ceprev = ce;
if ( cf->c_kids ) {
c->line = (char *)cf->c_kids;
- config_build_includes( c, e );
+ config_build_includes( c, e, op, rs );
}
}
return ce;
BackendDB *bptr;
ConfigArgs c;
ConfigTable *ct;
+ Connection conn = {0};
+ char opbuf[OPERATION_BUFFER_SIZE];
+ Operation *op;
+ slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
+ SlapReply rs = {REP_RESULT};
+
+ /* If we read the config from back-ldif, nothing to do here */
+ if ( cfb->cb_got_ldif )
+ return 0;
+
+ op = (Operation *)opbuf;
+ connection_fake_init( &conn, op, cfb );
+
+ op->o_dn = be->be_rootdn;
+ op->o_ndn = be->be_rootndn;
+
+ op->o_tag = LDAP_REQ_ADD;
+ op->o_callback = &cb;
+ op->o_bd = &cfb->cb_db;
/* create root of tree */
rdn = config_rdn;
c.line = (char *)cfb->cb_config;
ct = c.bi->bi_cf_table;
config_build_entry( &c, e, cfOc_global, &rdn, ct, NO_TABLE );
+ op->ora_e = e;
+ op->o_bd->be_add( op, &rs );
+ ce->ce_type = Cf_Global;
+ ce->ce_bi = c.bi;
parent = e;
ceparent = ce;
/* Create includeFile nodes... */
if ( cfb->cb_config->c_kids ) {
c.line = (char *)cfb->cb_config->c_kids;
- ceprev = config_build_includes( &c, parent );
+ ceprev = config_build_includes( &c, parent, op, &rs );
}
/* Create backend nodes. Skip if they don't provide a cf_table.
rdn.bv_len = sprintf(rdn.bv_val, "%s=%s", cfAd_backend->ad_cname.bv_val, bi->bi_type);
e = config_alloc_entry( &parent->e_nname, &rdn );
ce = e->e_private;
+ ce->ce_type = Cf_Backend;
ce->ce_bi = bi;
c.bi = bi;
config_build_entry( &c, e, cfOc_backend, &rdn, ct, BI_TABLE );
+ op->ora_e = e;
+ op->o_bd->be_add( op, &rs );
if ( !ceparent->ce_kids ) {
ceparent->ce_kids = ce;
} else {
ce = e->e_private;
c.be = bptr;
c.bi = bi;
+ ce->ce_type = Cf_Database;
ce->ce_be = c.be;
ce->ce_bi = c.bi;
config_build_entry( &c, e, cfOc_database, &rdn, ct, BE_TABLE );
+ op->ora_e = e;
+ op->o_bd->be_add( op, &rs );
if ( !ceparent->ce_kids ) {
ceparent->ce_kids = ce;
} else {
ce = oe->e_private;
c.be = bptr;
c.bi = &on->on_bi;
+ ce->ce_type = Cf_Overlay;
ce->ce_be = c.be;
ce->ce_bi = c.bi;
config_build_entry( &c, oe, cfOc_overlay, &rdn, ct, BI_TABLE );
+ op->ora_e = oe;
+ op->o_bd->be_add( op, &rs );
if ( !opar->ce_kids ) {
opar->ce_kids = ce;
} else {
oprev = ce;
}
}
- /* Set up ACLs */
- if ( bptr->be_acl ) {
- Entry *ae;
- CfEntryInfo *opar = ce;
-
- ae = config_alloc_entry( &e->e_nname, &access_rdn );
- ce = ae->e_private;
- c.be = bptr;
- c.bi = bi;
- ce->ce_be = c.be;
- ce->ce_bi = c.bi;
- config_build_entry( &c, ae, cfOc_access, &access_rdn, ct,
- NO_TABLE );
- if ( opar->ce_kids ) {
- ce->ce_sibs = opar->ce_kids;
- }
- opar->ce_kids = ce;
- }
}
return 0;
ber_dupbv( &dn, &be->be_rootdn );
ber_bvarray_add( &be->be_nsuffix, &dn );
+ /* Hide from namingContexts */
+ SLAP_BFLAGS(be) |= SLAP_BFLAG_CONFIG;
+
return 0;
}
parse_oidm( "slapd", i, 3, argv );
}
- i = init_config_attrs( ct );
+ bi->bi_cf_table = ct;
+
+ i = config_register_schema( ct, cf_ocs );
if ( i ) return i;
/* set up the notable AttributeDescriptions */
ads[3].sub = slap_schema.si_ad_ditContentRules;
ads[5].sub = slap_schema.si_ad_objectClasses;
- bi->bi_cf_table = ct;
-
i = 0;
for (;ct->name;ct++) {
if (strcmp(ct->name, ads[i].name)) continue;
if (!ads[i].name) break;
}
- /* set up the objectclasses */
- i = init_config_ocs( cf_ocs );
-
- return i;
+ return 0;
}
char *slapd_pid_file = NULL;
char *slapd_args_file = NULL;
-char *strtok_quote_ptr;
-
int use_reverse_lookup = 0;
#ifdef LDAP_SLAPI
static void fp_getline_init(ConfigArgs *c);
static int fp_parse_line(ConfigArgs *c);
-static char *strtok_quote(char *line, char *sep);
+static char *strtok_quote(char *line, char *sep, char **quote_ptr);
int read_config_file(const char *fname, int depth, ConfigArgs *cf);
return(c);
}
-int parse_config_table(ConfigTable *Conf, ConfigArgs *c) {
+ConfigTable *config_find_keyword(ConfigTable *Conf, ConfigArgs *c) {
+ int i;
+
+ for(i = 0; Conf[i].name; i++)
+ if( (Conf[i].length && (!strncasecmp(c->argv[0], Conf[i].name, Conf[i].length))) ||
+ (!strcasecmp(c->argv[0], Conf[i].name)) ) break;
+ if ( !Conf[i].name ) return NULL;
+ return Conf+i;
+}
+
+int config_add_vals(ConfigTable *Conf, ConfigArgs *c) {
int i, rc, arg_user, arg_type, iarg;
long larg;
ber_len_t barg;
void *ptr;
- for(i = 0; Conf[i].name; i++)
- if( (Conf[i].length && (!strncasecmp(c->argv[0], Conf[i].name, Conf[i].length))) ||
- (!strcasecmp(c->argv[0], Conf[i].name)) ) break;
- if(!Conf[i].name) return(ARG_UNKNOWN);
- arg_type = Conf[i].arg_type;
+ arg_type = Conf->arg_type;
if(arg_type == ARG_IGNORED) {
Debug(LDAP_DEBUG_CONFIG, "%s: keyword <%s> ignored\n",
- c->log, Conf[i].name, 0);
+ c->log, Conf->name, 0);
return(0);
}
- if(Conf[i].min_args && (c->argc < Conf[i].min_args)) {
+ if(Conf->min_args && (c->argc < Conf->min_args)) {
Debug(LDAP_DEBUG_CONFIG, "%s: keyword <%s> missing <%s> argument\n",
- c->log, Conf[i].name, Conf[i].what);
+ c->log, Conf->name, Conf->what);
return(ARG_BAD_CONF);
}
- if(Conf[i].max_args && (c->argc > Conf[i].max_args)) {
+ if(Conf->max_args && (c->argc > Conf->max_args)) {
Debug(LDAP_DEBUG_CONFIG, "%s: extra cruft after <%s> in <%s> line (ignored)\n",
- c->log, Conf[i].what, Conf[i].name);
+ c->log, Conf->what, Conf->name);
}
if((arg_type & ARG_DB) && !c->be) {
Debug(LDAP_DEBUG_CONFIG, "%s: keyword <%s> allowed only within database declaration\n",
- c->log, Conf[i].name, 0);
+ c->log, Conf->name, 0);
return(ARG_BAD_CONF);
}
if((arg_type & ARG_PRE_BI) && c->bi) {
Debug(LDAP_DEBUG_CONFIG, "%s: keyword <%s> must appear before any backend %sdeclaration\n",
- c->log, Conf[i].name, ((arg_type & ARG_PRE_DB)
+ c->log, Conf->name, ((arg_type & ARG_PRE_DB)
? "or database " : "") );
return(ARG_BAD_CONF);
}
if((arg_type & ARG_PRE_DB) && c->be && c->be != frontendDB) {
Debug(LDAP_DEBUG_CONFIG, "%s: keyword <%s> must appear before any database declaration\n",
- c->log, Conf[i].name, 0);
+ c->log, Conf->name, 0);
return(ARG_BAD_CONF);
}
if((arg_type & ARG_PAREN) && *c->argv[1] != '(' /*')'*/) {
Debug(LDAP_DEBUG_CONFIG, "%s: old <%s> format not supported\n",
- c->log, Conf[i].name, 0);
+ c->log, Conf->name, 0);
return(ARG_BAD_CONF);
}
- if((arg_type & ARGS_POINTER) && !Conf[i].arg_item) {
+ if((arg_type & ARGS_POINTER) && !Conf->arg_item && !(arg_type & ARG_OFFSET)) {
Debug(LDAP_DEBUG_CONFIG, "%s: null arg_item for <%s>\n",
- c->log, Conf[i].name, 0);
+ c->log, Conf->name, 0);
return(ARG_BAD_CONF);
}
c->type = arg_user = (arg_type & ARGS_USERLAND);
} else {
Debug(LDAP_DEBUG_CONFIG, "%s: ignoring ", c->log, 0, 0);
Debug(LDAP_DEBUG_CONFIG, "invalid %s value (%s) in <%s> line\n",
- Conf[i].what, c->argv[1], Conf[i].name);
+ Conf->what, c->argv[1], Conf->name);
return(0);
}
break;
if(iarg < j || larg < j || barg < j ) {
larg = larg ? larg : (barg ? barg : iarg);
Debug(LDAP_DEBUG_CONFIG, "%s: " , c->log, 0, 0);
- Debug(LDAP_DEBUG_CONFIG, "invalid %s value (%ld) in <%s> line\n", Conf[i].what, larg, Conf[i].name);
+ Debug(LDAP_DEBUG_CONFIG, "invalid %s value (%ld) in <%s> line\n", Conf->what, larg, Conf->name);
return(ARG_BAD_CONF);
}
switch(arg_type & ARGS_NUMERIC) {
case ARG_BER_LEN_T: c->value_ber_t = barg; break;
}
} else if(arg_type & ARG_STRING) {
- c->value_string = ch_strdup(c->argv[1]);
+ c->value_string = ch_strdup(c->argv[1]);
+ } else if(arg_type & ARG_BERVAL) {
+ ber_str2bv( c->argv[1], 0, 1, &c->value_bv );
} else if(arg_type & ARG_DN) {
struct berval bv;
ber_str2bv( c->argv[1], 0, 0, &bv );
if ( rc != LDAP_SUCCESS ) {
Debug(LDAP_DEBUG_CONFIG, "%s: " , c->log, 0, 0);
Debug(LDAP_DEBUG_CONFIG, "%s DN is invalid %d (%s)\n",
- Conf[i].name, rc, ldap_err2string( rc ));
+ Conf->name, rc, ldap_err2string( rc ));
return(ARG_BAD_CONF);
}
}
if(arg_type & ARG_MAGIC) {
if(!c->be) c->be = frontendDB;
- rc = (*((ConfigDriver*)Conf[i].arg_item))(c);
+ rc = (*((ConfigDriver*)Conf->arg_item))(c);
if(c->be == frontendDB) c->be = NULL;
if(rc) {
- Debug(LDAP_DEBUG_CONFIG, "%s: handler for <%s> exited with %d!",
- c->log, Conf[i].name, rc);
+ Debug(LDAP_DEBUG_CONFIG, "%s: handler for <%s> exited with %d!\n",
+ c->log, Conf->name, rc);
return(ARG_BAD_CONF);
}
return(0);
else if (c->bi)
ptr = c->bi->bi_private;
else {
- Debug(LDAP_DEBUG_CONFIG, "%s: offset for <%s> missing base pointer!",
- c->log, Conf[i].name, 0);
+ Debug(LDAP_DEBUG_CONFIG, "%s: offset for <%s> missing base pointer!\n",
+ c->log, Conf->name, 0);
return(ARG_BAD_CONF);
}
- ptr = (void *)((char *)ptr + (int)Conf[i].arg_item);
+ ptr = (void *)((char *)ptr + (int)Conf->arg_item);
} else if (arg_type & ARGS_POINTER) {
- ptr = Conf[i].arg_item;
+ ptr = Conf->arg_item;
}
- if(arg_type & ARGS_POINTER) switch(arg_type & ARGS_POINTER) {
+ if(arg_type & ARGS_POINTER)
+ switch(arg_type & ARGS_POINTER) {
case ARG_ON_OFF:
case ARG_INT: *(int*)ptr = iarg; break;
case ARG_LONG: *(long*)ptr = larg; break;
if(cc) {
if (arg_type & ARG_UNIQUE) {
Debug(LDAP_DEBUG_CONFIG, "%s: already set %s!\n",
- c->log, Conf[i].name, 0 );
+ c->log, Conf->name, 0 );
return(ARG_BAD_CONF);
}
ch_free(cc); /* potential memory leak */
*(char **)ptr = c->value_string;
break;
}
- }
+ case ARG_BERVAL:
+ *(struct berval *)ptr = c->value_bv;
+ break;
+ }
return(arg_user);
}
+int
+config_del_vals(ConfigTable *cf, ConfigArgs *c)
+{
+ int rc = 0;
+}
+
int
config_get_vals(ConfigTable *cf, ConfigArgs *c)
{
memset(&c->values, 0, sizeof(c->values));
c->rvalue_vals = NULL;
c->rvalue_nvals = NULL;
- c->emit = 1;
+ c->op = SLAP_CONFIG_EMIT;
c->type = cf->arg_type & ARGS_USERLAND;
if ( cf->arg_type & ARG_MAGIC ) {
if ( *(char **)ptr )
c->value_string = ch_strdup(*(char **)ptr);
break;
+ case ARG_BERVAL:
+ ber_dupbv( &c->value_bv, (struct berval *)ptr ); break;
}
}
if ( cf->arg_type & ARGS_POINTER) {
bv.bv_val = c->log;
switch(cf->arg_type & ARGS_POINTER) {
case ARG_INT: bv.bv_len = sprintf(bv.bv_val, "%d", c->value_int); break;
- case ARG_LONG: bv.bv_len = sprintf(bv.bv_val, "%l", c->value_long); break;
- case ARG_BER_LEN_T: bv.bv_len =sprintf(bv.bv_val, "%l",c->value_ber_t); break;
+ case ARG_LONG: bv.bv_len = sprintf(bv.bv_val, "%ld", c->value_long); break;
+ case ARG_BER_LEN_T: bv.bv_len = sprintf(bv.bv_val, "%ld", c->value_ber_t); break;
case ARG_ON_OFF: bv.bv_len = sprintf(bv.bv_val, "%s",
c->value_int ? "TRUE" : "FALSE"); break;
case ARG_STRING:
return 1;
}
break;
+ case ARG_BERVAL:
+ if ( !BER_BVISEMPTY( &c->value_bv )) {
+ bv = c->value_bv;
+ } else {
+ return 1;
+ }
+ break;
}
if (( cf->arg_type & ARGS_POINTER ) == ARG_STRING )
ber_bvarray_add(&c->rvalue_vals, &bv);
read_config_file(const char *fname, int depth, ConfigArgs *cf)
{
FILE *fp;
+ ConfigTable *ct;
ConfigArgs *c;
int rc;
snprintf( c->log, sizeof( c->log ), "%s: line %lu",
c->fname, c->lineno );
+ c->argc = 0;
if ( fp_parse_line( c ) ) {
goto badline;
}
continue;
}
- rc = parse_config_table( config_back_cf_table, c );
- if ( !rc ) {
- continue;
- }
- if ( rc & ARGS_USERLAND ) {
- switch(rc) { /* XXX a usertype would be opaque here */
- default:
- Debug(LDAP_DEBUG_CONFIG, "%s: unknown user type <%d>\n",
- c->log, *c->argv, 0);
+ c->op = LDAP_MOD_ADD;
+
+ ct = config_find_keyword( config_back_cf_table, c );
+ if ( ct ) {
+ rc = config_add_vals( ct, c );
+ if ( !rc ) continue;
+
+ if ( rc & ARGS_USERLAND ) {
+ /* XXX a usertype would be opaque here */
+ Debug(LDAP_DEBUG_CONFIG, "%s: unknown user type <%s>\n",
+ c->log, c->argv[0], 0);
goto badline;
- }
- } else if ( rc == ARG_BAD_CONF || rc != ARG_UNKNOWN ) {
- goto badline;
+ } else if ( rc == ARG_BAD_CONF ) {
+ goto badline;
+ }
- } else if ( c->bi && c->bi->bi_config ) { /* XXX to check: could both be/bi_config? oops */
- rc = (*c->bi->bi_config)(c->bi, c->fname, c->lineno, c->argc, c->argv);
+ } else if ( c->bi ) {
+ rc = SLAP_CONF_UNKNOWN;
+ if ( c->bi->bi_cf_table ) {
+ ct = config_find_keyword( c->bi->bi_cf_table, c );
+ if ( ct ) {
+ rc = config_add_vals( ct, c );
+ }
+ }
+ if ( c->bi->bi_config && rc == SLAP_CONF_UNKNOWN ) {
+ rc = (*c->bi->bi_config)(c->bi, c->fname, c->lineno,
+ c->argc, c->argv);
+ }
if ( rc ) {
switch(rc) {
case SLAP_CONF_UNKNOWN:
Debug(LDAP_DEBUG_CONFIG, "%s: "
"unknown directive <%s> inside backend info definition (ignored)\n",
- c->log, *c->argv, 0);
+ c->log, *c->argv, 0);
continue;
default:
goto badline;
}
}
-
+
} else if ( c->be ) {
+ rc = SLAP_CONF_UNKNOWN;
if ( c->be->be_cf_table ) {
- rc = parse_config_table( c->be->be_cf_table, c );
-
- if ( !rc ) continue;
-
- if ( rc != ARG_UNKNOWN ) goto badline;
+ ct = config_find_keyword( c->be->be_cf_table, c );
+ if ( ct ) {
+ rc = config_add_vals( ct, c );
+ }
}
-
- if ( c->be->be_config ) {
+ if ( c->be->be_config && rc == SLAP_CONF_UNKNOWN ) {
rc = (*c->be->be_config)(c->be, c->fname, c->lineno,
c->argc, c->argv);
- if ( rc ) {
- switch(rc) {
- case SLAP_CONF_UNKNOWN:
- Debug( LDAP_DEBUG_CONFIG, "%s: "
- "unknown directive <%s> inside backend database "
- "definition (ignored)\n",
- c->log, *c->argv, 0);
- continue;
- default:
- goto badline;
- }
+ }
+ if ( rc ) {
+ switch(rc) {
+ case SLAP_CONF_UNKNOWN:
+ Debug( LDAP_DEBUG_CONFIG, "%s: "
+ "unknown directive <%s> inside backend database "
+ "definition (ignored)\n",
+ c->log, *c->argv, 0);
+ continue;
+ default:
+ goto badline;
}
}
static char *
-strtok_quote( char *line, char *sep )
+strtok_quote( char *line, char *sep, char **quote_ptr )
{
int inquote;
char *tmp;
static char *next;
- strtok_quote_ptr = NULL;
+ *quote_ptr = NULL;
if ( line != NULL ) {
next = line;
}
default:
if ( ! inquote ) {
if ( strchr( sep, *next ) != NULL ) {
- strtok_quote_ptr = next;
+ *quote_ptr = next;
*next++ = '\0';
return( tmp );
}
char *token;
char *tline = ch_strdup(c->line);
char *hide[] = { "rootpw", "replica", "bindpw", "pseudorootpw", "dbpasswd", '\0' };
+ char *quote_ptr;
int i;
- c->argc = 0;
- token = strtok_quote(tline, " \t");
+ token = strtok_quote(tline, " \t", "e_ptr);
if(token) for(i = 0; hide[i]; i++) if(!strcasecmp(token, hide[i])) break;
- if(strtok_quote_ptr) *strtok_quote_ptr = ' ';
- Debug(LDAP_DEBUG_CONFIG, "line %lu (%s%s)\n", c->lineno, hide[i] ? hide[i] : c->line, hide[i] ? " ***" : "");
- if(strtok_quote_ptr) *strtok_quote_ptr = '\0';
+ if(quote_ptr) *quote_ptr = ' ';
+ Debug(LDAP_DEBUG_CONFIG, "line %lu (%s%s)\n", c->lineno,
+ hide[i] ? hide[i] : c->line, hide[i] ? " ***" : "");
+ if(quote_ptr) *quote_ptr = '\0';
- for(; token; token = strtok_quote(NULL, " \t")) {
+ for(; token; token = strtok_quote(NULL, " \t", "e_ptr)) {
if(c->argc == c->argv_size - 1) {
char **tmp;
tmp = ch_realloc(c->argv, (c->argv_size + ARGS_STEP) * sizeof(*c->argv));
free( str );
return( *out );
}
+
+int config_generic_wrapper( Backend *be, const char *fname, int lineno,
+ int argc, char **argv )
+{
+ ConfigArgs c = { 0 };
+ ConfigTable *ct;
+ int rc;
+
+ c.be = be;
+ c.fname = fname;
+ c.lineno = lineno;
+ c.argc = argc;
+ c.argv = argv;
+ sprintf( c.log, "%s: line %lu", fname, lineno );
+
+ rc = SLAP_CONF_UNKNOWN;
+ ct = config_find_keyword( be->be_cf_table, &c );
+ if ( ct )
+ rc = config_add_vals( ct, &c );
+ return rc;
+}
#define ARGS_USERLAND 0x00000fff
#define ARGS_TYPES 0x000ff000
-#define ARGS_POINTER 0x0001f000
+#define ARGS_POINTER 0x0003f000
#define ARGS_NUMERIC 0x0000f000
#define ARG_INT 0x00001000
#define ARG_LONG 0x00002000
#define ARG_BER_LEN_T 0x00004000
#define ARG_ON_OFF 0x00008000
#define ARG_STRING 0x00010000
-#define ARG_DN 0x00020000
-#define ARG_EXISTS 0x00040000 /* XXX not yet */
+#define ARG_BERVAL 0x00020000
+#define ARG_DN 0x00040000
#define ARG_IGNORED 0x00080000
#define ARGS_SYNTAX 0xfff00000
long v_long;
ber_len_t v_ber_t;
char *v_string;
+ struct berval v_bv;
struct {
struct berval vdn_dn;
struct berval vdn_ndn;
/* return values for emit mode */
BerVarray rvalue_vals;
BerVarray rvalue_nvals;
- int emit; /* emit instead of setting */
+#define SLAP_CONFIG_EMIT 0x2000 /* emit instead of set */
+ int op;
int type; /* ConfigTable.arg_type & ARGS_USERLAND */
BackendDB *be;
BackendInfo *bi;
#define value_long values.v_long
#define value_ber_t values.v_ber_t
#define value_string values.v_string
+#define value_bv values.v_bv
#define value_dn values.v_dn.vdn_dn
#define value_ndn values.v_dn.vdn_ndn
typedef int (ConfigDriver)(ConfigArgs *c);
+int config_register_schema(ConfigTable *ct, ConfigOCs *co);
int config_get_vals(ConfigTable *ct, ConfigArgs *c);
+int config_add_vals(ConfigTable *ct, ConfigArgs *c);
+ConfigTable * config_find_keyword(ConfigTable *ct, ConfigArgs *c);
case AF_LOCAL:
#ifdef LOCAL_CREDS
{
- int one = 1;
- setsockopt(l.sl_sd, 0, LOCAL_CREDS, &one, sizeof one);
+ int one = 1;
+ setsockopt(l.sl_sd, 0, LOCAL_CREDS, &one, sizeof one);
}
#endif
addrlen = sizeof(struct sockaddr_un);
}
ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
- if ( cat != NULL ) {
+ if ( cat && cat->tv_sec ) {
time_t diff = difftime( cat->tv_sec, now );
if ( diff == 0 )
diff = tdelta;
{
struct berval pdn = BER_BVNULL;
int manageDSAit;
+ BackendDB *op_be;
manageDSAit = get_manageDSAit( op );
goto cleanup;
}
+ /* If we've got a glued backend, check the real backend */
+ op_be = op->o_bd;
+ if ( SLAP_GLUE_INSTANCE( op->o_bd )) {
+ op->o_bd = select_backend( &op->o_req_ndn, manageDSAit, 0 );
+ }
+
/* check restrictions */
if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) {
send_ldap_result( op, rs );
int org_managedsait;
slap_callback cb = { NULL, slap_replog_cb, NULL, NULL };
+ op->o_bd = op_be;
+
if ( !repl_user ) {
struct berval csn = BER_BVNULL;
char csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
#ifdef HAVE_NT_SERVICE_MANAGER
char *configfile = ".\\slapd.conf";
+ char *configdir = ".\\slapd.d";
#else
char *configfile = SLAPD_DEFAULT_CONFIGFILE;
+ char *configdir = SLAPD_DEFAULT_CONFIGDIR;
#endif
char *serverName;
int serverMode = SLAP_SERVER_MODE;
{
int *i;
char *newConfigFile;
+ char *newConfigDir;
char *newUrls;
char *regService = NULL;
configfile = newConfigFile;
Debug ( LDAP_DEBUG_ANY, "new config file from registry is: %s\n", configfile, 0, 0 );
}
+
+ newConfigDir = (char*)lutil_getRegParam( regService, "ConfigDir" );
+ if ( newConfigDir != NULL ) {
+ configdir = newConfigDir;
+ Debug ( LDAP_DEBUG_ANY, "new config dir from registry is: %s\n", configdir, 0, 0 );
+ }
}
#endif
while ( (i = getopt( argc, argv,
- "c:d:f:h:n:o:s:StT:V"
+ "c:d:f:F:h:n:o:s:StT:V"
#if LDAP_PF_INET6
"46"
#endif
configfile = ch_strdup( optarg );
break;
+ case 'F': /* use config dir */
+ configdir = ch_strdup( optarg );
+ break;
+
case 'o': {
char *val = strchr( optarg, '=' );
struct berval opt;
}
#endif /* SLAP_DYNACL */
- if ( read_config( configfile, 0 ) != 0 ) {
+ if ( read_config( configfile, configdir ) != 0 ) {
rc = 1;
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 );
#endif
int increment = op->orm_increment;
int rc = 0;
+ BackendDB *op_be;
if( op->o_req_ndn.bv_len == 0 ) {
Debug( LDAP_DEBUG_ANY, "do_modify: root dse!\n", 0, 0, 0 );
goto cleanup;
}
+ /* If we've got a glued backend, check the real backend */
+ op_be = op->o_bd;
+ if ( SLAP_GLUE_INSTANCE( op->o_bd )) {
+ op->o_bd = select_backend( &op->o_req_ndn, manageDSAit, 0 );
+ }
+
/* check restrictions */
if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) {
send_ldap_result( op, rs );
size_t textlen = sizeof( textbuf );
slap_callback cb = { NULL, slap_replog_cb, NULL, NULL };
+ op->o_bd = op_be;
if ( !update ) {
rs->sr_err = slap_mods_no_update_check( modlist,
Backend *newSuperior_be = NULL;
int manageDSAit;
struct berval pdn = BER_BVNULL;
+ BackendDB *op_be;
if( op->o_req_ndn.bv_len == 0 ) {
Debug( LDAP_DEBUG_ANY, "do_modrdn: root dse!\n", 0, 0, 0 );
goto cleanup;
}
+ /* If we've got a glued backend, check the real backend */
+ op_be = op->o_bd;
+ if ( SLAP_GLUE_INSTANCE( op->o_bd )) {
+ op->o_bd = select_backend( &op->o_req_ndn, manageDSAit, 0 );
+ }
+
/* check restrictions */
if( backend_check_restrictions( op, rs, NULL ) != LDAP_SUCCESS ) {
send_ldap_result( op, rs );
#endif
{
slap_callback cb = { NULL, slap_replog_cb, NULL, NULL };
+
+ op->o_bd = op_be;
+
#ifdef SLAPD_MULTIMASTER
if ( !op->o_bd->be_update_ndn.bv_len || !repl_user )
#endif
switch (op->ors_scope) {
case LDAP_SCOPE_BASE:
- return SLAP_CB_CONTINUE;
+ rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ if (op->o_bd && op->o_bd->be_search) {
+ rs->sr_err = op->o_bd->be_search( op, rs );
+ }
+ return rs->sr_err;
case LDAP_SCOPE_ONELEVEL:
case LDAP_SCOPE_SUBTREE:
int i, nhash;
char **hashes;
int rc;
+ BackendDB *op_be;
cb2.sc_next = &cb;
goto error_return;
}
+ /* If we've got a glued backend, check the real backend */
+ op_be = op->o_bd;
+ if ( SLAP_GLUE_INSTANCE( op->o_bd )) {
+ op->o_bd = select_backend( &op->o_req_ndn, 0, 0 );
+ }
+
if (backend_check_restrictions( op, rs,
(struct berval *)&slap_EXOP_MODIFY_PASSWD ) != LDAP_SUCCESS) {
rc = rs->sr_err;
goto error_return;
}
+ op->o_bd = op_be;
+
/* Give the backend a chance to handle this itself */
if ( op->o_bd->be_extended ) {
rs->sr_err = op->o_bd->be_extended( op, rs );
/*
* config.c
*/
-LDAP_SLAPD_F (int) read_config LDAP_P(( const char *fname, int depth ));
+LDAP_SLAPD_F (int) read_config LDAP_P(( const char *fname, const char *dir ));
LDAP_SLAPD_F (void) config_destroy LDAP_P ((void));
LDAP_SLAPD_F (char **) slap_str2clist LDAP_P((
char ***, char *, const char * ));
LDAP_SLAPD_F (int) bindconf_unparse LDAP_P((
slap_bindconf *bc, struct berval *bv ));
LDAP_SLAPD_F (void) bindconf_free LDAP_P(( slap_bindconf *bc ));
+LDAP_SLAPD_F (int) config_generic_wrapper LDAP_P(( Backend *be,
+ const char *fname, int lineno, int argc, char **argv ));
#ifdef LDAP_SLAPI
LDAP_SLAPD_V (int) slapi_plugins_used;
* should just set SLAPI_RESULT_CODE rather than sending a
* result if they wish to change the result.
*/
- if ( op->o_pb != NULL ) {
+ if ( op->o_callback == NULL && op->o_pb != NULL ) {
slapi_int_pblock_set_operation( op->o_pb, op );
slapi_pblock_set( op->o_pb, SLAPI_RESULT_CODE,
(void *)rs->sr_err );
}
if( extensible ) {
+ *text = NULL;
return LDAP_SUCCESS;
}
}
}
+ *text = NULL;
return LDAP_SUCCESS;
}
LDAP_BEGIN_DECL
-#ifdef LDAP_DEVEL
#define SLAP_ACL_HONOR_DISCLOSE /* partially implemented */
+
+#ifdef LDAP_DEVEL
#define SLAP_DYNACL
-#define LDAP_COMP_MATCH /* experimental */
+#define LDAP_COMP_MATCH
#define LDAP_DYNAMIC_OBJECTS
#define LDAP_SYNC_TIMESTAMP
#define LDAP_COLLECTIVE_ATTRIBUTES
#define SLAP_CONTROL_X_TREE_DELETE LDAP_CONTROL_X_TREE_DELETE
+
+#ifdef ENABLE_REWRITE
+#define SLAP_AUTH_REWRITE 1 /* use librewrite for sasl-regexp */
+#endif
#endif
-#if defined(LDAP_DEVEL) && defined(ENABLE_REWRITE)
-/* use librewrite for sasl-regexp */
-#define SLAP_AUTH_REWRITE 1
-#endif /* LDAP_DEVEL && ENABLE_REWRITE */
/*
* SLAPD Memory allocation macros
AttributeDescription *si_ad_monitorContext;
AttributeDescription *si_ad_vendorName;
AttributeDescription *si_ad_vendorVersion;
+ AttributeDescription *si_ad_configContext;
/* subentry attribute descriptions */
AttributeDescription *si_ad_administrativeRole;
slap_mask_t bi_flags; /* backend flags */
#define SLAP_BFLAG_MONITOR 0x0001U /* a monitor backend */
+#define SLAP_BFLAG_CONFIG 0x0002U /* a config backend */
#define SLAP_BFLAG_NOLASTMODCMD 0x0010U
#define SLAP_BFLAG_INCREMENT 0x0100U
#define SLAP_BFLAG_ALIASES 0x1000U
#define SLAP_BFLAGS(be) ((be)->bd_info->bi_flags)
#define SLAP_MONITOR(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_MONITOR)
+#define SLAP_CONFIG(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_CONFIG)
#define SLAP_INCREMENT(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_INCREMENT)
#define SLAP_ALIASES(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_ALIASES)
#define SLAP_REFERRALS(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_REFERRALS)
{
char *options;
char *conffile = SLAPD_DEFAULT_CONFIGFILE;
+ char *confdir = SLAPD_DEFAULT_CONFIGDIR;
struct berval base = BER_BVNULL;
char *filterstr = NULL;
char *subtree = NULL;
switch( tool ) {
case SLAPADD:
- options = "b:cd:f:l:n:qtuvw";
+ options = "b:cd:f:F:l:n:qtuvw";
break;
case SLAPCAT:
- options = "a:b:cd:f:l:n:s:v";
+ options = "a:b:cd:f:F:l:n:s:v";
mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
break;
case SLAPDN:
- options = "d:f:v";
+ options = "d:f:F:v";
mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
break;
case SLAPTEST:
- options = "d:f:uv";
+ options = "d:f:F:uv";
mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
break;
case SLAPAUTH:
- options = "d:f:M:R:U:vX:";
+ options = "d:f:F:M:R:U:vX:";
mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
break;
case SLAPINDEX:
- options = "b:cd:f:n:qv";
+ options = "b:cd:f:F:n:qv";
mode |= SLAP_TOOL_READMAIN;
break;
case SLAPACL:
- options = "b:D:d:f:U:v";
+ options = "b:D:d:f:F:U:v";
mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
break;
conffile = strdup( optarg );
break;
+ case 'F': /* specify a conf dir */
+ confdir = strdup( optarg );
+ break;
+
case 'l': /* LDIF file */
ldiffile = strdup( optarg );
break;
exit( EXIT_FAILURE );
}
- rc = read_config( conffile, 0 );
+ rc = read_config( conffile, confdir );
if ( rc != 0 ) {
fprintf( stderr, "%s: bad configuration file!\n", progname );