u_int32_t sfsserv::authalloc (const sfsauth_cred *cp, u_int n) { u_int32_t authno; for (u_int i = 0; i < n; i++) { const sfsauth_cred &c = cp[i]; switch (c.type) { case SFS_UNIXCRED: case SFS_NOCRED: { if (!(authno = authnoalloc ())) return 0; if (c.type == SFS_UNIXCRED) { const sfs_unixcred &uc = *c.unixcred; authtab[authno] = authunixint_create ("localhost", uc.uid, uc.gid, uc.groups.size (), uc.groups.base ()); credtab[authno] = c; } else { authtab[authno] = authuint_create (authno); credtab[authno].set_type (SFS_NOCRED); } return authno; } default: break; } } return 0; }
static bool gid_alloc (gid_t *gidp, uid_t uid) { str path (sfssockdir << "/agent.sock"); int fd = unixsocket_connect (path); if (fd < 0) { warn << path << ": " << strerror (errno) << "\n"; return false; } close_on_exec (fd); AUTH *auth = authunixint_create ("localhost", uid, getgid (), 0, NULL); if (!auth) fatal ("could not create RPC authunix credentials\n"); int32_t res (EIO); srpc_callraw (fd, SETUID_PROG, SETUID_VERS, SETUIDPROC_SETUID, xdr_void, NULL, xdr_int32_t, &res, auth); if (res) { close (fd); warn ("sfscd rejected credentials: %s\n", strerror (errno)); return false; } u_int32_t gid (static_cast<u_int32_t> (sfs_badgid)); clnt_stat stat = srpc_callraw (fd, AGENT_PROG, AGENT_VERS, AGENT_AIDALLOC, xdr_void, NULL, xdr_u_int32_t, &gid, NULL); close (fd); if (stat || gid < sfs_resvgid_start || gid >= (sfs_resvgid_start + sfs_resvgid_count)) { warn << "no free group IDs.\n"; return false; } *gidp = static_cast<gid_t> (gid); return true; }