privops: add method PRV_AdjustFreq()

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.
This commit is contained in:
Thomas Kupper
2026-02-04 21:53:52 +01:00
committed by Miroslav Lichvar
parent fd60dabde7
commit 9a57ef8dbf
2 changed files with 77 additions and 0 deletions

View File

@@ -43,6 +43,7 @@
#define OP_BINDSOCKET 1027 #define OP_BINDSOCKET 1027
#define OP_NAME2IPADDRESS 1028 #define OP_NAME2IPADDRESS 1028
#define OP_RELOADDNS 1029 #define OP_RELOADDNS 1029
#define OP_ADJUSTFREQ 1030
#define OP_QUIT 1099 #define OP_QUIT 1099
union sockaddr_in46 { union sockaddr_in46 {
@@ -79,6 +80,13 @@ typedef struct {
char name[256]; char name[256];
} ReqName2IPAddress; } ReqName2IPAddress;
#ifdef PRIVOPS_ADJUSTFREQ
typedef struct {
int64_t freq;
int is_read_adj;
} ReqAdjustFreq;
#endif
typedef struct { typedef struct {
int op; int op;
union { union {
@@ -90,6 +98,9 @@ typedef struct {
ReqBindSocket bind_socket; ReqBindSocket bind_socket;
#ifdef PRIVOPS_NAME2IPADDRESS #ifdef PRIVOPS_NAME2IPADDRESS
ReqName2IPAddress name_to_ipaddress; ReqName2IPAddress name_to_ipaddress;
#endif
#ifdef PRIVOPS_ADJUSTFREQ
ReqAdjustFreq adjust_freq;
#endif #endif
} data; } data;
} PrvRequest; } PrvRequest;
@@ -110,6 +121,10 @@ typedef struct {
IPAddr addresses[DNS_MAX_ADDRESSES]; IPAddr addresses[DNS_MAX_ADDRESSES];
} ResName2IPAddress; } ResName2IPAddress;
typedef struct {
int64_t oldfreq;
} ResAdjustFreq;
typedef struct { typedef struct {
char msg[256]; char msg[256];
} ResFatalMsg; } ResFatalMsg;
@@ -126,6 +141,9 @@ typedef struct {
#endif #endif
#ifdef PRIVOPS_NAME2IPADDRESS #ifdef PRIVOPS_NAME2IPADDRESS
ResName2IPAddress name_to_ipaddress; ResName2IPAddress name_to_ipaddress;
#endif
#ifdef PRIVOPS_ADJUSTFREQ
ResAdjustFreq adjust_freq;
#endif #endif
} data; } data;
} PrvResponse; } PrvResponse;
@@ -302,6 +320,22 @@ do_reload_dns(PrvResponse *res)
} }
#endif #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 */ /* HELPER - main loop - action requests from the daemon */
@@ -350,6 +384,11 @@ helper_main(int fd)
case OP_RELOADDNS: case OP_RELOADDNS:
do_reload_dns(&res); do_reload_dns(&res);
break; break;
#endif
#ifdef PRIVOPS_ADJUSTFREQ
case OP_ADJUSTFREQ:
do_adjust_freq(&req.data.adjust_freq, &res);
break;
#endif #endif
case OP_QUIT: case OP_QUIT:
quit = 1; 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 void
PRV_Initialise(int level) PRV_Initialise(int level)
{ {

View File

@@ -64,6 +64,12 @@ void PRV_ReloadDNS(void);
#define PRV_ReloadDNS DNS_Reload #define PRV_ReloadDNS DNS_Reload
#endif #endif
#ifdef PRIVOPS_ADJUSTFREQ
int PRV_AdjustFreq(const int64_t *freq, int64_t *oldfreq);
#else
#define PRV_AdjustFreq adjfreq
#endif
#ifdef PRIVOPS_HELPER #ifdef PRIVOPS_HELPER
void PRV_Initialise(int scfilter_level); void PRV_Initialise(int scfilter_level);
void PRV_StartHelper(void); void PRV_StartHelper(void);