src/server/daemon/acl.c

changeset 54
3a1d5a52adfc
parent 53
5ec9abba1027
child 63
66442f81f823
--- a/src/server/daemon/acl.c	Fri Mar 01 22:44:54 2013 +0100
+++ b/src/server/daemon/acl.c	Sat Mar 16 23:11:34 2013 +0100
@@ -79,17 +79,25 @@
     acllist_add(sn, rq, acl, 0);
 }
 
+uint32_t acl_oflag2mask(int oflags) {
+    /* TODO:
+     * maybe there is a plattform where O_RDWR is not O_RDONLY | O_WRONLY
+     */
+    uint32_t access_mask = 0;
+    if((oflags & O_RDONLY) == O_RDONLY) {
+        access_mask |= ACL_READ_DATA;
+    }
+    if((oflags & O_WRONLY) == O_WRONLY) {
+        access_mask |= ACL_WRITE_DATA;
+    }
+    return access_mask;
+}
 
-int acl_evaluate(Session *sn, Request *rq, int access_mask) {
-    ACLListHandle *list = rq->acllist;
-    if(!list) {
-        return REQ_PROCEED;
+User* acllist_getuser(Session *sn, Request *rq, ACLListHandle *list) {
+    if(!sn || !rq || !list) {
+        return NULL;
     }
     
-    // we combine access_mask with the required access rights
-    access_mask = access_mask | rq->aclreqaccess;
-    
-    
     // get user
     User *user = NULL;
     if(list->defaultauthdb) {
@@ -99,62 +107,98 @@
             user = list->defaultauthdb->get_user(list->defaultauthdb, usr);
             if(!user) {
                 // wrong user name
-                return REQ_ABORTED;
+                return NULL;
             }
             if(!user->verify_password(user, pw)) {
                 // wrong password
                 user->free(user);
-                return REQ_ABORTED;
+                return NULL;
             }
             // ok - user is authenticated
         }
+    }
+    
+    return user;
+}
+
+void acl_set_error_status(Session *sn, Request *rq, ACLList *acl, User *user) {
+    if(!user) {
+        char *value = NULL;
+        if(acl->authprompt) {
+            size_t realmlen = strlen(acl->authprompt);
+            size_t len = realmlen + 16;
+            value = pool_malloc(sn->pool, len);
+            if(value) {
+                snprintf(
+                        value,
+                        len,
+                        "Basic realm=\"%s\"",
+                        acl->authprompt);
+            }
+        }
+        if(!value) {
+            value = "Basic realm=\"login\"";
+        }
+        pblock_nvinsert("www-authenticate", value, rq->srvhdrs);
+        protocol_status(sn, rq, PROTOCOL_UNAUTHORIZED, NULL);
     } else {
-        // TODO
+        protocol_status(sn, rq, PROTOCOL_FORBIDDEN, NULL);
+    }
+}
+
+int acl_evaluate(Session *sn, Request *rq, int access_mask) {
+    ACLListHandle *list = rq->acllist;
+    if(!list) {
+        return REQ_PROCEED;
+    }
+    
+    // we combine access_mask with the required access rights
+    access_mask |= rq->aclreqaccess;
+    
+    // get user
+    User *user = acllist_getuser(sn, rq, list);
+    
+    // evalutate all ACLs
+    ACLList *acl = acl_evallist(list, user, access_mask);
+    if(acl) {
+        acl_set_error_status(sn, rq, acl, user);
+        // TODO: don't free the user here
+        if(user) {
+            user->free(user);
+        }
         return REQ_ABORTED;
     }
     
+    // access allowed, we can free the user
+    if(user) {
+        user->free(user);
+    }
+    
+    return REQ_PROCEED;
+}
+
+ACLList* acl_evallist(ACLListHandle *list, User *user, int access_mask) {
+    if(!list) {
+        return NULL;
+    }
+    
     // evaluate each acl until one denies access
     ACLListElm *elm = list->listhead;
     while(elm) {
         ACLList *acl = elm->acl;
-        if(!wsacl_check(acl, user, access_mask)) {
+        if(!acl->check(acl, user, access_mask)) {
             // the acl denies access
-            
-            if(!user) {
-                char *value = NULL;
-                if(acl->authprompt) {
-                    size_t realmlen = strlen(acl->authprompt);
-                    size_t len = realmlen + 16;
-                    value = pool_malloc(sn->pool, len);
-                    if(value) {
-                        snprintf(
-                                value,
-                                len,
-                                "Basic realm=\"%s\"",
-                                acl->authprompt);
-                    }
-                }
-                if(!value) {
-                    value = "Basic realm=\"login\"";
-                }
-                pblock_nvinsert("www-authenticate", value, rq->srvhdrs);
-                protocol_status(sn, rq, PROTOCOL_UNAUTHORIZED, NULL);
-            } else {
-                user->free(user);
-            }
-            return REQ_ABORTED;
+            return acl;
         } 
         elm = elm->next;
     }
     
     // ok - all acls allowed access
-    if(user) {
-        user->free(user);
-    }
-    return REQ_PROCEED;
+    
+    return NULL;
 }
 
-int wsacl_affects_user(ACLEntry *ace, User *user) {
+int wsacl_affects_user(WSAce *ace, User *user) {
     int check_access = 0;
     
     /*
@@ -192,17 +236,16 @@
     return check_access;
 }
 
-int wsacl_check(ACLList *acl, User *user, int access_mask) { 
+int wsacl_check(WSAcl *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];   
+        WSAce *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 |
-                        (access_mask & ace->access_mask);
+                allowed_access |= (access_mask & ace->access_mask);
                 // check if we have all requested rights
                 if((allowed_access & access_mask) == access_mask) {
                     allow = 1;
@@ -221,5 +264,5 @@
     
     // TODO: events
     
-    return allow;
+    return allow; // allow is 0, if no ace set it to 1
 }

mercurial