diff options
author | Martin Pärtel <martin.partel@gmail.com> | 2012-05-18 12:30:31 +0300 |
---|---|---|
committer | Martin Pärtel <martin.partel@gmail.com> | 2012-05-18 12:30:31 +0300 |
commit | 1cfc042b5a5e6dc8ea5d81d9d719d472a1800167 (patch) | |
tree | 3d1eb3f2d8661d90d57d2f0364bee3ed9eba7fbb /src | |
parent | cb4cf90bd7e13ecb7b2a286d548fe853796948c4 (diff) | |
download | bindfs-1cfc042b5a5e6dc8ea5d81d9d719d472a1800167.tar.gz |
Fixed --create-as-user.
Diffstat (limited to 'src')
-rw-r--r-- | src/bindfs.c | 131 | ||||
-rw-r--r-- | src/usermap.c | 24 | ||||
-rw-r--r-- | src/usermap.h | 14 |
3 files changed, 51 insertions, 118 deletions
diff --git a/src/bindfs.c b/src/bindfs.c index 3bda72f..b0cd9a0 100644 --- a/src/bindfs.c +++ b/src/bindfs.c @@ -68,7 +68,7 @@ #include "misc.h" /* SETTINGS */ -static struct settings { +static struct Settings { const char *progname; struct permchain *permchain; /* permission bit rules. see permchain.h */ uid_t new_uid; /* user-specified uid */ @@ -143,9 +143,12 @@ static int is_mirrored_user(uid_t uid); /* Processes the virtual path to a real path. Don't free() the result. */ static const char *process_path(const char *path); -/* The common parts of getattr and fgetattr */ +/* The common parts of getattr and fgetattr. */ static int getattr_common(const char *path, struct stat *stbuf); +/* Chowns a new file if necessary. */ +static void chown_new_file(const char *path, struct fuse_context *fc, int (*chown_func)(const char*, uid_t, gid_t)); + /* FUSE callbacks */ static void *bindfs_init(); @@ -240,8 +243,8 @@ static int getattr_common(const char *procpath, struct stat *stbuf) stbuf->st_ctime = stbuf->st_mtime; /* Possibly map user/group */ - stbuf->st_uid = usermap_get_uid(settings.usermap, stbuf->st_uid); - stbuf->st_gid = usermap_get_gid(settings.usermap, stbuf->st_gid); + stbuf->st_uid = usermap_get_uid_or_default(settings.usermap, stbuf->st_uid, stbuf->st_uid); + stbuf->st_gid = usermap_get_gid_or_default(settings.usermap, stbuf->st_gid, stbuf->st_gid); /* Report user-defined owner/group if specified */ if (settings.new_uid != -1) @@ -280,6 +283,34 @@ static int getattr_common(const char *procpath, struct stat *stbuf) return 0; } +static void chown_new_file(const char *path, struct fuse_context *fc, int (*chown_func)(const char*, uid_t, gid_t)) +{ + uid_t file_owner; + gid_t file_group; + + if (settings.create_policy == CREATE_AS_USER) { + file_owner = fc->uid; + file_group = fc->gid; + } else { + file_owner = -1; + file_group = -1; + } + + file_owner = usermap_get_uid_or_default(settings.usermap_reverse, fc->uid, file_owner); + file_group = usermap_get_gid_or_default(settings.usermap_reverse, fc->gid, file_group); + + if (settings.create_for_uid != -1) + file_owner = settings.create_for_uid; + if (settings.create_for_gid != -1) + file_group = settings.create_for_gid; + + if ((file_owner != -1) || (file_group != -1)) { + if (chown_func(path, file_owner, file_group) == -1) { + DPRINTF("Failed to chown new file or directory (%d)", errno); + } + } +} + static void *bindfs_init() { assert(settings.permchain != NULL); @@ -392,8 +423,6 @@ static int bindfs_mknod(const char *path, mode_t mode, dev_t rdev) { int res; struct fuse_context *fc; - uid_t file_owner; - gid_t file_group; path = process_path(path); @@ -407,25 +436,7 @@ static int bindfs_mknod(const char *path, mode_t mode, dev_t rdev) return -errno; fc = fuse_get_context(); - - if (settings.create_policy == CREATE_AS_USER) { - file_owner = fc->uid; - file_group = fc->gid; - } - - file_owner = usermap_get_uid_or_none(settings.usermap_reverse, fc->uid); - file_group = usermap_get_gid_or_none(settings.usermap_reverse, fc->gid); - - if (settings.create_for_uid != -1) - file_owner = settings.create_for_uid; - if (settings.create_for_gid != -1) - file_group = settings.create_for_gid; - - if ((file_owner != -1) || (file_group != -1)) { - if (chown(path, file_owner, file_group) == -1) { - DPRINTF("Failed to chown new device node (%d)", errno); - } - } + chown_new_file(path, fc, &chown); return 0; } @@ -434,8 +445,6 @@ static int bindfs_mkdir(const char *path, mode_t mode) { int res; struct fuse_context *fc; - uid_t file_owner; - gid_t file_group; path = process_path(path); @@ -447,25 +456,7 @@ static int bindfs_mkdir(const char *path, mode_t mode) return -errno; fc = fuse_get_context(); - - if (settings.create_policy == CREATE_AS_USER) { - file_owner = fc->uid; - file_group = fc->gid; - } - - file_owner = usermap_get_uid_or_none(settings.usermap_reverse, fc->uid); - file_group = usermap_get_gid_or_none(settings.usermap_reverse, fc->gid); - - if (settings.create_for_uid != -1) - file_owner = settings.create_for_uid; - if (settings.create_for_gid != -1) - file_group = settings.create_for_gid; - - if ((file_owner != -1) || (file_group != -1)) { - if (chown(path, file_owner, file_group) == -1) { - DPRINTF("Failed to chown new directory (%d)", errno); - } - } + chown_new_file(path, fc, &chown); return 0; } @@ -500,8 +491,6 @@ static int bindfs_symlink(const char *from, const char *to) { int res; struct fuse_context *fc; - uid_t file_owner; - gid_t file_group; to = process_path(to); @@ -510,25 +499,7 @@ static int bindfs_symlink(const char *from, const char *to) return -errno; fc = fuse_get_context(); - - if (settings.create_policy == CREATE_AS_USER) { - file_owner = fc->uid; - file_group = fc->gid; - } - - file_owner = usermap_get_uid_or_none(settings.usermap_reverse, fc->uid); - file_group = usermap_get_gid_or_none(settings.usermap_reverse, fc->gid); - - if (settings.create_for_uid != -1) - file_owner = settings.create_for_uid; - if (settings.create_for_gid != -1) - file_group = settings.create_for_gid; - - if ((file_owner != -1) || (file_group != -1)) { - if (lchown(to, file_owner, file_group) == -1) { - DPRINTF("Failed to lchown new symlink (%d)", errno); - } - } + chown_new_file(to, fc, &lchown); return 0; } @@ -615,7 +586,7 @@ static int bindfs_chown(const char *path, uid_t uid, gid_t gid) if (uid != -1) { switch (settings.chown_policy) { case CHOWN_NORMAL: - uid = usermap_get_uid(settings.usermap_reverse, uid); + uid = usermap_get_uid_or_default(settings.usermap_reverse, uid, uid); break; case CHOWN_IGNORE: uid = -1; @@ -628,7 +599,7 @@ static int bindfs_chown(const char *path, uid_t uid, gid_t gid) if (gid != -1) { switch (settings.chgrp_policy) { case CHGRP_NORMAL: - gid = usermap_get_gid(settings.usermap_reverse, gid); + gid = usermap_get_gid_or_default(settings.usermap_reverse, gid, gid); break; case CHGRP_IGNORE: gid = -1; @@ -691,8 +662,6 @@ static int bindfs_create(const char *path, mode_t mode, struct fuse_file_info *f { int fd; struct fuse_context *fc; - uid_t file_owner; - gid_t file_group; path = process_path(path); @@ -704,25 +673,7 @@ static int bindfs_create(const char *path, mode_t mode, struct fuse_file_info *f return -errno; fc = fuse_get_context(); - - if (settings.create_policy == CREATE_AS_USER) { - file_owner = fc->uid; - file_group = fc->gid; - } - - file_owner = usermap_get_uid_or_none(settings.usermap_reverse, fc->uid); - file_group = usermap_get_gid_or_none(settings.usermap_reverse, fc->gid); - - if (settings.create_for_uid != -1) - file_owner = settings.create_for_uid; - if (settings.create_for_gid != -1) - file_group = settings.create_for_gid; - - if ((file_owner != -1) || (file_group != -1)) { - if (chown(path, file_owner, file_group) == -1) { - DPRINTF("Failed to chown new file (%d)", errno); - } - } + chown_new_file(path, fc, &chown); fi->fh = fd; return 0; diff --git a/src/usermap.c b/src/usermap.c index b900296..0cffa33 100644 --- a/src/usermap.c +++ b/src/usermap.c @@ -48,7 +48,7 @@ UsermapStatus usermap_add_uid(UserMap *map, uid_t from, uid_t to) map->user_from = (uid_t*)realloc(map->user_from, map->user_capacity * sizeof(uid_t)); map->user_to = (uid_t*)realloc(map->user_to, map->user_capacity * sizeof(uid_t)); } - if (usermap_get_uid(map, from) != from) { + if (usermap_get_uid_or_default(map, from, -1) != -1) { return usermap_status_duplicate_key; } i = map->user_size; @@ -69,7 +69,7 @@ UsermapStatus usermap_add_gid(UserMap *map, gid_t from, gid_t to) map->group_from = (gid_t*)realloc(map->group_from, map->group_capacity * sizeof(gid_t)); map->group_to = (gid_t*)realloc(map->group_to, map->group_capacity * sizeof(gid_t)); } - if (usermap_get_gid(map, from) != from) { + if (usermap_get_gid_or_default(map, from, -1) != -1) { return usermap_status_duplicate_key; } i = map->group_size; @@ -88,19 +88,7 @@ const char* usermap_errorstr(UsermapStatus status) } } -uid_t usermap_get_uid(UserMap *map, uid_t u) -{ - uid_t result = usermap_get_uid_or_none(map, u); - return (result != -1 ? result : u); -} - -gid_t usermap_get_gid(UserMap *map, gid_t g) -{ - gid_t result = usermap_get_gid_or_none(map, g); - return (result != -1 ? result : g); -} - -uid_t usermap_get_uid_or_none(UserMap *map, uid_t u) +uid_t usermap_get_uid_or_default(UserMap *map, uid_t u, uid_t deflt) { int i; for (i = 0; i < map->user_size; ++i) { @@ -108,10 +96,10 @@ uid_t usermap_get_uid_or_none(UserMap *map, uid_t u) return map->user_to[i]; } } - return -1; + return deflt; } -gid_t usermap_get_gid_or_none(UserMap *map, gid_t g) +gid_t usermap_get_gid_or_default(UserMap *map, gid_t g, gid_t deflt) { int i; for (i = 0; i < map->group_size; ++i) { @@ -119,5 +107,5 @@ gid_t usermap_get_gid_or_none(UserMap *map, gid_t g) return map->group_to[i]; } } - return -1; + return deflt; } diff --git a/src/usermap.h b/src/usermap.h index 8a74bb1..9c1387e 100644 --- a/src/usermap.h +++ b/src/usermap.h @@ -45,16 +45,10 @@ UsermapStatus usermap_add_gid(UserMap *map, gid_t from, gid_t to); const char* usermap_errorstr(UsermapStatus status); -/* Returns the uid that u is mapped to, or u if none. */ -uid_t usermap_get_uid(UserMap *map, uid_t u); +/* Returns the uid that u is mapped to, or deflt if none. */ +uid_t usermap_get_uid_or_default(UserMap *map, uid_t u, uid_t deflt); -/* Returns the gid that g is mapped to, or g if none. */ -gid_t usermap_get_gid(UserMap *map, gid_t g); - -/* Returns the uid that u is mapped to, or -1 if none. */ -uid_t usermap_get_uid_or_none(UserMap *map, uid_t u); - -/* Returns the gid that g is mapped to, or -1 if none. */ -gid_t usermap_get_gid_or_none(UserMap *map, gid_t g); +/* Returns the gid that g is mapped to, or deflt if none. */ +gid_t usermap_get_gid_or_default(UserMap *map, gid_t g, gid_t deflt); #endif |