diff -r b7908bf38f9f -r c6cf20b09043 src/server/daemon/vfs.c --- 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); +}