1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "alloc-util.h"
4 #include "def.h"
5 #include "dns-domain.h"
6 #include "extract-word.h"
7 #include "string-util.h"
8 #include "timesyncd-conf.h"
9 #include "timesyncd-manager.h"
10 #include "timesyncd-server.h"
11
manager_parse_server_string(Manager * m,ServerType type,const char * string)12 int manager_parse_server_string(Manager *m, ServerType type, const char *string) {
13 ServerName *first;
14 int r;
15
16 assert(m);
17 assert(string);
18
19 first = type == SERVER_FALLBACK ? m->fallback_servers : m->system_servers;
20
21 if (type == SERVER_FALLBACK)
22 m->have_fallbacks = true;
23
24 for (;;) {
25 _cleanup_free_ char *word = NULL;
26 bool found = false;
27
28 r = extract_first_word(&string, &word, NULL, 0);
29 if (r < 0)
30 return log_error_errno(r, "Failed to parse timesyncd server syntax \"%s\": %m", string);
31 if (r == 0)
32 break;
33
34 r = dns_name_is_valid_or_address(word);
35 if (r < 0)
36 return log_error_errno(r, "Failed to check validity of NTP server name or address '%s': %m", word);
37 if (r == 0) {
38 log_error("Invalid NTP server name or address, ignoring: %s", word);
39 continue;
40 }
41
42 /* Filter out duplicates */
43 LIST_FOREACH(names, n, first)
44 if (streq_ptr(n->string, word)) {
45 found = true;
46 break;
47 }
48
49 if (found)
50 continue;
51
52 r = server_name_new(m, NULL, type, word);
53 if (r < 0)
54 return r;
55 }
56
57 return 0;
58 }
59
manager_parse_fallback_string(Manager * m,const char * string)60 int manager_parse_fallback_string(Manager *m, const char *string) {
61 if (m->have_fallbacks)
62 return 0;
63
64 return manager_parse_server_string(m, SERVER_FALLBACK, string);
65 }
66
config_parse_servers(const char * unit,const char * filename,unsigned line,const char * section,unsigned section_line,const char * lvalue,int ltype,const char * rvalue,void * data,void * userdata)67 int config_parse_servers(
68 const char *unit,
69 const char *filename,
70 unsigned line,
71 const char *section,
72 unsigned section_line,
73 const char *lvalue,
74 int ltype,
75 const char *rvalue,
76 void *data,
77 void *userdata) {
78
79 Manager *m = userdata;
80 int r;
81
82 assert(filename);
83 assert(lvalue);
84 assert(rvalue);
85
86 if (isempty(rvalue))
87 manager_flush_server_names(m, ltype);
88 else {
89 r = manager_parse_server_string(m, ltype, rvalue);
90 if (r < 0) {
91 log_syntax(unit, LOG_WARNING, filename, line, r,
92 "Failed to parse NTP server string '%s', ignoring: %m", rvalue);
93 return 0;
94 }
95 }
96
97 return 0;
98 }
99
manager_parse_config_file(Manager * m)100 int manager_parse_config_file(Manager *m) {
101 int r;
102
103 assert(m);
104
105 r = config_parse_many_nulstr(
106 PKGSYSCONFDIR "/timesyncd.conf",
107 CONF_PATHS_NULSTR("systemd/timesyncd.conf.d"),
108 "Time\0",
109 config_item_perf_lookup, timesyncd_gperf_lookup,
110 CONFIG_PARSE_WARN,
111 m,
112 NULL);
113 if (r < 0)
114 return r;
115
116 if (m->poll_interval_min_usec < 16 * USEC_PER_SEC) {
117 log_warning("Invalid PollIntervalMinSec=. Using default value.");
118 m->poll_interval_min_usec = NTP_POLL_INTERVAL_MIN_USEC;
119 }
120
121 if (m->poll_interval_max_usec < m->poll_interval_min_usec) {
122 log_warning("PollIntervalMaxSec= is smaller than PollIntervalMinSec=. Using default value.");
123 m->poll_interval_max_usec = MAX(NTP_POLL_INTERVAL_MAX_USEC, m->poll_interval_min_usec * 32);
124 }
125
126 if (m->connection_retry_usec < 1 * USEC_PER_SEC) {
127 log_warning("Invalid ConnectionRetrySec=. Using default value.");
128 m->connection_retry_usec = DEFAULT_CONNECTION_RETRY_USEC;
129 }
130
131 return r;
132 }
133