Sun, 17 Mar 2013 17:54:20 +0100
added vfs_mkdir and vfs_unlink
--- a/src/server/config/acl.c Sun Mar 17 12:47:59 2013 +0100 +++ b/src/server/config/acl.c Sun Mar 17 17:54:20 2013 +0100 @@ -230,6 +230,8 @@ val = ACLCFG_WRITE_DATA; } else if(!sstrcmp(access, sstr("append"))) { val = ACLCFG_APPEND; + } else if(!sstrcmp(access, sstr("add"))) { + val = ACLCFG_ADD_FILE; } else if(!sstrcmp(access, sstr("add_file"))) { val = ACLCFG_ADD_FILE; } else if(!sstrcmp(access, sstr("add_subdirectory"))) {
--- a/src/server/daemon/vfs.c Sun Mar 17 12:47:59 2013 +0100 +++ b/src/server/daemon/vfs.c Sun Mar 17 17:54:20 2013 +0100 @@ -123,11 +123,11 @@ } SYS_FILE vfs_openWO(VFSContext *ctx, char *path) { - return vfs_open(ctx, path, O_WRONLY); + return vfs_open(ctx, path, O_WRONLY | O_CREAT); } SYS_FILE vfs_openRW(VFSContext *ctx, char *path) { - return vfs_open(ctx, path, O_RDONLY); + return vfs_open(ctx, path, O_RDONLY | O_WRONLY | O_CREAT); } int vfs_stat(VFSContext *ctx, char *path, struct stat *buf) { @@ -292,8 +292,69 @@ } } +int vfs_mkdir(VFSContext *ctx, char *path) { + if(ctx && ctx->vfs) { + return vfs_path_op(ctx, path, ctx->vfs->mkdir, ACL_ADD_FILE); + } else { + return vfs_path_op(ctx, path, sys_mkdir, ACL_ADD_FILE); + } +} + +int vfs_unlink(VFSContext *ctx, char *path) { + if(ctx && ctx->vfs) { + return vfs_path_op(ctx, path, ctx->vfs->unlink, ACL_DELETE); + } else { + return vfs_path_op(ctx, path, sys_unlink, ACL_DELETE); + } +} + // private +int vfs_path_op(VFSContext *ctx, char *path, vfs_op_f op, uint32_t access) { + Session *sn; + Request *rq; + uint32_t access_mask; + + if(ctx) { + access_mask = ctx->aclreqaccess; + access_mask |= access; + if(!ctx->pool) { + // TODO: log warning + // broken VFSContext + } + if(ctx->vfs) { + // ctx->aclreqaccess should be the complete access mask + uint32_t m = ctx->aclreqaccess; // save original access mask + ctx->aclreqaccess = access_mask; // set mask for vfs->fstat call + int ret = op(ctx, path); + ctx->aclreqaccess = m; // restore original access mask + return ret; + } + } else { + sn = NULL; + rq = NULL; + access_mask = access; + } + + // check ACLs + uid_t uid; // uid and gid will be initialized by sys_acl_check + gid_t gid; + if(sys_acl_check(ctx, access_mask, &uid, &gid)) { + return NULL; + } + + // do path operation + if(op(ctx, path)) { + // error + if(ctx) { + ctx->vfs_errno = errno; + sys_set_error_status(ctx); + } + return -1; + } + + return 0; +} int sys_acl_check(VFSContext *ctx, uint32_t acm, uid_t *uid, gid_t *gid) { /* @@ -329,17 +390,7 @@ void sys_set_error_status(VFSContext *ctx) { if(ctx->sn && ctx->rq) { - int status = 500; - switch(ctx->vfs_errno) { - case EACCES: { - status = 403; - break; - } - case ENOENT: { - status = 404; - break; - } - } + int status = util_errno2status(ctx->vfs_errno); protocol_status(ctx->sn, ctx->rq, status, NULL); } } @@ -375,3 +426,12 @@ void sys_dir_close(VFS_DIR dir) { closedir(dir->data); } + +int sys_mkdir(VFSContext *ctx, char *path) { + mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + return mkdir(path, mode); +} + +int sys_unlink(VFSContext *ctx, char *path) { + return unlink(path); +}
--- a/src/server/daemon/vfs.h Sun Mar 17 12:47:59 2013 +0100 +++ b/src/server/daemon/vfs.h Sun Mar 17 17:54:20 2013 +0100 @@ -50,6 +50,8 @@ int (*stat)(VFSContext *ctx, char *path, struct stat *buf); int (*fstat)(VFSContext *ctx, SYS_FILE fd, struct stat *buf); VFS_DIR (*opendir)(VFSContext *ctx, char *path); + int (*mkdir)(VFSContext *ctx, char *path); + int (*unlink)(VFSContext *ctx, char *path); }; struct VFSContext { @@ -111,8 +113,13 @@ int vfs_readdir(VFS_DIR dir, VFS_ENTRY *entry); int vfs_readdir_stat(VFS_DIR dir, VFS_ENTRY *entry); void vfs_closedir(VFS_DIR dir); +int vfs_mkdir(VFSContext *ctx, char *path); +int vfs_unlink(VFSContext *ctx, char *path); // private +typedef int(*vfs_op_f)(VFSContext *, char *); +int vfs_path_op(VFSContext *ctx, char *path, vfs_op_f op, uint32_t access); + int sys_acl_check(VFSContext *ctx, uint32_t acm, uid_t *uid, gid_t *gid); void sys_set_error_status(VFSContext *ctx); ssize_t sys_file_read(SYS_FILE fd, void *buf, size_t nbyte); @@ -120,6 +127,8 @@ void sys_file_close(SYS_FILE fd); int sys_dir_read(VFS_DIR dir, VFS_ENTRY *entry, int getstat); void sys_dir_close(VFS_DIR dir); +int sys_mkdir(VFSContext *ctx, char *path); +int sys_unlink(VFSContext *ctx, char *path); #ifdef __cplusplus }
--- a/src/server/public/nsapi.h Sun Mar 17 12:47:59 2013 +0100 +++ b/src/server/public/nsapi.h Sun Mar 17 17:54:20 2013 +0100 @@ -1315,6 +1315,8 @@ #define netbuf_getbytes netbuf_getbytes #define netbuf_grab netbuf_grab +NSAPI_PUBLIC int util_errno2status(int errno_value); +#define util_errno2status util_errno2status /* end new macro and function definitions */
--- a/src/server/safs/service.c Sun Mar 17 12:47:59 2013 +0100 +++ b/src/server/safs/service.c Sun Mar 17 17:54:20 2013 +0100 @@ -41,14 +41,6 @@ #include <errno.h> -// TODO: system sendfile Abstraktionen in neue Datei auslagern -/* -ssize_t sys_sendfile(int out_fd, int in_fd, off_t *off, size_t len) { - -} -*/ -#define sys_sendfile sendfile - /* * prepares for servicing a file
--- a/src/server/util/util.c Sun Mar 17 12:47:59 2013 +0100 +++ b/src/server/util/util.c Sun Mar 17 17:54:20 2013 +0100 @@ -49,6 +49,8 @@ //include "nspr.h" +#include <errno.h> + #include "../daemon/netsite.h" #include "../public/nsapi.h" @@ -172,3 +174,20 @@ return rv; } #endif + + +NSAPI_PUBLIC int util_errno2status(int errno_value) { + switch(errno_value) { + case 0: { + return 200; + } + case EACCES: { + return 403; + } + case ENOENT: { + return 404; + break; + } + } + return 500; +}
--- a/src/server/webdav/webdav.c Sun Mar 17 12:47:59 2013 +0100 +++ b/src/server/webdav/webdav.c Sun Mar 17 17:54:20 2013 +0100 @@ -36,6 +36,7 @@ #include "../util/pblock.h" #include "../util/date.h" +#include "../daemon/vfs.h" #include "../daemon/protocol.h" #include "davparser.h" @@ -158,12 +159,12 @@ int webdav_mkcol(pblock *pb, Session *sn, Request *rq) { char *ppath = pblock_findkeyval(pb_key_ppath, rq->vars); - int status = 201; - if(mkdir(ppath, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) { - status = 403; + VFSContext *vfs = vfs_request_context(sn, rq); + if(vfs_mkdir(vfs, ppath)) { + return REQ_ABORTED; } - protocol_status(sn, rq, status, NULL); + protocol_status(sn, rq, 201, NULL); pblock_removekey(pb_key_content_type, rq->srvhdrs); pblock_nninsert("content-length", 0, rq->srvhdrs); http_start_response(sn, rq);