/src/samba/lib/param/util.c
Line | Count | Source |
1 | | /* |
2 | | Unix SMB/CIFS implementation. |
3 | | Samba utility functions |
4 | | Copyright (C) Andrew Tridgell 1992-1998 |
5 | | Copyright (C) Jeremy Allison 2001-2002 |
6 | | Copyright (C) Simo Sorce 2001 |
7 | | Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003. |
8 | | Copyright (C) James J Myers 2003 |
9 | | Copyright (C) Jelmer Vernooij 2005-2007 |
10 | | |
11 | | This program is free software; you can redistribute it and/or modify |
12 | | it under the terms of the GNU General Public License as published by |
13 | | the Free Software Foundation; either version 3 of the License, or |
14 | | (at your option) any later version. |
15 | | |
16 | | This program is distributed in the hope that it will be useful, |
17 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | | GNU General Public License for more details. |
20 | | |
21 | | You should have received a copy of the GNU General Public License |
22 | | along with this program. If not, see <http://www.gnu.org/licenses/>. |
23 | | */ |
24 | | |
25 | | #include "includes.h" |
26 | | #include "dynconfig/dynconfig.h" |
27 | | #include "system/network.h" |
28 | | #include "system/filesys.h" |
29 | | #include "system/dir.h" |
30 | | #include "param/param.h" |
31 | | #include "libds/common/roles.h" |
32 | | #include "tdb.h" |
33 | | |
34 | | /** |
35 | | * @file |
36 | | * @brief Misc utility functions |
37 | | */ |
38 | | |
39 | | |
40 | | bool lpcfg_is_mydomain(struct loadparm_context *lp_ctx, |
41 | | const char *domain) |
42 | 0 | { |
43 | 0 | return strequal(lpcfg_workgroup(lp_ctx), domain); |
44 | 0 | } |
45 | | |
46 | | bool lpcfg_is_my_domain_or_realm(struct loadparm_context *lp_ctx, |
47 | | const char *domain) |
48 | 0 | { |
49 | 0 | return strequal(lpcfg_workgroup(lp_ctx), domain) || |
50 | 0 | strequal(lpcfg_realm(lp_ctx), domain); |
51 | 0 | } |
52 | | |
53 | | /** |
54 | | see if a string matches either our primary or one of our secondary |
55 | | netbios aliases. do a case insensitive match |
56 | | */ |
57 | | bool lpcfg_is_myname(struct loadparm_context *lp_ctx, const char *name) |
58 | 0 | { |
59 | 0 | const char **aliases; |
60 | 0 | int i; |
61 | |
|
62 | 0 | if (strcasecmp_m(name, lpcfg_netbios_name(lp_ctx)) == 0) { |
63 | 0 | return true; |
64 | 0 | } |
65 | | |
66 | 0 | aliases = lpcfg_netbios_aliases(lp_ctx); |
67 | 0 | for (i=0; aliases && aliases[i]; i++) { |
68 | 0 | if (strcasecmp_m(name, aliases[i]) == 0) { |
69 | 0 | return true; |
70 | 0 | } |
71 | 0 | } |
72 | | |
73 | 0 | return false; |
74 | 0 | } |
75 | | |
76 | | static char *lpcfg_common_path(TALLOC_CTX* mem_ctx, |
77 | | const char *parent, |
78 | | const char *name) |
79 | 0 | { |
80 | 0 | char *fname, *dname; |
81 | 0 | bool ok; |
82 | |
|
83 | 0 | if (name == NULL) { |
84 | 0 | return NULL; |
85 | 0 | } |
86 | 0 | if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) { |
87 | 0 | return talloc_strdup(mem_ctx, name); |
88 | 0 | } |
89 | | |
90 | 0 | dname = talloc_strdup(mem_ctx, parent); |
91 | 0 | if (dname == NULL) { |
92 | 0 | return NULL; |
93 | 0 | } |
94 | 0 | trim_string(dname,"","/"); |
95 | |
|
96 | 0 | ok = directory_create_or_exist(dname, 0755); |
97 | 0 | if (!ok) { |
98 | 0 | DEBUG(1, ("Unable to create directory %s for file %s. " |
99 | 0 | "Error was %s\n", dname, name, strerror(errno))); |
100 | 0 | return NULL; |
101 | 0 | } |
102 | | |
103 | 0 | fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name); |
104 | 0 | if (fname == NULL) { |
105 | 0 | return dname; |
106 | 0 | } |
107 | 0 | talloc_free(dname); |
108 | |
|
109 | 0 | return fname; |
110 | 0 | } |
111 | | |
112 | | |
113 | | /** |
114 | | A useful function for returning a path in the Samba lock directory. |
115 | | **/ |
116 | | char *lpcfg_lock_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, |
117 | | const char *name) |
118 | 0 | { |
119 | 0 | return lpcfg_common_path(mem_ctx, lpcfg_lock_directory(lp_ctx), name); |
120 | 0 | } |
121 | | |
122 | | /** |
123 | | A useful function for returning a path in the Samba state directory. |
124 | | **/ |
125 | | char *lpcfg_state_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, |
126 | | const char *name) |
127 | 0 | { |
128 | 0 | return lpcfg_common_path(mem_ctx, lpcfg_state_directory(lp_ctx), name); |
129 | 0 | } |
130 | | |
131 | | /** |
132 | | A useful function for returning a path in the Samba cache directory. |
133 | | **/ |
134 | | char *lpcfg_cache_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, |
135 | | const char *name) |
136 | 0 | { |
137 | 0 | return lpcfg_common_path(mem_ctx, lpcfg_cache_directory(lp_ctx), name); |
138 | 0 | } |
139 | | |
140 | | /** |
141 | | * @brief Returns an absolute path to a file in the directory containing the current config file |
142 | | * |
143 | | * @param name File to find, relative to the config file directory. |
144 | | * |
145 | | * @retval Pointer to a talloc'ed string containing the full path. |
146 | | **/ |
147 | | |
148 | | char *lpcfg_config_path(TALLOC_CTX* mem_ctx, struct loadparm_context *lp_ctx, |
149 | | const char *name) |
150 | 0 | { |
151 | 0 | char *fname, *config_dir, *p; |
152 | 0 | config_dir = talloc_strdup(mem_ctx, lpcfg_configfile(lp_ctx)); |
153 | 0 | if (config_dir == NULL) { |
154 | 0 | config_dir = talloc_strdup(mem_ctx, lp_default_path()); |
155 | 0 | } |
156 | 0 | p = strrchr(config_dir, '/'); |
157 | 0 | if (p == NULL) { |
158 | 0 | talloc_free(config_dir); |
159 | 0 | config_dir = talloc_strdup(mem_ctx, "."); |
160 | 0 | if (config_dir == NULL) { |
161 | 0 | return NULL; |
162 | 0 | } |
163 | 0 | } else { |
164 | 0 | p[0] = '\0'; |
165 | 0 | } |
166 | 0 | fname = talloc_asprintf(mem_ctx, "%s/%s", config_dir, name); |
167 | 0 | talloc_free(config_dir); |
168 | 0 | return fname; |
169 | 0 | } |
170 | | |
171 | | /** |
172 | | * @brief Returns an absolute path to a file in the Samba private directory. |
173 | | * |
174 | | * @param name File to find, relative to PRIVATEDIR. |
175 | | * if name is not relative, then use it as-is |
176 | | * |
177 | | * @retval Pointer to a talloc'ed string containing the full path. |
178 | | **/ |
179 | | char *lpcfg_private_path(TALLOC_CTX* mem_ctx, |
180 | | struct loadparm_context *lp_ctx, |
181 | | const char *name) |
182 | 0 | { |
183 | 0 | char *fname; |
184 | 0 | if (name == NULL) { |
185 | 0 | return NULL; |
186 | 0 | } |
187 | 0 | if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) { |
188 | 0 | return talloc_strdup(mem_ctx, name); |
189 | 0 | } |
190 | 0 | fname = talloc_asprintf(mem_ctx, "%s/%s", lpcfg_private_dir(lp_ctx), name); |
191 | 0 | return fname; |
192 | 0 | } |
193 | | |
194 | | /** |
195 | | * @brief Returns an absolute path to a NTDB or TDB file in the Samba |
196 | | * private directory. |
197 | | * |
198 | | * @param name File to find, relative to PRIVATEDIR, without .tdb extension. |
199 | | * |
200 | | * @retval Pointer to a talloc'ed string containing the full path, for |
201 | | * use with dbwrap_local_open(). |
202 | | **/ |
203 | | char *lpcfg_private_db_path(TALLOC_CTX *mem_ctx, |
204 | | struct loadparm_context *lp_ctx, |
205 | | const char *name) |
206 | 0 | { |
207 | 0 | return talloc_asprintf(mem_ctx, "%s/%s.tdb", |
208 | 0 | lpcfg_private_dir(lp_ctx), name); |
209 | 0 | } |
210 | | |
211 | | /** |
212 | | return a path in the smbd.tmp directory, where all temporary file |
213 | | for smbd go. If NULL is passed for name then return the directory |
214 | | path itself |
215 | | */ |
216 | | char *smbd_tmp_path(TALLOC_CTX *mem_ctx, |
217 | | struct loadparm_context *lp_ctx, |
218 | | const char *name) |
219 | 0 | { |
220 | 0 | char *fname, *dname; |
221 | 0 | bool ok; |
222 | |
|
223 | 0 | dname = lpcfg_private_path(mem_ctx, lp_ctx, "smbd.tmp"); |
224 | 0 | if (dname == NULL) { |
225 | 0 | return NULL; |
226 | 0 | } |
227 | | |
228 | 0 | ok = directory_create_or_exist(dname, 0755); |
229 | 0 | if (!ok) { |
230 | 0 | return NULL; |
231 | 0 | } |
232 | | |
233 | 0 | if (name == NULL) { |
234 | 0 | return dname; |
235 | 0 | } |
236 | | |
237 | 0 | fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name); |
238 | 0 | if (fname == NULL) { |
239 | 0 | return dname; |
240 | 0 | } |
241 | 0 | talloc_free(dname); |
242 | |
|
243 | 0 | return fname; |
244 | 0 | } |
245 | | |
246 | | const char *lpcfg_imessaging_path(TALLOC_CTX *mem_ctx, |
247 | | struct loadparm_context *lp_ctx) |
248 | 0 | { |
249 | 0 | return smbd_tmp_path(mem_ctx, lp_ctx, "msg"); |
250 | 0 | } |
251 | | |
252 | | const char *lpcfg_sam_name(struct loadparm_context *lp_ctx) |
253 | 0 | { |
254 | 0 | switch (lpcfg_server_role(lp_ctx)) { |
255 | 0 | case ROLE_DOMAIN_BDC: |
256 | 0 | case ROLE_DOMAIN_PDC: |
257 | 0 | case ROLE_ACTIVE_DIRECTORY_DC: |
258 | 0 | case ROLE_IPA_DC: |
259 | 0 | return lpcfg_workgroup(lp_ctx); |
260 | 0 | default: |
261 | 0 | return lpcfg_netbios_name(lp_ctx); |
262 | 0 | } |
263 | 0 | } |
264 | | |
265 | | const char *lpcfg_sam_dnsname(struct loadparm_context *lp_ctx) |
266 | 0 | { |
267 | 0 | switch (lpcfg_server_role(lp_ctx)) { |
268 | 0 | case ROLE_ACTIVE_DIRECTORY_DC: |
269 | 0 | case ROLE_IPA_DC: |
270 | 0 | return lpcfg_dnsdomain(lp_ctx); |
271 | 0 | default: |
272 | 0 | return NULL; |
273 | 0 | } |
274 | 0 | } |
275 | | |
276 | | static int |
277 | | tdb_fetch_lifetime_fn(TDB_DATA key, TDB_DATA data, void *private_data) |
278 | 0 | { |
279 | 0 | if (data.dsize < 256) { |
280 | 0 | long *result = private_data; |
281 | 0 | char tmp[data.dsize + 1]; |
282 | 0 | memcpy(tmp, data.dptr, data.dsize); |
283 | 0 | tmp[data.dsize] = '\0'; |
284 | 0 | *result = atol(tmp); |
285 | 0 | return 0; |
286 | 0 | } |
287 | 0 | return -1; |
288 | 0 | } |
289 | | |
290 | | static long tdb_fetch_lifetime(struct tdb_context *tdb, |
291 | | const char *keystr) |
292 | 0 | { |
293 | 0 | long result = -1; |
294 | 0 | int ret; |
295 | |
|
296 | 0 | ret = tdb_parse_record( |
297 | 0 | tdb, |
298 | 0 | (TDB_DATA){ |
299 | 0 | .dptr = discard_const_p(uint8_t, keystr), |
300 | 0 | .dsize = strlen(keystr), |
301 | 0 | }, |
302 | 0 | tdb_fetch_lifetime_fn, |
303 | 0 | &result); |
304 | 0 | if (ret == -1) { |
305 | 0 | return -1; |
306 | 0 | } |
307 | 0 | return result; |
308 | 0 | } |
309 | | |
310 | | void lpcfg_default_kdc_policy(TALLOC_CTX *mem_ctx, |
311 | | struct loadparm_context *lp_ctx, |
312 | | time_t *svc_tkt_lifetime, |
313 | | time_t *usr_tkt_lifetime, |
314 | | time_t *renewal_lifetime) |
315 | 0 | { |
316 | 0 | long val; |
317 | 0 | TDB_CONTEXT *ctx = NULL; |
318 | 0 | const char *kdc_tdb = NULL; |
319 | |
|
320 | 0 | kdc_tdb = lpcfg_cache_path(mem_ctx, lp_ctx, "gpo.tdb"); |
321 | 0 | if (kdc_tdb) |
322 | 0 | ctx = tdb_open(kdc_tdb, 0, TDB_DEFAULT, O_RDWR, 0600); |
323 | |
|
324 | 0 | if (!ctx || ( val = tdb_fetch_lifetime(ctx, "kdc:service_ticket_lifetime") ) == -1 ) |
325 | 0 | val = lpcfg_parm_long(lp_ctx, NULL, "kdc", "service ticket lifetime", 10); |
326 | 0 | *svc_tkt_lifetime = val * 60 * 60; |
327 | |
|
328 | 0 | if (!ctx || ( val = tdb_fetch_lifetime(ctx, "kdc:user_ticket_lifetime") ) == -1 ) |
329 | 0 | val = lpcfg_parm_long(lp_ctx, NULL, "kdc", "user ticket lifetime", 10); |
330 | 0 | *usr_tkt_lifetime = val * 60 * 60; |
331 | |
|
332 | 0 | if (!ctx || ( val = tdb_fetch_lifetime(ctx, "kdc:renewal_lifetime") ) == -1 ) |
333 | 0 | val = lpcfg_parm_long(lp_ctx, NULL, "kdc", "renewal lifetime", 24 * 7); |
334 | 0 | *renewal_lifetime = val * 60 * 60; |
335 | |
|
336 | 0 | if (ctx != NULL) { |
337 | 0 | tdb_close(ctx); |
338 | | ctx = NULL; |
339 | 0 | } |
340 | 0 | } |