return 0;
}
+int get_owner(char *path, uid_t *uid)
+{
+ int ret;
+ struct stat st;
+
+ bzero(&st, sizeof(st));
+ ret = lstat(path, &st);
+ if (ret == -1) {
+ DEBUG(DEBUG_ERR, (__location__ " Failed to lstat(%s) %s\n", path, strerror(errno)));
+ return -EIO;
+ }
+
+ *uid = st.st_uid;
+ return 0;
+}
+
static void unlink_object(const char *path)
{
char *rmcmd = NULL;
}
*sptr = 0;
- if (ppath[0] == 0) {
- free(ppath);
- ppath = NULL;
- goto finished;
- }
-
finished:
return ppath;
}
{
char *new_path = NULL;
char *old_path = NULL;
+ uid_t uid = fuse_get_context()->uid;
int ret;
if (!read_write) {
DEBUG(DEBUG_DEBUG, (__location__ " MKNOD:%s mode:%o rdev:%x\n", path, (int)mode, (int)rdev));
- ret = switch_to_real_user();
- if (ret != 0) {
- DEBUG(DEBUG_ERR, (__location__ " SETEUID failed\n"));
+ if (uid != 0) {
+ ret = -EPERM;
goto finished;
}
-
ret = mknod(old_path, mode, rdev);
if (ret != 0) {
DEBUG(DEBUG_DEBUG,(__location__ " MKNOD %s mode:%o rdev:%x failed with errno:%u\n", old_path, mode, (int)rdev, errno));
/* if the mknod was successful we try to delete any local cached
entries for this name
*/
- switch_back_to_root();
unlink_object(new_path);
unlink_parent_dir_cache(new_path);
finished:
- switch_back_to_root();
if (old_path != NULL) {
free(old_path);
}
{
char *new_path = NULL;
char *old_path = NULL;
+ uid_t obj_uid;
+ uid_t uid = fuse_get_context()->uid;
int ret;
if (!read_write) {
goto finished;
}
-
DEBUG(DEBUG_DEBUG, (__location__ " CHMOD:%s mode:%o\n", path, mode));
- ret = switch_to_real_user();
+ ret = get_owner(old_path, &obj_uid);
if (ret != 0) {
- DEBUG(DEBUG_ERR, (__location__ " SETEUID failed\n"));
+ DEBUG(DEBUG_ERR, (__location__ " get_owner failed\n"));
goto finished;
}
+ if ((uid != obj_uid) && (uid != 0)) {
+ ret = -EPERM;
+ goto finished;
+ }
ret = chmod(old_path, mode);
if (ret != 0) {
/* if the chmod was successful we try to delete any local cached
entries for this name
*/
- switch_back_to_root();
unlink_object(new_path);
unlink_parent_dir_cache(new_path);
finished:
- switch_back_to_root();
if (old_path != NULL) {
free(old_path);
}
{
char *new_path = NULL;
char *old_path = NULL;
+ uid_t obj_uid;
+ uid_t uid = fuse_get_context()->uid;
int ret;
if (!read_write) {
DEBUG(DEBUG_DEBUG, (__location__ " UTIME %s\n", path));
- ret = switch_to_real_user();
+ ret = get_owner(old_path, &obj_uid);
if (ret != 0) {
- DEBUG(DEBUG_ERR, (__location__ " SETEUID failed\n"));
+ DEBUG(DEBUG_ERR, (__location__ " get_owner failed\n"));
goto finished;
}
+ if ((uid != obj_uid) && (uid != 0)) {
+ ret = -EPERM;
+ goto finished;
+ }
ret = utime(old_path, times);
if (ret != 0) {
/* if the utime was successful we try to delete any local cached
entries for this name
*/
- switch_back_to_root();
unlink_object(new_path);
unlink_parent_dir_cache(new_path);
finished:
- switch_back_to_root();
if (old_path != NULL) {
free(old_path);
}
{
char *new_path = NULL;
char *old_path = NULL;
+ uid_t uid = fuse_get_context()->uid;
+ gid_t gid = fuse_get_context()->gid;
int ret;
if (!read_write) {
DEBUG(DEBUG_DEBUG, (__location__ " TRUNCATE %s offset %d\n", path, (int)offset));
- ret = switch_to_real_user();
+ ret = verify_permission(uid, gid, old_path, CAN_WRITE);
if (ret != 0) {
- DEBUG(DEBUG_ERR, (__location__ " SETEUID failed\n"));
goto finished;
}
-
ret = truncate(old_path, offset);
if (ret != 0) {
DEBUG(DEBUG_DEBUG,(__location__ " TRUNCATE %s offset %d failed with errno:%u\n", old_path, (int)offset, errno));
/* if the truncate was successful we try to delete any local cached
entries for this name
*/
- switch_back_to_root();
unlink_object(new_path);
unlink_parent_dir_cache(new_path);
finished:
- switch_back_to_root();
if (old_path != NULL) {
free(old_path);
}