From 54462bdd66000b20ff13b8545ed58a838a12b793 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 29 Oct 2003 13:26:34 +0000 Subject: [PATCH] Allow user,group,umask to be specified for Unix file socket --- CHANGELOG | 7 ++++ src/unix.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 110 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 19e1430..c2f90be 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,13 @@ Possible compatibility problems with earlier versions marked with '*'. --- (IN PROGRESS) +Incorporate patch by Morten Bogeskov which allows a Unix file socket +server to specify uid/gid/mask for socket using the format + unix:[user=uid,][group=gid,][umask=mask,]file=path +If file= is omitted the existing format is assumed, e.g. + unix:path +in which case the mask is 0666 (rw for everybody). + Major restructure of YAZ source. All source in libyaz is in src directory. Programs in client (yaz-client), ztest (yaz-ztest), zoom (zoom programs), util (utility programs such as ASN.1 compiler, yaz-marcdump). diff --git a/src/unix.c b/src/unix.c index 2c1c979..c38c205 100644 --- a/src/unix.c +++ b/src/unix.c @@ -2,7 +2,7 @@ * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: unix.c,v 1.1 2003-10-27 12:21:36 adam Exp $ + * $Id: unix.c,v 1.2 2003-10-29 13:26:34 adam Exp $ * UNIX socket COMSTACK. By Morten Bøgeskov. */ #ifndef WIN32 @@ -15,6 +15,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -65,6 +69,9 @@ typedef struct unix_state int towrite; /* to verify against user input */ int (*complete)(const unsigned char *buf, int len); /* length/comple. */ struct sockaddr_un addr; /* returned by cs_straddr */ + int uid; + int gid; + int umask; char buf[128]; /* returned by cs_addrstr */ } unix_state; @@ -163,11 +170,102 @@ static int unix_strtoaddr_ex(const char *str, struct sockaddr_un *add) static void *unix_straddr(COMSTACK h, const char *str) { unix_state *sp = (unix_state *)h->cprivate; + char * s = strdup(str); + char * f = s; + const char * file = NULL; + char * eol; + + sp->uid = sp->gid = sp->umask = -1; + + if (eol = strchr(s, ',')) + { + do + { + if (eol = strchr(s, ',')) + *eol++ = '\0'; + if (sp->uid == -1 && strncmp(s, "user=", 5) == 0) + { + char * arg = s + 5; + if (strspn(arg, "0123456789") == strlen(arg)) + { + sp->uid = atoi(arg); + } + else + { + struct passwd * pw = getpwnam(arg); + if(pw == NULL) + { + printf("No such user\n"); + free(f); + return; + } + sp->uid = pw->pw_uid; + } + } + else if (sp->gid == -1 && strncmp(s, "group=", 6) == 0) + { + char * arg = s + 6; + if (strspn(arg, "0123456789") == strlen(arg)) + { + sp->gid = atoi(arg); + } + else + { + struct group * gr = getgrnam(arg); + if (gr == NULL) + { + printf("No such group\n"); + free(f); + return; + } + sp->gid = gr->gr_gid; + } + } + else if (sp->umask == -1 && strncmp(s, "umask=", 6) == 0) + { + char * end; + char * arg = s + 6; + + sp->umask = strtol(arg, &end, 8); + if (errno == EINVAL || + *end) + { + printf("Invalid umask\n"); + free(f); + return; + } + } + else if (file == NULL && strncmp(s, "file=", 5) == 0) + { + char * arg = s + 5; + file = arg; + } + else + { + printf("invalid or double argument: %s\n", s); + free(f); + return; + } + } while(s = eol); + } + else + { + file = str; + } + if(! file) + { + errno = EINVAL; + return 0; + } TRC(fprintf(stderr, "unix_straddr: %s\n", str ? str : "NULL")); - if (!unix_strtoaddr_ex (str, &sp->addr)) + if (!unix_strtoaddr_ex (file, &sp->addr)) + { + free(f); return 0; + } + free(f); return &sp->addr; } @@ -250,6 +348,7 @@ static int unix_rcvconnect(COMSTACK h) static int unix_bind(COMSTACK h, void *address, int mode) { + unix_state *sp = (unix_state *)h->cprivate; struct sockaddr *addr = (struct sockaddr *)address; const char * path = ((struct sockaddr_un *)addr)->sun_path; struct stat stat_buf; @@ -291,7 +390,8 @@ static int unix_bind(COMSTACK h, void *address, int mode) h->cerrno = CSYSERR; return -1; } - chmod(path, 0777); + chown(path, sp->uid, sp->gid); + chmod(path, sp->umask != -1 ? sp->umask : 0666); if (mode == CS_SERVER && listen(h->iofile, 3) < 0) { h->cerrno = CSYSERR; -- 1.7.10.4