From 65587fea65b84322c87182ecf4662d0ba59e3040 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Thu, 17 Mar 2005 23:29:48 +0000 Subject: [PATCH] Sync with HEAD --- include/ldap_defaults.h | 1 + servers/slapd/acl.c | 1 + servers/slapd/add.c | 9 + servers/slapd/back-bdb/config.c | 28 +- servers/slapd/back-bdb/init.c | 2 +- servers/slapd/back-bdb/referral.c | 8 +- servers/slapd/back-ldif/ldif.c | 1110 +++++++++++++++-------------- servers/slapd/backover.c | 4 +- servers/slapd/bconfig.c | 441 +++++++++--- servers/slapd/config.c | 220 +++--- servers/slapd/config.h | 14 +- servers/slapd/daemon.c | 6 +- servers/slapd/delete.c | 9 + servers/slapd/main.c | 17 +- servers/slapd/modify.c | 8 + servers/slapd/modrdn.c | 10 + servers/slapd/overlays/glue.c | 6 +- servers/slapd/passwd.c | 9 + servers/slapd/proto-slap.h | 4 +- servers/slapd/result.c | 2 +- servers/slapd/schema_check.c | 2 + servers/slapd/slap.h | 16 +- servers/slapd/slapcommon.c | 21 +- 23 files changed, 1168 insertions(+), 780 deletions(-) diff --git a/include/ldap_defaults.h b/include/ldap_defaults.h index 440417f7c4..414413c56a 100644 --- a/include/ldap_defaults.h +++ b/include/ldap_defaults.h @@ -46,6 +46,7 @@ */ /* 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" diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index 6babdba339..fdb2b9156f 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -2042,6 +2042,7 @@ aci_set_gather( SetCookie *cookie, struct berval *name, AttributeDescription *de 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; diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 92f6759aea..d15fb7f3fc 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -205,6 +205,7 @@ fe_op_add( Operation *op, SlapReply *rs ) Modifications *modlist = op->ora_modlist; Modifications **modtail = &modlist; int rc = 0; + BackendDB *op_be; manageDSAit = get_manageDSAit( op ); @@ -236,6 +237,12 @@ fe_op_add( Operation *op, SlapReply *rs ) 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 ); @@ -269,6 +276,8 @@ fe_op_add( Operation *op, SlapReply *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, diff --git a/servers/slapd/back-bdb/config.c b/servers/slapd/back-bdb/config.c index a6d4d28e68..a70fbb3e8f 100644 --- a/servers/slapd/back-bdb/config.c +++ b/servers/slapd/back-bdb/config.c @@ -122,7 +122,7 @@ static ConfigOCs bdbocs[] = { 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; } @@ -144,7 +144,7 @@ bdb_cf_gen(ConfigArgs *c) 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: @@ -240,28 +240,8 @@ int bdb_back_init_cf( BackendInfo *bi ) 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; } diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c index 8893333fc3..e202de4cfc 100644 --- a/servers/slapd/back-bdb/init.c +++ b/servers/slapd/back-bdb/init.c @@ -536,7 +536,7 @@ bdb_back_initialize( 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; diff --git a/servers/slapd/back-bdb/referral.c b/servers/slapd/back-bdb/referral.c index c52288bc26..c79aee6057 100644 --- a/servers/slapd/back-bdb/referral.c +++ b/servers/slapd/back-bdb/referral.c @@ -53,7 +53,13 @@ dn2entry_retry: /* 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: diff --git a/servers/slapd/back-ldif/ldif.c b/servers/slapd/back-ldif/ldif.c index 56f147489d..bba08ade48 100644 --- a/servers/slapd/back-ldif/ldif.c +++ b/servers/slapd/back-ldif/ldif.c @@ -29,10 +29,11 @@ #include #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; @@ -43,14 +44,52 @@ struct ldif_info { #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; @@ -61,10 +100,9 @@ dn2path(struct berval * dn, struct berval * rootdn, struct berval * base_path) 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; @@ -73,29 +111,29 @@ static char * slurp_file(int fd) { 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; } @@ -107,48 +145,48 @@ static int spew_file(int fd, char * spew) { 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; } @@ -158,132 +196,171 @@ static Entry * get_entry_for_fd(int fd) { /* 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; @@ -293,65 +370,65 @@ static int apply_modify_to_entry(Entry * entry, 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; } @@ -371,35 +448,35 @@ ldif_back_bind( Operation *op, SlapReply *rs ) /* 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 */ @@ -409,9 +486,9 @@ ldif_back_bind( Operation *op, SlapReply *rs ) 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; } @@ -423,27 +500,27 @@ static int ldif_back_search(Operation *op, SlapReply *rs) 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;iors_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;iors_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; @@ -452,205 +529,196 @@ static int ldif_back_search(Operation *op, SlapReply *rs) 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; } @@ -658,7 +726,7 @@ static int ldif_back_modrdn(Operation *op, SlapReply *rs) { 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; @@ -667,56 +735,57 @@ static int ldif_back_modrdn(Operation *op, SlapReply *rs) { 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); @@ -731,38 +800,37 @@ static int ldif_back_compare(Operation *op, SlapReply *rs) { 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; @@ -771,143 +839,107 @@ static int ldif_tool_entry_open(BackendDB * be, int mode) { } 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;itool_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 in \"directory \" 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 ) { @@ -915,14 +947,15 @@ 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); @@ -932,29 +965,33 @@ ldif_back_db_destroy( 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; @@ -989,5 +1026,8 @@ ldif_back_initialize( 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; } diff --git a/servers/slapd/backover.c b/servers/slapd/backover.c index 8532f4b708..e1b31a50c1 100644 --- a/servers/slapd/backover.c +++ b/servers/slapd/backover.c @@ -659,9 +659,11 @@ overlay_config( BackendDB *be, const char *ov ) /* 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; diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 171b688354..e83f6c737b 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -36,7 +36,6 @@ #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 { @@ -57,10 +56,24 @@ typedef struct ConfigFile { 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; @@ -68,6 +81,8 @@ typedef struct 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 @@ -80,19 +95,25 @@ static char *passwd_salt; 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; @@ -191,6 +212,11 @@ ConfigTable config_back_cf_table[] = { "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' " @@ -238,10 +264,10 @@ ConfigTable config_back_cf_table[] = { { "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, @@ -291,7 +317,7 @@ ConfigTable config_back_cf_table[] = { { "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, @@ -439,10 +465,10 @@ ConfigTable config_back_cf_table[] = { { "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, @@ -551,7 +577,7 @@ static ConfigOCs cf_ocs[] = { "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 $ " @@ -578,7 +604,7 @@ static ConfigOCs cf_ocs[] = { "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 $ " @@ -594,11 +620,6 @@ static ConfigOCs cf_ocs[] = { "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 } }; @@ -607,7 +628,7 @@ config_generic(ConfigArgs *c) { char *p; int i; - if ( c->emit ) { + if ( c->op == SLAP_CONFIG_EMIT ) { int rc = 0; switch(c->type) { case CFG_CONCUR: @@ -1038,7 +1059,7 @@ config_generic(ConfigArgs *c) { 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; @@ -1046,11 +1067,20 @@ config_fname(ConfigArgs *c) { 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); @@ -1084,7 +1114,7 @@ config_search_base(ConfigArgs *c) { 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); @@ -1117,12 +1147,14 @@ config_passwd_hash(ConfigArgs *c) { 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; @@ -1134,7 +1166,7 @@ config_sizelimit(ConfigArgs *c) { 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; @@ -1182,7 +1214,7 @@ config_timelimit(ConfigArgs *c) { 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; @@ -1227,7 +1259,7 @@ config_timelimit(ConfigArgs *c) { 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])) { @@ -1245,7 +1277,7 @@ config_suffix(ConfigArgs *c) { 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 ); @@ -1289,7 +1321,7 @@ config_suffix(ConfigArgs *c) { 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); @@ -1306,7 +1338,7 @@ config_rootdn(ConfigArgs *c) { 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; @@ -1348,7 +1380,7 @@ config_restrict(ConfigArgs *c) { { 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 ); } @@ -1376,7 +1408,7 @@ config_allows(ConfigArgs *c) { { 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); @@ -1402,7 +1434,7 @@ config_disallows(ConfigArgs *c) { { 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); @@ -1428,7 +1460,7 @@ config_requires(ConfigArgs *c) { { 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); @@ -1465,7 +1497,7 @@ config_loglevel(ConfigArgs *c) { { BER_BVNULL, 0 } }; - if (c->emit) { + if (c->op == SLAP_CONFIG_EMIT) { return mask_to_verbs( loglevel_ops, ldap_syslog, &c->rvalue_vals ); } @@ -1501,7 +1533,7 @@ config_loglevel(ConfigArgs *c) { 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 ); @@ -1525,7 +1557,7 @@ config_syncrepl(ConfigArgs *c) { 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; @@ -1567,7 +1599,7 @@ config_security(ConfigArgs *c) { 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; @@ -1686,7 +1718,7 @@ config_replica(ConfigArgs *c) { 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++) { @@ -1791,7 +1823,7 @@ static int 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); @@ -1824,7 +1856,7 @@ config_updatedn(ConfigArgs *c) { 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; @@ -1858,7 +1890,7 @@ config_include(ConfigArgs *c) { 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)); @@ -1900,7 +1932,7 @@ config_tls_option(ConfigArgs *c) { "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); @@ -1935,7 +1967,7 @@ config_tls_config(ConfigArgs *c) { "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) { @@ -2471,38 +2503,17 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv ) 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; @@ -2531,6 +2542,183 @@ config_find_base( CfEntryInfo *root, struct berval *dn, CfEntryInfo **last ) 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 ) { @@ -2578,6 +2766,13 @@ config_back_modify( Operation *op, SlapReply *rs ) 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 ); @@ -2656,6 +2851,7 @@ config_build_entry( ConfigArgs *c, Entry *e, ObjectClass *oc, 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; @@ -2672,14 +2868,15 @@ config_build_entry( ConfigArgs *c, Entry *e, ObjectClass *oc, 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 ); + } } } @@ -2688,14 +2885,15 @@ config_build_entry( ConfigArgs *c, Entry *e, ObjectClass *oc, 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 ); + } } } @@ -2717,7 +2915,8 @@ config_build_entry( ConfigArgs *c, Entry *e, ObjectClass *oc, } static CfEntryInfo * -config_build_includes( ConfigArgs *c, Entry *parent ) +config_build_includes( ConfigArgs *c, Entry *parent, + Operation *op, SlapReply *rs ) { Entry *e; int i; @@ -2733,7 +2932,11 @@ config_build_includes( ConfigArgs *c, Entry *parent ) 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 { @@ -2742,7 +2945,7 @@ config_build_includes( ConfigArgs *c, Entry *parent ) 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; @@ -2760,6 +2963,25 @@ config_back_db_open( BackendDB *be ) 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; @@ -2771,6 +2993,10 @@ config_back_db_open( BackendDB *be ) 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; @@ -2778,7 +3004,7 @@ config_back_db_open( BackendDB *be ) /* 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. @@ -2795,9 +3021,12 @@ config_back_db_open( BackendDB *be ) 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 { @@ -2827,9 +3056,12 @@ config_back_db_open( BackendDB *be ) 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 { @@ -2851,9 +3083,12 @@ config_back_db_open( BackendDB *be ) 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 { @@ -2862,24 +3097,6 @@ config_back_db_open( BackendDB *be ) 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; @@ -2909,6 +3126,9 @@ config_back_db_init( Backend *be ) ber_dupbv( &dn, &be->be_rootdn ); ber_bvarray_add( &be->be_nsuffix, &dn ); + /* Hide from namingContexts */ + SLAP_BFLAGS(be) |= SLAP_BFLAG_CONFIG; + return 0; } @@ -2969,7 +3189,9 @@ config_back_initialize( BackendInfo *bi ) 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 */ @@ -2977,8 +3199,6 @@ config_back_initialize( BackendInfo *bi ) 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; @@ -2991,9 +3211,6 @@ config_back_initialize( BackendInfo *bi ) if (!ads[i].name) break; } - /* set up the objectclasses */ - i = init_config_ocs( cf_ocs ); - - return i; + return 0; } diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 48cba471a4..747df41959 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -72,8 +72,6 @@ int slap_conn_max_pending_auth = SLAP_CONN_MAX_PENDING_AUTH; char *slapd_pid_file = NULL; char *slapd_args_file = NULL; -char *strtok_quote_ptr; - int use_reverse_lookup = 0; #ifdef LDAP_SLAPI @@ -84,7 +82,7 @@ static int fp_getline(FILE *fp, ConfigArgs *c); 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); @@ -103,55 +101,61 @@ new_config_args( BackendDB *be, const char *fname, int lineno, int argc, char ** 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); @@ -175,7 +179,7 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) { } 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; @@ -184,7 +188,7 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) { 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) { @@ -194,7 +198,9 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) { 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 ); @@ -202,17 +208,17 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) { 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); @@ -223,15 +229,16 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) { 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; @@ -241,7 +248,7 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) { 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 */ @@ -249,10 +256,19 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) { *(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) { @@ -267,7 +283,7 @@ 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 ) { @@ -295,14 +311,16 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c) 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: @@ -312,6 +330,13 @@ config_get_vals(ConfigTable *cf, ConfigArgs *c) 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); @@ -388,6 +413,7 @@ int read_config_file(const char *fname, int depth, ConfigArgs *cf) { FILE *fp; + ConfigTable *ct; ConfigArgs *c; int rc; @@ -430,6 +456,7 @@ read_config_file(const char *fname, int depth, ConfigArgs *cf) snprintf( c->log, sizeof( c->log ), "%s: line %lu", c->fname, c->lineno ); + c->argc = 0; if ( fp_parse_line( c ) ) { goto badline; } @@ -439,58 +466,69 @@ read_config_file(const char *fname, int depth, ConfigArgs *cf) 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; } } @@ -709,13 +747,13 @@ void bindconf_free( slap_bindconf *bc ) { 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; } @@ -750,7 +788,7 @@ strtok_quote( char *line, char *sep ) default: if ( ! inquote ) { if ( strchr( sep, *next ) != NULL ) { - strtok_quote_ptr = next; + *quote_ptr = next; *next++ = '\0'; return( tmp ); } @@ -838,17 +876,18 @@ fp_parse_line(ConfigArgs *c) 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)); @@ -929,3 +968,24 @@ slap_str2clist( char ***out, char *in, const char *brkstr ) 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; +} diff --git a/servers/slapd/config.h b/servers/slapd/config.h index d43c442977..ac4ceab069 100644 --- a/servers/slapd/config.h +++ b/servers/slapd/config.h @@ -29,15 +29,15 @@ typedef struct ConfigTable { #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 @@ -77,6 +77,7 @@ typedef struct config_args_s { 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; @@ -85,7 +86,8 @@ typedef struct config_args_s { /* 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; @@ -95,9 +97,13 @@ typedef struct config_args_s { #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); diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index 3438fe1df6..2893a905f9 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -980,8 +980,8 @@ static int slap_open_listener( 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); @@ -1672,7 +1672,7 @@ slapd_daemon_task( } 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; diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c index 6762093c4a..40a87c07f3 100644 --- a/servers/slapd/delete.c +++ b/servers/slapd/delete.c @@ -107,6 +107,7 @@ fe_op_delete( Operation *op, SlapReply *rs ) { struct berval pdn = BER_BVNULL; int manageDSAit; + BackendDB *op_be; manageDSAit = get_manageDSAit( op ); @@ -138,6 +139,12 @@ fe_op_delete( Operation *op, SlapReply *rs ) 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 ); @@ -196,6 +203,8 @@ fe_op_delete( Operation *op, SlapReply *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]; diff --git a/servers/slapd/main.c b/servers/slapd/main.c index c88876e046..944faff679 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -253,8 +253,10 @@ int main( int argc, char **argv ) #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; @@ -288,6 +290,7 @@ int main( int argc, char **argv ) { int *i; char *newConfigFile; + char *newConfigDir; char *newUrls; char *regService = NULL; @@ -319,11 +322,17 @@ int main( int argc, char **argv ) 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 @@ -385,6 +394,10 @@ int main( int argc, char **argv ) configfile = ch_strdup( optarg ); break; + case 'F': /* use config dir */ + configdir = ch_strdup( optarg ); + break; + case 'o': { char *val = strchr( optarg, '=' ); struct berval opt; @@ -624,7 +637,7 @@ unhandled_option:; } #endif /* SLAP_DYNACL */ - if ( read_config( configfile, 0 ) != 0 ) { + if ( read_config( configfile, configdir ) != 0 ) { rc = 1; SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 ); diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index ea961ef57f..5f7199f4f1 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -225,6 +225,7 @@ fe_op_modify( Operation *op, SlapReply *rs ) #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 ); @@ -330,6 +331,12 @@ fe_op_modify( Operation *op, SlapReply *rs ) 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 ); @@ -424,6 +431,7 @@ fe_op_modify( Operation *op, SlapReply *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, diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index c9e6c02dac..c9171d709b 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -203,6 +203,7 @@ fe_op_modrdn( Operation *op, SlapReply *rs ) 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 ); @@ -252,6 +253,12 @@ fe_op_modrdn( Operation *op, SlapReply *rs ) 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 ); @@ -320,6 +327,9 @@ fe_op_modrdn( Operation *op, SlapReply *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 diff --git a/servers/slapd/overlays/glue.c b/servers/slapd/overlays/glue.c index b5e53f13c8..13da05a952 100644 --- a/servers/slapd/overlays/glue.c +++ b/servers/slapd/overlays/glue.c @@ -271,7 +271,11 @@ glue_op_search ( Operation *op, SlapReply *rs ) 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: diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c index e056a83604..a262a9911a 100644 --- a/servers/slapd/passwd.c +++ b/servers/slapd/passwd.c @@ -51,6 +51,7 @@ int passwd_extop( int i, nhash; char **hashes; int rc; + BackendDB *op_be; cb2.sc_next = &cb; @@ -108,6 +109,12 @@ int passwd_extop( 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; @@ -159,6 +166,8 @@ int passwd_extop( 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 ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index be1ce92e60..f91874a5ae 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -439,7 +439,7 @@ LDAP_SLAPD_F (int) slap_global_control LDAP_P (( /* * 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 * )); @@ -454,6 +454,8 @@ LDAP_SLAPD_F (int) bindconf_parse LDAP_P(( 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; diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 2dfc11eb75..f1abb5110b 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -579,7 +579,7 @@ slap_send_ldap_result( Operation *op, SlapReply *rs ) * 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 ); diff --git a/servers/slapd/schema_check.c b/servers/slapd/schema_check.c index d765934758..0cc2b886ed 100644 --- a/servers/slapd/schema_check.c +++ b/servers/slapd/schema_check.c @@ -424,6 +424,7 @@ entry_schema_check( } if( extensible ) { + *text = NULL; return LDAP_SUCCESS; } @@ -471,6 +472,7 @@ entry_schema_check( } } + *text = NULL; return LDAP_SUCCESS; } diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 2214f0cb8e..da0d71040e 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -58,20 +58,21 @@ 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 @@ -822,6 +823,7 @@ struct slap_internal_schema { AttributeDescription *si_ad_monitorContext; AttributeDescription *si_ad_vendorName; AttributeDescription *si_ad_vendorVersion; + AttributeDescription *si_ad_configContext; /* subentry attribute descriptions */ AttributeDescription *si_ad_administrativeRole; @@ -2029,6 +2031,7 @@ struct slap_backend_info { 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 @@ -2038,6 +2041,7 @@ struct slap_backend_info { #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) diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c index b49c6c5325..4a0c55a600 100644 --- a/servers/slapd/slapcommon.c +++ b/servers/slapd/slapcommon.c @@ -108,6 +108,7 @@ slap_tool_init( { char *options; char *conffile = SLAPD_DEFAULT_CONFIGFILE; + char *confdir = SLAPD_DEFAULT_CONFIGDIR; struct berval base = BER_BVNULL; char *filterstr = NULL; char *subtree = NULL; @@ -127,36 +128,36 @@ slap_tool_init( 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; @@ -192,6 +193,10 @@ slap_tool_init( conffile = strdup( optarg ); break; + case 'F': /* specify a conf dir */ + confdir = strdup( optarg ); + break; + case 'l': /* LDIF file */ ldiffile = strdup( optarg ); break; @@ -336,7 +341,7 @@ slap_tool_init( exit( EXIT_FAILURE ); } - rc = read_config( conffile, 0 ); + rc = read_config( conffile, confdir ); if ( rc != 0 ) { fprintf( stderr, "%s: bad configuration file!\n", progname ); -- 2.39.5