]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lldpcli: check for privileges by checking access to control socket
authorVincent Bernat <bernat@luffy.cx>
Thu, 20 Feb 2014 20:52:46 +0000 (21:52 +0100)
committerVincent Bernat <bernat@luffy.cx>
Thu, 20 Feb 2014 20:57:23 +0000 (21:57 +0100)
Instead of relying on having used the suid bit to run the program, we
check if the real UID/GID could have opened the control socket. This
really fix #56.

NEWS
src/client/lldpcli.c

diff --git a/NEWS b/NEWS
index 86205ed472f3f0a706b7e57712b9234586522aa0..30537444a1361fc1baacb7bb69bccde3ff4bb9e1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ lldpd (0.7.8)
     + Don't hard-code default values for system name, system
       description and port description. When the field is not present,
       just don't display it.
+    + Fix lldpcli behaviour when suid.
   * Features:
     + Android support
     + Add the possibility to disable privilege separation (lower
index 0049a87fc5124c7c424cdf3d39c87ff8c4a295d2..4223c90f253ab95dfc29bbed949f81a1c6290d7e 100644 (file)
@@ -42,6 +42,7 @@ extern const char     *__progname;
 
 /* Global for completion */
 static struct cmd_node *root = NULL;
+const char *ctlname = NULL;
 
 static int
 is_lldpctl(const char *name)
@@ -80,8 +81,10 @@ usage()
 static int
 is_privileged()
 {
-       return (getuid() == geteuid() && getgid() == getegid()) ||
-           getuid() == 0;
+       /* Check we can access the control socket with read/write
+        * privileges. The `access()` function uses the real UID and real GID,
+        * therefore we don't have to mangle with our identity. */
+       return (ctlname && access(ctlname, R_OK|W_OK) == 0);
 }
 
 static char*
@@ -417,11 +420,12 @@ main(int argc, char *argv[])
        lldpctl_conn_t *conn = NULL;
        const char *options = is_lldpctl(argv[0])?"hdvf:":"hdsvf:c:u:";
 
-       const char *ctlname = lldpctl_get_default_transport();
        int gotinputs = 0;
        struct inputs inputs;
        TAILQ_INIT(&inputs);
 
+       ctlname = lldpctl_get_default_transport();
+
        /* Initialize logging */
        while ((ch = getopt(argc, argv, options)) != -1) {
                switch (ch) {