new pathcheck saf and code cleanup

Fri, 01 Mar 2013 21:15:52 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 01 Mar 2013 21:15:52 +0100
changeset 52
aced2245fb1c
parent 51
b28cf69f42e8
child 53
5ec9abba1027

new pathcheck saf and code cleanup

src/server/config/acl.c file | annotate | diff | comparison | revisions
src/server/config/acl.h file | annotate | diff | comparison | revisions
src/server/daemon/acl.c file | annotate | diff | comparison | revisions
src/server/daemon/acl.h file | annotate | diff | comparison | revisions
src/server/daemon/request.c file | annotate | diff | comparison | revisions
src/server/daemon/ws-fn.c file | annotate | diff | comparison | revisions
src/server/public/nsapi.h file | annotate | diff | comparison | revisions
src/server/safs/pathcheck.c file | annotate | diff | comparison | revisions
src/server/safs/pathcheck.h file | annotate | diff | comparison | revisions
src/server/util/netbuf.c file | annotate | diff | comparison | revisions
src/server/util/object.c file | annotate | diff | comparison | revisions
--- a/src/server/config/acl.c	Thu Feb 28 20:00:05 2013 +0100
+++ b/src/server/config/acl.c	Fri Mar 01 21:15:52 2013 +0100
@@ -162,45 +162,7 @@
     sstr_t *accessmask = sstrsplit(s, sstr(","), &maskn);
     for(int i=0;i<maskn;i++) {
         sstr_t access = accessmask[i];
-        if(!sstrcmp(access, sstr("read"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_READ;
-        } else if(!sstrcmp(access, sstr("write"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_WRITE;
-        } else if(!sstrcmp(access, sstr("read_data"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_READ_DATA;
-        } else if(!sstrcmp(access, sstr("write_data"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_WRITE_DATA;
-        } else if(!sstrcmp(access, sstr("append"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_APPEND;
-        } else if(!sstrcmp(access, sstr("add_file"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_ADD_FILE;
-        } else if(!sstrcmp(access, sstr("add_subdirectory"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_ADD_SUBDIRECTORY;
-        } else if(!sstrcmp(access, sstr("read_xattr"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_READ_XATTR;
-        } else if(!sstrcmp(access, sstr("write_xattr"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_WRITE_XATTR;
-        } else if(!sstrcmp(access, sstr("execute"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_EXECUTE;
-        } else if(!sstrcmp(access, sstr("delete_child"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_DELETE_CHILD;
-        } else if(!sstrcmp(access, sstr("delete"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_DELETE;
-        } else if(!sstrcmp(access, sstr("read_attributes"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_READ_ATTRIBUTES;
-        } else if(!sstrcmp(access, sstr("write_attributes"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_WRITE_ATTRIBUTES;
-        } else if(!sstrcmp(access, sstr("list"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_LIST;
-        } else if(!sstrcmp(access, sstr("read_acl"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_READ_ACL;
-        } else if(!sstrcmp(access, sstr("write_acl"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_WRITE_ACL;
-        } else if(!sstrcmp(access, sstr("write_owner"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_WRITE_OWNER;
-        } else if(!sstrcmp(access, sstr("synchronize"))) {
-            ace->access_mask = ace->access_mask | ACLCFG_SYNCHRONIZE;
-        }
+        ace->access_mask = ace->access_mask | accstr2int(access);
     }
     free(accessmask);
     n++; // next token
@@ -255,3 +217,47 @@
     
     return 0;
 }
+
+uint32_t accstr2int(sstr_t access) {
+    uint32_t val = 0;
+    if(!sstrcmp(access, sstr("read"))) {
+        val = ACLCFG_READ;
+    } else if(!sstrcmp(access, sstr("write"))) {
+        val = ACLCFG_WRITE;
+    } else if(!sstrcmp(access, sstr("read_data"))) {
+        val = ACLCFG_READ_DATA;
+    } else if(!sstrcmp(access, sstr("write_data"))) {
+        val = ACLCFG_WRITE_DATA;
+    } else if(!sstrcmp(access, sstr("append"))) {
+        val = ACLCFG_APPEND;
+    } else if(!sstrcmp(access, sstr("add_file"))) {
+        val = ACLCFG_ADD_FILE;
+    } else if(!sstrcmp(access, sstr("add_subdirectory"))) {
+        val = ACLCFG_ADD_SUBDIRECTORY;
+    } else if(!sstrcmp(access, sstr("read_xattr"))) {
+        val = ACLCFG_READ_XATTR;
+    } else if(!sstrcmp(access, sstr("write_xattr"))) {
+        val = ACLCFG_WRITE_XATTR;
+    } else if(!sstrcmp(access, sstr("execute"))) {
+        val = ACLCFG_EXECUTE;
+    } else if(!sstrcmp(access, sstr("delete_child"))) {
+        val = ACLCFG_DELETE_CHILD;
+    } else if(!sstrcmp(access, sstr("delete"))) {
+        val = ACLCFG_DELETE;
+    } else if(!sstrcmp(access, sstr("read_attributes"))) {
+        val = ACLCFG_READ_ATTRIBUTES;
+    } else if(!sstrcmp(access, sstr("write_attributes"))) {
+        val = ACLCFG_WRITE_ATTRIBUTES;
+    } else if(!sstrcmp(access, sstr("list"))) {
+        val = ACLCFG_LIST;
+    } else if(!sstrcmp(access, sstr("read_acl"))) {
+        val = ACLCFG_READ_ACL;
+    } else if(!sstrcmp(access, sstr("write_acl"))) {
+        val = ACLCFG_WRITE_ACL;
+    } else if(!sstrcmp(access, sstr("write_owner"))) {
+        val = ACLCFG_WRITE_OWNER;
+    } else if(!sstrcmp(access, sstr("synchronize"))) {
+        val = ACLCFG_SYNCHRONIZE;
+    }
+    return val;
+}
--- a/src/server/config/acl.h	Thu Feb 28 20:00:05 2013 +0100
+++ b/src/server/config/acl.h	Fri Mar 01 21:15:52 2013 +0100
@@ -125,6 +125,11 @@
 int acl_parse(void *p, ConfigLine *begin, ConfigLine *end, sstr_t line);
 int parse_ace(ACLFile *f, sstr_t line);
 
+/*
+ * converts a access right string to an integer value
+ */
+uint32_t accstr2int(sstr_t access);
+
 #ifdef	__cplusplus
 }
 #endif
--- a/src/server/daemon/acl.c	Thu Feb 28 20:00:05 2013 +0100
+++ b/src/server/daemon/acl.c	Fri Mar 01 21:15:52 2013 +0100
@@ -41,7 +41,10 @@
     rq->acllist = handle;
 }
 
-void acllist_append(Session *sn, Request *rq, ACLList *acl) {
+/*
+ * append or prepend an ACL
+ */
+void acllist_add(Session *sn, Request *rq, ACLList *acl, int append) {
     if(!rq->acllist) {
         acllist_createhandle(sn, rq);
     }
@@ -58,31 +61,22 @@
         list->listhead = elm;
         list->listtail = elm;
     } else {
-        list->listtail->next = elm;
-        list->listtail = elm;
+        if(append) {
+            list->listtail->next = elm;
+            list->listtail = elm;
+        } else {
+            elm->next = list->listhead;
+            list->listhead = elm;
+        }
     }
 }
 
+void acllist_append(Session *sn, Request *rq, ACLList *acl) {
+    acllist_add(sn, rq, acl, 1);
+}
+
 void acllist_prepend(Session *sn, Request *rq, ACLList *acl) {
-    if(!rq->acllist) {
-        acllist_createhandle(sn, rq);
-    }
-    ACLListHandle *list = rq->acllist;
-    
-    if(!list->defaultauthdb && acl->authdb) {
-        list->defaultauthdb = acl->authdb;
-    }
-    
-    ACLListElm *elm = pool_malloc(sn->pool, sizeof(ACLListElm));
-    elm->acl = acl;
-    elm->next = NULL;
-    if(list->listhead == NULL) {
-        list->listhead = elm;
-        list->listtail = elm;
-    } else {
-        elm->next = list->listhead;
-        list->listhead = elm;
-    }
+    acllist_add(sn, rq, acl, 0);
 }
 
 
@@ -92,6 +86,10 @@
         return REQ_PROCEED;
     }
     
+    // we combine access_mask with the required access rights
+    access_mask = access_mask | rq->aclreqaccess;
+    
+    
     // get user
     User *user = NULL;
     if(list->defaultauthdb) {
@@ -105,6 +103,7 @@
             }
             if(!user->verify_password(user, pw)) {
                 // wrong password
+                user->free(user);
                 return REQ_ABORTED;
             }
             // ok - user is authenticated
@@ -128,57 +127,62 @@
                         rq->srvhdrs);
                 protocol_status(sn, rq, PROTOCOL_UNAUTHORIZED, NULL);
             }
+            user->free(user);
             return REQ_ABORTED;
         } 
         elm = elm->next;
     }
     
     // ok - all acls allowed access
+    user->free(user);
     return REQ_PROCEED;
 }
 
+int wsacl_affects_user(ACLEntry *ace, User *user) {
+    int check_access = 0;
+    
+    /*
+     * an ace can affect
+     *   a named user or group (ace->who is set)
+     *   the owner of the resource (ACL_OWNER is set)
+     *   the owning group of the resource (ACL_GROUP is set)
+     *   everyone (ACL_EVERYONE is set)
+     * 
+     * Only one of this conditions should be true. The behavior on
+     * illegal flag combination is undefined. We assume that the acls
+     * are created correctly by the configuration loader.
+     */
+    
+    if(ace->who && user) {
+        // this ace is defined for a named user or group
+        if((ace->flags & ACL_IDENTIFIER_GROUP) == ACL_IDENTIFIER_GROUP) {
+            if(user->check_group(user, ace->who)) {
+                // the user is in the group
+                check_access = 1;
+            }
+        } else {
+            if(!strcmp(user->name, ace->who)) {
+                check_access = 1;
+            }
+        }
+    } else if((ace->flags & ACL_OWNER) == ACL_OWNER) {
+        // TODO
+    } else if((ace->flags & ACL_GROUP) == ACL_GROUP) {
+        // TODO
+    } else if((ace->flags & ACL_EVERYONE) == ACL_EVERYONE) {
+        check_access = 1;
+    }
+    
+    return check_access;
+}
+
 int wsacl_check(ACLList *acl, User *user, int access_mask) { 
     int allow = 0;
     uint32_t allowed_access = 0;
     // check each access control entry
     for(int i=0;i<acl->acenum;i++) {
-        ACLEntry *ace = acl->ace[i];
-        int check_access = 0;
-        
-        /*
-         * an ace can affect
-         *   a named user or group (ace->who is set)
-         *   the owner of the resource (ACL_OWNER is set)
-         *   the owning group of the resource (ACL_GROUP is set)
-         *   everyone (ACL_EVERYONE is set)
-         * 
-         * Only one of this conditions should be true. The behavior on
-         * illegal flag combination is undefined. We assume that the acls
-         * are created correctly by the configuration loader.
-         */
-        
-        if(ace->who && user) {
-            // this ace is defined for a named user or group
-            if((ace->flags & ACL_IDENTIFIER_GROUP) == ACL_IDENTIFIER_GROUP) {
-                if(user->check_group(user, ace->who)) {
-                    // the user is in the group
-                    check_access = 1;
-                }
-            } else {
-                if(!strcmp(user->name, ace->who)) {
-                    check_access = 1;
-                }
-            }
-        } else if((ace->flags & ACL_OWNER) == ACL_OWNER) {
-            // TODO
-        } else if((ace->flags & ACL_GROUP) == ACL_GROUP) {
-            // TODO
-        } else if((ace->flags & ACL_EVERYONE) == ACL_EVERYONE) {
-            check_access = 1;
-        }
-        
-        
-        if(check_access) {
+        ACLEntry *ace = acl->ace[i];   
+        if(wsacl_affects_user(ace, user)) {
             if(ace->type == ACL_TYPE_ALLOWED) {
                 // add all new access rights 
                 allowed_access = allowed_access |
--- a/src/server/daemon/acl.h	Thu Feb 28 20:00:05 2013 +0100
+++ b/src/server/daemon/acl.h	Fri Mar 01 21:15:52 2013 +0100
@@ -143,6 +143,7 @@
 
 
 // private
+int wsacl_affects_user(ACLEntry *ace, User *user);
 int wsacl_check(ACLList *acl, User *user, int access_mask);
 
 
--- a/src/server/daemon/request.c	Thu Feb 28 20:00:05 2013 +0100
+++ b/src/server/daemon/request.c	Fri Mar 01 21:15:52 2013 +0100
@@ -69,6 +69,7 @@
     rq->aclname = NULL;
     rq->aclpb = NULL;
     rq->acllist = NULL;
+    rq->aclreqaccess = 0;
     rq->request_is_cacheable = 0;
     rq->directive_is_cacheable = 0;
     rq->cached_headers = NULL;
--- a/src/server/daemon/ws-fn.c	Thu Feb 28 20:00:05 2013 +0100
+++ b/src/server/daemon/ws-fn.c	Fri Mar 01 21:15:52 2013 +0100
@@ -55,6 +55,7 @@
     { "auth-basic", auth_basic, NULL, 0 },
     { "auth-db", auth_db, NULL, 0 },
     { "require-auth", require_auth, NULL, 0},
+    { "require-access", require_access, NULL, 0},
     { "append-acl", append_acl, NULL, 0},
     { "check-acl", check_acl, NULL, 0},
     { "print-message", print_message, NULL, 0},
--- a/src/server/public/nsapi.h	Thu Feb 28 20:00:05 2013 +0100
+++ b/src/server/public/nsapi.h	Fri Mar 01 21:15:52 2013 +0100
@@ -991,6 +991,7 @@
     pblock *aclpb;              /* OBSOLETE */
     /* 3.0 ACL list pointer */
     ACLListHandle *acllist;
+    uint32_t aclreqaccess; /* new - required access rights */
 
     int request_is_cacheable;   /* */
     int directive_is_cacheable; /* set by SAFs with no external side effects that make decisions based solely on URI and path */
--- a/src/server/safs/pathcheck.c	Thu Feb 28 20:00:05 2013 +0100
+++ b/src/server/safs/pathcheck.c	Fri Mar 01 21:15:52 2013 +0100
@@ -34,6 +34,9 @@
 #include "../daemon/acldata.h"
 #include "../daemon/session.h"
 
+#include "../ucx/string.h"
+#include "../config/acl.h"
+
 int require_auth(pblock *pb, Session *sn, Request *rq) {
     char *user = pblock_findkeyval(pb_key_auth_user, rq->vars);
 
@@ -50,6 +53,23 @@
     return REQ_PROCEED;
 }
 
+int require_access(pblock *pb, Session *sn, Request *rq) {
+    char *mask_str = pblock_findval("mask", rq->vars);
+    if(!mask_str) {
+        // misconfig
+        // TODO: log
+        return REQ_ABORTED;
+    }
+    
+    uint32_t access_mask = 0;
+    size_t n = 0;
+    sstr_t *rights = sstrsplit(sstr(mask_str), sstrn(",", 1), &n);
+    for(int i=0;i<n;i++) {
+        sstr_t right = rights[i];
+        access_mask = access_mask | accstr2int(right);
+    }
+}
+
 int append_acl(pblock *pb, Session *sn, Request *rq) {
     ServerConfiguration *config = session_get_config(sn);
     
--- a/src/server/safs/pathcheck.h	Thu Feb 28 20:00:05 2013 +0100
+++ b/src/server/safs/pathcheck.h	Fri Mar 01 21:15:52 2013 +0100
@@ -37,6 +37,8 @@
 
 int require_auth(pblock *pb, Session *sn, Request *rq);
 
+int require_access(pblock *pb, Session *sn, Request *rq);
+
 int append_acl(pblock *pb, Session *sn, Request *rq);
 
 int check_acl(pblock *pb, Session *sn, Request *rq);
--- a/src/server/util/netbuf.c	Thu Feb 28 20:00:05 2013 +0100
+++ b/src/server/util/netbuf.c	Fri Mar 01 21:15:52 2013 +0100
@@ -161,7 +161,7 @@
 
 NSAPI_PUBLIC int netbuf_grab(netbuf *buf, int sz) {
     int n;
-
+    
     if(!buf->inbuf) {
         buf->inbuf = (unsigned char *) malloc(sz);
         buf->maxsize = sz;
--- a/src/server/util/object.c	Thu Feb 28 20:00:05 2013 +0100
+++ b/src/server/util/object.c	Fri Mar 01 21:15:52 2013 +0100
@@ -97,7 +97,7 @@
 
 
 
-
+// TODO: remove
 httpd_objset* create_test_objset() {
     httpd_objset *objset = malloc(sizeof(httpd_objset));
     objset->obj = calloc(1, sizeof(httpd_object*));

mercurial