--- (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).
* 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
#include <fcntl.h>
#include <signal.h>
+#include <grp.h>
+#include <pwd.h>
+#include <sys/types.h>
+
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
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;
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;
}
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;
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;