]> git.sur5r.net Git - openldap/commitdiff
Adding back-config pieces
authorHoward Chu <hyc@openldap.org>
Sun, 20 Feb 2005 18:33:40 +0000 (18:33 +0000)
committerHoward Chu <hyc@openldap.org>
Sun, 20 Feb 2005 18:33:40 +0000 (18:33 +0000)
servers/slapd/Makefile.in
servers/slapd/bconfig.c [new file with mode: 0644]
servers/slapd/config.c
servers/slapd/config.h
servers/slapd/slap.h

index 8c5ed6218942206882390965d91b8830b923001f..465e26f7056e4f4e4046895d3a917863700a6486 100644 (file)
@@ -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 \
diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c
new file mode 100644 (file)
index 0000000..a1af4a4
--- /dev/null
@@ -0,0 +1,343 @@
+/* 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;
+}
index 6bc3b79b310d95c17c13a38395911d705173f6b2..0f542a905e4e85e52873159bd03aeb699486919f 100644 (file)
@@ -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);
 }
 
index 69ed0366fcc0de5ee87970facb86279877a9863e..3c614e7355e22d736fc8136d4a1f0a94617993ba 100644 (file)
@@ -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 );
index 799a5b7d8a41e519533cb6d8c51d26545376e6cd..58745a592e857d7dd25dad709840c64c6532972a 100644 (file)
@@ -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 */
 };