If we fail to open the privileged socket, open the unprivileged one.
authorRoy Marples <roy@marples.name>
Mon, 15 Sep 2014 16:14:13 +0000 (16:14 +0000)
committerRoy Marples <roy@marples.name>
Mon, 15 Sep 2014 16:14:13 +0000 (16:14 +0000)
src/dhcpcd-gtk/main.c
src/dhcpcd-online/dhcpcd-online.c
src/dhcpcd-qt/dhcpcd-qt.cpp
src/dhcpcd-qt/dhcpcd-qt.h
src/libdhcpcd/dhcpcd.c
src/libdhcpcd/dhcpcd.h

index c28570160e3279a9795f0a968f37685f39cfeeee..9226cb12cb82128fb63264ceec0ae8ff125c5112 100644 (file)
@@ -389,8 +389,12 @@ dhcpcd_try_open(gpointer data)
        static int last_error;
 
        con = (DHCPCD_CONNECTION *)data;
-       fd = dhcpcd_open(con);
+       fd = dhcpcd_open(con, true);
        if (fd == -1) {
+               if (errno == EACCES || errno == EPERM) {
+                       if ((fd = dhcpcd_open(con, false)) != -1)
+                               goto unprived;
+               }
                if (errno != last_error) {
                        g_critical("dhcpcd_open: %s", strerror(errno));
                        last_error = errno;
@@ -398,6 +402,7 @@ dhcpcd_try_open(gpointer data)
                return TRUE;
        }
 
+unprived:
        if (!dhcpcd_watch(fd, dhcpcd_cb, con)) {
                dhcpcd_close(con);
                return TRUE;
index 6a5871b269025f5bd45d79df2993d4aa04cec164..9260b69dd4d67eb8ca92418787abe63bbd19156d 100644 (file)
@@ -150,7 +150,7 @@ main(int argc, char **argv)
 
        dhcpcd_set_status_callback(con, do_status_cb, &pfd);
 
-       if ((pfd.fd = dhcpcd_open(con)) == -1) {
+       if ((pfd.fd = dhcpcd_open(con, false)) == -1) {
                lerrno = errno;
                syslog(LOG_WARNING, "dhcpcd_open: %m");
                if (xflag)
@@ -195,7 +195,7 @@ main(int argc, char **argv)
                        do_exit(con, EXIT_FAILURE);
                }
                if (pfd.fd == -1) {
-                       if ((pfd.fd = dhcpcd_open(con)) == -1) {
+                       if ((pfd.fd = dhcpcd_open(con, false)) == -1) {
                                if (lerrno != errno) {
                                        lerrno = errno;
                                        syslog(LOG_WARNING, "dhcpcd_open: %m");
index ee988f297417e8fbe5f6397f5b03d653eb6ce5eb..7fb0b8c6e3f5120da1c915220380a4ad3e4d1a9c 100644 (file)
@@ -88,6 +88,18 @@ DhcpcdQt::~DhcpcdQt()
 
 }
 
+DHCPCD_CONNECTION *DhcpcdQt::getConnection()
+{
+
+       return con;
+}
+
+QList<DhcpcdWi *> *DhcpcdQt::getWis()
+{
+
+       return wis;
+}
+
 void DhcpcdQt::animate()
 {
        const char *icon;
@@ -344,13 +356,20 @@ void DhcpcdQt::dhcpcd_wpa_status_cb(DHCPCD_WPA *wpa, const char *status,
 }
 
 void DhcpcdQt::tryOpen() {
-       int fd = dhcpcd_open(con);
+       int fd = dhcpcd_open(con, true);
        static int last_error;
 
        if (fd == -1) {
+               if (errno == EACCES || errno == EPERM) {
+                       if ((fd = dhcpcd_open(con, false)) != -1)
+                               goto unprived;
+               }
                if (errno != last_error) {
                        last_error = errno;
-                       qCritical("dhcpcd_open: %s", strerror(errno));
+                       const char *errt = strerror(errno);
+                       qCritical("dhcpcd_open: %s", errt);
+                       trayIcon->setToolTip(
+                           tr("Error connecting to dhcpcd: %1").arg(errt));
                }
                if (retryOpenTimer == NULL) {
                        retryOpenTimer = new QTimer(this);
@@ -361,6 +380,7 @@ void DhcpcdQt::tryOpen() {
                return;
        }
 
+unprived:
        /* Start listening to WPA events */
        dhcpcd_wpa_start(con);
 
@@ -371,6 +391,8 @@ void DhcpcdQt::tryOpen() {
 
        notifier = new QSocketNotifier(fd, QSocketNotifier::Read);
        connect(notifier, SIGNAL(activated(int)), this, SLOT(dispatch()));
+
+       preferencesAction->setEnabled(dhcpcd_privileged(con));
 }
 
 void DhcpcdQt::dispatch() {
@@ -487,6 +509,7 @@ void DhcpcdQt::createActions()
 
        preferencesAction = new QAction(tr("&Preferences"), this);
        preferencesAction->setIcon(QIcon::fromTheme("preferences-system-network"));
+       preferencesAction->setEnabled(false);
        connect(preferencesAction, SIGNAL(triggered()),
            this, SLOT(showPreferences()));
 
index efa1bf03c3db5385c77881dfdaf5574f320320f2..17f115128b823051c09f0f733b49cc2af5413a51 100644 (file)
@@ -56,8 +56,7 @@ public:
        DhcpcdQt();
        ~DhcpcdQt();
 
-       void closeAbout();
-
+       DHCPCD_CONNECTION *getConnection();
        static void dhcpcd_status_cb(DHCPCD_CONNECTION *con,
            const char *status, void *d);
        void statusCallback(const char *status);
@@ -71,7 +70,9 @@ public:
        void wpaStatusCallback(DHCPCD_WPA *wpa, const char *status);
 
        static QIcon getIcon(QString category, QString name);
+       QList<DhcpcdWi *> *getWis();
 
+       void closeAbout();
        void dialogClosed(QDialog *dialog);
 
 protected:
index 4a8823d4d677cbd07514441ec99e1a59a3d6f9b4..3bfbb56f3b162a022041ae2e4792fb06982726cb 100644 (file)
@@ -153,7 +153,7 @@ dhcpcd_command_arg(DHCPCD_CONNECTION *con, const char *cmd, const char *arg,
 
 
 static int
-dhcpcd_connect(int opts)
+dhcpcd_connect(const char *path, int opts)
 {
        int fd;
        socklen_t len;
@@ -165,7 +165,7 @@ dhcpcd_connect(int opts)
 
        memset(&sun, 0, sizeof(sun));
        sun.sun_family = AF_UNIX;
-       strlcpy(sun.sun_path, DHCPCD_SOCKET, sizeof(sun.sun_path));
+       strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
        len = (socklen_t)SUN_LEN(&sun);
        if (connect(fd, (struct sockaddr *)&sun, len) == 0)
                return fd;
@@ -572,8 +572,9 @@ strverscmp(const char *s1, const char *s2)
 #endif
 
 int
-dhcpcd_open(DHCPCD_CONNECTION *con)
+dhcpcd_open(DHCPCD_CONNECTION *con, bool privileged)
 {
+       const char *path = privileged ? DHCPCD_SOCKET : DHCPCD_UNPRIV_SOCKET;
        char cmd[128];
        ssize_t bytes;
        size_t nifs, n;
@@ -586,7 +587,7 @@ dhcpcd_open(DHCPCD_CONNECTION *con)
                return -1;
        }
        /* We need to block the command fd */
-       con->command_fd = dhcpcd_connect(0);
+       con->command_fd = dhcpcd_connect(path, 0);
        if (con->command_fd == -1)
                goto err_exit;
 
@@ -600,9 +601,10 @@ dhcpcd_open(DHCPCD_CONNECTION *con)
                goto err_exit;
 
        con->open = true;
+       con->privileged = privileged;
        update_status(con, NULL);
 
-       con->listen_fd = dhcpcd_connect(SOCK_NONBLOCK);
+       con->listen_fd = dhcpcd_connect(path, SOCK_NONBLOCK);
        if (con->listen_fd == -1)
                goto err_exit;
 
@@ -634,6 +636,14 @@ dhcpcd_get_fd(DHCPCD_CONNECTION *con)
        return con->listen_fd;
 }
 
+bool
+dhcpcd_privileged(DHCPCD_CONNECTION *con)
+{
+
+       assert(con);
+       return con->privileged;
+}
+
 const char *
 dhcpcd_status(DHCPCD_CONNECTION *con)
 {
index 8c788e801e8d84f9a807952680c2c328c3c26200..d4f7aaea48005883030ef2577502771410cc578e 100644 (file)
@@ -39,6 +39,9 @@ extern "C" {
 #ifndef DHCPCD_SOCKET
 #define DHCPCD_SOCKET          "/var/run/dhcpcd.sock"
 #endif
+#ifndef DHCPCD_UNPRIV_SOCKET
+#define DHCPCD_UNPRIV_SOCKET   "/var/run/dhcpcd.unpriv.sock"
+#endif
 
 #ifndef WPA_CTRL_DIR
 #define WPA_CTRL_DIR           "/var/run/wpa_supplicant"
@@ -136,6 +139,7 @@ typedef struct dhcpcd_wpa {
 typedef struct dhcpcd_connection {
        struct dhcpcd_connection *next;
        bool open;
+       bool privileged;
        int command_fd;
        int listen_fd;
 
@@ -177,7 +181,7 @@ const char * dhcpcd_version(DHCPCD_CONNECTION *);
 const char * dhcpcd_status(DHCPCD_CONNECTION *);
 const char * dhcpcd_cffile(DHCPCD_CONNECTION *);
 bool dhcpcd_realloc(DHCPCD_CONNECTION *, size_t);
-int dhcpcd_open(DHCPCD_CONNECTION *);
+int dhcpcd_open(DHCPCD_CONNECTION *, bool priv);
 void dhcpcd_close(DHCPCD_CONNECTION *);
 void dhcpcd_free(DHCPCD_CONNECTION *);
 void dhcpcd_set_if_callback(DHCPCD_CONNECTION *,
@@ -185,6 +189,7 @@ void dhcpcd_set_if_callback(DHCPCD_CONNECTION *,
 void dhcpcd_set_status_callback(DHCPCD_CONNECTION *,
     void (*)(DHCPCD_CONNECTION *, const char *, void *), void *);
 int dhcpcd_get_fd(DHCPCD_CONNECTION *);
+bool dhcpcd_privileged(DHCPCD_CONNECTION *);
 void dhcpcd_dispatch(DHCPCD_CONNECTION *);
 DHCPCD_IF * dhcpcd_interfaces(DHCPCD_CONNECTION *);
 DHCPCD_IF * dhcpcd_get_if(DHCPCD_CONNECTION *, const char *, const char *);