int DirNode::mkdir(const char *plaintextPath, mode_t mode, uid_t uid, gid_t gid) { string cyName = rootDir + naming->encodePath(plaintextPath); rAssert(!cyName.empty()); VLOG(1) << "mkdir on " << cyName; // if uid or gid are set, then that should be the directory owner #if 0 int olduid = -1; int oldgid = -1; if (uid != 0) olduid = setfsuid(uid); if (gid != 0) oldgid = setfsgid(gid); #endif int res = unix::mkdir(cyName.c_str(), mode); #if 0 if (olduid >= 0) setfsuid(olduid); if (oldgid >= 0) setfsgid(oldgid); #endif if (res == -1) { int eno = errno; RLOG(WARNING) << "mkdir error on " << cyName << " mode " << mode << ": " << strerror(eno); res = -eno; } else res = 0; return res; }
Result<bool> ChangeFileOrDirOwnershipToUser(const std::string& path, const std::string& username) { std::lock_guard<std::mutex> lock(mPermissionsMutex); auto previuousuid = setfsuid(-1); auto previuousgid = setfsgid(-1); setfsuid(0); setfsgid(0); struct passwd* pwd = GetUserFromPasswordFile(username); auto returnVal = chown(path.c_str(), pwd->pw_uid, pwd->pw_gid); free(pwd); if (returnVal < 0) { std::string error{"Cannot chown dir/file: "}; error.append(path); error.append(" error number: "); error.append(std::to_string(errno)); error.append(" current fs permissions are for uid: "); error.append(std::to_string(setfsuid(-1))); setfsuid(previuousuid); setfsgid(previuousgid); return Result<bool>{false, error}; } setfsuid(previuousuid); setfsgid(previuousgid); return Result<bool>{true}; }
uid_t setuser(uid_t uid) { uid_t orig_uid = setfsuid(uid); if (uid != setfsuid(uid)) LogCrit(COMPONENT_FSAL, "Could not set user identity"); return orig_uid; }
int main(int argc, char *argv[]) { #if HAVE_LIBCAP pthread_t t1, t2; assert (geteuid () == 0); diod_log_init (argv[0]); _prtcap ("task0", CAP_DAC_OVERRIDE); /* root, expect set */ _prtcap ("task0", CAP_CHOWN); msg ("task0: setfsuid 1"); setfsuid (1); _prtcap ("task0", CAP_DAC_OVERRIDE); /* non-root, expect clr */ _prtcap ("task0", CAP_CHOWN); msg ("task0: setfsuid 0"); /* root, expect set */ setfsuid (0); _prtcap ("task0", CAP_DAC_OVERRIDE); _prtcap ("task0", CAP_CHOWN); msg ("task0: setfsuid 1"); setfsuid (1); _prtcap ("task0", CAP_DAC_OVERRIDE); /* non-root, expect clr */ _prtcap ("task0", CAP_CHOWN); msg ("task0: set cap"); _setcap ("task0", CAP_DAC_OVERRIDE); _setcap ("task0", CAP_CHOWN); _prtcap ("task0", CAP_DAC_OVERRIDE); /* root with cap explicitly set, */ _prtcap ("task0", CAP_CHOWN); /* expect set */ msg ("task0: setfsuid 2"); setfsuid (2); _prtcap ("task0", CAP_DAC_OVERRIDE);/* non-root with cap explicitly set, */ _prtcap ("task0", CAP_CHOWN); /* (as root) expect set */ msg ("task0: clr cap"); _clrcap ("task0", CAP_DAC_OVERRIDE); _clrcap ("task0", CAP_CHOWN); _prtcap ("task0", CAP_DAC_OVERRIDE);/* non-root with cap explicitly clr, */ _prtcap ("task0", CAP_CHOWN); /* (as non-root) expect clr */ _create (&t1, proc1, NULL); _create (&t2, proc2, NULL); _join (t2, NULL); _join (t1, NULL); _prtcap ("task0", CAP_DAC_OVERRIDE); /* after threads, expect clr */ _prtcap ("task0", CAP_CHOWN); #else fprintf (stderr, "libcap unavailable\n"); exit (77); #endif exit (0); }
static int fsuid_chdir (uid_t uid, const char *path) { int errsv; int ret; /* Note we don't check errors here because we can't, basically */ (void) setfsuid (uid); ret = chdir (path); errsv = errno; (void) setfsuid (0); errno = errsv; return ret; }
static int fsuid_access (uid_t uid, const char *path, int mode) { int errsv; int ret; /* Note we don't check errors here because we can't, basically */ (void) setfsuid (uid); ret = access (path, mode); errsv = errno; (void) setfsuid (0); errno = errsv; return ret; }
static int drop_privs() { int res; struct __user_cap_header_struct head; struct __user_cap_data_struct newcaps; head.version = _LINUX_CAPABILITY_VERSION; head.pid = 0; res = capget(&head, &oldcaps); if(res == -1) { fprintf(stderr, "%s: failed to get capabilities: %s\n", progname, strerror(errno)); return -1; } oldfsuid = setfsuid(getuid()); oldfsgid = setfsgid(getgid()); newcaps = oldcaps; /* Keep CAP_SYS_ADMIN for mount */ newcaps.effective &= (1 << CAP_SYS_ADMIN); head.version = _LINUX_CAPABILITY_VERSION; head.pid = 0; res = capset(&head, &newcaps); if(res == -1) { fprintf(stderr, "%s: failed to set capabilities: %s\n", progname, strerror(errno)); return -1; } return 0; }
static void drop_privs(void) { if (getuid() != 0) { oldfsuid = setfsuid(getuid()); oldfsgid = setfsgid(getgid()); } }
int main(int argc, char **argv) { int ret, verbose = 0, c, opt_index, bypass = 0, decimal = 0; char *file = NULL; setfsuid(getuid()); setfsgid(getgid()); if (argc == 1) help(); while ((c = getopt_long(argc, argv, short_options, long_options, &opt_index)) != EOF) { switch (c) { case 'h': help(); break; case 'v': version(); break; case 'V': verbose = 1; break; case 'D': decimal = 1; break; case 'b': bypass = 1; break; case 'd': bpf_dump_op_table(); die(); case 'i': file = xstrdup(optarg); break; case '?': switch (optopt) { case 'i': panic("Option -%c requires an argument!\n", optopt); default: if (isprint(optopt)) printf("Unknown option character `0x%X\'!\n", optopt); die(); } default: break; } } if (argc == 2) file = xstrdup(argv[1]); if (!file) panic("No Berkeley Packet Filter program specified!\n"); ret = compile_filter(file, verbose, bypass, decimal); xfree(file); return ret; }
static void restore_privs(void) { if (getuid() != 0) { setfsuid(oldfsuid); setfsgid(oldfsgid); } }
int prepare_creds_return_uid(const char *username) { struct passwd *pwd; // First try name pwd = getpwnam(username); if (!pwd) { // Then try UID pwd = getpwuid(atoi(username)); if (!pwd) { perror("getpwuid"); exit(1); } } setenv("HOME", pwd->pw_dir, 1); setenv("USER", pwd->pw_name, 1); if (setgid(pwd->pw_gid) < 0) { perror("setgid"); exit(1); } initgroups(pwd->pw_name, pwd->pw_gid); if (setfsuid(pwd->pw_uid) < 0) { perror("setfsuid"); exit(1); } return pwd->pw_uid; }
static void meta_open(const char *name) { if (!strcmp(name, "-")) { metafile = stdout; return; } if (setfsuid(getuid()) < 0) die("Failed to switch FS UID: %m"); metafile = fopen(name, "w"); if (setfsuid(geteuid()) < 0) die("Failed to switch FS UID back: %m"); if (!metafile) die("Failed to open metafile '%s'",name); }
/* * The following functions deal with setting the client's uid/gid. */ void auth_override_uid(uid_t uid) { #if defined(HAVE_BROKEN_SETFSUID) uid = (unsigned short) uid; #endif #if defined(HAVE_SETFSUID) setfsuid(uid); #else #if defined(MAYBE_HAVE_SETFSUID) if (have_setfsuid) setfsuid(uid); else #endif seteuid(uid); #endif }
static void setfsids(uid_t cred_uid, gid_t cred_gid, gid_t * cred_gids, int cred_len) { setfsuid(cred_uid); setfsgid(cred_gid); /* First, set the user ID. */ if (auth_uid != cred_uid) { if (setfsuid(cred_uid) < 0) dbg_printf(__FILE__, __LINE__, L_ERROR, "Unable to setfsuid %d: %s\n", cred_uid, strerror(errno)); else auth_uid = cred_uid; } /* Next, the group ID. */ if (auth_gid != cred_gid) { if (setfsgid(cred_gid) < 0) dbg_printf(__FILE__, __LINE__, L_ERROR, "Unable to setfsgid %d: %s\n", cred_gid, strerror(errno)); else auth_gid = cred_gid; } #ifdef HAVE_SETGROUPS /* Finally, set the supplementary group IDs if possible. */ if (cred_len < 0 || cred_len > NGRPS) dbg_printf(__FILE__, __LINE__, L_ERROR, "Negative or huge cred_len: %d\n", cred_len); else if (cred_len != auth_gidlen || memcmp(cred_gids, auth_gids, auth_gidlen * sizeof(gid_t))) { if (setgroups(cred_len, cred_gids) < 0) dbg_printf(__FILE__, __LINE__, L_ERROR, "Unable to setgroups: %s\n", strerror(errno)); else { memcpy(auth_gids, cred_gids, cred_len * sizeof(gid_t)); auth_gidlen = cred_len; } } #endif /* HAVE_SETGROUPS */ }
int singularity_mount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data) { if ( ( mountflags & MS_BIND ) ) { setfsuid(singularity_priv_getuid()); } return mount(source, target, filesystemtype, mountflags, data); }
/* * When running as root, change the file system access to a user. */ void SetUserFileSystemAccess(const std::string& username) { struct passwd* pwd = GetUserFromPasswordFile(username); setfsuid(pwd->pw_uid); setfsgid(pwd->pw_gid); free(pwd); }
Result<std::string> ReadAsciiFileContentAsRoot(const std::string& filename) { std::lock_guard<std::mutex> lock(mPermissionsMutex); auto previuousuid = setfsuid(-1); auto previuousgid = setfsgid(-1); // RAII resource cleanup; de-escalate privileges from root to previous: std::shared_ptr<void> resetPreviousPermisions(nullptr, [&](void*) { setfsuid(previuousuid); setfsgid(previuousgid); }); setfsuid(0); setfsgid(0); auto result = ReadAsciiFileContent(filename); return result; }
static void drop_privs(void) { if (getuid() != 0) { #ifdef HAVE_SET_FSID oldfsuid = setfsuid(getuid()); oldfsgid = setfsgid(getgid()); #else fprintf(stderr, "%s: Implement alternative setfsuid/gid \n", progname); #endif } }
static void restore_privs(void) { if (getuid() != 0) { #ifdef HAVE_SET_FSID setfsuid(oldfsuid); setfsgid(oldfsgid); #else fprintf(stderr, "%s: Implement alternative setfsuid/gid \n", progname); #endif } }
int main(int ac, char **av) { int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ uid_t uid; /* parse standard options */ if ((msg = parse_opts(ac, av, (option_t *) NULL, NULL)) != (char *)NULL) { tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg); } setup(); uid = geteuid(); uid = 1; while (!getpwuid(uid)) { uid++; } /* Check for looping state if -i option is given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; TEST(setfsuid(uid)); if (TEST_RETURN == -1) { tst_resm(TFAIL, "call failed unexpectedly - errno %d", TEST_ERRNO); continue; } if (!STD_FUNCTIONAL_TEST) { tst_resm(TPASS, "call succeeded"); continue; } if (TEST_RETURN == uid) { tst_resm(TFAIL, "setfsuid() returned %ld, expected anything but %d", TEST_RETURN, uid); } else { tst_resm(TPASS, "setfsuid() returned expected value : " "%ld", TEST_RETURN); } } cleanup(); return 0; /*NOTREACHED*/}
Result<bool> RemoveFileAsRoot(const std::string& filename) { std::lock_guard<std::mutex> lock(mPermissionsMutex); auto previuousuid = setfsuid(-1); auto previuousgid = setfsgid(-1); // RAII resource cleanup; de-escalate privileges from root to previous: std::shared_ptr<void> resetPreviousPermisions(nullptr, [&](void*) { setfsuid(previuousuid); setfsgid(previuousgid); }); setfsuid(0); setfsgid(0); int rc = unlink(filename.c_str()); if (rc == -1) { return Result<bool>{false, "Unable to unlink file"}; } return Result<bool>{true}; }
/** * Create a symbolic link pointing to "to" named "from" */ int encfs_symlink(const char *to, const char *from) { EncFS_Context *ctx = context(); if (isReadOnly(ctx)) return -EROFS; int res = -EIO; std::shared_ptr<DirNode> FSRoot = ctx->getRoot(&res); if (!FSRoot) return res; try { string fromCName = FSRoot->cipherPath(from); // allow fully qualified names in symbolic links. string toCName = FSRoot->relativeCipherPath(to); VLOG(1) << "symlink " << fromCName << " -> " << toCName; // use setfsuid / setfsgid so that the new link will be owned by the // uid/gid provided by the fuse_context. int olduid = -1; int oldgid = -1; if (ctx->publicFilesystem) { fuse_context *context = fuse_get_context(); olduid = setfsuid(context->uid); oldgid = setfsgid(context->gid); } res = ::symlink(toCName.c_str(), fromCName.c_str()); if (olduid >= 0) setfsuid(olduid); if (oldgid >= 0) setfsgid(oldgid); if (res == -1) res = -errno; else res = ESUCCESS; } catch (encfs::Error &err) { RLOG(ERROR) << "error caught in symlink: " << err.what(); } return res; }
int main(int ac, char **av) { int lc; char *msg; uid_t uid; if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); uid = 1; while (getpwuid(uid)) { uid++; } /* Check for looping state if -i option is given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; TEST(setfsuid(uid)); if (TEST_RETURN == -1) { tst_resm(TFAIL, "call failed unexpectedly - errno %d", TEST_ERRNO); continue; } if (!STD_FUNCTIONAL_TEST) { tst_resm(TPASS, "call succeeded"); continue; } if (TEST_RETURN == uid) { tst_resm(TFAIL, "setfsuid() returned %ld, expected %d", TEST_RETURN, uid); } else { tst_resm(TPASS, "setfsuid() returned expected value : " "%ld", TEST_RETURN); } } cleanup(); tst_exit(); tst_exit(); }
int prepare_creds_return_uid(char *username) { struct passwd *pwd; pwd = getpwnam(username); if (!pwd) { perror("getpwnam"); exit(1); } setenv("HOME", pwd->pw_dir, 1); setenv("USER", username, 1); setgid(pwd->pw_gid); initgroups(username, pwd->pw_gid); setfsuid(pwd->pw_uid); return pwd->pw_uid; }
static void restore_privs() { struct __user_cap_header_struct head; int res; head.version = _LINUX_CAPABILITY_VERSION; head.pid = 0; res = capset(&head, &oldcaps); if(res == -1) fprintf(stderr, "%s: failed to restore capabilities: %s\n", progname, strerror(errno)); setfsuid(oldfsuid); setfsgid(oldfsgid); }
void ftpwho_exit(const int ret) { # ifndef HAVE_SYS_FSUID_H disablesignals(); # endif if (shm_data_cur != NULL) { shm_data_cur->state = FTPWHO_STATE_FREE; if ( # ifndef NO_INETD standalone == 0 && # endif chrooted != 0) { (void) msync((void *) shm_data_cur, sizeof (FTPWhoEntry), MS_ASYNC); } (void) munmap((void *) shm_data_cur, sizeof (FTPWhoEntry)); } if (mmap_fd != -1) { (void) close(mmap_fd); } # ifdef WITH_PRIVSEP if ( # ifndef NO_INETD standalone == 0 && # endif scoreboardfile != NULL) { (void) privsep_removeftpwhoentry(); } # else if ( # ifndef NO_INETD standalone == 0 && # endif chrooted == 0 && scoreboardfile != NULL) { # ifndef NON_ROOT_FTP # ifndef HAVE_SYS_FSUID_H (void) seteuid((uid_t) 0); # else (void) setfsuid((uid_t) 0); # endif # endif (void) unlink(scoreboardfile); } #endif _exit(ret); }
/* * from man 7 capabilities, section * Effect of User ID Changes on Capabilities: * 4. If the file system user ID is changed from 0 to nonzero (see setfsuid(2)) * then the following capabilities are cleared from the effective set: * CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_FOWNER, CAP_FSETID, * CAP_LINUX_IMMUTABLE (since Linux 2.2.30), CAP_MAC_OVERRIDE, and CAP_MKNOD * (since Linux 2.2.30). If the file system UID is changed from nonzero to 0, * then any of these capabilities that are enabled in the permitted set * are enabled in the effective set. */ static int setfsugid(int uid, int gid) { /* * We still need DAC_OVERRIDE because we don't change * supplementary group ids, and hence may be subjected DAC rules */ cap_value_t cap_list[] = { CAP_DAC_OVERRIDE, }; setfsgid(gid); setfsuid(uid); if (uid != 0 || gid != 0) { return do_cap_set(cap_list, ARRAY_SIZE(cap_list), 0); } return 0; }
nix_uid_t nix_linux_setfsuid(nix_uid_t uid, nix_env_t *env) { #ifdef HAVE_SETFSUID int rv; errno = 0; rv = setfsuid((uid_t)uid); if (errno != 0) { nix_env_set_errno(env, errno); return (-1); } return (rv); #else nix_uid_t last = g_fsuid; g_fsuid = uid; return (last); #endif }
int main(int argc, char *argv[]) { int type; if (argc != 3) { fprintf(stderr, "usage: %s DIR " "[rshared|rslave|rprivate|runclone|shared|slave|private|unclone]\n" , argv[0]); return 1; } fprintf(stdout, "%s %s %s\n", argv[0], argv[1], argv[2]); if (strcmp(argv[2],"rshared")==0) type=(MS_SHARED|MS_REC); else if (strcmp(argv[2],"rslave")==0) type=(MS_SLAVE|MS_REC); else if (strcmp(argv[2],"rprivate")==0) type=(MS_PRIVATE|MS_REC); else if (strcmp(argv[2],"runclone")==0) type=(MS_UNCLONE|MS_REC); else if (strcmp(argv[2],"shared")==0) type=MS_SHARED; else if (strcmp(argv[2],"slave")==0) type=MS_SLAVE; else if (strcmp(argv[2],"private")==0) type=MS_PRIVATE; else if (strcmp(argv[2],"unclone")==0) type=MS_UNCLONE; else { fprintf(stderr, "invalid operation: %s\n", argv[2]); return 1; } setfsuid(getuid()); if (mount("", argv[1], "ext2", type, "") == -1) { perror("mount"); return 1; } return 0; }
static void change_fsid (uid_t olduid, gid_t oldgid, uid_t uid, gid_t gid) { uid_t u; gid_t g; if (uid != olduid) { u = setfsuid (uid); if (u == -1) err ("setfsuid"); else if (u != olduid) msg ("setfsuid returned %d (wanted %d)", u, olduid); } if (gid != oldgid) { g = setfsgid (gid); if (g == -1) err ("setfsgid"); else if (g != oldgid) msg ("setfsgid returned %d (wanted %d)", g, oldgid); } if (!check_fsid (uid, gid)) msg_exit ("setfsuid/setfsgid failed"); msg ("fsid changed to %d:%d", uid, gid); }