--- 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 }