]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
privops: add method PRV_AdjustFreq()
authorThomas Kupper <tom@kupper.org>
Wed, 4 Feb 2026 20:53:52 +0000 (21:53 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Wed, 25 Feb 2026 11:35:50 +0000 (12:35 +0100)
In preparation of adding OpenBSD support:

OpenBSD doesn't support timex but adjusting frequency using the
adjfreq(2) system call. Add a privops method PRV_AdjustFreq() to allow
unprivileged processes to set the time.

privops.c
privops.h

index 16114ce3d38f1c58fe0d9c36b23837eabb7053b6..a42e983350b4653a61f90f6bc2441c27805e6caf 100644 (file)
--- a/privops.c
+++ b/privops.c
@@ -43,6 +43,7 @@
 #define OP_BINDSOCKET     1027
 #define OP_NAME2IPADDRESS 1028
 #define OP_RELOADDNS      1029
+#define OP_ADJUSTFREQ     1030
 #define OP_QUIT           1099
 
 union sockaddr_in46 {
@@ -79,6 +80,13 @@ typedef struct {
   char name[256];
 } ReqName2IPAddress;
 
+#ifdef PRIVOPS_ADJUSTFREQ
+typedef struct {
+  int64_t freq;
+  int is_read_adj;
+} ReqAdjustFreq;
+#endif
+
 typedef struct {
   int op;
   union {
@@ -90,6 +98,9 @@ typedef struct {
     ReqBindSocket bind_socket;
 #ifdef PRIVOPS_NAME2IPADDRESS
     ReqName2IPAddress name_to_ipaddress;
+#endif
+#ifdef PRIVOPS_ADJUSTFREQ
+    ReqAdjustFreq adjust_freq;
 #endif
   } data;
 } PrvRequest;
@@ -110,6 +121,10 @@ typedef struct {
   IPAddr addresses[DNS_MAX_ADDRESSES];
 } ResName2IPAddress;
 
+typedef struct {
+  int64_t oldfreq;
+} ResAdjustFreq;
+
 typedef struct {
   char msg[256];
 } ResFatalMsg;
@@ -126,6 +141,9 @@ typedef struct {
 #endif
 #ifdef PRIVOPS_NAME2IPADDRESS
     ResName2IPAddress name_to_ipaddress;
+#endif
+#ifdef PRIVOPS_ADJUSTFREQ
+    ResAdjustFreq adjust_freq;
 #endif
   } data;
 } PrvResponse;
@@ -302,6 +320,22 @@ do_reload_dns(PrvResponse *res)
 }
 #endif
 
+
+/* ======================================================================= */
+
+/* HELPER - perform adjustfreq() */
+
+#ifdef PRIVOPS_ADJUSTFREQ
+static void
+do_adjust_freq(const ReqAdjustFreq *req, PrvResponse *res)
+{
+  res->rc = adjfreq(req->is_read_adj ? NULL : &req->freq,
+                    &res->data.adjust_freq.oldfreq);
+  if (res->rc)
+    res->res_errno = errno;
+}
+#endif
+
 /* ======================================================================= */
 
 /* HELPER - main loop - action requests from the daemon */
@@ -350,6 +384,11 @@ helper_main(int fd)
       case OP_RELOADDNS:
         do_reload_dns(&res);
         break;
+#endif
+#ifdef PRIVOPS_ADJUSTFREQ
+      case OP_ADJUSTFREQ:
+        do_adjust_freq(&req.data.adjust_freq, &res);
+        break;
 #endif
       case OP_QUIT:
         quit = 1;
@@ -625,6 +664,38 @@ PRV_ReloadDNS(void)
 
 /* ======================================================================= */
 
+/* DAEMON - request adjfreq() */
+
+#ifdef PRIVOPS_ADJUSTFREQ
+int
+PRV_AdjustFreq(const int64_t *freq, int64_t *oldfreq)
+{
+  PrvRequest req;
+  PrvResponse res;
+
+  if (!have_helper())
+    /* helper is not running */
+    return adjfreq(freq, oldfreq);
+
+  memset(&req, 0, sizeof (req));
+  req.op = OP_ADJUSTFREQ;
+
+  if (freq == NULL)
+    req.data.adjust_freq.is_read_adj = 1;
+  else
+    req.data.adjust_freq.freq = *freq;
+
+  submit_request(&req, &res);
+
+  if (oldfreq)
+    *oldfreq = res.data.adjust_freq.oldfreq;
+
+  return res.rc;
+}
+#endif
+
+/* ======================================================================= */
+
 void
 PRV_Initialise(int level)
 {
index 53513c7269540dbbdd1326acd68e0c247cbe6624..fe23613d53ba1bcd8eaf40a54169ed485036cb19 100644 (file)
--- a/privops.h
+++ b/privops.h
@@ -64,6 +64,12 @@ void PRV_ReloadDNS(void);
 #define PRV_ReloadDNS DNS_Reload
 #endif
 
+#ifdef PRIVOPS_ADJUSTFREQ
+int PRV_AdjustFreq(const int64_t *freq, int64_t *oldfreq);
+#else
+#define PRV_AdjustFreq adjfreq
+#endif
+
 #ifdef PRIVOPS_HELPER
 void PRV_Initialise(int scfilter_level);
 void PRV_StartHelper(void);