Add user option to specify the user to which ptp4l should switch after
opening the PHC device and before opening the network/UDS ports. Create
the directory that will contain the UDS-RW/RO sockets if it doesn't
exist.

In the jbod mode or with a bonded interface, all their PHC devices need
to have the permission set for the non-root user to be able to open them
later.

Modify the PHC switching function to not recreate an NTPSHM servo as it
needs root permissions to attach the memory segment.

Signed-off-by: Miroslav Lichvar <mlich...@redhat.com>
---
 clock.c  | 29 ++++++++++++++++++++++-------
 config.c |  1 +
 ptp4l.8  | 10 ++++++++++
 3 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/clock.c b/clock.c
index d428ae2..3e904bc 100644
--- a/clock.c
+++ b/clock.c
@@ -1218,6 +1218,16 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
                return NULL;
        }
 
+       create_uds_directory(config_get_string(config, NULL, "uds_address"),
+                            config_get_string(config, NULL, "user"));
+       create_uds_directory(config_get_string(config, NULL, "uds_ro_address"),
+                            config_get_string(config, NULL, "user"));
+
+       /* Drop the root privileges before opening the ports. */
+       if (drop_root_privileges(config_get_string(config, NULL, "user"))) {
+               return NULL;
+       }
+
        /* Create the UDS interfaces. */
 
        c->uds_rw_port = port_open(phc_device, phc_index, timestamping, 0,
@@ -1751,16 +1761,21 @@ int clock_switch_phc(struct clock *c, int phc_index)
        }
        fadj = (int) clockadj_get_freq(clkid);
        clockadj_set_freq(clkid, fadj);
-       servo = servo_create(c->config, c->servo_type, -fadj, max_adj, 0);
-       if (!servo) {
-               pr_err("Switching PHC, failed to create clock servo");
-               phc_close(clkid);
-               return -1;
+
+       if (c->servo_type == CLOCK_SERVO_NTPSHM) {
+               servo_reset(c->servo);
+       } else {
+               servo = servo_create(c->config, c->servo_type, -fadj, max_adj, 
0);
+               if (!servo) {
+                       pr_err("Switching PHC, failed to create clock servo");
+                       phc_close(clkid);
+                       return -1;
+               }
+               servo_destroy(c->servo);
+               c->servo = servo;
        }
        phc_close(c->clkid);
-       servo_destroy(c->servo);
        c->clkid = clkid;
-       c->servo = servo;
        c->servo_state = SERVO_UNLOCKED;
        return 0;
 }
diff --git a/config.c b/config.c
index 4472d3d..06e5fd1 100644
--- a/config.c
+++ b/config.c
@@ -332,6 +332,7 @@ struct config_item config_tab[] = {
        PORT_ITEM_INT("unicast_master_table", 0, 0, INT_MAX),
        PORT_ITEM_INT("unicast_req_duration", 3600, 10, INT_MAX),
        GLOB_ITEM_INT("use_syslog", 1, 0, 1),
+       GLOB_ITEM_STR("user", ""),
        GLOB_ITEM_STR("userDescription", ""),
        GLOB_ITEM_INT("utc_offset", CURRENT_UTC_OFFSET, 0, INT_MAX),
        GLOB_ITEM_INT("verbose", 0, 0, 1),
diff --git a/ptp4l.8 b/ptp4l.8
index fe9e150..021ca9a 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -803,6 +803,16 @@ This option enables using the "write phase" feature of a 
PTP Hardware
 Clock.  If supported by the device, this mode uses the hardware's
 built in phase offset control instead of frequency offset control.
 The default value is 0 (disabled).
+.TP
+.B user
+The name of the user to which should
+.B ptp4l
+switch after start in order to drop the root privileges. By default,
+.B ptp4l
+will keep the identity of the user under which it is started. With the 
+.B boundary_clock_jbod
+option, or if using a bonded interface, the non-root user must have permissions
+to open the PHC devices to be able to switch between them.
 
 .SH UNICAST DISCOVERY OPTIONS
 
-- 
2.26.3



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

Reply via email to