Commit efc8c43b authored by Howard Chu's avatar Howard Chu
Browse files

Adding back-config pieces

parent a26148af
......@@ -23,7 +23,7 @@ SUBDIRS=back-* shell-backends slapi overlays
NT_SRCS = nt_svc.c
NT_OBJS = nt_svc.o ../../libraries/liblutil/slapdmsg.res
SRCS = main.c globals.c config.c daemon.c \
SRCS = main.c globals.c bconfig.c config.c daemon.c \
connection.c search.c filter.c add.c cr.c \
attr.c entry.c backend.c result.c operation.c \
dn.c compare.c modify.c delete.c modrdn.c ch_malloc.c \
......@@ -40,7 +40,7 @@ SRCS = main.c globals.c config.c daemon.c \
slappasswd.c slaptest.c slapauth.c slapacl.c component.c \
$(@PLAT@_SRCS)
OBJS = main.o globals.o config.o daemon.o \
OBJS = main.o globals.o bconfig.o config.o daemon.o \
connection.o search.o filter.o add.o cr.o \
attr.o entry.o backend.o result.o operation.o \
dn.o compare.o modify.o delete.o modrdn.o ch_malloc.o \
......
/* bconfig.c - the config backend */
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 2005 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
/* ACKNOWLEDGEMENTS:
* This work was originally developed by Howard Chu for inclusion
* in OpenLDAP Software.
*/
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include "slap.h"
#include "config.h"
#define CONFIG_DN "cn=config"
typedef struct CfEntryInfo {
struct CfEntryInfo *ce_sibs;
struct CfEntryInfo *ce_kids;
Entry *ce_entry;
ConfigTable *ce_table;
} CfEntryInfo;
typedef struct {
ConfigFile *cb_config;
CfEntryInfo *cb_root;
} CfBackInfo;
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 ( dn_match( &root->ce_entry->e_nname, dn ))
return root;
c = dn->bv_val+dn->bv_len;
for (;*c != ',';c--);
while(root) {
*last = root;
for (--c;c>dn->bv_val && *c != ',';c--);
if ( *c == ',' )
c++;
cdn.bv_val = c;
cdn.bv_len = dn->bv_len - (c-dn->bv_val);
root = root->ce_kids;
for (;root;root=root->ce_sibs) {
if ( dn_match( &root->ce_entry->e_nname, &cdn )) {
if ( cdn.bv_val == dn->bv_val ) {
return root;
}
break;
}
}
}
return root;
}
static int
config_send( Operation *op, SlapReply *rs, CfEntryInfo *ce, int depth )
{
int rc = 0;
if ( test_filter( op, ce->ce_entry, op->ors_filter ) == LDAP_COMPARE_TRUE )
{
rs->sr_attrs = op->ors_attrs;
rs->sr_entry = ce->ce_entry;
rc = send_search_entry( op, rs );
}
if ( op->ors_scope == LDAP_SCOPE_SUBTREE ) {
if ( ce->ce_kids ) {
rc = config_send( op, rs, ce->ce_kids, 1 );
if ( rc ) return rc;
}
if ( depth ) {
for (ce=ce->ce_sibs; ce; ce=ce->ce_sibs) {
rc = config_send( op, rs, ce, 0 );
if ( rc ) break;
}
}
}
return rc;
}
static int
config_back_search( Operation *op, SlapReply *rs )
{
CfBackInfo *cfb;
CfEntryInfo *ce, *last;
int rc;
if ( !be_isroot( op ) ) {
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
send_ldap_result( op, rs );
}
cfb = (CfBackInfo *)op->o_bd->be_private;
ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );
if ( !ce ) {
if ( last )
rs->sr_matched = last->ce_entry->e_name.bv_val;
rs->sr_err = LDAP_NO_SUCH_OBJECT;
goto out;
}
switch ( op->ors_scope ) {
case LDAP_SCOPE_BASE:
case LDAP_SCOPE_SUBTREE:
config_send( op, rs, ce, 0 );
break;
case LDAP_SCOPE_ONELEVEL:
for (ce = ce->ce_kids; ce; ce=ce->ce_sibs) {
config_send( op, rs, ce, 1 );
}
break;
}
rs->sr_err = LDAP_SUCCESS;
out:
send_ldap_result( op, rs );
return 0;
}
static Entry *
config_alloc_entry( struct berval *pdn, struct berval *rdn )
{
Entry *e = ch_calloc( 1, sizeof(Entry) );
CfEntryInfo *ce = ch_calloc( 1, sizeof(CfEntryInfo) );
e->e_private = ce;
ce->ce_entry = e;
build_new_dn( &e->e_name, pdn, rdn, NULL );
ber_dupbv( &e->e_nname, &e->e_name );
return e;
}
static int
config_build_entry( Entry *e, void *private, char *oc, struct berval *rdn )
{
struct berval vals[2];
struct berval ad_name;
AttributeDescription *ad = NULL;
int rc;
char *ptr;
const char *text;
BER_BVZERO( &vals[1] );
ber_str2bv( oc, 0, 0, &vals[0] );
attr_merge(e, slap_schema.si_ad_objectClass, vals, NULL );
ptr = strchr(rdn->bv_val, '=');
ad_name.bv_val = rdn->bv_val;
ad_name.bv_len = ptr - rdn->bv_val;
rc = slap_bv2ad( &ad_name, &ad, &text );
if ( rc ) {
return rc;
}
vals[0].bv_val = ptr+1;
vals[0].bv_len = rdn->bv_len - (vals[0].bv_val - rdn->bv_val);
attr_merge(e, ad, vals, NULL );
return 0;
}
static int
config_back_db_open( BackendDB *be )
{
CfBackInfo *cfb = be->be_private;
struct berval rdn;
Entry *e, *parent;
CfEntryInfo *ce, *ceparent, *ceprev;
int i, buflen = 0;
char *buf = NULL;
BackendInfo *bi;
BackendDB *bptr;
/* create root of tree */
ber_str2bv( CONFIG_DN, STRLENOF( CONFIG_DN ), 0, &rdn );
e = config_alloc_entry( NULL, &rdn );
ce = e->e_private;
ce->ce_table = be->bd_info->bi_cf_table;
cfb->cb_root = ce;
config_build_entry( e, be->be_private, "olcGlobal", &rdn );
parent = e;
ceparent = ce;
/* Create backend nodes. Skip if they don't provide a cf_table.
* There usually aren't any of these.
*/
bi = backendInfo;
for (i=0; i<nBackendInfo; i++, bi++) {
if (!bi->bi_cf_table) continue;
if (!bi->bi_private) continue;
if ( buflen < STRLENOF("olcbackend=")+strlen(bi->bi_type)+1) {
buflen = STRLENOF("olcbackend=") + strlen(bi->bi_type)+1;
buf = realloc(buf, buflen);
}
rdn.bv_val = buf;
rdn.bv_len = sprintf(buf, "olcBackend=%s", bi->bi_type);
e = config_alloc_entry( &parent->e_nname, &rdn );
ce = e->e_private;
ce->ce_table = bi->bi_cf_table;
config_build_entry( e, bi->bi_private, "olcBackendConfig",
&rdn );
if ( !ceparent->ce_kids ) {
ceparent->ce_kids = ce;
} else {
ceprev->ce_sibs = ce;
}
ceprev = ce;
}
/* Create database nodes... */
for (i=0; i<nBackendDB; i++) {
if ( i == 0 ) {
bptr = frontendDB;
} else {
bptr = &backendDB[i];
}
bi = bptr->bd_info;
if ( buflen < STRLENOF("olcdatabase={xxxxxxxx}")+strlen(bi->bi_type)+1) {
buflen = STRLENOF("olcdatabase={xxxxxxxx}")+strlen(bi->bi_type)+1;
buf = realloc(buf, buflen);
}
rdn.bv_val = buf;
rdn.bv_len = sprintf(buf, "olcDatabase={%0x}%s", i, bi->bi_type);
e = config_alloc_entry( &parent->e_nname, &rdn );
ce = e->e_private;
ce->ce_table = bptr->be_cf_table;
config_build_entry( e, bptr->be_private, "olcDatabaseConfig",
&rdn );
if ( !ceparent->ce_kids ) {
ceparent->ce_kids = ce;
} else {
ceprev->ce_sibs = ce;
}
ceprev = ce;
/* Iterate through overlays */
}
/* Create includeFile nodes... */
return 0;
}
static int
config_back_db_destroy( Backend *be )
{
free( be->be_private );
return 0;
}
int
config_back_initialize( BackendInfo *bi )
{
bi->bi_open = 0;
bi->bi_close = 0;
bi->bi_config = 0;
bi->bi_destroy = 0;
bi->bi_db_init = 0;
bi->bi_db_config = 0;
bi->bi_db_open = config_back_db_open;
bi->bi_db_close = 0;
bi->bi_db_destroy = config_back_db_destroy;
bi->bi_op_bind = config_back_bind;
bi->bi_op_unbind = 0;
bi->bi_op_search = config_back_search;
bi->bi_op_compare = 0;
bi->bi_op_modify = 0;
bi->bi_op_modrdn = 0;
bi->bi_op_add = 0;
bi->bi_op_delete = 0;
bi->bi_op_abandon = 0;
bi->bi_extended = 0;
bi->bi_chk_referrals = 0;
bi->bi_connection_init = 0;
bi->bi_connection_destroy = 0;
return 0;
}
void config_back_init( ConfigFile *cfp, ConfigTable *ct )
{
BackendInfo bi = {0};
BackendDB *be;
struct berval dn;
CfBackInfo *cfb;
bi.bi_type = "config";
bi.bi_init = config_back_initialize;
bi.bi_cf_table = ct;
backend_add( &bi );
be = backend_db_init( bi.bi_type );
ber_str2bv( CONFIG_DN, 0, 1, &be->be_rootdn );
ber_dupbv( &be->be_rootndn, &be->be_rootdn );
ber_dupbv( &dn, &be->be_rootdn );
ber_bvarray_add( &be->be_suffix, &dn );
ber_dupbv( &dn, &be->be_rootdn );
ber_bvarray_add( &be->be_nsuffix, &dn );
cfb = ch_calloc( 1, sizeof(CfBackInfo));
cfb->cb_config = cfp;
be->be_private = cfb;
}
......@@ -89,6 +89,9 @@ static char *strtok_quote(char *line, char *sep);
static int load_ucdata(char *path);
#endif
/* state info for back-config */
static ConfigFile cf_prv, *cfn = &cf_prv;
int read_config_file(const char *fname, int depth, ConfigArgs *cf);
static int add_syncrepl LDAP_P(( Backend *, char **, int ));
......@@ -297,7 +300,7 @@ ConfigTable SystemConfiguration[] = {
&config_generic, "( OLcfgAt:29 NAME 'olcMaxDerefDepth' "
"SYNTAX OMsInteger )", NULL, NULL },
#ifdef SLAPD_MODULES
{ "moduleload", "file", 2, 2, 0, ARG_MAGIC|CFG_MODLOAD,
{ "moduleload", "file", 2, 0, 0, ARG_MAGIC|CFG_MODLOAD,
&config_generic, "( OLcfgAt:30 NAME 'olcModuleLoad' "
"SYNTAX OMsDirectoryString )", NULL, NULL },
{ "modulepath", "path", 2, 2, 0, ARG_MAGIC|CFG_MODPATH,
......@@ -620,7 +623,7 @@ int parse_config_table(ConfigTable *Conf, ConfigArgs *c) {
}
int
init_config_schema(ConfigTable *ct) {
init_config_attrs(ConfigTable *ct) {
LDAPAttributeType *at;
int i, code;
const char *err;
......@@ -654,13 +657,17 @@ read_config(const char *fname, int depth) {
int i;
char *argv[3];
/* Schema initialization should normally be part of bi_open */
for (i=0; OidMacros[i].name; i++ ) {
argv[1] = OidMacros[i].name;
argv[2] = OidMacros[i].oid;
parse_oidm( "slapd", i, 3, argv );
}
i = init_config_schema(SystemConfiguration);
i = init_config_attrs(SystemConfiguration);
if ( i ) return i;
config_back_init( &cf_prv, SystemConfiguration );
return read_config_file(fname, depth, NULL);
}
......@@ -696,6 +703,11 @@ read_config_file(const char *fname, int depth, ConfigArgs *cf)
fname, strerror(errno), errno);
return(1);
}
#ifdef SLAPD_MODULES
cfn->c_modlast = &cfn->c_modpaths;
#endif
ber_str2bv( fname, 0, 1, &cfn->c_file );
fname = cfn->c_file.bv_val;
Debug(LDAP_DEBUG_CONFIG, "reading config file %s\n", fname, 0, 0);
......@@ -827,7 +839,9 @@ config_generic(ConfigArgs *c) {
case CFG_DATABASE:
c->bi = NULL;
if(!(c->be = backend_db_init(c->argv[1]))) {
if ( !strcasecmp( c->argv[1], "config" )) {
c->be = backendDB;
} else if(!(c->be = backend_db_init(c->argv[1]))) {
Debug(LDAP_DEBUG_ANY, "%s: "
"database %s failed init!\n", c->log, c->argv[1], 0);
return(1);
......@@ -923,12 +937,6 @@ config_generic(ConfigArgs *c) {
parse_acl(c->be, c->fname, c->lineno, c->argc, c->argv);
break;
#if 0
case CFG_AUDITLOG:
c->be->be_auditlogfile = c->value_string;
break;
#endif
case CFG_REPLOG:
if(SLAP_MONITOR(c->be)) {
Debug(LDAP_DEBUG_ANY, "%s: "
......@@ -948,6 +956,11 @@ config_generic(ConfigArgs *c) {
c->log, 0, 0);
return(1);
}
{
struct berval bv;
ber_str2bv( c->argv[1], 0, 1, &bv );
ber_bvarray_add( &cfn->c_dseFiles, &bv );
}
break;
case CFG_LOGFILE: {
......@@ -973,10 +986,31 @@ config_generic(ConfigArgs *c) {
case CFG_MODLOAD:
if(module_load(c->argv[1], c->argc - 2, (c->argc > 2) ? c->argv + 2 : NULL))
return(1);
/* Record this load on the current path */
{
struct berval bv;
ber_str2bv(c->line, 0, 1, &bv);
ber_bvarray_add( &cfn->c_modlast->mp_loads, &bv );
}
break;
case CFG_MODPATH:
if(module_path(c->argv[1])) return(1);
/* Record which path was used with each module */
{
ModPaths *mp;
if (!cfn->c_modpaths.mp_loads)
mp = &cfn->c_modpaths;
else
mp = ch_malloc( sizeof( ModPaths ));
ber_str2bv(c->argv[1], 0, 1, &mp->mp_path);
mp->mp_next = NULL;
mp->mp_loads = NULL;
cfn->c_modlast->mp_next = mp;
cfn->c_modlast = mp;
}
break;
#endif
......@@ -1635,12 +1669,26 @@ config_updateref(ConfigArgs *c) {
int
config_include(ConfigArgs *c) {
char *savefname = ch_strdup(c->argv[1]);
unsigned long savelineno = c->lineno;
int rc;
rc = read_config_file(savefname, c->depth + 1, c);
free(savefname);
ConfigFile *cf = ch_calloc( 1, sizeof(ConfigFile));
ConfigFile *cfsave = cfn;
ConfigFile *cf2 = NULL;
if ( cfn->c_kids ) {
for (cf2=cfn->c_kids; cf2 && cf2->c_sibs; cf2=cf2->c_sibs) ;
cf2->c_sibs = cf;
} else {
cfn->c_kids = cf;
}
cfn = cf;
rc = read_config_file(c->argv[1], c->depth + 1, c);
c->lineno = savelineno - 1;
cfn = cfsave;
if ( rc ) {
if ( cf2 ) cf2->c_sibs = NULL;
else cfn->c_kids = NULL;
ch_free( cf );
}
return(rc);
}
......
......@@ -15,7 +15,7 @@
* <http://www.OpenLDAP.org/license.html>.
*/
typedef struct config_table_s {
typedef struct ConfigTable {
char *name;
char *what;
int min_args;
......@@ -76,3 +76,24 @@ typedef struct config_args_s {
} ConfigArgs;
typedef int (ConfigDriver)(ConfigArgs *c);
#ifdef SLAPD_MODULES
typedef struct modpath_s {
struct modpath_s *mp_next;
struct berval mp_path;
BerVarray mp_loads;
} ModPaths;
#endif
typedef struct ConfigFile {
struct ConfigFile *c_sibs;
struct ConfigFile *c_kids;
struct berval c_file;
#ifdef SLAPD_MODULES
ModPaths c_modpaths;
ModPaths *c_modlast;
#endif
BerVarray c_dseFiles;
} ConfigFile;
void config_back_init( ConfigFile *cfp, ConfigTable *ct );
......@@ -1704,6 +1704,7 @@ struct slap_backend_db {
char *be_realm;
void *be_pb; /* Netscape plugin */
struct ConfigTable *be_cf_table;
void *be_private; /* anything the backend database needs */
};
......@@ -1911,6 +1912,8 @@ typedef int (BI_tool_id2entry_get) LDAP_P(( BackendDB *be, ID id, Entry **e ));
typedef ID (BI_tool_entry_modify) LDAP_P(( BackendDB *be, Entry *e,
struct berval *text ));
struct ConfigTable; /* config.h */
struct slap_backend_info {
char *bi_type; /* type of backend */
......@@ -2033,6 +2036,7 @@ struct slap_backend_info {
char bi_ctrls[SLAP_MAX_CIDS + 1];
unsigned int bi_nDB; /* number of databases of this type */
struct ConfigTable *bi_cf_table;
void *bi_private; /* anything the backend type needs */
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment