src/server/daemon/config.c

changeset 51
b28cf69f42e8
parent 46
636e05eb48f6
child 54
3a1d5a52adfc
--- a/src/server/daemon/config.c	Sat Jan 19 21:52:21 2013 +0100
+++ b/src/server/daemon/config.c	Thu Feb 28 20:00:05 2013 +0100
@@ -501,6 +501,11 @@
     sstr_t objfile = cfg_directivelist_get_str(
             obj->directives,
             sstr("ObjectFile"));
+    sstr_t aclfile = cfg_directivelist_get_str(
+            obj->directives,
+            sstr("ACLFile"));
+    
+    // load the object config file
     sstr_t base = sstr("config/");
     sstr_t file;
     file.length = base.length + objfile.length + 1;
@@ -508,6 +513,7 @@
     file.ptr[file.length] = 0;
     file = sstrncat(2, file, base, objfile);
 
+    // the file is managed by the configuration manager
     ConfigFile *f = cfgmgr_get_file(file);
     if(f == NULL) {
         f = malloc(sizeof(ConfigFile));
@@ -519,6 +525,21 @@
     vs->objectfile = sstrdup(file); // TODO: pool
     vs->objects = (HTTPObjectConfig*)f->data; // TODO: ref
     
+    // load acl config file
+    file.length = base.length + aclfile.length + 1;
+    file.ptr = alloca(file.length);
+    file.ptr[file.length] = 0;
+    file = sstrncat(2, file, base, aclfile);
+    
+    ConfigFile *aclf = cfgmgr_get_file(file);
+    if(aclf == NULL) {
+        aclf = malloc(sizeof(ConfigFile));
+        aclf->file = sstrdup(file);
+        aclf->reload = acl_conf_reload;
+        aclf->reload(aclf, cfg);
+        cfgmgr_attach_file(aclf);
+    }
+    
     // set the access log for the virtual server
     // TODO: don't use always the default
     vs->log = get_default_access_log();
@@ -644,3 +665,91 @@
     file->data = mimemap;
     return 0;
 }
+
+int acl_conf_reload(ConfigFile *file, ServerConfiguration *cfg) {
+    ACLFile *aclfile = load_acl_file(file->file.ptr);
+    
+    ACLData *acldata = acl_data_new();
+    UCX_FOREACH(UcxList*, aclfile->namedACLs, elm) {
+        ACLConfig *ac = elm->data;
+        ACLList *acl = acl_config_convert(cfg, ac);
+        ucx_map_sstr_put(acldata->namedACLs, ac->id, acl);
+    }
+    free_acl_file(aclfile);
+    
+    cfg->acls = acldata;
+    
+    struct stat s;
+    if(stat(file->file.ptr, &s) != 0) {
+        perror("object_conf_reload: stat");
+        return -1;
+    }
+    file->last_modified = s.st_mtim.tv_sec;
+    return 0;
+}
+
+ACLList* acl_config_convert(ServerConfiguration *cfg, ACLConfig *acl) {
+    ACLList *acllist = malloc(sizeof(ACLList));
+    acllist->authdb = NULL;
+    acllist->authprompt = NULL;
+    acllist->ace = NULL;
+    acllist->ece = NULL;
+    
+    size_t s = ucx_list_size(acl->entries);
+    ACLEntry **aces = calloc(s, sizeof(ACLEntry*));
+    ACLEntry **eces = calloc(s, sizeof(ACLEntry*));
+    int ai = 0;
+    int ei = 0;
+    
+    // convert entries
+    UCX_FOREACH(UcxList*, acl->entries, elm) {
+        ACEConfig *acecfg = elm->data;
+        
+        // copy data
+        ACLEntry *ace = malloc(sizeof(ACLEntry));
+        ace->access_mask = acecfg->access_mask;
+        ace->flags = acecfg->flags;
+        ace->type = acecfg->type;
+        ace->who = sstrdup(acecfg->who).ptr;
+        
+        // add the entry to the correct array
+        if(ace->type >= ACL_TYPE_AUDIT) {
+            eces[ei] = ace;
+            ei++;
+        } else {
+            aces[ai] = ace;
+            ai++;
+        }
+    }
+    
+    // create new entrie arrays with perfect fitting size
+    if(ai > 0) {
+        acllist->ace = calloc(ai, sizeof(ACLEntry*));
+    }
+    if(ei > 0) {
+        acllist->ece = calloc(ei, sizeof(ACLEntry*));
+    }
+    memcpy(acllist->ace, aces, ai*sizeof(ACLEntry*));
+    memcpy(acllist->ece, eces, ei*sizeof(ACLEntry*));
+    acllist->acenum = ai;
+    acllist->ecenum = ei;
+    
+    free(aces);
+    free(eces);
+    
+    // get authentication information
+    if(acl->authparam) {
+        sstr_t authdb_str = cfg_param_get(acl->authparam, sstr("authdb"));
+        sstr_t prompt_str = cfg_param_get(acl->authparam, sstr("prompt"));
+        
+        if(authdb_str.ptr) {
+            AuthDB *authdb = ucx_map_sstr_get(cfg->authdbs, authdb_str);
+            acllist->authdb = authdb;
+            if(authdb && prompt_str.ptr) {
+                acllist->authprompt = sstrdup(prompt_str).ptr;
+            }
+        }
+    }
+    
+    return acllist;
+}

mercurial