Drop root before binding the UDS socket and change the default UDS
address to follow to location of the server UDS.

Signed-off-by: Miroslav Lichvar <mlich...@redhat.com>
---
 pmc.8        | 13 +++++++++++--
 pmc.c        | 10 ++++++++--
 pmc_common.c | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/pmc.8 b/pmc.8
index e0ab5ac..c6ee42f 100644
--- a/pmc.8
+++ b/pmc.8
@@ -81,8 +81,9 @@ Specify the boundary hops value in sent messages. The default 
is 1.
 Specify the domain number in sent messages. The default is 0.
 .TP
 .BI \-i " interface"
-Specify the network interface. The default is /var/run/pmc.$pid for the Unix 
Domain
-Socket transport and eth0 for the other transports.
+Specify the network interface. The default is pmc.$pid for the Unix Domain
+Socket transport and eth0 for the other transports. A relative path of the Unix
+Domain socket is relative to the directory of the server's socket.
 .TP
 .BI \-s " uds-address"
 Specifies the address of the server's UNIX domain socket.
@@ -144,6 +145,14 @@ options. The name of the section is the name of the 
configured port (e.g.
 .B domainNumber
 The domain attribute of the local clock. The default is 0.
 
+.TP
+.B user
+The name of the user to which should
+.B pmc
+switch in order to drop the root privileges. By default,
+.B pmc
+will keep the identity of the user under which it is started.
+
 .SH PORT OPTIONS
 .TP
 .B transportSpecific
diff --git a/pmc.c b/pmc.c
index 00d6014..194e450 100644
--- a/pmc.c
+++ b/pmc.c
@@ -546,7 +546,7 @@ static void usage(char *progname)
                " -f [file] read configuration from 'file'\n"
                " -h        prints this message and exits\n"
                " -i [dev]  interface device to use, default 'eth0'\n"
-               "           for network and '/var/run/pmc.$pid' for UDS.\n"
+               "           for network and 'pmc.$pid' for UDS.\n"
                " -s [path] server address for UDS, default '/var/run/ptp4l'.\n"
                " -t [hex]  transport specific field, default 0x0\n"
                " -v        prints the software version and exits\n"
@@ -680,8 +680,9 @@ int main(int argc, char *argv[])
 
        if (!iface_name) {
                if (transport_type == TRANS_UDS) {
+                       /* Directory will be copied from ptp4l address */
                        snprintf(uds_local, sizeof(uds_local),
-                                "/var/run/pmc.%d", getpid());
+                                "pmc.%d", getpid());
                        iface_name = uds_local;
                } else {
                        iface_name = "eth0";
@@ -695,6 +696,11 @@ int main(int argc, char *argv[])
        print_set_syslog(1);
        print_set_verbose(1);
 
+       if (drop_root_privileges(config_get_string(cfg, NULL, "user"))) {
+               config_destroy(cfg);
+               return -1;
+       }
+
        pmc = pmc_create(cfg, transport_type, iface_name, boundary_hops,
                         domain_number, transport_specific, zero_datalen);
        if (!pmc) {
diff --git a/pmc_common.c b/pmc_common.c
index 101df55..fc2fbd8 100644
--- a/pmc_common.c
+++ b/pmc_common.c
@@ -18,6 +18,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 #include <errno.h>
+#include <libgen.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
@@ -373,11 +374,39 @@ struct pmc {
        int zero_length_gets;
 };
 
+static int complete_uds_address(struct config *cfg, const char *iface,
+                               char *uds, size_t len)
+{
+       char *dir, buf[MAX_IFNAME_SIZE + 1];
+
+       /* Don't change absolute paths */
+       if (iface[0] == '/') {
+               if (snprintf(uds, len, "%s", iface) >= len) {
+                       pr_err("UDS path too long");
+                       return -1;
+               }
+               return 0;
+       }
+
+       /* Relative paths are relative to the directory of the server socket */
+       if (snprintf(buf, sizeof(buf), "%s",
+                    config_get_string(cfg, NULL,
+                                      "uds_address")) >= sizeof(buf) ||
+           !(dir = dirname(buf)) ||
+           snprintf(uds, len, "%s/%s", buf, iface) >= len) {
+               pr_err("UDS path too long");
+               return -1;
+       }
+
+       return 0;
+}
+
 struct pmc *pmc_create(struct config *cfg, enum transport_type transport_type,
                       const char *iface_name, UInteger8 boundary_hops,
                       UInteger8 domain_number, UInteger8 transport_specific,
                       int zero_datalen)
 {
+       char uds[MAX_IFNAME_SIZE + 1];
        struct pmc *pmc;
 
        pmc = calloc(1, sizeof *pmc);
@@ -386,6 +415,9 @@ struct pmc *pmc_create(struct config *cfg, enum 
transport_type transport_type,
 
        if (transport_type == TRANS_UDS) {
                pmc->port_identity.portNumber = getpid();
+               if (complete_uds_address(cfg, iface_name, uds, sizeof(uds)))
+                   goto failed;
+               iface_name = uds;
        } else {
                if (generate_clock_identity(&pmc->port_identity.clockIdentity,
                                            iface_name)) {
-- 
2.26.3



_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to