src/server/daemon/vfs.c

changeset 56
c6cf20b09043
parent 55
b7908bf38f9f
child 57
b3a89736b23e
equal deleted inserted replaced
55:b7908bf38f9f 56:c6cf20b09043
121 SYS_FILE vfs_openRO(VFSContext *ctx, char *path) { 121 SYS_FILE vfs_openRO(VFSContext *ctx, char *path) {
122 return vfs_open(ctx, path, O_RDONLY); 122 return vfs_open(ctx, path, O_RDONLY);
123 } 123 }
124 124
125 SYS_FILE vfs_openWO(VFSContext *ctx, char *path) { 125 SYS_FILE vfs_openWO(VFSContext *ctx, char *path) {
126 return vfs_open(ctx, path, O_WRONLY); 126 return vfs_open(ctx, path, O_WRONLY | O_CREAT);
127 } 127 }
128 128
129 SYS_FILE vfs_openRW(VFSContext *ctx, char *path) { 129 SYS_FILE vfs_openRW(VFSContext *ctx, char *path) {
130 return vfs_open(ctx, path, O_RDONLY); 130 return vfs_open(ctx, path, O_RDONLY | O_WRONLY | O_CREAT);
131 } 131 }
132 132
133 int vfs_stat(VFSContext *ctx, char *path, struct stat *buf) { 133 int vfs_stat(VFSContext *ctx, char *path, struct stat *buf) {
134 Session *sn; 134 Session *sn;
135 Request *rq; 135 Request *rq;
290 } else { 290 } else {
291 free(dir); 291 free(dir);
292 } 292 }
293 } 293 }
294 294
295 int vfs_mkdir(VFSContext *ctx, char *path) {
296 if(ctx && ctx->vfs) {
297 return vfs_path_op(ctx, path, ctx->vfs->mkdir, ACL_ADD_FILE);
298 } else {
299 return vfs_path_op(ctx, path, sys_mkdir, ACL_ADD_FILE);
300 }
301 }
302
303 int vfs_unlink(VFSContext *ctx, char *path) {
304 if(ctx && ctx->vfs) {
305 return vfs_path_op(ctx, path, ctx->vfs->unlink, ACL_DELETE);
306 } else {
307 return vfs_path_op(ctx, path, sys_unlink, ACL_DELETE);
308 }
309 }
310
295 311
296 // private 312 // private
313 int vfs_path_op(VFSContext *ctx, char *path, vfs_op_f op, uint32_t access) {
314 Session *sn;
315 Request *rq;
316 uint32_t access_mask;
317
318 if(ctx) {
319 access_mask = ctx->aclreqaccess;
320 access_mask |= access;
321 if(!ctx->pool) {
322 // TODO: log warning
323 // broken VFSContext
324 }
325 if(ctx->vfs) {
326 // ctx->aclreqaccess should be the complete access mask
327 uint32_t m = ctx->aclreqaccess; // save original access mask
328 ctx->aclreqaccess = access_mask; // set mask for vfs->fstat call
329 int ret = op(ctx, path);
330 ctx->aclreqaccess = m; // restore original access mask
331 return ret;
332 }
333 } else {
334 sn = NULL;
335 rq = NULL;
336 access_mask = access;
337 }
338
339 // check ACLs
340 uid_t uid; // uid and gid will be initialized by sys_acl_check
341 gid_t gid;
342 if(sys_acl_check(ctx, access_mask, &uid, &gid)) {
343 return NULL;
344 }
345
346 // do path operation
347 if(op(ctx, path)) {
348 // error
349 if(ctx) {
350 ctx->vfs_errno = errno;
351 sys_set_error_status(ctx);
352 }
353 return -1;
354 }
355
356 return 0;
357 }
297 358
298 int sys_acl_check(VFSContext *ctx, uint32_t acm, uid_t *uid, gid_t *gid) { 359 int sys_acl_check(VFSContext *ctx, uint32_t acm, uid_t *uid, gid_t *gid) {
299 /* 360 /*
300 * we don't allow remote root access, so a uid of 0 means that 361 * we don't allow remote root access, so a uid of 0 means that
301 * no file system acl check is needed 362 * no file system acl check is needed
327 return 0; 388 return 0;
328 } 389 }
329 390
330 void sys_set_error_status(VFSContext *ctx) { 391 void sys_set_error_status(VFSContext *ctx) {
331 if(ctx->sn && ctx->rq) { 392 if(ctx->sn && ctx->rq) {
332 int status = 500; 393 int status = util_errno2status(ctx->vfs_errno);
333 switch(ctx->vfs_errno) {
334 case EACCES: {
335 status = 403;
336 break;
337 }
338 case ENOENT: {
339 status = 404;
340 break;
341 }
342 }
343 protocol_status(ctx->sn, ctx->rq, status, NULL); 394 protocol_status(ctx->sn, ctx->rq, status, NULL);
344 } 395 }
345 } 396 }
346 397
347 ssize_t sys_file_read(SYS_FILE fd, void *buf, size_t nbyte) { 398 ssize_t sys_file_read(SYS_FILE fd, void *buf, size_t nbyte) {
373 } 424 }
374 425
375 void sys_dir_close(VFS_DIR dir) { 426 void sys_dir_close(VFS_DIR dir) {
376 closedir(dir->data); 427 closedir(dir->data);
377 } 428 }
429
430 int sys_mkdir(VFSContext *ctx, char *path) {
431 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
432 return mkdir(path, mode);
433 }
434
435 int sys_unlink(VFSContext *ctx, char *path) {
436 return unlink(path);
437 }

mercurial