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