diff --git a/ChangeLog b/ChangeLog index d0d5abd460..6afaa9d0c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Tue Sep 18 22:22:00 EST 2007 Daniel P. Berrange + + * qemud/qemud.c: Allow customization of UNIX socket permissions + and group ownership from config file + * docs/libvir.html: Added docs on UNIX socket perms & group owner + config parameters + Tue Sep 18 21:34:00 EST 2007 Daniel P. Berrange * configure.in: Added checks for locating Avahi. diff --git a/docs/libvir.html b/docs/libvir.html index 8b899a486b..47a1d22859 100644 --- a/docs/libvir.html +++ b/docs/libvir.html @@ -2210,6 +2210,34 @@ Blank lines and comments beginning with # are ignored. + + unix_sock_group "groupname" + "root" + + The UNIX group to own the UNIX domain socket. If the socket permissions allow + group access, then applications running under matching group can access the + socket. Only valid if running as root + + + + + unix_sock_ro_perms "octal-perms" + "0777" + + The permissions for the UNIX domain socket for read-only client connections. + The default allows any user to monitor domains. + + + + + unix_sock_rw_perms "octal-perms" + "0700" + + The permissions for the UNIX domain socket for read-write client connections. + The default allows only root to manage domains. + + + tls_no_verify_certificate [0|1] 0 (certificates are verified) diff --git a/docs/remote.html b/docs/remote.html index 42366021b7..976fd5682f 100644 --- a/docs/remote.html +++ b/docs/remote.html @@ -484,6 +484,25 @@ Blank lines and comments beginning with # are ignored. includes the machine's short hostname. This must be unique to the local LAN segment. + unix_sock_group "groupname" + "root" + + The UNIX group to own the UNIX domain socket. If the socket permissions allow + group access, then applications running under matching group can access the + socket. Only valid if running as root + + unix_sock_ro_perms "octal-perms" + "0777" + + The permissions for the UNIX domain socket for read-only client connections. + The default allows any user to monitor domains. + + unix_sock_rw_perms "octal-perms" + "0700" + + The permissions for the UNIX domain socket for read-write client connections. + The default allows only root to manage domains. + tls_no_verify_certificate [0|1] 0 (certificates are verified) diff --git a/qemud/qemud.c b/qemud/qemud.c index a2554b8050..8e3ba546a3 100644 --- a/qemud/qemud.c +++ b/qemud/qemud.c @@ -48,6 +48,7 @@ #include #include #include +#include #include @@ -72,6 +73,10 @@ static int listen_tcp = 0; static const char *tls_port = LIBVIRTD_TLS_PORT; static const char *tcp_port = LIBVIRTD_TCP_PORT; +static gid_t unix_sock_gid = 0; /* Only root by default */ +static int unix_sock_rw_perms = 0700; /* Allow user only */ +static int unix_sock_ro_perms = 0777; /* Allow world */ + #ifdef HAVE_AVAHI static int mdns_adv = 1; static const char *mdns_name = NULL; @@ -449,6 +454,7 @@ static int qemudListenUnix(struct qemud_server *server, struct qemud_socket *sock = calloc(1, sizeof(struct qemud_socket)); struct sockaddr_un addr; mode_t oldmask; + gid_t oldgrp; if (!sock) { qemudLog(QEMUD_ERR, "Failed to allocate memory for struct qemud_socket"); @@ -475,16 +481,19 @@ static int qemudListenUnix(struct qemud_server *server, addr.sun_path[0] = '\0'; - if (readonly) - oldmask = umask(~(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)); - else - oldmask = umask(~(S_IRUSR | S_IWUSR)); + oldgrp = getgid(); + oldmask = umask(readonly ? ~unix_sock_ro_perms : ~unix_sock_rw_perms); + if (getuid() == 0) + setgid(unix_sock_gid); + if (bind(sock->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { qemudLog(QEMUD_ERR, "Failed to bind socket to '%s': %s", path, strerror(errno)); goto cleanup; } umask(oldmask); + if (getuid() == 0) + setgid(oldgrp); if (listen(sock->fd, 30) < 0) { qemudLog(QEMUD_ERR, "Failed to listen for connections on '%s': %s", @@ -1556,6 +1565,43 @@ remoteReadConfigFile (const char *filename) CHECK_TYPE ("tcp_port", VIR_CONF_STRING); tcp_port = p ? strdup (p->str) : tcp_port; + p = virConfGetValue (conf, "unix_sock_group"); + CHECK_TYPE ("unix_sock_group", VIR_CONF_STRING); + if (p && p->str) { + if (getuid() != 0) { + qemudLog (QEMUD_WARN, "Cannot set group when not running as root"); + } else { + struct group *grp = getgrnam(p->str); + if (!grp) { + qemudLog (QEMUD_ERR, "Failed to lookup group '%s'", p->str); + return -1; + } + unix_sock_gid = grp->gr_gid; + } + } + + p = virConfGetValue (conf, "unix_sock_ro_perms"); + CHECK_TYPE ("unix_sock_ro_perms", VIR_CONF_STRING); + if (p && p->str) { + char *tmp = NULL; + unix_sock_ro_perms = strtol(p->str, &tmp, 8); + if (*tmp) { + qemudLog (QEMUD_ERR, "Failed to parse mode '%s'", p->str); + return -1; + } + } + + p = virConfGetValue (conf, "unix_sock_rw_perms"); + CHECK_TYPE ("unix_sock_rw_perms", VIR_CONF_STRING); + if (p && p->str) { + char *tmp = NULL; + unix_sock_rw_perms = strtol(p->str, &tmp, 8); + if (*tmp) { + qemudLog (QEMUD_ERR, "Failed to parse mode '%s'", p->str); + return -1; + } + } + #ifdef HAVE_AVAHI p = virConfGetValue (conf, "mdns_adv"); CHECK_TYPE ("mdns_adv", VIR_CONF_LONG);