]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
controlgroup option changes group ownership of the control socket.
authorRoy Marples <roy@marples.name>
Fri, 9 May 2014 12:09:05 +0000 (12:09 +0000)
committerRoy Marples <roy@marples.name>
Fri, 9 May 2014 12:09:05 +0000 (12:09 +0000)
control.c
dhcpcd.conf.5.in
dhcpcd.h
if-options.c

index 2550da6b12b2095a9a67ce0a5f5950c4cb07bc40..958a32f6b718afa3ffad0b2e1dc9afbb39388cb2 100644 (file)
--- a/control.c
+++ b/control.c
@@ -173,6 +173,9 @@ control_start(struct dhcpcd_ctx *ctx, const char *ifname)
        if (bind(ctx->control_fd, (struct sockaddr *)&sun, len) == -1 ||
            chmod(ctx->control_sock,
                S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) == -1 ||
+           (ctx->control_group &&
+               chown(ctx->control_sock,
+               geteuid(), ctx->control_group) == -1) ||
            listen(ctx->control_fd, sizeof(ctx->control_fds)) == -1)
        {
                close(ctx->control_fd);
index b75af9494597f1d60d52bbeb980581c3868f261d..327fea3d988728c43c92847e1f993882699124b2 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd April 28, 2014
+.Dd May 9, 2014
 .Dt DHCPCD.CONF 5
 .Os
 .Sh NAME
@@ -105,6 +105,11 @@ such as FireWire and InfiniBand.
 In most cases,
 .Nm dhcpcd
 will set this automatically.
+.It Ic controlgroup Ar group
+Sets the group ownership of
+.Pa @RUNDIR@/dhcpcd.sock
+so that users other than root can connect to
+.Nm dhcpcd .
 .It Ic debug
 Echo debug messages to the stderr and syslog.
 .It Ic dev Ar value
index 6554f6935786bc016981af4cf6bb72e942a7f60a..7eadaa3b22d456aaba7d09be75c030bdbef95fe6 100644 (file)
--- a/dhcpcd.h
+++ b/dhcpcd.h
@@ -96,6 +96,7 @@ struct dhcpcd_ctx {
        int control_fd;
        struct fd_list *control_fds;
        char control_sock[sizeof(CONTROLSOCKET) + IF_NAMESIZE];
+       gid_t control_group;
 
        /* DHCP Enterprise options, RFC3925 */
        struct dhcp_opt *vivso;
index 90a28a29ba5f0e731d5ddf15246c090995b2a92a..b7f5c56f33112a29296f1f8780685248a52a9921 100644 (file)
@@ -36,6 +36,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <getopt.h>
+#include <grp.h>
 #include <limits.h>
 #include <paths.h>
 #include <stdio.h>
@@ -89,6 +90,7 @@
 #define O_DHCP6                        O_BASE + 31
 #define O_IPV4                 O_BASE + 32
 #define O_IPV6                 O_BASE + 33
+#define O_CONTROLGRP           O_BASE + 34
 
 const struct option cf_options[] = {
        {"background",      no_argument,       NULL, 'b'},
@@ -172,6 +174,7 @@ const struct option cf_options[] = {
        {"nodhcp",          no_argument,       NULL, O_NODHCP},
        {"dhcp6",           no_argument,       NULL, O_DHCP6},
        {"nodhcp6",         no_argument,       NULL, O_NODHCP6},
+       {"controlgroup",    required_argument, NULL, O_CONTROLGRP},
        {NULL,              0,                 NULL, '\0'}
 };
 
@@ -615,7 +618,8 @@ static int
 parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
     int opt, const char *arg, struct dhcp_opt **ldop, struct dhcp_opt **edop)
 {
-       int i, l, t;
+       int i, t;
+       long l;
        unsigned long u;
        char *p = NULL, *fp, *np, **nconf;
        ssize_t s;
@@ -628,6 +632,11 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo,
        size_t *dop_len, dl;
        struct vivco *vivco;
        struct token *token;
+       struct group *grp;
+#ifdef _REENTRANT
+#error foo
+       struct group grpbuf;
+#endif
 #ifdef INET6
        size_t sl;
        struct if_ia *ia;
@@ -1774,6 +1783,58 @@ err_sla:
        case O_NODHCP6:
                ifo->options &= ~DHCPCD_DHCP6;
                break;
+       case O_CONTROLGRP:
+#ifdef _REENTRANT
+               l = sysconf(_SC_GETGR_R_SIZE_MAX);
+               if (l == -1)
+                       dl = 1024;
+               else
+                       dl = (size_t)l;
+               p = malloc(dl);
+               if (p == NULL) {
+                       syslog(LOG_ERR, "%s: malloc: %m", __func__);
+                       return -1;
+               }
+               while ((i = getgrnam_r(arg, &grpbuf, p, (size_t)l, &grp)) ==
+                   ERANGE)
+               {
+                       size_t nl = dl * 2;
+                       if (nl < dl) {
+                               syslog(LOG_ERR, "control_group: out of buffer");
+                               free(p);
+                               return -1;
+                       }
+                       dl = nl;
+                       np = realloc(p, dl);
+                       if (np == NULL) {
+                               syslog(LOG_ERR, "control_group: realloc: %m");
+                               free(p);
+                               return -1;
+                       }
+                       p = np;
+               }
+               if (i != 0) {
+                       errno = i;
+                       syslog(LOG_ERR, "getgrnam_r: %m");
+                       free(p);
+                       return -1;
+               }
+               if (grp == NULL) {
+                       syslog(LOG_ERR, "controlgroup: %s: not found", arg);
+                       free(p);
+                       return -1;
+               }
+               ctx->control_group = grp->gr_gid;
+               free(p);
+#else
+               grp = getgrnam(arg);
+               if (grp == NULL) {
+                       syslog(LOG_ERR, "controlgroup: %s: not found", arg);
+                       return -1;
+               }
+               ctx->control_group = grp->gr_gid;
+#endif
+               break;
        default:
                return 0;
        }