src/server/daemon/vfs.c

branch
webdav
changeset 211
2160585200ac
parent 193
aa8393527b1e
child 241
4adad7faf452
equal deleted inserted replaced
210:21274e5950af 211:2160585200ac
50 static VFS sys_vfs = { 50 static VFS sys_vfs = {
51 sys_vfs_open, 51 sys_vfs_open,
52 sys_vfs_stat, 52 sys_vfs_stat,
53 sys_vfs_fstat, 53 sys_vfs_fstat,
54 sys_vfs_opendir, 54 sys_vfs_opendir,
55 sys_vfs_fdopendir,
55 sys_vfs_mkdir, 56 sys_vfs_mkdir,
56 sys_vfs_unlink, 57 sys_vfs_unlink,
57 VFS_CHECKS_ACL 58 VFS_CHECKS_ACL,
59 NULL
58 }; 60 };
59 61
60 static VFS_IO sys_file_io = { 62 static VFS_IO sys_file_io = {
61 sys_file_read, 63 sys_file_read,
62 sys_file_write, 64 sys_file_write,
200 VFS_DIR dir = ctx->vfs->opendir(ctx, path); 202 VFS_DIR dir = ctx->vfs->opendir(ctx, path);
201 ctx->aclreqaccess = m; // restore original access mask 203 ctx->aclreqaccess = m; // restore original access mask
202 return dir; 204 return dir;
203 } 205 }
204 206
207 VFS_DIR vfs_fdopendir(VFSContext *ctx, SYS_FILE fd) {
208 WS_ASSERT(ctx);
209 WS_ASSERT(path);
210
211 uint32_t access_mask = ctx->aclreqaccess | ACL_LIST;
212
213 // ctx->aclreqaccess should be the complete access mask
214 uint32_t m = ctx->aclreqaccess; // save original access mask
215 ctx->aclreqaccess = access_mask; // set mask for vfs->open call
216 if((ctx->vfs->flags & VFS_CHECKS_ACL) != VFS_CHECKS_ACL) {
217 // VFS does not evaluates the ACL itself, so we have to do it here
218 SysACL sysacl;
219 if(sys_acl_check(ctx, access_mask, &sysacl)) {
220 return NULL;
221 }
222 }
223 VFS_DIR dir = ctx->vfs->fdopendir(ctx, fd);
224 ctx->aclreqaccess = m; // restore original access mask
225 return dir;
226 }
227
205 int vfs_readdir(VFS_DIR dir, VFS_ENTRY *entry) { 228 int vfs_readdir(VFS_DIR dir, VFS_ENTRY *entry) {
206 WS_ASSERT(dir); 229 WS_ASSERT(dir);
207 WS_ASSERT(entry); 230 WS_ASSERT(entry);
208 231
209 return dir->io->readdir(dir, entry, 0); 232 return dir->io->readdir(dir, entry, 0);
416 return NULL; 439 return NULL;
417 } 440 }
418 dir->ctx = ctx; 441 dir->ctx = ctx;
419 dir->data = dir_data; 442 dir->data = dir_data;
420 dir->fd = dir_fd; 443 dir->fd = dir_fd;
444 dir->io = &sys_dir_io;
445 return dir;
446 }
447
448 VFS_DIR sys_vfs_fdopendir(VFSContext *ctx, SYS_FILE fd) {
449 uint32_t access_mask = ctx->aclreqaccess;
450 pool_handle_t *pool = ctx->pool;
451
452 // check ACLs
453 SysACL sysacl;
454 if(sys_acl_check(ctx, access_mask, &sysacl)) {
455 return NULL;
456 }
457
458 if(sysacl.acl) {
459 if(!fs_acl_check_fd(&sysacl, ctx->user, fd->fd, access_mask)) {
460 acl_set_error_status(ctx->sn, ctx->rq, sysacl.acl, ctx->user);
461 return NULL;
462 }
463 }
464
465 // open directory
466 DIR *sys_dir = fdopendir(fd->fd);
467 if(!sys_dir) {
468 if(ctx) {
469 ctx->vfs_errno = errno;
470 sys_set_error_status(ctx);
471 }
472 return NULL;
473 }
474
475 SysVFSDir *dir_data = VFS_MALLOC(pool, sizeof(SysVFSDir));
476 if(!dir_data) {
477 closedir(sys_dir);
478 return NULL;
479 }
480 long maxfilelen = fpathconf(fd->fd, _PC_NAME_MAX);
481 size_t entry_len = offsetof(struct dirent, d_name) + maxfilelen + 1;
482 dir_data->cur = VFS_MALLOC(pool, entry_len);
483 if(!dir_data->cur) {
484 closedir(sys_dir);
485 VFS_FREE(pool, dir_data);
486 return NULL;
487 }
488 dir_data->dir = sys_dir;
489
490 VFSDir *dir = VFS_MALLOC(pool, sizeof(VFSDir));
491 if(!dir) {
492 closedir(sys_dir);
493 VFS_FREE(pool, dir_data->cur);
494 VFS_FREE(pool, dir_data);
495 return NULL;
496 }
497 dir->ctx = ctx;
498 dir->data = dir_data;
499 dir->fd = fd->fd;
421 dir->io = &sys_dir_io; 500 dir->io = &sys_dir_io;
422 return dir; 501 return dir;
423 } 502 }
424 503
425 int sys_vfs_mkdir(VFSContext *ctx, char *path) { 504 int sys_vfs_mkdir(VFSContext *ctx, char *path) {
537 return sys_dir_read(dir, entry, getstat); 616 return sys_dir_read(dir, entry, getstat);
538 } else { 617 } else {
539 entry->name = name; 618 entry->name = name;
540 if(getstat) { 619 if(getstat) {
541 // TODO: check ACLs again for new path 620 // TODO: check ACLs again for new path
621 entry->stat_errno = 0;
542 if(fstatat(dir->fd, result->d_name, &entry->stat, 0)) { 622 if(fstatat(dir->fd, result->d_name, &entry->stat, 0)) {
543 entry->stat_errno = errno; 623 entry->stat_errno = errno;
544 } 624 }
545 entry->stat_extra = NULL; 625 entry->stat_extra = NULL;
546 } 626 }

mercurial