]> git.ipfire.org Git - thirdparty/chrony.git/blame - sys_netbsd.c
examples: harden systemd services
[thirdparty/chrony.git] / sys_netbsd.c
CommitLineData
88840341 1/*
88840341
RC
2 chronyd/chronyc - Programs for keeping computer clocks accurate.
3
4 **********************************************************************
5 * Copyright (C) Richard P. Curnow 1997-2001
6 * Copyright (C) J. Hannken-Illjes 2001
33967780 7 * Copyright (C) Miroslav Lichvar 2015
88840341
RC
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
8e23110a 20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
88840341
RC
21 *
22 **********************************************************************
23
24 =======================================================================
25
82510e6b 26 Driver file for the NetBSD and FreeBSD operating system.
88840341
RC
27 */
28
da2c8d90
ML
29#include "config.h"
30
d2d82e2e 31#include "sysincl.h"
88840341
RC
32
33#include "sys_netbsd.h"
d2d82e2e 34#include "sys_timex.h"
88840341 35#include "logging.h"
46f0ad6b 36#include "privops.h"
692ef054
ML
37#include "util.h"
38
39/* Maximum frequency offset accepted by the kernel (in ppm) */
40#define MAX_FREQ 500.0
41
42/* Minimum assumed rate at which the kernel updates the clock frequency */
43#define MIN_TICK_RATE 100
44
45/* Interval between kernel updates of the adjtime() offset */
46#define ADJTIME_UPDATE_INTERVAL 1.0
47
48/* Maximum adjtime() slew rate (in ppm) */
49#define MAX_ADJTIME_SLEWRATE 5000.0
50
51/* Minimum offset adjtime() slews faster than MAX_FREQ */
52#define MIN_FASTSLEW_OFFSET 1.0
53
54/* ================================================== */
55
56/* Positive offset means system clock is fast of true time, therefore
57 slew backwards */
58
59static void
60accrue_offset(double offset, double corr_rate)
61{
62 struct timeval newadj, oldadj;
d0dfa1de 63 double doldadj;
692ef054
ML
64
65 UTI_DoubleToTimeval(-offset, &newadj);
66
82510e6b 67 if (PRV_AdjustTime(&newadj, &oldadj) < 0)
f282856c 68 LOG_FATAL("adjtime() failed");
692ef054
ML
69
70 /* Add the old remaining adjustment if not zero */
cfe706f0 71 doldadj = UTI_TimevalToDouble(&oldadj);
d0dfa1de
ML
72 if (doldadj != 0.0) {
73 UTI_DoubleToTimeval(-offset + doldadj, &newadj);
82510e6b 74 if (PRV_AdjustTime(&newadj, NULL) < 0)
f282856c 75 LOG_FATAL("adjtime() failed");
692ef054
ML
76 }
77}
78
79/* ================================================== */
80
81static void
d0dfa1de 82get_offset_correction(struct timespec *raw,
692ef054
ML
83 double *corr, double *err)
84{
85 struct timeval remadj;
86 double adjustment_remaining;
4b511143
BC
87#ifdef MACOSX
88 struct timeval tv = {0, 0};
692ef054 89
4b511143
BC
90 if (PRV_AdjustTime(&tv, &remadj) < 0)
91 LOG_FATAL("adjtime() failed");
92
93 if (PRV_AdjustTime(&remadj, NULL) < 0)
94 LOG_FATAL("adjtime() failed");
95#else
82510e6b 96 if (PRV_AdjustTime(NULL, &remadj) < 0)
f282856c 97 LOG_FATAL("adjtime() failed");
4b511143 98#endif
692ef054 99
cfe706f0 100 adjustment_remaining = UTI_TimevalToDouble(&remadj);
692ef054
ML
101
102 *corr = adjustment_remaining;
103 if (err) {
104 if (*corr != 0.0)
105 *err = 1.0e-6 * MAX_ADJTIME_SLEWRATE / ADJTIME_UPDATE_INTERVAL;
106 else
107 *err = 0.0;
108 }
109}
88840341
RC
110
111/* ================================================== */
112
113void
114SYS_NetBSD_Initialise(void)
115{
692ef054
ML
116 SYS_Timex_InitialiseWithFunctions(MAX_FREQ, 1.0 / MIN_TICK_RATE,
117 NULL, NULL, NULL,
118 MIN_FASTSLEW_OFFSET, MAX_ADJTIME_SLEWRATE,
119 accrue_offset, get_offset_correction);
88840341
RC
120}
121
122/* ================================================== */
123
124void
125SYS_NetBSD_Finalise(void)
126{
d2d82e2e 127 SYS_Timex_Finalise();
88840341
RC
128}
129
130/* ================================================== */
131
7b6435b2
ML
132#ifdef FEAT_PRIVDROP
133void
e4cccc11 134SYS_NetBSD_DropRoot(uid_t uid, gid_t gid, SYS_ProcessContext context, int clock_control)
7b6435b2 135{
82510e6b 136#ifdef NETBSD
7b6435b2 137 int fd;
82510e6b 138#endif
7b6435b2 139
82510e6b
ML
140 /* On NetBSD the helper is used only for socket binding, but on FreeBSD
141 it's used also for setting and adjusting the system clock */
8e9716d5
ML
142 if (context == SYS_MAIN_PROCESS)
143 PRV_StartHelper();
46f0ad6b 144
3cf6acdf 145 UTI_DropRoot(uid, gid);
7b6435b2 146
82510e6b 147#ifdef NETBSD
e4cccc11
ML
148 if (!clock_control)
149 return;
150
7b6435b2
ML
151 /* Check if we have write access to /dev/clockctl */
152 fd = open("/dev/clockctl", O_WRONLY);
153 if (fd < 0)
f282856c 154 LOG_FATAL("Can't write to /dev/clockctl");
7b6435b2 155 close(fd);
82510e6b 156#endif
7b6435b2
ML
157}
158#endif