str agent_usersock (bool create_dir) { str dir = agent_userdir (myaid () & 0xffffffff, create_dir); if (!dir) return NULL; return strbuf ("%s/agent-%" U64F "d.sock", dir.cstr (), myaid ()); }
int main (int argc, char **argv) { #ifdef MAINTAINER if (getenv ("SFS_RUNINPLACE")) { setgid (getgid ()); setuid (getuid ()); } #endif /* MAINTAINER */ setprogname (argv[0]); sfsconst_init (); const uid_t procuid = getuid (); uid_t newuid = procuid; uid_t uid = myaid () & INT64 (0xffffffff); gid_t gid; bool opt_gid = false; bool opt_login = false; bool opt_nogid = false; bool opt_U = false; str opt_chdir; size_t num_u = 0; int ch; while ((ch = getopt (argc, argv, "lu:U:g:GC:")) != -1) switch (ch) { case 'l': opt_login = true; break; case 'u': if (num_u++ || !convertint (optarg, &uid)) usage (); break; case 'U': if (num_u++ || !convertint (optarg, &newuid)) usage (); uid = newuid; opt_U = true; break; case 'g': if (opt_nogid || !convertint (optarg, &gid)) usage (); opt_gid = true; break; case 'G': if (opt_gid) usage (); opt_nogid = true; case 'C': if (opt_chdir) usage (); opt_chdir = optarg; break; default: usage (); } argc -= optind; argv += optind; if (procuid && (newuid != procuid || uid != procuid)) fatal ("only root can change uids.\n"); if (!opt_gid && !opt_nogid) opt_gid = gid_alloc (&gid, uid); fixgroups (newuid != uid, uid, opt_gid, gid); if (opt_U) sfs_setlogin (newuid); if (setgid (getgid ()) < 0 || setuid (newuid) < 0) fatal ("setuid/setgid: %m\n"); vec<char *> av; char *path = argc > 0 ? argv[0] : getenv ("SHELL"); if (!path) fatal ("no SHELL environment variable\n"); av.push_back (path); for (int i = 1; i < argc; i++) av.push_back (argv[i]); av.push_back (NULL); str av0; if (opt_login) { const char *p = strrchr (path, '/'); p = p ? p + 1 : path; av0 = strbuf ("-%s", p); av[0] = const_cast<char *> (av0.cstr ()); } if (opt_chdir) { if (chdir (opt_chdir) < 0) warn << opt_chdir << ": " << strerror (errno) << "\n"; else if (opt_chdir[0] == '/') { str e (strbuf ("PWD=%s", opt_chdir.cstr ())); xputenv (e); } else if (const char *p = getenv ("PWD")) { str e (strbuf ("PWD=%s/%s", p, opt_chdir.cstr ())); xputenv (e); } } str aidvar (strbuf ("SFS_AID=") << myaid ()); xputenv (aidvar); /* The SFS libraries use asynchronous IO which some programs don't * like. Thus, we remove the O_NONBLOCK flag from stdin/stdout. */ make_sync (0); make_sync (1); execvp (path, av.base ()); warnx ("%s: %m\n", path); return 1; }