Cleanup socket directory creation code

This commit is contained in:
Marc André Tanner 2015-08-03 12:28:09 +02:00
parent 4ab9cb7fcc
commit 42962ff827
1 changed files with 21 additions and 10 deletions

View File

@ -267,26 +267,36 @@ static bool session_alive(const char *name) {
static bool create_socket_dir(struct sockaddr_un *sockaddr) { static bool create_socket_dir(struct sockaddr_un *sockaddr) {
sockaddr->sun_path[0] = '\0'; sockaddr->sun_path[0] = '\0';
uid_t uid = getuid();
size_t maxlen = sizeof(sockaddr->sun_path);
char *dirs[] = { getenv("HOME"), getenv("TMPDIR"), "/tmp" };
int socketfd = socket(AF_UNIX, SOCK_STREAM, 0); int socketfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (socketfd == -1) if (socketfd == -1)
return false; return false;
size_t maxlen = sizeof(sockaddr->sun_path);
uid_t uid = getuid();
struct passwd *pw = getpwuid(uid); struct passwd *pw = getpwuid(uid);
if ((!dirs[0] || !dirs[0][0]) && pw) char *home = getenv("HOME");
dirs[0] = pw->pw_dir; if ((!home || !home[0]) && pw)
home = pw->pw_dir;
struct {
char *dir;
bool personal; /* whether it is a per user directory */
} dirs[] = {
{ home, true },
{ getenv("TMPDIR"), false },
{ "/tmp", false },
};
for (unsigned int i = 0; i < countof(dirs); i++) { for (unsigned int i = 0; i < countof(dirs); i++) {
char *dir = dirs[i];
struct stat sb; struct stat sb;
bool ishome = (i == 0); char *dir = dirs[i].dir;
bool ispersonal = dirs[i].personal;
if (!dir) if (!dir)
continue; continue;
if (!xsnprintf(sockaddr->sun_path, maxlen, "%s/%s%s/", dir, ishome ? "." : "", server.name)) if (!xsnprintf(sockaddr->sun_path, maxlen, "%s/%s%s/", dir, dir == home ? "." : "", server.name))
continue; continue;
mode_t mask = umask(0); mode_t mask = umask(0);
int r = mkdir(sockaddr->sun_path, ishome ? S_IRWXU : S_IRWXU|S_IRWXG|S_IRWXO|S_ISVTX); int r = mkdir(sockaddr->sun_path, ispersonal ? S_IRWXU : S_IRWXU|S_IRWXG|S_IRWXO|S_ISVTX);
umask(mask); umask(mask);
if (r != 0 && errno != EEXIST) if (r != 0 && errno != EEXIST)
continue; continue;
@ -298,7 +308,8 @@ static bool create_socket_dir(struct sockaddr_un *sockaddr) {
} }
size_t dirlen = strlen(sockaddr->sun_path); size_t dirlen = strlen(sockaddr->sun_path);
if (!ishome) { if (!ispersonal) {
/* create subdirectory only accessible to user */
if (pw && !xsnprintf(sockaddr->sun_path+dirlen, maxlen-dirlen, "%s/", pw->pw_name)) if (pw && !xsnprintf(sockaddr->sun_path+dirlen, maxlen-dirlen, "%s/", pw->pw_name))
continue; continue;
if (!pw && !xsnprintf(sockaddr->sun_path+dirlen, maxlen-dirlen, "%d/", uid)) if (!pw && !xsnprintf(sockaddr->sun_path+dirlen, maxlen-dirlen, "%d/", uid))