Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Parameter loading functions
4 : Copyright (C) Karl Auer 1993-1998
5 :
6 : Largely re-written by Andrew Tridgell, September 1994
7 :
8 : Copyright (C) Simo Sorce 2001
9 : Copyright (C) Alexander Bokovoy 2002
10 : Copyright (C) Stefan (metze) Metzmacher 2002
11 : Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12 : Copyright (C) Michael Adam 2008
13 : Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14 : Copyright (C) Andrew Bartlett 2011
15 :
16 : This program is free software; you can redistribute it and/or modify
17 : it under the terms of the GNU General Public License as published by
18 : the Free Software Foundation; either version 3 of the License, or
19 : (at your option) any later version.
20 :
21 : This program is distributed in the hope that it will be useful,
22 : but WITHOUT ANY WARRANTY; without even the implied warranty of
23 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 : GNU General Public License for more details.
25 :
26 : You should have received a copy of the GNU General Public License
27 : along with this program. If not, see <http://www.gnu.org/licenses/>.
28 : */
29 :
30 : /*
31 : * Load parameters.
32 : *
33 : * This module provides suitable callback functions for the params
34 : * module. It builds the internal table of service details which is
35 : * then used by the rest of the server.
36 : *
37 : * To add a parameter:
38 : *
39 : * 1) add it to the global or service structure definition
40 : * 2) add it to the parm_table
41 : * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42 : * 4) If it's a global then initialise it in init_globals. If a local
43 : * (ie. service) parameter then initialise it in the sDefault structure
44 : *
45 : *
46 : * Notes:
47 : * The configuration file is processed sequentially for speed. It is NOT
48 : * accessed randomly as happens in 'real' Windows. For this reason, there
49 : * is a fair bit of sequence-dependent code here - ie., code which assumes
50 : * that certain things happen before others. In particular, the code which
51 : * happens at the boundary between sections is delicately poised, so be
52 : * careful!
53 : *
54 : */
55 :
56 : #define LOADPARM_SUBSTITUTION_INTERNALS 1
57 : #include "includes.h"
58 : #include "system/filesys.h"
59 : #include "util_tdb.h"
60 : #include "lib/param/loadparm.h"
61 : #include "lib/param/param.h"
62 : #include "printing.h"
63 : #include "lib/smbconf/smbconf.h"
64 : #include "lib/smbconf/smbconf_init.h"
65 :
66 : #include "include/smb_ldap.h"
67 : #include "../librpc/gen_ndr/svcctl.h"
68 : #include "intl.h"
69 : #include "../libcli/smb/smb_signing.h"
70 : #include "dbwrap/dbwrap.h"
71 : #include "dbwrap/dbwrap_rbt.h"
72 : #include "../lib/util/bitmap.h"
73 : #include "librpc/gen_ndr/nbt.h"
74 : #include "librpc/gen_ndr/dns.h"
75 : #include "source4/lib/tls/tls.h"
76 : #include "libcli/auth/ntlm_check.h"
77 : #include "lib/crypto/gnutls_helpers.h"
78 : #include "lib/util/string_wrappers.h"
79 : #include "auth/credentials/credentials.h"
80 : #include "source3/lib/substitute.h"
81 : #include "source3/librpc/gen_ndr/ads.h"
82 : #include "lib/util/time_basic.h"
83 : #include "libds/common/flags.h"
84 :
85 : #ifdef HAVE_SYS_SYSCTL_H
86 : #include <sys/sysctl.h>
87 : #endif
88 :
89 : bool b_loaded = false;
90 :
91 : /* the special value for the include parameter
92 : * to be interpreted not as a file name but to
93 : * trigger loading of the global smb.conf options
94 : * from registry. */
95 : #ifndef INCLUDE_REGISTRY_NAME
96 : #define INCLUDE_REGISTRY_NAME "registry"
97 : #endif
98 :
99 : static bool in_client = false; /* Not in the client by default */
100 : static struct smbconf_csn conf_last_csn;
101 :
102 : static int config_backend = CONFIG_BACKEND_FILE;
103 :
104 : /* some helpful bits */
105 : #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && \
106 : (ServicePtrs != NULL) && \
107 : (ServicePtrs[(i)] != NULL) && ServicePtrs[(i)]->valid)
108 : #define VALID(i) ((ServicePtrs != NULL) && (ServicePtrs[i]!= NULL) && \
109 : ServicePtrs[i]->valid)
110 :
111 : #define USERSHARE_VALID 1
112 : #define USERSHARE_PENDING_DELETE 2
113 :
114 : static bool defaults_saved = false;
115 :
116 : #include "lib/param/param_global.h"
117 :
118 : static struct loadparm_global Globals;
119 :
120 : /* This is a default service used to prime a services structure */
121 : static const struct loadparm_service _sDefault =
122 : {
123 : .valid = true,
124 : .autoloaded = false,
125 : .usershare = 0,
126 : .usershare_last_mod = {0, 0},
127 : .szService = NULL,
128 : .path = NULL,
129 : .invalid_users = NULL,
130 : .valid_users = NULL,
131 : .admin_users = NULL,
132 : .copy = NULL,
133 : .include = NULL,
134 : .preexec = NULL,
135 : .postexec = NULL,
136 : .root_preexec = NULL,
137 : .root_postexec = NULL,
138 : .cups_options = NULL,
139 : .print_command = NULL,
140 : .lpq_command = NULL,
141 : .lprm_command = NULL,
142 : .lppause_command = NULL,
143 : .lpresume_command = NULL,
144 : .queuepause_command = NULL,
145 : .queueresume_command = NULL,
146 : ._printername = NULL,
147 : .printjob_username = NULL,
148 : .dont_descend = NULL,
149 : .hosts_allow = NULL,
150 : .hosts_deny = NULL,
151 : .magic_script = NULL,
152 : .magic_output = NULL,
153 : .veto_files = NULL,
154 : .hide_files = NULL,
155 : .veto_oplock_files = NULL,
156 : .comment = NULL,
157 : .force_user = NULL,
158 : .force_group = NULL,
159 : .read_list = NULL,
160 : .write_list = NULL,
161 : .volume = NULL,
162 : .fstype = NULL,
163 : .vfs_objects = NULL,
164 : .msdfs_proxy = NULL,
165 : .aio_write_behind = NULL,
166 : .dfree_command = NULL,
167 : .min_print_space = 0,
168 : .max_print_jobs = 1000,
169 : .max_reported_print_jobs = 0,
170 : .create_mask = 0744,
171 : .force_create_mode = 0,
172 : .directory_mask = 0755,
173 : .force_directory_mode = 0,
174 : .max_connections = 0,
175 : .default_case = CASE_LOWER,
176 : .printing = DEFAULT_PRINTING,
177 : .csc_policy = 0,
178 : .block_size = 1024,
179 : .dfree_cache_time = 0,
180 : .preexec_close = false,
181 : .root_preexec_close = false,
182 : .case_sensitive = Auto,
183 : .preserve_case = true,
184 : .short_preserve_case = true,
185 : .hide_dot_files = true,
186 : .hide_special_files = false,
187 : .hide_unreadable = false,
188 : .hide_unwriteable_files = false,
189 : .browseable = true,
190 : .access_based_share_enum = false,
191 : .available = true,
192 : .read_only = true,
193 : .spotlight = false,
194 : .guest_only = false,
195 : .administrative_share = false,
196 : .guest_ok = false,
197 : .printable = false,
198 : .print_notify_backchannel = false,
199 : .map_system = false,
200 : .map_hidden = false,
201 : .map_archive = true,
202 : .store_dos_attributes = true,
203 : .smbd_max_xattr_size = 65536,
204 : .dmapi_support = false,
205 : .locking = true,
206 : .strict_locking = Auto,
207 : .posix_locking = true,
208 : .oplocks = true,
209 : .kernel_oplocks = false,
210 : .level2_oplocks = true,
211 : .mangled_names = MANGLED_NAMES_ILLEGAL,
212 : .wide_links = false,
213 : .follow_symlinks = true,
214 : .sync_always = false,
215 : .strict_allocate = false,
216 : .strict_rename = false,
217 : .strict_sync = true,
218 : .mangling_char = '~',
219 : .copymap = NULL,
220 : .delete_readonly = false,
221 : .fake_oplocks = false,
222 : .delete_veto_files = false,
223 : .dos_filemode = false,
224 : .dos_filetimes = true,
225 : .dos_filetime_resolution = false,
226 : .fake_directory_create_times = false,
227 : .blocking_locks = true,
228 : .inherit_permissions = false,
229 : .inherit_acls = false,
230 : .inherit_owner = false,
231 : .msdfs_root = false,
232 : .msdfs_shuffle_referrals = false,
233 : .use_client_driver = false,
234 : .default_devmode = true,
235 : .force_printername = false,
236 : .nt_acl_support = true,
237 : .force_unknown_acl_user = false,
238 : ._use_sendfile = false,
239 : .map_acl_inherit = false,
240 : .afs_share = false,
241 : .ea_support = true,
242 : .acl_check_permissions = true,
243 : .acl_map_full_control = true,
244 : .acl_group_control = false,
245 : .acl_allow_execute_always = false,
246 : .acl_flag_inherited_canonicalization = true,
247 : .aio_read_size = 1,
248 : .aio_write_size = 1,
249 : .map_readonly = MAP_READONLY_NO,
250 : .server_smb_encrypt = SMB_ENCRYPTION_DEFAULT,
251 : .kernel_share_modes = false,
252 : .durable_handles = true,
253 : .check_parent_directory_delete_on_close = false,
254 : .param_opt = NULL,
255 : .smbd_search_ask_sharemode = true,
256 : .smbd_getinfo_ask_sharemode = true,
257 : .spotlight_backend = SPOTLIGHT_BACKEND_NOINDEX,
258 : .honor_change_notify_privilege = false,
259 : .volume_serial_number = -1,
260 : .dummy = ""
261 : };
262 :
263 : /*
264 : * This is a copy of the default service structure. Service options in the
265 : * global section would otherwise overwrite the initial default values.
266 : */
267 : static struct loadparm_service sDefault;
268 :
269 : /* local variables */
270 : static struct loadparm_service **ServicePtrs = NULL;
271 : static int iNumServices = 0;
272 : static int iServiceIndex = 0;
273 : static struct db_context *ServiceHash;
274 : static bool bInGlobalSection = true;
275 : static bool bGlobalOnly = false;
276 : static struct file_lists *file_lists = NULL;
277 : static unsigned int *flags_list = NULL;
278 :
279 : static void set_allowed_client_auth(void);
280 :
281 : static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
282 : static void free_param_opts(struct parmlist_entry **popts);
283 :
284 : /**
285 : * Function to return the default value for the maximum number of open
286 : * file descriptors permitted. This function tries to consult the
287 : * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
288 : * the smaller of those.
289 : */
290 85676 : static int max_open_files(void)
291 : {
292 85676 : int sysctl_max = MAX_OPEN_FILES;
293 85676 : int rlimit_max = MAX_OPEN_FILES;
294 :
295 : #ifdef HAVE_SYSCTLBYNAME
296 : {
297 : size_t size = sizeof(sysctl_max);
298 : sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
299 : 0);
300 : }
301 : #endif
302 :
303 : #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
304 : {
305 211 : struct rlimit rl;
306 :
307 85676 : ZERO_STRUCT(rl);
308 :
309 85676 : if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
310 85676 : rlimit_max = rl.rlim_cur;
311 :
312 : #if defined(RLIM_INFINITY)
313 85676 : if(rl.rlim_cur == RLIM_INFINITY)
314 0 : rlimit_max = MAX_OPEN_FILES;
315 : #endif
316 : }
317 : #endif
318 :
319 85676 : if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
320 0 : DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
321 : "minimum Windows limit (%d)\n",
322 : sysctl_max,
323 : MIN_OPEN_FILES_WINDOWS));
324 0 : sysctl_max = MIN_OPEN_FILES_WINDOWS;
325 : }
326 :
327 85676 : if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
328 716 : DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
329 : "minimum Windows limit (%d)\n",
330 : rlimit_max,
331 : MIN_OPEN_FILES_WINDOWS));
332 716 : rlimit_max = MIN_OPEN_FILES_WINDOWS;
333 : }
334 :
335 85676 : return MIN(sysctl_max, rlimit_max);
336 : }
337 :
338 : /**
339 : * Common part of freeing allocated data for one parameter.
340 : */
341 54195768 : static void free_one_parameter_common(void *parm_ptr,
342 : struct parm_struct parm)
343 : {
344 54195768 : if ((parm.type == P_STRING) ||
345 40427396 : (parm.type == P_USTRING))
346 : {
347 13928079 : lpcfg_string_free((char**)parm_ptr);
348 40267689 : } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
349 4569369 : TALLOC_FREE(*((char***)parm_ptr));
350 : }
351 54195768 : }
352 :
353 : /**
354 : * Free the allocated data for one parameter for a share
355 : * given as a service struct.
356 : */
357 70450590 : static void free_one_parameter(struct loadparm_service *service,
358 : struct parm_struct parm)
359 : {
360 0 : void *parm_ptr;
361 :
362 70450590 : if (parm.p_class != P_LOCAL) {
363 49233810 : return;
364 : }
365 :
366 21216780 : parm_ptr = lp_parm_ptr(service, &parm);
367 :
368 21216780 : free_one_parameter_common(parm_ptr, parm);
369 : }
370 :
371 : /**
372 : * Free the allocated parameter data of a share given
373 : * as a service struct.
374 : */
375 136005 : static void free_parameters(struct loadparm_service *service)
376 : {
377 0 : uint32_t i;
378 :
379 70586595 : for (i=0; parm_table[i].label; i++) {
380 70450590 : free_one_parameter(service, parm_table[i]);
381 : }
382 136005 : }
383 :
384 : /**
385 : * Free the allocated data for one parameter for a given share
386 : * specified by an snum.
387 : */
388 32978988 : static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
389 : {
390 42994 : void *parm_ptr;
391 :
392 32978988 : if (snum < 0) {
393 32978988 : parm_ptr = lp_parm_ptr(NULL, &parm);
394 0 : } else if (parm.p_class != P_LOCAL) {
395 0 : return;
396 : } else {
397 0 : parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
398 : }
399 :
400 32978988 : free_one_parameter_common(parm_ptr, parm);
401 : }
402 :
403 : /**
404 : * Free the allocated parameter data for a share specified
405 : * by an snum.
406 : */
407 63666 : static void free_parameters_by_snum(int snum)
408 : {
409 83 : uint32_t i;
410 :
411 33042654 : for (i=0; parm_table[i].label; i++) {
412 32978988 : free_one_parameter_by_snum(snum, parm_table[i]);
413 : }
414 63666 : }
415 :
416 : /**
417 : * Free the allocated global parameters.
418 : */
419 63666 : static void free_global_parameters(void)
420 : {
421 83 : uint32_t i;
422 83 : struct parm_struct *parm;
423 :
424 63666 : free_param_opts(&Globals.param_opt);
425 63666 : free_parameters_by_snum(GLOBAL_SECTION_SNUM);
426 :
427 : /* Reset references in the defaults because the context is going to be freed */
428 33042737 : for (i=0; parm_table[i].label; i++) {
429 32978988 : parm = &parm_table[i];
430 32978988 : if ((parm->type == P_STRING) ||
431 23970791 : (parm->type == P_USTRING)) {
432 9167904 : if ((parm->def.svalue != NULL) &&
433 260096 : (*(parm->def.svalue) != '\0')) {
434 79424 : if (talloc_parent(parm->def.svalue) == Globals.ctx) {
435 79424 : parm->def.svalue = NULL;
436 : }
437 : }
438 : }
439 : }
440 63666 : TALLOC_FREE(Globals.ctx);
441 63666 : }
442 :
443 : struct lp_stored_option {
444 : struct lp_stored_option *prev, *next;
445 : const char *label;
446 : const char *value;
447 : };
448 :
449 : static struct lp_stored_option *stored_options;
450 :
451 : /*
452 : save options set by lp_set_cmdline() into a list. This list is
453 : re-applied when we do a globals reset, so that cmdline set options
454 : are sticky across reloads of smb.conf
455 : */
456 30791 : bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
457 : {
458 82 : struct lp_stored_option *entry, *entry_next;
459 42145 : for (entry = stored_options; entry != NULL; entry = entry_next) {
460 12126 : entry_next = entry->next;
461 12126 : if (strcmp(pszParmName, entry->label) == 0) {
462 772 : DLIST_REMOVE(stored_options, entry);
463 772 : talloc_free(entry);
464 772 : break;
465 : }
466 : }
467 :
468 30791 : entry = talloc(NULL, struct lp_stored_option);
469 30791 : if (!entry) {
470 0 : return false;
471 : }
472 :
473 30791 : entry->label = talloc_strdup(entry, pszParmName);
474 30791 : if (!entry->label) {
475 0 : talloc_free(entry);
476 0 : return false;
477 : }
478 :
479 30791 : entry->value = talloc_strdup(entry, pszParmValue);
480 30791 : if (!entry->value) {
481 0 : talloc_free(entry);
482 0 : return false;
483 : }
484 :
485 30791 : DLIST_ADD_END(stored_options, entry);
486 :
487 30709 : return true;
488 : }
489 :
490 88098 : static bool apply_lp_set_cmdline(void)
491 : {
492 88098 : struct lp_stored_option *entry = NULL;
493 142757 : for (entry = stored_options; entry != NULL; entry = entry->next) {
494 54659 : if (!lp_set_cmdline_helper(entry->label, entry->value)) {
495 0 : DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
496 : entry->label, entry->value));
497 0 : return false;
498 : }
499 : }
500 87836 : return true;
501 : }
502 :
503 : /***************************************************************************
504 : Initialise the global parameter structure.
505 : ***************************************************************************/
506 :
507 851812 : void loadparm_s3_init_globals(struct loadparm_context *lp_ctx,
508 : bool reinit_globals)
509 : {
510 10022 : static bool done_init = false;
511 851812 : char *s = NULL;
512 10022 : int i;
513 :
514 : /* If requested to initialize only once and we've already done it... */
515 851812 : if (!reinit_globals && done_init) {
516 : /* ... then we have nothing more to do */
517 756325 : return;
518 : }
519 :
520 85676 : if (!done_init) {
521 : /* The logfile can be set before this is invoked. Free it if so. */
522 38992 : lpcfg_string_free(&Globals.logfile);
523 38992 : done_init = true;
524 : } else {
525 46684 : free_global_parameters();
526 : }
527 :
528 : /* This memset and the free_global_parameters() above will
529 : * wipe out smb.conf options set with lp_set_cmdline(). The
530 : * apply_lp_set_cmdline() call puts these values back in the
531 : * table once the defaults are set */
532 85676 : ZERO_STRUCT(Globals);
533 :
534 85676 : Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
535 :
536 : /* Initialize the flags list if necessary */
537 85676 : if (flags_list == NULL) {
538 0 : get_flags();
539 : }
540 :
541 44465844 : for (i = 0; parm_table[i].label; i++) {
542 44380168 : if ((parm_table[i].type == P_STRING ||
543 32220305 : parm_table[i].type == P_USTRING))
544 : {
545 12337344 : lpcfg_string_set(
546 : Globals.ctx,
547 12337344 : (char **)lp_parm_ptr(NULL, &parm_table[i]),
548 : "");
549 : }
550 : }
551 :
552 :
553 85676 : lpcfg_string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
554 85676 : lpcfg_string_set(Globals.ctx, &sDefault.printjob_username, "%U");
555 :
556 85676 : init_printer_values(lp_ctx, Globals.ctx, &sDefault);
557 :
558 85676 : sDefault.ntvfs_handler = str_list_make_v3_const(Globals.ctx, "unixuid default", NULL);
559 :
560 85676 : DEBUG(3, ("Initialising global parameters\n"));
561 :
562 : /* Must manually force to upper case here, as this does not go via the handler */
563 85676 : lpcfg_string_set(Globals.ctx, &Globals.netbios_name,
564 85676 : myhostname_upper());
565 :
566 85676 : lpcfg_string_set(Globals.ctx, &Globals.smb_passwd_file,
567 : get_dyn_SMB_PASSWD_FILE());
568 85676 : lpcfg_string_set(Globals.ctx, &Globals.private_dir,
569 : get_dyn_PRIVATE_DIR());
570 85676 : lpcfg_string_set(Globals.ctx, &Globals.binddns_dir,
571 : get_dyn_BINDDNS_DIR());
572 :
573 : /* use the new 'hash2' method by default, with a prefix of 1 */
574 85676 : lpcfg_string_set(Globals.ctx, &Globals.mangling_method, "hash2");
575 85676 : Globals.mangle_prefix = 1;
576 :
577 85676 : lpcfg_string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
578 :
579 : /* using UTF8 by default allows us to support all chars */
580 85676 : lpcfg_string_set(Globals.ctx, &Globals.unix_charset,
581 : DEFAULT_UNIX_CHARSET);
582 :
583 : /* Use codepage 850 as a default for the dos character set */
584 85676 : lpcfg_string_set(Globals.ctx, &Globals.dos_charset,
585 : DEFAULT_DOS_CHARSET);
586 :
587 : /*
588 : * Allow the default PASSWD_CHAT to be overridden in local.h.
589 : */
590 85676 : lpcfg_string_set(Globals.ctx, &Globals.passwd_chat,
591 : DEFAULT_PASSWD_CHAT);
592 :
593 85676 : lpcfg_string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
594 :
595 85676 : lpcfg_string_set(Globals.ctx, &Globals.passwd_program, "");
596 85676 : lpcfg_string_set(Globals.ctx, &Globals.lock_directory,
597 : get_dyn_LOCKDIR());
598 85676 : lpcfg_string_set(Globals.ctx, &Globals.state_directory,
599 : get_dyn_STATEDIR());
600 85676 : lpcfg_string_set(Globals.ctx, &Globals.cache_directory,
601 : get_dyn_CACHEDIR());
602 85676 : lpcfg_string_set(Globals.ctx, &Globals.pid_directory,
603 : get_dyn_PIDDIR());
604 85676 : lpcfg_string_set(Globals.ctx, &Globals.nbt_client_socket_address,
605 : "0.0.0.0");
606 : /*
607 : * By default support explicit binding to broadcast
608 : * addresses.
609 : */
610 85676 : Globals.nmbd_bind_explicit_broadcast = true;
611 :
612 85676 : s = talloc_asprintf(Globals.ctx, "Samba %s", samba_version_string());
613 85676 : if (s == NULL) {
614 0 : smb_panic("init_globals: ENOMEM");
615 : }
616 85676 : lpcfg_string_set(Globals.ctx, &Globals.server_string, s);
617 85676 : TALLOC_FREE(s);
618 : #ifdef DEVELOPER
619 85676 : lpcfg_string_set(Globals.ctx, &Globals.panic_action,
620 : "/bin/sleep 999999999");
621 : #endif
622 :
623 85676 : lpcfg_string_set(Globals.ctx, &Globals.socket_options,
624 : DEFAULT_SOCKET_OPTIONS);
625 :
626 85676 : lpcfg_string_set(Globals.ctx, &Globals.logon_drive, "");
627 : /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
628 85676 : lpcfg_string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
629 85676 : lpcfg_string_set(Globals.ctx, &Globals.logon_path,
630 : "\\\\%N\\%U\\profile");
631 :
632 85887 : Globals.name_resolve_order =
633 85676 : str_list_make_v3_const(Globals.ctx,
634 : DEFAULT_NAME_RESOLVE_ORDER,
635 : NULL);
636 85676 : lpcfg_string_set(Globals.ctx, &Globals.password_server, "*");
637 :
638 85676 : Globals.algorithmic_rid_base = BASE_RID;
639 :
640 85676 : Globals.load_printers = true;
641 85676 : Globals.printcap_cache_time = 750; /* 12.5 minutes */
642 :
643 85676 : Globals.config_backend = config_backend;
644 85676 : Globals._server_role = ROLE_AUTO;
645 :
646 : /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
647 : /* Discovered by 2 days of pain by Don McCall @ HP :-). */
648 85676 : Globals.max_xmit = 0x4104;
649 85676 : Globals.max_mux = 50; /* This is *needed* for profile support. */
650 85676 : Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
651 85676 : Globals._disable_spoolss = false;
652 85676 : Globals.max_smbd_processes = 0;/* no limit specified */
653 85676 : Globals.username_level = 0;
654 85676 : Globals.deadtime = 10080;
655 85676 : Globals.getwd_cache = true;
656 85676 : Globals.large_readwrite = true;
657 85676 : Globals.max_log_size = 5000;
658 85676 : Globals.max_open_files = max_open_files();
659 85676 : Globals.server_max_protocol = PROTOCOL_SMB3_11;
660 85676 : Globals.server_min_protocol = PROTOCOL_SMB2_02;
661 85676 : Globals._client_max_protocol = PROTOCOL_DEFAULT;
662 85676 : Globals.client_min_protocol = PROTOCOL_SMB2_02;
663 85676 : Globals._client_ipc_max_protocol = PROTOCOL_DEFAULT;
664 85676 : Globals._client_ipc_min_protocol = PROTOCOL_DEFAULT;
665 85676 : Globals._security = SEC_AUTO;
666 85676 : Globals.encrypt_passwords = true;
667 85676 : Globals.client_schannel = true;
668 85676 : Globals.winbind_sealed_pipes = true;
669 85676 : Globals.require_strong_key = true;
670 85676 : Globals.reject_md5_servers = true;
671 85676 : Globals.server_schannel = true;
672 85676 : Globals.server_schannel_require_seal = true;
673 85676 : Globals.reject_md5_clients = true;
674 85676 : Globals.read_raw = true;
675 85676 : Globals.write_raw = true;
676 85676 : Globals.null_passwords = false;
677 85676 : Globals.old_password_allowed_period = 60;
678 85676 : Globals.obey_pam_restrictions = false;
679 85676 : Globals.syslog = 1;
680 85676 : Globals.syslog_only = false;
681 85676 : Globals.timestamp_logs = true;
682 85676 : lpcfg_string_set(Globals.ctx, &Globals.log_level, "0");
683 85676 : Globals.debug_prefix_timestamp = false;
684 85676 : Globals.debug_hires_timestamp = true;
685 85676 : Globals.debug_syslog_format = false;
686 85676 : Globals.debug_pid = false;
687 85676 : Globals.debug_uid = false;
688 85676 : Globals.debug_class = false;
689 85676 : Globals.enable_core_files = true;
690 85676 : Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
691 85676 : Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
692 85676 : Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
693 85676 : Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
694 85676 : Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
695 85676 : Globals.lm_interval = 60;
696 85676 : Globals.time_server = false;
697 85676 : Globals.bind_interfaces_only = false;
698 85676 : Globals.unix_password_sync = false;
699 85676 : Globals.pam_password_change = false;
700 85676 : Globals.passwd_chat_debug = false;
701 85676 : Globals.passwd_chat_timeout = 2; /* 2 second default. */
702 85676 : Globals.nt_pipe_support = true; /* Do NT pipes by default. */
703 85676 : Globals.nt_status_support = true; /* Use NT status by default. */
704 85676 : Globals.smbd_profiling_level = 0;
705 85676 : Globals.stat_cache = true; /* use stat cache by default */
706 85676 : Globals.max_stat_cache_size = 512; /* 512k by default */
707 85676 : Globals.restrict_anonymous = 0;
708 85676 : Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
709 85676 : Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
710 85676 : Globals._lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
711 85676 : Globals.ntlm_auth = NTLM_AUTH_NTLMV2_ONLY; /* Do NOT use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
712 85676 : Globals.nt_hash_store = NT_HASH_STORE_ALWAYS; /* Fill in NT hash when setting password */
713 85676 : Globals.raw_ntlmv2_auth = false; /* Reject NTLMv2 without NTLMSSP */
714 85676 : Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
715 : /* Note, that we will also use NTLM2 session security (which is different), if it is available */
716 :
717 85676 : Globals.allow_dcerpc_auth_level_connect = false; /* we don't allow this by default */
718 :
719 85676 : Globals.map_to_guest = 0; /* By Default, "Never" */
720 85676 : Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
721 85676 : Globals.enhanced_browsing = true;
722 85676 : Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
723 85676 : Globals.use_mmap = true;
724 85676 : Globals.unicode = true;
725 85676 : Globals.smb1_unix_extensions = true;
726 85676 : Globals.reset_on_zero_vc = false;
727 85676 : Globals.log_writeable_files_on_exit = false;
728 85676 : Globals.create_krb5_conf = true;
729 85676 : Globals.include_system_krb5_conf = true;
730 85676 : Globals._winbind_max_domain_connections = 1;
731 :
732 : /* hostname lookups can be very expensive and are broken on
733 : a large number of sites (tridge) */
734 85676 : Globals.hostname_lookups = false;
735 :
736 85676 : Globals.change_notify = true,
737 85676 : Globals.kernel_change_notify = true,
738 :
739 85676 : lpcfg_string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
740 85676 : lpcfg_string_set(Globals.ctx, &Globals.ldap_suffix, "");
741 85676 : lpcfg_string_set(Globals.ctx, &Globals._ldap_machine_suffix, "");
742 85676 : lpcfg_string_set(Globals.ctx, &Globals._ldap_user_suffix, "");
743 85676 : lpcfg_string_set(Globals.ctx, &Globals._ldap_group_suffix, "");
744 85676 : lpcfg_string_set(Globals.ctx, &Globals._ldap_idmap_suffix, "");
745 :
746 85676 : lpcfg_string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
747 85676 : Globals.ldap_ssl = LDAP_SSL_START_TLS;
748 85676 : Globals.ldap_deref = -1;
749 85676 : Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
750 85676 : Globals.ldap_delete_dn = false;
751 85676 : Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
752 85676 : Globals.ldap_follow_referral = Auto;
753 85676 : Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
754 85676 : Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
755 85676 : Globals.ldap_page_size = LDAP_PAGE_SIZE;
756 :
757 85676 : Globals.ldap_debug_level = 0;
758 85676 : Globals.ldap_debug_threshold = 10;
759 :
760 85676 : Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SEAL;
761 :
762 85676 : Globals.ldap_server_require_strong_auth =
763 : LDAP_SERVER_REQUIRE_STRONG_AUTH_YES;
764 :
765 : /* This is what we tell the afs client. in reality we set the token
766 : * to never expire, though, when this runs out the afs client will
767 : * forget the token. Set to 0 to get NEVERDATE.*/
768 85676 : Globals.afs_token_lifetime = 604800;
769 85676 : Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
770 :
771 : /* these parameters are set to defaults that are more appropriate
772 : for the increasing samba install base:
773 :
774 : as a member of the workgroup, that will possibly become a
775 : _local_ master browser (lm = true). this is opposed to a forced
776 : local master browser startup (pm = true).
777 :
778 : doesn't provide WINS server service by default (wsupp = false),
779 : and doesn't provide domain master browser services by default, either.
780 :
781 : */
782 :
783 85676 : Globals.show_add_printer_wizard = true;
784 85676 : Globals.os_level = 20;
785 85676 : Globals.local_master = true;
786 85676 : Globals._domain_master = Auto; /* depending on _domain_logons */
787 85676 : Globals._domain_logons = false;
788 85676 : Globals.browse_list = true;
789 85676 : Globals.we_are_a_wins_server = false;
790 85676 : Globals.wins_proxy = false;
791 :
792 85676 : TALLOC_FREE(Globals.init_logon_delayed_hosts);
793 85676 : Globals.init_logon_delay = 100; /* 100 ms default delay */
794 :
795 85676 : Globals.wins_dns_proxy = true;
796 85676 : Globals.dns_port = DNS_SERVICE_PORT;
797 :
798 85676 : Globals.allow_trusted_domains = true;
799 85676 : lpcfg_string_set(Globals.ctx, &Globals.idmap_backend, "tdb");
800 :
801 85676 : lpcfg_string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
802 85676 : lpcfg_string_set(Globals.ctx, &Globals.template_homedir,
803 : "/home/%D/%U");
804 85676 : lpcfg_string_set(Globals.ctx, &Globals.winbind_separator, "\\");
805 85676 : lpcfg_string_set(Globals.ctx, &Globals.winbindd_socket_directory,
806 : dyn_WINBINDD_SOCKET_DIR);
807 :
808 85676 : lpcfg_string_set(Globals.ctx, &Globals.cups_server, "");
809 85676 : lpcfg_string_set(Globals.ctx, &Globals.iprint_server, "");
810 :
811 85676 : lpcfg_string_set(Globals.ctx, &Globals._ctdbd_socket, "");
812 :
813 85676 : Globals.cluster_addresses = NULL;
814 85676 : Globals.clustering = false;
815 85676 : Globals.ctdb_timeout = 0;
816 85676 : Globals.ctdb_locktime_warn_threshold = 0;
817 :
818 85676 : Globals.winbind_cache_time = 300; /* 5 minutes */
819 85676 : Globals.winbind_reconnect_delay = 30; /* 30 seconds */
820 85676 : Globals.winbind_request_timeout = 60; /* 60 seconds */
821 85676 : Globals.winbind_max_clients = 200;
822 85676 : Globals.winbind_enum_users = false;
823 85676 : Globals.winbind_enum_groups = false;
824 85676 : Globals.winbind_use_default_domain = false;
825 85676 : Globals.winbind_nested_groups = true;
826 85676 : Globals.winbind_expand_groups = 0;
827 85676 : Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
828 85676 : Globals.winbind_refresh_tickets = false;
829 85676 : Globals.winbind_offline_logon = false;
830 85676 : Globals.winbind_scan_trusted_domains = false;
831 :
832 85676 : Globals.idmap_cache_time = 86400 * 7; /* a week by default */
833 85676 : Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
834 :
835 85676 : Globals.passdb_expand_explicit = false;
836 :
837 85676 : Globals.name_cache_timeout = 660; /* In seconds */
838 :
839 85676 : Globals.client_use_spnego = true;
840 :
841 85676 : Globals.client_signing = SMB_SIGNING_DEFAULT;
842 85676 : Globals._client_ipc_signing = SMB_SIGNING_DEFAULT;
843 85676 : Globals.server_signing = SMB_SIGNING_DEFAULT;
844 :
845 85676 : Globals.defer_sharing_violations = true;
846 85676 : Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL);
847 :
848 85676 : Globals.enable_privileges = true;
849 85676 : Globals.host_msdfs = true;
850 85676 : Globals.enable_asu_support = false;
851 :
852 : /* User defined shares. */
853 85676 : s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
854 85676 : if (s == NULL) {
855 0 : smb_panic("init_globals: ENOMEM");
856 : }
857 85676 : lpcfg_string_set(Globals.ctx, &Globals.usershare_path, s);
858 85676 : TALLOC_FREE(s);
859 85676 : lpcfg_string_set(Globals.ctx, &Globals.usershare_template_share, "");
860 85676 : Globals.usershare_max_shares = 0;
861 : /* By default disallow sharing of directories not owned by the sharer. */
862 85676 : Globals.usershare_owner_only = true;
863 : /* By default disallow guest access to usershares. */
864 85676 : Globals.usershare_allow_guests = false;
865 :
866 85676 : Globals.keepalive = DEFAULT_KEEPALIVE;
867 :
868 : /* By default no shares out of the registry */
869 85676 : Globals.registry_shares = false;
870 :
871 85676 : Globals.min_receivefile_size = 0;
872 :
873 85676 : Globals.multicast_dns_register = true;
874 :
875 85676 : Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
876 85676 : Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
877 85676 : Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
878 85676 : Globals.smb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
879 85676 : Globals.smb2_leases = true;
880 85676 : Globals.server_multi_channel_support = true;
881 :
882 85676 : lpcfg_string_set(Globals.ctx, &Globals.ncalrpc_dir,
883 : get_dyn_NCALRPCDIR());
884 :
885 85676 : Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
886 :
887 85676 : Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
888 :
889 85676 : Globals.tls_enabled = true;
890 85676 : Globals.tls_verify_peer = TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE;
891 :
892 85676 : lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
893 85676 : lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
894 85676 : lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
895 85676 : lpcfg_string_set(Globals.ctx,
896 : &Globals.tls_priority,
897 : "NORMAL:-VERS-SSL3.0");
898 :
899 85676 : Globals._preferred_master = Auto;
900 :
901 85676 : Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
902 85676 : Globals.dns_zone_scavenging = false;
903 :
904 85676 : lpcfg_string_set(Globals.ctx, &Globals.ntp_signd_socket_directory,
905 : get_dyn_NTP_SIGND_SOCKET_DIR());
906 :
907 85676 : s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
908 85676 : if (s == NULL) {
909 0 : smb_panic("init_globals: ENOMEM");
910 : }
911 85676 : Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
912 85676 : TALLOC_FREE(s);
913 :
914 : #ifdef MIT_KDC_PATH
915 11756 : Globals.mit_kdc_command = str_list_make_v3_const(NULL, MIT_KDC_PATH, NULL);
916 : #endif
917 :
918 85676 : s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
919 85676 : if (s == NULL) {
920 0 : smb_panic("init_globals: ENOMEM");
921 : }
922 85676 : Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
923 85676 : TALLOC_FREE(s);
924 :
925 85676 : s = talloc_asprintf(talloc_tos(), "%s/samba-gpupdate", get_dyn_SCRIPTSBINDIR());
926 85676 : if (s == NULL) {
927 0 : smb_panic("init_globals: ENOMEM");
928 : }
929 85676 : Globals.gpo_update_command = str_list_make_v3_const(NULL, s, NULL);
930 85676 : TALLOC_FREE(s);
931 :
932 85676 : Globals.apply_group_policies = false;
933 :
934 85676 : s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
935 85676 : if (s == NULL) {
936 0 : smb_panic("init_globals: ENOMEM");
937 : }
938 85676 : Globals.spn_update_command = str_list_make_v3_const(NULL, s, NULL);
939 85676 : TALLOC_FREE(s);
940 :
941 85676 : Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
942 :
943 85676 : Globals.cldap_port = 389;
944 :
945 85676 : Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
946 :
947 85676 : Globals.nbt_port = NBT_NAME_SERVICE_PORT;
948 :
949 85676 : Globals.krb5_port = 88;
950 :
951 85676 : Globals.kpasswd_port = 464;
952 :
953 85676 : Globals.kdc_enable_fast = true;
954 :
955 85676 : Globals.aio_max_threads = 100;
956 :
957 85676 : lpcfg_string_set(Globals.ctx,
958 : &Globals.rpc_server_dynamic_port_range,
959 : "49152-65535");
960 85676 : Globals.rpc_low_port = SERVER_TCP_LOW_PORT;
961 85676 : Globals.rpc_high_port = SERVER_TCP_HIGH_PORT;
962 85676 : Globals.prefork_children = 4;
963 85676 : Globals.prefork_backoff_increment = 10;
964 85676 : Globals.prefork_maximum_backoff = 120;
965 :
966 85676 : Globals.ldap_max_anonymous_request_size = 256000;
967 85676 : Globals.ldap_max_authenticated_request_size = 16777216;
968 85676 : Globals.ldap_max_search_request_size = 256000;
969 :
970 : /* Async DNS query timeout (in seconds). */
971 85676 : Globals.async_dns_timeout = 10;
972 :
973 85676 : Globals.client_smb_encrypt = SMB_ENCRYPTION_DEFAULT;
974 :
975 85676 : Globals._client_use_kerberos = CRED_USE_KERBEROS_DESIRED;
976 :
977 85676 : Globals.client_protection = CRED_CLIENT_PROTECTION_DEFAULT;
978 :
979 85676 : Globals.winbind_use_krb5_enterprise_principals = true;
980 :
981 85887 : Globals.client_smb3_signing_algorithms =
982 85676 : str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
983 85887 : Globals.server_smb3_signing_algorithms =
984 85676 : str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
985 :
986 85887 : Globals.client_smb3_encryption_algorithms =
987 85676 : str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
988 85887 : Globals.server_smb3_encryption_algorithms =
989 85676 : str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
990 :
991 85676 : Globals.min_domain_uid = 1000;
992 :
993 : /*
994 : * By default allow smbd and winbindd to start samba-dcerpcd as
995 : * a named-pipe helper.
996 : */
997 85676 : Globals.rpc_start_on_demand_helpers = true;
998 :
999 85676 : Globals.ad_dc_functional_level = DS_DOMAIN_FUNCTION_2008_R2,
1000 :
1001 85676 : Globals.acl_claims_evaluation = ACL_CLAIMS_EVALUATION_AD_DC_ONLY;
1002 :
1003 : /* Now put back the settings that were set with lp_set_cmdline() */
1004 85676 : apply_lp_set_cmdline();
1005 : }
1006 :
1007 : /* Convenience routine to setup an lp_context with additional s3 variables */
1008 446366 : static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
1009 : {
1010 4015 : struct loadparm_context *lp_ctx;
1011 :
1012 446366 : lp_ctx = loadparm_init_s3(mem_ctx,
1013 : loadparm_s3_helpers());
1014 446366 : if (lp_ctx == NULL) {
1015 0 : DEBUG(0, ("loadparm_init_s3 failed\n"));
1016 0 : return NULL;
1017 : }
1018 :
1019 446366 : lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
1020 446366 : if (lp_ctx->sDefault == NULL) {
1021 0 : DBG_ERR("talloc_zero failed\n");
1022 0 : TALLOC_FREE(lp_ctx);
1023 0 : return NULL;
1024 : }
1025 :
1026 446366 : *lp_ctx->sDefault = _sDefault;
1027 446366 : lp_ctx->services = NULL; /* We do not want to access this directly */
1028 446366 : lp_ctx->bInGlobalSection = bInGlobalSection;
1029 446366 : lp_ctx->flags = flags_list;
1030 :
1031 446366 : return lp_ctx;
1032 : }
1033 :
1034 : /*******************************************************************
1035 : Convenience routine to grab string parameters into talloced memory
1036 : and run standard_sub_basic on them. The buffers can be written to by
1037 : callers without affecting the source string.
1038 : ********************************************************************/
1039 :
1040 2465935 : static char *loadparm_s3_global_substitution_fn(
1041 : TALLOC_CTX *mem_ctx,
1042 : const struct loadparm_substitution *lp_sub,
1043 : const char *s,
1044 : void *private_data)
1045 : {
1046 28152 : char *ret;
1047 :
1048 : /* The follow debug is useful for tracking down memory problems
1049 : especially if you have an inner loop that is calling a lp_*()
1050 : function that returns a string. Perhaps this debug should be
1051 : present all the time? */
1052 :
1053 : #if 0
1054 : DEBUG(10, ("lp_string(%s)\n", s));
1055 : #endif
1056 2465935 : if (!s) {
1057 46 : return NULL;
1058 : }
1059 :
1060 2465889 : ret = talloc_sub_basic(mem_ctx,
1061 : get_current_username(),
1062 : get_current_user_info_domain(),
1063 : s);
1064 2465889 : if (trim_char(ret, '\"', '\"')) {
1065 34 : if (strchr(ret,'\"') != NULL) {
1066 34 : TALLOC_FREE(ret);
1067 34 : ret = talloc_sub_basic(mem_ctx,
1068 : get_current_username(),
1069 : get_current_user_info_domain(),
1070 : s);
1071 : }
1072 : }
1073 2437737 : return ret;
1074 : }
1075 :
1076 : static const struct loadparm_substitution s3_global_substitution = {
1077 : .substituted_string_fn = loadparm_s3_global_substitution_fn,
1078 : };
1079 :
1080 4865194 : const struct loadparm_substitution *loadparm_s3_global_substitution(void)
1081 : {
1082 4865194 : return &s3_global_substitution;
1083 : }
1084 :
1085 : /*
1086 : In this section all the functions that are used to access the
1087 : parameters from the rest of the program are defined
1088 : */
1089 :
1090 : #define FN_GLOBAL_SUBSTITUTED_STRING(fn_name,ptr) \
1091 : char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub) \
1092 : {return lpcfg_substituted_string(ctx, lp_sub, *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : "");}
1093 : #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1094 : const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1095 : #define FN_GLOBAL_LIST(fn_name,ptr) \
1096 : const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1097 : #define FN_GLOBAL_BOOL(fn_name,ptr) \
1098 : bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1099 : #define FN_GLOBAL_CHAR(fn_name,ptr) \
1100 : char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1101 : #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1102 : int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1103 :
1104 : #define FN_LOCAL_SUBSTITUTED_STRING(fn_name,val) \
1105 : char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub, int i) \
1106 : {return lpcfg_substituted_string((ctx), lp_sub, (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1107 : #define FN_LOCAL_CONST_STRING(fn_name,val) \
1108 : const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1109 : #define FN_LOCAL_LIST(fn_name,val) \
1110 : const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1111 : #define FN_LOCAL_BOOL(fn_name,val) \
1112 : bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1113 : #define FN_LOCAL_INTEGER(fn_name,val) \
1114 : int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1115 :
1116 : #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1117 : bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1118 : #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1119 : int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1120 : #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1121 : char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1122 :
1123 238 : int lp_winbind_max_domain_connections(void)
1124 : {
1125 270 : if (lp_winbind_offline_logon() &&
1126 32 : lp__winbind_max_domain_connections() > 1) {
1127 0 : DEBUG(1, ("offline logons active, restricting max domain "
1128 : "connections to 1\n"));
1129 0 : return 1;
1130 : }
1131 238 : return MAX(1, lp__winbind_max_domain_connections());
1132 : }
1133 :
1134 : /* These functions remain in source3/param for now */
1135 :
1136 : #include "lib/param/param_functions.c"
1137 :
1138 163082 : FN_LOCAL_SUBSTITUTED_STRING(servicename, szService)
1139 271096 : FN_LOCAL_CONST_STRING(const_servicename, szService)
1140 :
1141 : /* These functions cannot be auto-generated */
1142 1217 : FN_LOCAL_BOOL(autoloaded, autoloaded)
1143 4555 : FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1144 :
1145 : /* local prototypes */
1146 :
1147 : static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1148 : static const char *get_boolean(bool bool_value);
1149 : static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1150 : void *userdata);
1151 : static bool hash_a_service(const char *name, int number);
1152 : static void free_service_byindex(int iService);
1153 : static void show_parameter(int parmIndex);
1154 : static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1155 : static bool lp_parameter_value_is_valid(const char *parm_name, const char *val);
1156 :
1157 : /*
1158 : * This is a helper function for parametrical options support. It returns a
1159 : * pointer to parametrical option value if it exists or NULL otherwise. Actual
1160 : * parametrical functions are quite simple
1161 : */
1162 2824297 : static struct parmlist_entry *get_parametrics(int snum, const char *type,
1163 : const char *option)
1164 : {
1165 2824297 : if (snum >= iNumServices) return NULL;
1166 :
1167 2824297 : if (snum < 0) {
1168 837663 : return get_parametric_helper(NULL, type, option, Globals.param_opt);
1169 : } else {
1170 1986634 : return get_parametric_helper(ServicePtrs[snum],
1171 : type, option, Globals.param_opt);
1172 : }
1173 : }
1174 :
1175 817 : static void discard_whitespace(char *str)
1176 : {
1177 817 : size_t len = strlen(str);
1178 817 : size_t i = 0;
1179 :
1180 20684 : while (i < len) {
1181 19867 : if (isspace(str[i])) {
1182 1141 : memmove(&str[i], &str[i+1], len-i);
1183 1141 : len -= 1;
1184 1141 : continue;
1185 : }
1186 18726 : i += 1;
1187 : }
1188 817 : }
1189 :
1190 : /**
1191 : * @brief Go through all global parametric parameters
1192 : *
1193 : * @param regex_str A regular expression to scan param for
1194 : * @param max_matches Max number of submatches the regexp expects
1195 : * @param cb Function to call on match. Should return true
1196 : * when it wants wi_scan_global_parametrics to stop
1197 : * scanning
1198 : * @param private_data Anonymous pointer passed to cb
1199 : *
1200 : * @return 0: success, regcomp/regexec return value on error.
1201 : * See "man regexec" for possible errors
1202 : */
1203 :
1204 45 : int lp_wi_scan_global_parametrics(
1205 : const char *regex_str, size_t max_matches,
1206 : bool (*cb)(const char *string, regmatch_t matches[],
1207 : void *private_data),
1208 : void *private_data)
1209 : {
1210 0 : struct parmlist_entry *data;
1211 0 : regex_t regex;
1212 0 : int ret;
1213 :
1214 45 : ret = regcomp(®ex, regex_str, REG_ICASE);
1215 45 : if (ret != 0) {
1216 0 : return ret;
1217 : }
1218 :
1219 862 : for (data = Globals.param_opt; data != NULL; data = data->next) {
1220 817 : size_t keylen = strlen(data->key);
1221 817 : char key[keylen+1];
1222 817 : regmatch_t matches[max_matches];
1223 0 : bool stop;
1224 :
1225 817 : memcpy(key, data->key, sizeof(key));
1226 817 : discard_whitespace(key);
1227 :
1228 817 : ret = regexec(®ex, key, max_matches, matches, 0);
1229 817 : if (ret == REG_NOMATCH) {
1230 762 : continue;
1231 : }
1232 55 : if (ret != 0) {
1233 0 : goto fail;
1234 : }
1235 :
1236 55 : stop = cb(key, matches, private_data);
1237 55 : if (stop) {
1238 0 : break;
1239 : }
1240 : }
1241 :
1242 45 : ret = 0;
1243 45 : fail:
1244 45 : regfree(®ex);
1245 45 : return ret;
1246 : }
1247 :
1248 :
1249 : #define MISSING_PARAMETER(name) \
1250 : DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1251 :
1252 : /*******************************************************************
1253 : convenience routine to return enum parameters.
1254 : ********************************************************************/
1255 10072 : static int lp_enum(const char *s,const struct enum_list *_enum)
1256 : {
1257 0 : int i;
1258 :
1259 10072 : if (!s || !*s || !_enum) {
1260 0 : MISSING_PARAMETER(lp_enum);
1261 0 : return (-1);
1262 : }
1263 :
1264 11958 : for (i=0; _enum[i].name; i++) {
1265 11958 : if (strequal(_enum[i].name,s))
1266 10072 : return _enum[i].value;
1267 : }
1268 :
1269 0 : DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1270 0 : return (-1);
1271 : }
1272 :
1273 : #undef MISSING_PARAMETER
1274 :
1275 : /* Return parametric option from a given service. Type is a part of option before ':' */
1276 : /* Parametric option has following syntax: 'Type: option = value' */
1277 465821 : char *lp_parm_substituted_string(TALLOC_CTX *mem_ctx,
1278 : const struct loadparm_substitution *lp_sub,
1279 : int snum,
1280 : const char *type,
1281 : const char *option,
1282 : const char *def)
1283 : {
1284 465821 : struct parmlist_entry *data = get_parametrics(snum, type, option);
1285 :
1286 465821 : SMB_ASSERT(lp_sub != NULL);
1287 :
1288 465821 : if (data == NULL||data->value==NULL) {
1289 464517 : if (def) {
1290 464517 : return lpcfg_substituted_string(mem_ctx, lp_sub, def);
1291 : } else {
1292 0 : return NULL;
1293 : }
1294 : }
1295 :
1296 1304 : return lpcfg_substituted_string(mem_ctx, lp_sub, data->value);
1297 : }
1298 :
1299 : /* Return parametric option from a given service. Type is a part of option before ':' */
1300 : /* Parametric option has following syntax: 'Type: option = value' */
1301 199397 : const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1302 : {
1303 199397 : struct parmlist_entry *data = get_parametrics(snum, type, option);
1304 :
1305 199397 : if (data == NULL||data->value==NULL)
1306 182775 : return def;
1307 :
1308 15809 : return data->value;
1309 : }
1310 :
1311 :
1312 : /* Return parametric option from a given service. Type is a part of option before ':' */
1313 : /* Parametric option has following syntax: 'Type: option = value' */
1314 :
1315 103865 : const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1316 : {
1317 103865 : struct parmlist_entry *data = get_parametrics(snum, type, option);
1318 :
1319 103865 : if (data == NULL||data->value==NULL)
1320 24557 : return (const char **)def;
1321 :
1322 79308 : if (data->list==NULL) {
1323 38642 : data->list = str_list_make_v3(NULL, data->value, NULL);
1324 : }
1325 :
1326 79308 : return discard_const_p(const char *, data->list);
1327 : }
1328 :
1329 : /* Return parametric option from a given service. Type is a part of option before ':' */
1330 : /* Parametric option has following syntax: 'Type: option = value' */
1331 :
1332 267136 : int lp_parm_int(int snum, const char *type, const char *option, int def)
1333 : {
1334 267136 : struct parmlist_entry *data = get_parametrics(snum, type, option);
1335 :
1336 267136 : if (data && data->value && *data->value)
1337 14145 : return lp_int(data->value);
1338 :
1339 252976 : return def;
1340 : }
1341 :
1342 : /* Return parametric option from a given service. Type is a part of option before ':' */
1343 : /* Parametric option has following syntax: 'Type: option = value' */
1344 :
1345 20408 : unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1346 : {
1347 20408 : struct parmlist_entry *data = get_parametrics(snum, type, option);
1348 :
1349 20408 : if (data && data->value && *data->value)
1350 30 : return lp_ulong(data->value);
1351 :
1352 20376 : return def;
1353 : }
1354 :
1355 : /* Return parametric option from a given service. Type is a part of option before ':' */
1356 : /* Parametric option has following syntax: 'Type: option = value' */
1357 :
1358 8627 : unsigned long long lp_parm_ulonglong(int snum, const char *type,
1359 : const char *option, unsigned long long def)
1360 : {
1361 8627 : struct parmlist_entry *data = get_parametrics(snum, type, option);
1362 :
1363 8627 : if (data && data->value && *data->value) {
1364 408 : return lp_ulonglong(data->value);
1365 : }
1366 :
1367 8219 : return def;
1368 : }
1369 :
1370 : /* Return parametric option from a given service. Type is a part of option
1371 : * before ':' */
1372 : /* Parametric option has following syntax: 'Type: option = value' */
1373 :
1374 1607068 : bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1375 : {
1376 1607068 : struct parmlist_entry *data = get_parametrics(snum, type, option);
1377 :
1378 1607068 : if (data && data->value && *data->value)
1379 739690 : return lp_bool(data->value);
1380 :
1381 862904 : return def;
1382 : }
1383 :
1384 : /* Return parametric option from a given service. Type is a part of option before ':' */
1385 : /* Parametric option has following syntax: 'Type: option = value' */
1386 :
1387 151975 : int lp_parm_enum(int snum, const char *type, const char *option,
1388 : const struct enum_list *_enum, int def)
1389 : {
1390 151975 : struct parmlist_entry *data = get_parametrics(snum, type, option);
1391 :
1392 151975 : if (data && data->value && *data->value && _enum)
1393 10072 : return lp_enum(data->value, _enum);
1394 :
1395 141052 : return def;
1396 : }
1397 :
1398 : /**
1399 : * free a param_opts structure.
1400 : * param_opts handling should be moved to talloc;
1401 : * then this whole functions reduces to a TALLOC_FREE().
1402 : */
1403 :
1404 3002090 : static void free_param_opts(struct parmlist_entry **popts)
1405 : {
1406 282 : struct parmlist_entry *opt, *next_opt;
1407 :
1408 3002090 : if (*popts != NULL) {
1409 1108919 : DEBUG(5, ("Freeing parametrics:\n"));
1410 : }
1411 3002090 : opt = *popts;
1412 6959408 : while (opt != NULL) {
1413 3957318 : lpcfg_string_free(&opt->key);
1414 3957318 : lpcfg_string_free(&opt->value);
1415 3957318 : TALLOC_FREE(opt->list);
1416 3957318 : next_opt = opt->next;
1417 3957318 : TALLOC_FREE(opt);
1418 3957318 : opt = next_opt;
1419 : }
1420 3002090 : *popts = NULL;
1421 3002090 : }
1422 :
1423 : /***************************************************************************
1424 : Free the dynamically allocated parts of a service struct.
1425 : ***************************************************************************/
1426 :
1427 136005 : static void free_service(struct loadparm_service *pservice)
1428 : {
1429 136005 : if (!pservice)
1430 0 : return;
1431 :
1432 136005 : if (pservice->szService)
1433 136005 : DEBUG(5, ("free_service: Freeing service %s\n",
1434 : pservice->szService));
1435 :
1436 136005 : free_parameters(pservice);
1437 :
1438 136005 : lpcfg_string_free(&pservice->szService);
1439 136005 : TALLOC_FREE(pservice->copymap);
1440 :
1441 136005 : free_param_opts(&pservice->param_opt);
1442 :
1443 136005 : ZERO_STRUCTP(pservice);
1444 : }
1445 :
1446 :
1447 : /***************************************************************************
1448 : remove a service indexed in the ServicePtrs array from the ServiceHash
1449 : and free the dynamically allocated parts
1450 : ***************************************************************************/
1451 :
1452 136005 : static void free_service_byindex(int idx)
1453 : {
1454 136005 : if ( !LP_SNUM_OK(idx) )
1455 0 : return;
1456 :
1457 136005 : ServicePtrs[idx]->valid = false;
1458 :
1459 : /* we have to cleanup the hash record */
1460 :
1461 136005 : if (ServicePtrs[idx]->szService) {
1462 136005 : char *canon_name = canonicalize_servicename(
1463 : talloc_tos(),
1464 136005 : ServicePtrs[idx]->szService );
1465 :
1466 136005 : dbwrap_delete_bystring(ServiceHash, canon_name );
1467 136005 : TALLOC_FREE(canon_name);
1468 : }
1469 :
1470 136005 : free_service(ServicePtrs[idx]);
1471 136005 : TALLOC_FREE(ServicePtrs[idx]);
1472 : }
1473 :
1474 : /***************************************************************************
1475 : Add a new service to the services array initialising it with the given
1476 : service.
1477 : ***************************************************************************/
1478 :
1479 2834110 : static int add_a_service(const struct loadparm_service *pservice, const char *name)
1480 : {
1481 148 : int i;
1482 2834110 : struct loadparm_service **tsp = NULL;
1483 :
1484 : /* it might already exist */
1485 2834110 : if (name) {
1486 2834110 : i = getservicebyname(name, NULL);
1487 2834110 : if (i >= 0) {
1488 2643913 : return (i);
1489 : }
1490 : }
1491 :
1492 : /* Re use empty slots if any before allocating new one.*/
1493 11208725 : for (i=0; i < iNumServices; i++) {
1494 11142955 : if (ServicePtrs[i] == NULL) {
1495 124347 : break;
1496 : }
1497 : }
1498 190117 : if (i == iNumServices) {
1499 : /* if not, then create one */
1500 65770 : tsp = talloc_realloc(NULL, ServicePtrs,
1501 : struct loadparm_service *,
1502 : iNumServices + 1);
1503 65770 : if (tsp == NULL) {
1504 0 : DEBUG(0, ("add_a_service: failed to enlarge "
1505 : "ServicePtrs!\n"));
1506 0 : return (-1);
1507 : }
1508 65770 : ServicePtrs = tsp;
1509 65770 : iNumServices++;
1510 : }
1511 190117 : ServicePtrs[i] = talloc_zero(ServicePtrs, struct loadparm_service);
1512 190117 : if (!ServicePtrs[i]) {
1513 0 : DEBUG(0,("add_a_service: out of memory!\n"));
1514 0 : return (-1);
1515 : }
1516 :
1517 190117 : ServicePtrs[i]->valid = true;
1518 :
1519 190117 : copy_service(ServicePtrs[i], pservice, NULL);
1520 190117 : if (name)
1521 190117 : lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->szService,
1522 : name);
1523 :
1524 190117 : DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1525 : i, ServicePtrs[i]->szService));
1526 :
1527 190117 : if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1528 0 : return (-1);
1529 : }
1530 :
1531 190049 : return (i);
1532 : }
1533 :
1534 : /***************************************************************************
1535 : Convert a string to uppercase and remove whitespaces.
1536 : ***************************************************************************/
1537 :
1538 4043311 : char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1539 : {
1540 1912 : char *result;
1541 :
1542 4043311 : if ( !src ) {
1543 0 : DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1544 0 : return NULL;
1545 : }
1546 :
1547 4043311 : result = talloc_strdup(ctx, src);
1548 4043311 : SMB_ASSERT(result != NULL);
1549 :
1550 4043311 : if (!strlower_m(result)) {
1551 0 : TALLOC_FREE(result);
1552 0 : return NULL;
1553 : }
1554 4041399 : return result;
1555 : }
1556 :
1557 : /***************************************************************************
1558 : Add a name/index pair for the services array to the hash table.
1559 : ***************************************************************************/
1560 :
1561 190117 : static bool hash_a_service(const char *name, int idx)
1562 : {
1563 68 : char *canon_name;
1564 :
1565 190117 : if ( !ServiceHash ) {
1566 2206 : DEBUG(10,("hash_a_service: creating servicehash\n"));
1567 2206 : ServiceHash = db_open_rbt(NULL);
1568 2206 : if ( !ServiceHash ) {
1569 0 : DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1570 0 : return false;
1571 : }
1572 : }
1573 :
1574 190117 : DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1575 : idx, name));
1576 :
1577 190117 : canon_name = canonicalize_servicename(talloc_tos(), name );
1578 :
1579 190117 : dbwrap_store_bystring(ServiceHash, canon_name,
1580 : make_tdb_data((uint8_t *)&idx, sizeof(idx)),
1581 : TDB_REPLACE);
1582 :
1583 190117 : TALLOC_FREE(canon_name);
1584 :
1585 190049 : return true;
1586 : }
1587 :
1588 : /***************************************************************************
1589 : Add a new home service, with the specified home directory, defaults coming
1590 : from service ifrom.
1591 : ***************************************************************************/
1592 :
1593 10808 : bool lp_add_home(const char *pszHomename, int iDefaultService,
1594 : const char *user, const char *pszHomedir)
1595 : {
1596 0 : const struct loadparm_substitution *lp_sub =
1597 10808 : loadparm_s3_global_substitution();
1598 0 : int i;
1599 0 : char *global_path;
1600 :
1601 10808 : if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1602 10808 : pszHomedir[0] == '\0') {
1603 0 : return false;
1604 : }
1605 :
1606 10808 : i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1607 :
1608 10808 : if (i < 0)
1609 0 : return false;
1610 :
1611 10808 : global_path = lp_path(talloc_tos(), lp_sub, GLOBAL_SECTION_SNUM);
1612 10808 : if (!(*(ServicePtrs[iDefaultService]->path))
1613 0 : || strequal(ServicePtrs[iDefaultService]->path, global_path)) {
1614 10808 : lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
1615 : pszHomedir);
1616 : }
1617 10808 : TALLOC_FREE(global_path);
1618 :
1619 10808 : if (!(*(ServicePtrs[i]->comment))) {
1620 0 : char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1621 0 : if (comment == NULL) {
1622 0 : return false;
1623 : }
1624 0 : lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment,
1625 : comment);
1626 0 : TALLOC_FREE(comment);
1627 : }
1628 :
1629 : /* set the browseable flag from the global default */
1630 :
1631 10808 : ServicePtrs[i]->browseable = sDefault.browseable;
1632 10808 : ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1633 :
1634 10808 : ServicePtrs[i]->autoloaded = true;
1635 :
1636 10808 : DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1637 : user, ServicePtrs[i]->path ));
1638 :
1639 10808 : return true;
1640 : }
1641 :
1642 : /***************************************************************************
1643 : Add a new service, based on an old one.
1644 : ***************************************************************************/
1645 :
1646 0 : int lp_add_service(const char *pszService, int iDefaultService)
1647 : {
1648 0 : if (iDefaultService < 0) {
1649 0 : return add_a_service(&sDefault, pszService);
1650 : }
1651 :
1652 0 : return (add_a_service(ServicePtrs[iDefaultService], pszService));
1653 : }
1654 :
1655 : /***************************************************************************
1656 : Add the IPC service.
1657 : ***************************************************************************/
1658 :
1659 23303 : static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1660 : {
1661 23303 : char *comment = NULL;
1662 23303 : int i = add_a_service(&sDefault, ipc_name);
1663 :
1664 23303 : if (i < 0)
1665 0 : return false;
1666 :
1667 23303 : comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1668 : Globals.server_string);
1669 23303 : if (comment == NULL) {
1670 0 : return false;
1671 : }
1672 :
1673 23303 : lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1674 23303 : lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1675 23303 : lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1676 23303 : ServicePtrs[i]->max_connections = 0;
1677 23303 : ServicePtrs[i]->available = true;
1678 23303 : ServicePtrs[i]->read_only = true;
1679 23303 : ServicePtrs[i]->guest_only = false;
1680 23303 : ServicePtrs[i]->administrative_share = true;
1681 23303 : ServicePtrs[i]->guest_ok = guest_ok;
1682 23303 : ServicePtrs[i]->printable = false;
1683 23303 : ServicePtrs[i]->browseable = sDefault.browseable;
1684 23303 : ServicePtrs[i]->autoloaded = false;
1685 :
1686 23303 : DEBUG(3, ("adding IPC service\n"));
1687 :
1688 23303 : TALLOC_FREE(comment);
1689 23303 : return true;
1690 : }
1691 :
1692 : /***************************************************************************
1693 : Add a new printer service, with defaults coming from service iFrom.
1694 : ***************************************************************************/
1695 :
1696 0 : bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1697 : {
1698 0 : const char *comment = "From Printcap";
1699 0 : int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1700 :
1701 0 : if (i < 0)
1702 0 : return false;
1703 :
1704 : /* note that we do NOT default the availability flag to true - */
1705 : /* we take it from the default service passed. This allows all */
1706 : /* dynamic printers to be disabled by disabling the [printers] */
1707 : /* entry (if/when the 'available' keyword is implemented!). */
1708 :
1709 : /* the printer name is set to the service name. */
1710 0 : lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->_printername,
1711 : pszPrintername);
1712 0 : lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1713 :
1714 : /* set the browseable flag from the global default */
1715 0 : ServicePtrs[i]->browseable = sDefault.browseable;
1716 :
1717 : /* Printers cannot be read_only. */
1718 0 : ServicePtrs[i]->read_only = false;
1719 : /* No oplocks on printer services. */
1720 0 : ServicePtrs[i]->oplocks = false;
1721 : /* Printer services must be printable. */
1722 0 : ServicePtrs[i]->printable = true;
1723 :
1724 0 : DEBUG(3, ("adding printer service %s\n", pszPrintername));
1725 :
1726 0 : return true;
1727 : }
1728 :
1729 :
1730 : /***************************************************************************
1731 : Check whether the given parameter name is valid.
1732 : Parametric options (names containing a colon) are considered valid.
1733 : ***************************************************************************/
1734 :
1735 26305 : bool lp_parameter_is_valid(const char *pszParmName)
1736 : {
1737 28369 : return ((lpcfg_map_parameter(pszParmName) != -1) ||
1738 2068 : (strchr(pszParmName, ':') != NULL));
1739 : }
1740 :
1741 : /***************************************************************************
1742 : Check whether the given name is the name of a global parameter.
1743 : Returns true for strings belonging to parameters of class
1744 : P_GLOBAL, false for all other strings, also for parametric options
1745 : and strings not belonging to any option.
1746 : ***************************************************************************/
1747 :
1748 2683 : bool lp_parameter_is_global(const char *pszParmName)
1749 : {
1750 2683 : int num = lpcfg_map_parameter(pszParmName);
1751 :
1752 2683 : if (num >= 0) {
1753 2381 : return (parm_table[num].p_class == P_GLOBAL);
1754 : }
1755 :
1756 302 : return false;
1757 : }
1758 :
1759 : /**************************************************************************
1760 : Determine the canonical name for a parameter.
1761 : Indicate when it is an inverse (boolean) synonym instead of a
1762 : "usual" synonym.
1763 : **************************************************************************/
1764 :
1765 0 : bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1766 : bool *inverse)
1767 : {
1768 0 : int num;
1769 :
1770 0 : if (!lp_parameter_is_valid(parm_name)) {
1771 0 : *canon_parm = NULL;
1772 0 : return false;
1773 : }
1774 :
1775 0 : num = map_parameter_canonical(parm_name, inverse);
1776 0 : if (num < 0) {
1777 : /* parametric option */
1778 0 : *canon_parm = parm_name;
1779 : } else {
1780 0 : *canon_parm = parm_table[num].label;
1781 : }
1782 :
1783 0 : return true;
1784 :
1785 : }
1786 :
1787 : /**************************************************************************
1788 : Determine the canonical name for a parameter.
1789 : Turn the value given into the inverse boolean expression when
1790 : the synonym is an inverse boolean synonym.
1791 :
1792 : Return true if
1793 : - parm_name is a valid parameter name and
1794 : - val is a valid value for this parameter and
1795 : - in case the parameter is an inverse boolean synonym, if the val
1796 : string could successfully be converted to the reverse bool.
1797 : Return false in all other cases.
1798 : **************************************************************************/
1799 :
1800 2925 : bool lp_canonicalize_parameter_with_value(const char *parm_name,
1801 : const char *val,
1802 : const char **canon_parm,
1803 : const char **canon_val)
1804 : {
1805 21 : int num;
1806 21 : bool inverse;
1807 21 : bool ret;
1808 :
1809 2925 : if (!lp_parameter_is_valid(parm_name)) {
1810 0 : *canon_parm = NULL;
1811 0 : *canon_val = NULL;
1812 0 : return false;
1813 : }
1814 :
1815 2925 : num = map_parameter_canonical(parm_name, &inverse);
1816 2925 : if (num < 0) {
1817 : /* parametric option */
1818 385 : *canon_parm = parm_name;
1819 385 : *canon_val = val;
1820 385 : return true;
1821 : }
1822 :
1823 2540 : *canon_parm = parm_table[num].label;
1824 2540 : if (inverse) {
1825 217 : if (!lp_invert_boolean(val, canon_val)) {
1826 0 : *canon_val = NULL;
1827 0 : return false;
1828 : }
1829 : } else {
1830 2323 : *canon_val = val;
1831 : }
1832 :
1833 2540 : ret = lp_parameter_value_is_valid(*canon_parm, *canon_val);
1834 :
1835 2540 : return ret;
1836 : }
1837 :
1838 : /***************************************************************************
1839 : Map a parameter's string representation to the index of the canonical
1840 : form of the parameter (it might be a synonym).
1841 : Returns -1 if the parameter string is not recognised.
1842 : ***************************************************************************/
1843 :
1844 2925 : static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1845 : {
1846 21 : int parm_num, canon_num;
1847 2925 : bool loc_inverse = false;
1848 :
1849 2925 : parm_num = lpcfg_map_parameter(pszParmName);
1850 2925 : if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) {
1851 : /* invalid, parametric or no candidate for synonyms ... */
1852 2696 : goto done;
1853 : }
1854 :
1855 85640 : for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1856 85640 : if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1857 229 : parm_num = canon_num;
1858 229 : goto done;
1859 : }
1860 : }
1861 :
1862 0 : done:
1863 2925 : if (inverse != NULL) {
1864 2925 : *inverse = loc_inverse;
1865 : }
1866 2925 : return parm_num;
1867 : }
1868 :
1869 : /***************************************************************************
1870 : return true if parameter number parm1 is a synonym of parameter
1871 : number parm2 (parm2 being the principal name).
1872 : set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1873 : false otherwise.
1874 : ***************************************************************************/
1875 :
1876 85640 : static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1877 : {
1878 85640 : if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1879 458 : (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1880 229 : (parm_table[parm1].flags & FLAG_SYNONYM) &&
1881 229 : !(parm_table[parm2].flags & FLAG_SYNONYM))
1882 : {
1883 229 : if (inverse != NULL) {
1884 229 : if ((parm_table[parm1].type == P_BOOLREV) &&
1885 217 : (parm_table[parm2].type == P_BOOL))
1886 : {
1887 217 : *inverse = true;
1888 : } else {
1889 12 : *inverse = false;
1890 : }
1891 : }
1892 229 : return true;
1893 : }
1894 85411 : return false;
1895 : }
1896 :
1897 : /***************************************************************************
1898 : Show one parameter's name, type, [values,] and flags.
1899 : (helper functions for show_parameter_list)
1900 : ***************************************************************************/
1901 :
1902 0 : static void show_parameter(int parmIndex)
1903 : {
1904 0 : size_t enumIndex, flagIndex;
1905 0 : size_t parmIndex2;
1906 0 : bool hadFlag;
1907 0 : bool hadSyn;
1908 0 : bool inverse;
1909 0 : const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1910 : "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1911 : "P_ENUM", "P_BYTES", "P_CMDLIST" };
1912 0 : unsigned flags[] = { FLAG_DEPRECATED, FLAG_SYNONYM };
1913 0 : const char *flag_names[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL};
1914 :
1915 0 : printf("%s=%s", parm_table[parmIndex].label,
1916 0 : type[parm_table[parmIndex].type]);
1917 0 : if (parm_table[parmIndex].type == P_ENUM) {
1918 0 : printf(",");
1919 0 : for (enumIndex=0;
1920 0 : parm_table[parmIndex].enum_list[enumIndex].name;
1921 0 : enumIndex++)
1922 : {
1923 0 : printf("%s%s",
1924 : enumIndex ? "|" : "",
1925 0 : parm_table[parmIndex].enum_list[enumIndex].name);
1926 : }
1927 : }
1928 0 : printf(",");
1929 0 : hadFlag = false;
1930 0 : for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1931 0 : if (parm_table[parmIndex].flags & flags[flagIndex]) {
1932 0 : printf("%s%s",
1933 : hadFlag ? "|" : "",
1934 : flag_names[flagIndex]);
1935 0 : hadFlag = true;
1936 : }
1937 : }
1938 :
1939 : /* output synonyms */
1940 0 : hadSyn = false;
1941 0 : for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1942 0 : if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1943 0 : printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1944 : parm_table[parmIndex2].label);
1945 0 : } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1946 0 : if (!hadSyn) {
1947 0 : printf(" (synonyms: ");
1948 0 : hadSyn = true;
1949 : } else {
1950 0 : printf(", ");
1951 : }
1952 0 : printf("%s%s", parm_table[parmIndex2].label,
1953 0 : inverse ? "[i]" : "");
1954 : }
1955 : }
1956 0 : if (hadSyn) {
1957 0 : printf(")");
1958 : }
1959 :
1960 0 : printf("\n");
1961 0 : }
1962 :
1963 : /*
1964 : * Check the value for a P_ENUM
1965 : */
1966 44 : static bool check_enum_parameter(struct parm_struct *parm, const char *value)
1967 : {
1968 6 : int i;
1969 :
1970 265 : for (i = 0; parm->enum_list[i].name; i++) {
1971 265 : if (strwicmp(value, parm->enum_list[i].name) == 0) {
1972 38 : return true;
1973 : }
1974 : }
1975 0 : return false;
1976 : }
1977 :
1978 : /**************************************************************************
1979 : Check whether the given value is valid for the given parameter name.
1980 : **************************************************************************/
1981 :
1982 2540 : static bool lp_parameter_value_is_valid(const char *parm_name, const char *val)
1983 : {
1984 2540 : bool ret = false, tmp_bool;
1985 2540 : int num = lpcfg_map_parameter(parm_name), tmp_int;
1986 2540 : uint64_t tmp_int64 = 0;
1987 20 : struct parm_struct *parm;
1988 :
1989 : /* parametric options (parameter names containing a colon) cannot
1990 : be checked and are therefore considered valid. */
1991 2540 : if (strchr(parm_name, ':') != NULL) {
1992 0 : return true;
1993 : }
1994 :
1995 2540 : if (num >= 0) {
1996 2540 : parm = &parm_table[num];
1997 2540 : switch (parm->type) {
1998 1043 : case P_BOOL:
1999 : case P_BOOLREV:
2000 1043 : ret = set_boolean(val, &tmp_bool);
2001 1043 : break;
2002 :
2003 16 : case P_INTEGER:
2004 16 : ret = (sscanf(val, "%d", &tmp_int) == 1);
2005 16 : break;
2006 :
2007 18 : case P_OCTAL:
2008 18 : ret = (sscanf(val, "%o", &tmp_int) == 1);
2009 18 : break;
2010 :
2011 44 : case P_ENUM:
2012 44 : ret = check_enum_parameter(parm, val);
2013 44 : break;
2014 :
2015 8 : case P_BYTES:
2016 8 : if (conv_str_size_error(val, &tmp_int64) &&
2017 8 : tmp_int64 <= INT_MAX) {
2018 8 : ret = true;
2019 : }
2020 8 : break;
2021 :
2022 1411 : case P_CHAR:
2023 : case P_LIST:
2024 : case P_STRING:
2025 : case P_USTRING:
2026 : case P_CMDLIST:
2027 1411 : ret = true;
2028 1411 : break;
2029 : }
2030 : }
2031 2520 : return ret;
2032 : }
2033 :
2034 : /***************************************************************************
2035 : Show all parameter's name, type, [values,] and flags.
2036 : ***************************************************************************/
2037 :
2038 0 : void show_parameter_list(void)
2039 : {
2040 0 : int classIndex, parmIndex;
2041 0 : const char *section_names[] = { "local", "global", NULL};
2042 :
2043 0 : for (classIndex=0; section_names[classIndex]; classIndex++) {
2044 0 : printf("[%s]\n", section_names[classIndex]);
2045 0 : for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2046 0 : if (parm_table[parmIndex].p_class == classIndex) {
2047 0 : show_parameter(parmIndex);
2048 : }
2049 : }
2050 : }
2051 0 : }
2052 :
2053 : /***************************************************************************
2054 : Get the standard string representation of a boolean value ("yes" or "no")
2055 : ***************************************************************************/
2056 :
2057 217 : static const char *get_boolean(bool bool_value)
2058 : {
2059 0 : static const char *yes_str = "yes";
2060 0 : static const char *no_str = "no";
2061 :
2062 217 : return (bool_value ? yes_str : no_str);
2063 : }
2064 :
2065 : /***************************************************************************
2066 : Provide the string of the negated boolean value associated to the boolean
2067 : given as a string. Returns false if the passed string does not correctly
2068 : represent a boolean.
2069 : ***************************************************************************/
2070 :
2071 217 : bool lp_invert_boolean(const char *str, const char **inverse_str)
2072 : {
2073 0 : bool val;
2074 :
2075 217 : if (!set_boolean(str, &val)) {
2076 0 : return false;
2077 : }
2078 :
2079 217 : *inverse_str = get_boolean(!val);
2080 217 : return true;
2081 : }
2082 :
2083 : /***************************************************************************
2084 : Provide the canonical string representation of a boolean value given
2085 : as a string. Return true on success, false if the string given does
2086 : not correctly represent a boolean.
2087 : ***************************************************************************/
2088 :
2089 0 : bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2090 : {
2091 0 : bool val;
2092 :
2093 0 : if (!set_boolean(str, &val)) {
2094 0 : return false;
2095 : }
2096 :
2097 0 : *canon_str = get_boolean(val);
2098 0 : return true;
2099 : }
2100 :
2101 : /***************************************************************************
2102 : Find a service by name. Otherwise works like get_service.
2103 : ***************************************************************************/
2104 :
2105 3613936 : int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2106 : {
2107 3613936 : int iService = -1;
2108 197 : char *canon_name;
2109 197 : TDB_DATA data;
2110 197 : NTSTATUS status;
2111 :
2112 3613936 : if (ServiceHash == NULL) {
2113 2197 : return -1;
2114 : }
2115 :
2116 3611729 : canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2117 :
2118 3611729 : status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2119 : &data);
2120 :
2121 3611729 : if (NT_STATUS_IS_OK(status) &&
2122 3423818 : (data.dptr != NULL) &&
2123 3423818 : (data.dsize == sizeof(iService)))
2124 : {
2125 3423818 : memcpy(&iService, data.dptr, sizeof(iService));
2126 : }
2127 :
2128 3611729 : TALLOC_FREE(canon_name);
2129 :
2130 3611729 : if ((iService != -1) && (LP_SNUM_OK(iService))
2131 3423818 : && (pserviceDest != NULL)) {
2132 0 : copy_service(pserviceDest, ServicePtrs[iService], NULL);
2133 : }
2134 :
2135 3611542 : return (iService);
2136 : }
2137 :
2138 : /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2139 779826 : struct loadparm_service *lp_service(const char *pszServiceName)
2140 : {
2141 779826 : int iService = getservicebyname(pszServiceName, NULL);
2142 779826 : if (iService == -1 || !LP_SNUM_OK(iService)) {
2143 1 : return NULL;
2144 : }
2145 779776 : return ServicePtrs[iService];
2146 : }
2147 :
2148 0 : struct loadparm_service *lp_servicebynum(int snum)
2149 : {
2150 0 : if ((snum == -1) || !LP_SNUM_OK(snum)) {
2151 0 : return NULL;
2152 : }
2153 0 : return ServicePtrs[snum];
2154 : }
2155 :
2156 0 : struct loadparm_service *lp_default_loadparm_service(void)
2157 : {
2158 0 : return &sDefault;
2159 : }
2160 :
2161 2777200 : static struct smbconf_ctx *lp_smbconf_ctx(void)
2162 : {
2163 0 : sbcErr err;
2164 0 : static struct smbconf_ctx *conf_ctx = NULL;
2165 :
2166 2777200 : if (conf_ctx == NULL) {
2167 431 : err = smbconf_init(NULL, &conf_ctx, "registry:");
2168 431 : if (!SBC_ERROR_IS_OK(err)) {
2169 0 : DEBUG(1, ("error initializing registry configuration: "
2170 : "%s\n", sbcErrorString(err)));
2171 0 : conf_ctx = NULL;
2172 : }
2173 : }
2174 :
2175 2777200 : return conf_ctx;
2176 : }
2177 :
2178 3224 : static bool process_smbconf_service(struct smbconf_service *service)
2179 : {
2180 0 : uint32_t count;
2181 0 : bool ret;
2182 :
2183 3224 : if (service == NULL) {
2184 0 : return false;
2185 : }
2186 :
2187 3224 : ret = lp_do_section(service->name, NULL);
2188 3224 : if (ret != true) {
2189 0 : return false;
2190 : }
2191 16123 : for (count = 0; count < service->num_params; count++) {
2192 :
2193 12899 : if (!bInGlobalSection && bGlobalOnly) {
2194 0 : ret = true;
2195 : } else {
2196 12899 : const char *pszParmName = service->param_names[count];
2197 12899 : const char *pszParmValue = service->param_values[count];
2198 :
2199 12899 : DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2200 :
2201 12899 : ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2202 : pszParmName, pszParmValue);
2203 : }
2204 :
2205 12899 : if (ret != true) {
2206 0 : return false;
2207 : }
2208 : }
2209 3224 : if (iServiceIndex >= 0) {
2210 3224 : return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2211 : }
2212 0 : return true;
2213 : }
2214 :
2215 : /**
2216 : * load a service from registry and activate it
2217 : */
2218 2776967 : bool process_registry_service(const char *service_name)
2219 : {
2220 0 : sbcErr err;
2221 2776967 : struct smbconf_service *service = NULL;
2222 2776967 : TALLOC_CTX *mem_ctx = talloc_stackframe();
2223 2776967 : struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2224 2776967 : bool ret = false;
2225 :
2226 2776967 : if (conf_ctx == NULL) {
2227 0 : goto done;
2228 : }
2229 :
2230 2776967 : DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2231 :
2232 2776967 : if (!smbconf_share_exists(conf_ctx, service_name)) {
2233 : /*
2234 : * Registry does not contain data for this service (yet),
2235 : * but make sure lp_load doesn't return false.
2236 : */
2237 2776151 : ret = true;
2238 2776151 : goto done;
2239 : }
2240 :
2241 816 : err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2242 816 : if (!SBC_ERROR_IS_OK(err)) {
2243 0 : goto done;
2244 : }
2245 :
2246 816 : ret = process_smbconf_service(service);
2247 816 : if (!ret) {
2248 0 : goto done;
2249 : }
2250 :
2251 : /* store the csn */
2252 816 : smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2253 :
2254 2776967 : done:
2255 2776967 : TALLOC_FREE(mem_ctx);
2256 2776967 : return ret;
2257 : }
2258 :
2259 : /*
2260 : * process_registry_globals
2261 : */
2262 0 : static bool process_registry_globals(void)
2263 : {
2264 0 : bool ret;
2265 :
2266 0 : add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2267 :
2268 0 : if (!bInGlobalSection && bGlobalOnly) {
2269 0 : ret = true;
2270 : } else {
2271 0 : const char *pszParmName = "registry shares";
2272 0 : const char *pszParmValue = "yes";
2273 :
2274 0 : DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2275 :
2276 0 : ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2277 : pszParmName, pszParmValue);
2278 : }
2279 :
2280 0 : if (!ret) {
2281 0 : return ret;
2282 : }
2283 :
2284 0 : return process_registry_service(GLOBAL_NAME);
2285 : }
2286 :
2287 233 : bool process_registry_shares(void)
2288 : {
2289 0 : sbcErr err;
2290 0 : uint32_t count;
2291 233 : struct smbconf_service **service = NULL;
2292 233 : uint32_t num_shares = 0;
2293 233 : TALLOC_CTX *mem_ctx = talloc_stackframe();
2294 233 : struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2295 233 : bool ret = false;
2296 :
2297 233 : if (conf_ctx == NULL) {
2298 0 : goto done;
2299 : }
2300 :
2301 233 : err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2302 233 : if (!SBC_ERROR_IS_OK(err)) {
2303 0 : goto done;
2304 : }
2305 :
2306 233 : ret = true;
2307 :
2308 2653 : for (count = 0; count < num_shares; count++) {
2309 2420 : if (strequal(service[count]->name, GLOBAL_NAME)) {
2310 12 : continue;
2311 : }
2312 2408 : ret = process_smbconf_service(service[count]);
2313 2408 : if (!ret) {
2314 0 : goto done;
2315 : }
2316 : }
2317 :
2318 : /* store the csn */
2319 233 : smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2320 :
2321 233 : done:
2322 233 : TALLOC_FREE(mem_ctx);
2323 233 : return ret;
2324 : }
2325 :
2326 : /**
2327 : * reload those shares from registry that are already
2328 : * activated in the services array.
2329 : */
2330 28189 : static bool reload_registry_shares(void)
2331 : {
2332 0 : int i;
2333 28189 : bool ret = true;
2334 :
2335 2801222 : for (i = 0; i < iNumServices; i++) {
2336 2773033 : if (!VALID(i)) {
2337 6083 : continue;
2338 : }
2339 :
2340 2766950 : if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2341 0 : continue;
2342 : }
2343 :
2344 2766950 : ret = process_registry_service(ServicePtrs[i]->szService);
2345 2766950 : if (!ret) {
2346 0 : goto done;
2347 : }
2348 : }
2349 :
2350 28189 : done:
2351 28189 : return ret;
2352 : }
2353 :
2354 :
2355 : #define MAX_INCLUDE_DEPTH 100
2356 :
2357 : static uint8_t include_depth;
2358 :
2359 : /**
2360 : * Free the file lists
2361 : */
2362 66088 : static void free_file_list(void)
2363 : {
2364 134 : struct file_lists *f;
2365 134 : struct file_lists *next;
2366 :
2367 66088 : f = file_lists;
2368 225415 : while( f ) {
2369 159327 : next = f->next;
2370 159327 : TALLOC_FREE( f );
2371 159327 : f = next;
2372 : }
2373 66088 : file_lists = NULL;
2374 65954 : }
2375 :
2376 :
2377 : /**
2378 : * Utility function for outsiders to check if we're running on registry.
2379 : */
2380 49208 : bool lp_config_backend_is_registry(void)
2381 : {
2382 49208 : return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2383 : }
2384 :
2385 : /**
2386 : * Utility function to check if the config backend is FILE.
2387 : */
2388 49106 : bool lp_config_backend_is_file(void)
2389 : {
2390 49106 : return (lp_config_backend() == CONFIG_BACKEND_FILE);
2391 : }
2392 :
2393 : /*******************************************************************
2394 : Check if a config file has changed date.
2395 : ********************************************************************/
2396 :
2397 148635 : bool lp_file_list_changed(void)
2398 : {
2399 148635 : struct file_lists *f = file_lists;
2400 :
2401 148635 : DEBUG(6, ("lp_file_list_changed()\n"));
2402 :
2403 825899 : while (f) {
2404 677685 : if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2405 0 : struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2406 :
2407 0 : if (conf_ctx == NULL) {
2408 0 : return false;
2409 : }
2410 0 : if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2411 : NULL))
2412 : {
2413 0 : DEBUGADD(6, ("registry config changed\n"));
2414 0 : return true;
2415 : }
2416 : } else {
2417 677685 : struct timespec mod_time = {
2418 : .tv_sec = 0,
2419 : };
2420 677685 : struct timeval_buf tbuf = {
2421 : .buf = {0},
2422 : };
2423 677685 : char *n2 = NULL;
2424 677685 : struct stat sb = {0};
2425 3821 : int rc;
2426 :
2427 677685 : n2 = talloc_sub_basic(talloc_tos(),
2428 : get_current_username(),
2429 : get_current_user_info_domain(),
2430 677685 : f->name);
2431 677685 : if (!n2) {
2432 421 : return false;
2433 : }
2434 677685 : DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2435 : f->name, n2,
2436 : timespec_string_buf(&f->modtime,
2437 : true,
2438 : &tbuf)));
2439 :
2440 677685 : rc = stat(n2, &sb);
2441 677685 : if (rc == 0) {
2442 570444 : mod_time = get_mtimespec(&sb);
2443 : }
2444 :
2445 1248129 : if (mod_time.tv_sec > 0 &&
2446 570444 : ((timespec_compare(&mod_time, &f->modtime) != 0) ||
2447 570023 : (f->subfname == NULL) ||
2448 570023 : (strcmp(n2, f->subfname) != 0)))
2449 : {
2450 421 : f->modtime = mod_time;
2451 :
2452 421 : DEBUGADD(6,
2453 : ("file %s modified: %s\n", n2,
2454 : timespec_string_buf(&f->modtime,
2455 : true,
2456 : &tbuf)));
2457 :
2458 421 : TALLOC_FREE(f->subfname);
2459 421 : f->subfname = talloc_strdup(f, n2);
2460 421 : if (f->subfname == NULL) {
2461 0 : smb_panic("talloc_strdup failed");
2462 : }
2463 421 : TALLOC_FREE(n2);
2464 421 : return true;
2465 : }
2466 677264 : TALLOC_FREE(n2);
2467 : }
2468 677264 : f = f->next;
2469 : }
2470 144393 : return false;
2471 : }
2472 :
2473 :
2474 : /**
2475 : * Initialize iconv conversion descriptors.
2476 : *
2477 : * This is called the first time it is needed, and also called again
2478 : * every time the configuration is reloaded, because the charset or
2479 : * codepage might have changed.
2480 : **/
2481 49106 : static void init_iconv(void)
2482 : {
2483 49106 : struct smb_iconv_handle *ret = NULL;
2484 :
2485 49106 : ret = reinit_iconv_handle(NULL,
2486 : lp_dos_charset(),
2487 : lp_unix_charset());
2488 49106 : if (ret == NULL) {
2489 0 : smb_panic("reinit_iconv_handle failed");
2490 : }
2491 49106 : }
2492 :
2493 : /***************************************************************************
2494 : Handle the include operation.
2495 : ***************************************************************************/
2496 : static bool bAllowIncludeRegistry = true;
2497 :
2498 166775 : bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2499 : const char *pszParmValue, char **ptr)
2500 : {
2501 0 : char *fname;
2502 :
2503 166775 : if (include_depth >= MAX_INCLUDE_DEPTH) {
2504 0 : DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2505 : include_depth));
2506 0 : return false;
2507 : }
2508 :
2509 166775 : if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2510 0 : if (!bAllowIncludeRegistry) {
2511 0 : return true;
2512 : }
2513 0 : if (lp_ctx->bInGlobalSection) {
2514 0 : bool ret;
2515 0 : include_depth++;
2516 0 : ret = process_registry_globals();
2517 0 : include_depth--;
2518 0 : return ret;
2519 : } else {
2520 0 : DEBUG(1, ("\"include = registry\" only effective "
2521 : "in %s section\n", GLOBAL_NAME));
2522 0 : return false;
2523 : }
2524 : }
2525 :
2526 166775 : fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2527 : get_current_user_info_domain(),
2528 : pszParmValue);
2529 :
2530 166775 : add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2531 :
2532 166775 : if (service == NULL) {
2533 28331 : lpcfg_string_set(Globals.ctx, ptr, fname);
2534 : } else {
2535 138444 : lpcfg_string_set(service, ptr, fname);
2536 : }
2537 :
2538 166775 : if (file_exist(fname)) {
2539 0 : bool ret;
2540 143343 : include_depth++;
2541 143343 : ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2542 143343 : include_depth--;
2543 143343 : TALLOC_FREE(fname);
2544 143343 : return ret;
2545 : }
2546 :
2547 23432 : DEBUG(2, ("Can't find include file %s\n", fname));
2548 23432 : TALLOC_FREE(fname);
2549 23432 : return true;
2550 : }
2551 :
2552 2506 : bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2553 : {
2554 2506 : char *config_option = NULL;
2555 2506 : const char *range = NULL;
2556 2506 : bool ret = false;
2557 :
2558 2506 : SMB_ASSERT(low != NULL);
2559 2506 : SMB_ASSERT(high != NULL);
2560 :
2561 2506 : if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2562 0 : domain_name = "*";
2563 : }
2564 :
2565 2506 : config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2566 : domain_name);
2567 2506 : if (config_option == NULL) {
2568 0 : DEBUG(0, ("out of memory\n"));
2569 0 : return false;
2570 : }
2571 :
2572 2506 : range = lp_parm_const_string(-1, config_option, "range", NULL);
2573 2506 : if (range == NULL) {
2574 2200 : DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2575 2200 : goto done;
2576 : }
2577 :
2578 306 : if (sscanf(range, "%u - %u", low, high) != 2) {
2579 0 : DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2580 : range, domain_name));
2581 0 : goto done;
2582 : }
2583 :
2584 306 : ret = true;
2585 :
2586 2506 : done:
2587 2506 : talloc_free(config_option);
2588 2506 : return ret;
2589 :
2590 : }
2591 :
2592 2502 : bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2593 : {
2594 2502 : return lp_idmap_range("*", low, high);
2595 : }
2596 :
2597 53 : const char *lp_idmap_backend(const char *domain_name)
2598 : {
2599 53 : char *config_option = NULL;
2600 53 : const char *backend = NULL;
2601 :
2602 53 : if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2603 0 : domain_name = "*";
2604 : }
2605 :
2606 53 : config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2607 : domain_name);
2608 53 : if (config_option == NULL) {
2609 0 : DEBUG(0, ("out of memory\n"));
2610 0 : return false;
2611 : }
2612 :
2613 53 : backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2614 53 : if (backend == NULL) {
2615 0 : DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2616 0 : goto done;
2617 : }
2618 :
2619 53 : done:
2620 53 : talloc_free(config_option);
2621 53 : return backend;
2622 : }
2623 :
2624 49 : const char *lp_idmap_default_backend(void)
2625 : {
2626 49 : return lp_idmap_backend("*");
2627 : }
2628 :
2629 : /***************************************************************************
2630 : Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2631 : ***************************************************************************/
2632 :
2633 0 : static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2634 : {
2635 0 : const char *suffix_string;
2636 :
2637 0 : suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2638 : Globals.ldap_suffix );
2639 0 : if ( !suffix_string ) {
2640 0 : DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2641 0 : return "";
2642 : }
2643 :
2644 0 : return suffix_string;
2645 : }
2646 :
2647 0 : const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2648 : {
2649 0 : if (Globals._ldap_machine_suffix[0])
2650 0 : return append_ldap_suffix(ctx, Globals._ldap_machine_suffix);
2651 :
2652 0 : return talloc_strdup(ctx, Globals.ldap_suffix);
2653 : }
2654 :
2655 0 : const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2656 : {
2657 0 : if (Globals._ldap_user_suffix[0])
2658 0 : return append_ldap_suffix(ctx, Globals._ldap_user_suffix);
2659 :
2660 0 : return talloc_strdup(ctx, Globals.ldap_suffix);
2661 : }
2662 :
2663 0 : const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2664 : {
2665 0 : if (Globals._ldap_group_suffix[0])
2666 0 : return append_ldap_suffix(ctx, Globals._ldap_group_suffix);
2667 :
2668 0 : return talloc_strdup(ctx, Globals.ldap_suffix);
2669 : }
2670 :
2671 0 : const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2672 : {
2673 0 : if (Globals._ldap_idmap_suffix[0])
2674 0 : return append_ldap_suffix(ctx, Globals._ldap_idmap_suffix);
2675 :
2676 0 : return talloc_strdup(ctx, Globals.ldap_suffix);
2677 : }
2678 :
2679 : /**
2680 : return the parameter pointer for a parameter
2681 : */
2682 70422807 : void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2683 : {
2684 70422807 : if (service == NULL) {
2685 49205637 : if (parm->p_class == P_LOCAL)
2686 13960818 : return (void *)(((char *)&sDefault)+parm->offset);
2687 35244819 : else if (parm->p_class == P_GLOBAL)
2688 35244819 : return (void *)(((char *)&Globals)+parm->offset);
2689 0 : else return NULL;
2690 : } else {
2691 21217170 : return (void *)(((char *)service) + parm->offset);
2692 : }
2693 : }
2694 :
2695 : /***************************************************************************
2696 : Process a parameter for a particular service number. If snum < 0
2697 : then assume we are in the globals.
2698 : ***************************************************************************/
2699 :
2700 395320 : bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2701 : {
2702 395320 : TALLOC_CTX *frame = talloc_stackframe();
2703 3886 : struct loadparm_context *lp_ctx;
2704 3886 : bool ok;
2705 :
2706 395320 : lp_ctx = setup_lp_context(frame);
2707 395320 : if (lp_ctx == NULL) {
2708 0 : TALLOC_FREE(frame);
2709 0 : return false;
2710 : }
2711 :
2712 395320 : if (snum < 0) {
2713 172339 : ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2714 : } else {
2715 222981 : ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2716 : pszParmName, pszParmValue);
2717 : }
2718 :
2719 395320 : TALLOC_FREE(frame);
2720 :
2721 391434 : return ok;
2722 : }
2723 :
2724 : /***************************************************************************
2725 : set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2726 : FLAG_CMDLINE won't be overridden by loads from smb.conf.
2727 : ***************************************************************************/
2728 :
2729 54659 : static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2730 : {
2731 88 : int parmnum, i;
2732 54659 : parmnum = lpcfg_map_parameter(pszParmName);
2733 54659 : if (parmnum >= 0) {
2734 54028 : flags_list[parmnum] &= ~FLAG_CMDLINE;
2735 54028 : if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2736 0 : return false;
2737 : }
2738 54028 : flags_list[parmnum] |= FLAG_CMDLINE;
2739 :
2740 : /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2741 : * be grouped in the table, so we don't have to search the
2742 : * whole table */
2743 54028 : for (i=parmnum-1;
2744 54025 : i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2745 54028 : && parm_table[i].p_class == parm_table[parmnum].p_class;
2746 0 : i--) {
2747 0 : flags_list[i] |= FLAG_CMDLINE;
2748 : }
2749 150045 : for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2750 96066 : && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2751 21019 : flags_list[i] |= FLAG_CMDLINE;
2752 : }
2753 :
2754 53946 : return true;
2755 : }
2756 :
2757 : /* it might be parametric */
2758 631 : if (strchr(pszParmName, ':') != NULL) {
2759 631 : set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2760 631 : return true;
2761 : }
2762 :
2763 0 : DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2764 0 : return false;
2765 : }
2766 :
2767 : /***************************************************************************
2768 : Process a parameter.
2769 : ***************************************************************************/
2770 :
2771 17241843 : static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2772 : void *userdata)
2773 : {
2774 17241843 : if (!bInGlobalSection && bGlobalOnly)
2775 2362077 : return true;
2776 :
2777 14879750 : DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2778 :
2779 14879750 : if (bInGlobalSection) {
2780 3764535 : return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2781 : } else {
2782 11115215 : return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2783 : pszParmName, pszParmValue);
2784 : }
2785 : }
2786 :
2787 :
2788 : static const char *ad_dc_req_vfs_mods[] = {"dfs_samba4", "acl_xattr", NULL};
2789 :
2790 : /*
2791 : * check that @vfs_objects includes all vfs modules required by an AD DC.
2792 : */
2793 3987 : static bool check_ad_dc_required_mods(const char **vfs_objects)
2794 : {
2795 10 : int i;
2796 10 : int j;
2797 10 : int got_req;
2798 :
2799 11957 : for (i = 0; ad_dc_req_vfs_mods[i] != NULL; i++) {
2800 7984 : got_req = false;
2801 11961 : for (j = 0; vfs_objects[j] != NULL; j++) {
2802 11959 : if (!strwicmp(ad_dc_req_vfs_mods[i], vfs_objects[j])) {
2803 7954 : got_req = true;
2804 7954 : break;
2805 : }
2806 : }
2807 7972 : if (!got_req) {
2808 2 : DEBUG(0, ("vfs objects specified without required AD "
2809 : "DC module: %s\n", ad_dc_req_vfs_mods[i]));
2810 2 : return false;
2811 : }
2812 : }
2813 :
2814 3985 : DEBUG(6, ("vfs objects specified with all required AD DC modules\n"));
2815 3977 : return true;
2816 : }
2817 :
2818 :
2819 : /***************************************************************************
2820 : Initialize any local variables in the sDefault table, after parsing a
2821 : [globals] section.
2822 : ***************************************************************************/
2823 :
2824 38867 : static void init_locals(void)
2825 : {
2826 : /*
2827 : * We run this check once the [globals] is parsed, to force
2828 : * the VFS objects and other per-share settings we need for
2829 : * the standard way a AD DC is operated. We may change these
2830 : * as our code evolves, which is why we force these settings.
2831 : *
2832 : * We can't do this at the end of lp_load_ex(), as by that
2833 : * point the services have been loaded and they will already
2834 : * have "" as their vfs objects.
2835 : */
2836 38867 : if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2837 3993 : const char **vfs_objects = lp_vfs_objects(-1);
2838 3993 : if (vfs_objects != NULL) {
2839 : /* ignore return, only warn if modules are missing */
2840 3987 : check_ad_dc_required_mods(vfs_objects);
2841 : } else {
2842 6 : if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2843 0 : lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2844 6 : } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2845 6 : lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2846 : } else {
2847 0 : lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2848 : }
2849 : }
2850 :
2851 3993 : lp_do_parameter(-1, "map hidden", "no");
2852 3993 : lp_do_parameter(-1, "map system", "no");
2853 3993 : lp_do_parameter(-1, "map readonly", "no");
2854 3993 : lp_do_parameter(-1, "map archive", "no");
2855 3993 : lp_do_parameter(-1, "store dos attributes", "yes");
2856 : }
2857 38867 : }
2858 :
2859 : /***************************************************************************
2860 : Process a new section (service). At this stage all sections are services.
2861 : Later we'll have special sections that permit server parameters to be set.
2862 : Returns true on success, false on failure.
2863 : ***************************************************************************/
2864 :
2865 3451256 : bool lp_do_section(const char *pszSectionName, void *userdata)
2866 : {
2867 3451256 : struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2868 287 : bool bRetval;
2869 6847103 : bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2870 3395847 : (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2871 :
2872 : /* if we were in a global section then do the local inits */
2873 3451256 : if (bInGlobalSection && !isglobal)
2874 36832 : init_locals();
2875 :
2876 : /* if we've just struck a global section, note the fact. */
2877 3451256 : bInGlobalSection = isglobal;
2878 3451256 : if (lp_ctx != NULL) {
2879 3448032 : lp_ctx->bInGlobalSection = isglobal;
2880 : }
2881 :
2882 : /* check for multiple global sections */
2883 3451256 : if (bInGlobalSection) {
2884 55409 : DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2885 55409 : return true;
2886 : }
2887 :
2888 3395847 : if (!bInGlobalSection && bGlobalOnly)
2889 595842 : return true;
2890 :
2891 : /* if we have a current service, tidy it up before moving on */
2892 2799997 : bRetval = true;
2893 :
2894 2799997 : if ((iServiceIndex >= 0) && (ServicePtrs[iServiceIndex] != NULL))
2895 2773094 : bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2896 :
2897 : /* if all is still well, move to the next record in the services array */
2898 2799975 : if (bRetval) {
2899 : /* We put this here to avoid an odd message order if messages are */
2900 : /* issued by the post-processing of a previous section. */
2901 2799997 : DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2902 :
2903 2799997 : iServiceIndex = add_a_service(&sDefault, pszSectionName);
2904 2799997 : if (iServiceIndex < 0) {
2905 0 : DEBUG(0, ("Failed to add a new service\n"));
2906 0 : return false;
2907 : }
2908 : /* Clean all parametric options for service */
2909 : /* They will be added during parsing again */
2910 2799997 : free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2911 : }
2912 :
2913 2799849 : return bRetval;
2914 : }
2915 :
2916 : /***************************************************************************
2917 : Display the contents of a parameter of a single services record.
2918 : ***************************************************************************/
2919 :
2920 1420 : bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2921 : {
2922 1420 : bool result = false;
2923 4 : struct loadparm_context *lp_ctx;
2924 :
2925 1420 : lp_ctx = setup_lp_context(talloc_tos());
2926 1420 : if (lp_ctx == NULL) {
2927 0 : return false;
2928 : }
2929 :
2930 1420 : if (isGlobal) {
2931 1023 : result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2932 : } else {
2933 397 : result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2934 : }
2935 1420 : TALLOC_FREE(lp_ctx);
2936 1420 : return result;
2937 : }
2938 :
2939 : #if 0
2940 : /***************************************************************************
2941 : Display the contents of a single copy structure.
2942 : ***************************************************************************/
2943 : static void dump_copy_map(bool *pcopymap)
2944 : {
2945 : int i;
2946 : if (!pcopymap)
2947 : return;
2948 :
2949 : printf("\n\tNon-Copied parameters:\n");
2950 :
2951 : for (i = 0; parm_table[i].label; i++)
2952 : if (parm_table[i].p_class == P_LOCAL &&
2953 : parm_table[i].ptr && !pcopymap[i] &&
2954 : (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2955 : {
2956 : printf("\t\t%s\n", parm_table[i].label);
2957 : }
2958 : }
2959 : #endif
2960 :
2961 : /***************************************************************************
2962 : Return TRUE if the passed service number is within range.
2963 : ***************************************************************************/
2964 :
2965 2151187 : bool lp_snum_ok(int iService)
2966 : {
2967 2151187 : return (LP_SNUM_OK(iService) && ServicePtrs[iService]->available);
2968 : }
2969 :
2970 : /***************************************************************************
2971 : Auto-load some home services.
2972 : ***************************************************************************/
2973 :
2974 49106 : static void lp_add_auto_services(const char *str)
2975 : {
2976 125 : char *s;
2977 125 : char *p;
2978 125 : int homes;
2979 125 : char *saveptr;
2980 :
2981 49106 : if (!str)
2982 0 : return;
2983 :
2984 49106 : s = talloc_strdup(talloc_tos(), str);
2985 49106 : if (!s) {
2986 0 : smb_panic("talloc_strdup failed");
2987 : return;
2988 : }
2989 :
2990 49106 : homes = lp_servicenumber(HOMES_NAME);
2991 :
2992 49108 : for (p = strtok_r(s, LIST_SEP, &saveptr); p;
2993 2 : p = strtok_r(NULL, LIST_SEP, &saveptr)) {
2994 0 : char *home;
2995 :
2996 2 : if (lp_servicenumber(p) >= 0)
2997 0 : continue;
2998 :
2999 2 : home = get_user_home_dir(talloc_tos(), p);
3000 :
3001 2 : if (home && home[0] && homes >= 0)
3002 0 : lp_add_home(p, homes, p, home);
3003 :
3004 2 : TALLOC_FREE(home);
3005 : }
3006 49106 : TALLOC_FREE(s);
3007 : }
3008 :
3009 : /***************************************************************************
3010 : Auto-load one printer.
3011 : ***************************************************************************/
3012 :
3013 0 : void lp_add_one_printer(const char *name, const char *comment,
3014 : const char *location, void *pdata)
3015 : {
3016 0 : int printers = lp_servicenumber(PRINTERS_NAME);
3017 0 : int i;
3018 :
3019 0 : if (lp_servicenumber(name) < 0) {
3020 0 : lp_add_printer(name, printers);
3021 0 : if ((i = lp_servicenumber(name)) >= 0) {
3022 0 : lpcfg_string_set(ServicePtrs[i],
3023 0 : &ServicePtrs[i]->comment, comment);
3024 0 : ServicePtrs[i]->autoloaded = true;
3025 : }
3026 : }
3027 0 : }
3028 :
3029 : /***************************************************************************
3030 : Have we loaded a services file yet?
3031 : ***************************************************************************/
3032 :
3033 306683 : bool lp_loaded(void)
3034 : {
3035 306683 : return (b_loaded);
3036 : }
3037 :
3038 : /***************************************************************************
3039 : Unload unused services.
3040 : ***************************************************************************/
3041 :
3042 1405 : void lp_killunused(struct smbd_server_connection *sconn,
3043 : bool (*snumused) (struct smbd_server_connection *, int))
3044 : {
3045 0 : int i;
3046 132008 : for (i = 0; i < iNumServices; i++) {
3047 130603 : if (!VALID(i))
3048 806 : continue;
3049 :
3050 : /* don't kill autoloaded or usershare services */
3051 129797 : if ( ServicePtrs[i]->autoloaded ||
3052 129790 : ServicePtrs[i]->usershare == USERSHARE_VALID) {
3053 7 : continue;
3054 : }
3055 :
3056 129790 : if (!snumused || !snumused(sconn, i)) {
3057 124353 : free_service_byindex(i);
3058 : }
3059 : }
3060 1405 : }
3061 :
3062 : /**
3063 : * Kill all except autoloaded and usershare services - convenience wrapper
3064 : */
3065 200 : void lp_kill_all_services(void)
3066 : {
3067 200 : lp_killunused(NULL, NULL);
3068 200 : }
3069 :
3070 : /***************************************************************************
3071 : Unload a service.
3072 : ***************************************************************************/
3073 :
3074 22 : void lp_killservice(int iServiceIn)
3075 : {
3076 22 : if (VALID(iServiceIn)) {
3077 22 : free_service_byindex(iServiceIn);
3078 : }
3079 22 : }
3080 :
3081 : /***************************************************************************
3082 : Save the current values of all global and sDefault parameters into the
3083 : defaults union. This allows testparm to show only the
3084 : changed (ie. non-default) parameters.
3085 : ***************************************************************************/
3086 :
3087 2035 : static void lp_save_defaults(void)
3088 : {
3089 5 : int i;
3090 5 : struct parmlist_entry * parm;
3091 1056165 : for (i = 0; parm_table[i].label; i++) {
3092 1054130 : if (!(flags_list[i] & FLAG_CMDLINE)) {
3093 1048657 : flags_list[i] |= FLAG_DEFAULT;
3094 : }
3095 :
3096 1054130 : if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3097 71225 : && parm_table[i].p_class == parm_table[i - 1].p_class)
3098 71225 : continue;
3099 982905 : switch (parm_table[i].type) {
3100 83435 : case P_LIST:
3101 : case P_CMDLIST:
3102 83435 : parm_table[i].def.lvalue = str_list_copy(
3103 83435 : NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3104 83435 : break;
3105 260480 : case P_STRING:
3106 : case P_USTRING:
3107 260480 : lpcfg_string_set(
3108 : Globals.ctx,
3109 : &parm_table[i].def.svalue,
3110 260480 : *(char **)lp_parm_ptr(
3111 : NULL, &parm_table[i]));
3112 260480 : if (parm_table[i].def.svalue == NULL) {
3113 0 : smb_panic("lpcfg_string_set() failed");
3114 : }
3115 259840 : break;
3116 356125 : case P_BOOL:
3117 : case P_BOOLREV:
3118 357000 : parm_table[i].def.bvalue =
3119 356125 : *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3120 356125 : break;
3121 2035 : case P_CHAR:
3122 2040 : parm_table[i].def.cvalue =
3123 2035 : *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3124 2035 : break;
3125 280830 : case P_INTEGER:
3126 : case P_OCTAL:
3127 : case P_ENUM:
3128 : case P_BYTES:
3129 281520 : parm_table[i].def.ivalue =
3130 280830 : *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3131 280830 : break;
3132 : }
3133 : }
3134 :
3135 2151 : for (parm=Globals.param_opt; parm; parm=parm->next) {
3136 116 : if (!(parm->priority & FLAG_CMDLINE)) {
3137 9 : parm->priority |= FLAG_DEFAULT;
3138 : }
3139 : }
3140 :
3141 2035 : for (parm=sDefault.param_opt; parm; parm=parm->next) {
3142 0 : if (!(parm->priority & FLAG_CMDLINE)) {
3143 0 : parm->priority |= FLAG_DEFAULT;
3144 : }
3145 : }
3146 :
3147 2035 : defaults_saved = true;
3148 2035 : }
3149 :
3150 : /***********************************************************
3151 : If we should send plaintext/LANMAN passwords in the client
3152 : ************************************************************/
3153 :
3154 49106 : static void set_allowed_client_auth(void)
3155 : {
3156 49106 : if (Globals.client_ntlmv2_auth) {
3157 48710 : Globals.client_lanman_auth = false;
3158 : }
3159 49106 : if (!Globals.client_lanman_auth) {
3160 48716 : Globals.client_plaintext_auth = false;
3161 : }
3162 48981 : }
3163 :
3164 : /***************************************************************************
3165 : JRA.
3166 : The following code allows smbd to read a user defined share file.
3167 : Yes, this is my intent. Yes, I'm comfortable with that...
3168 :
3169 : THE FOLLOWING IS SECURITY CRITICAL CODE.
3170 :
3171 : It washes your clothes, it cleans your house, it guards you while you sleep...
3172 : Do not f%^k with it....
3173 : ***************************************************************************/
3174 :
3175 : #define MAX_USERSHARE_FILE_SIZE (10*1024)
3176 :
3177 : /***************************************************************************
3178 : Check allowed stat state of a usershare file.
3179 : Ensure we print out who is dicking with us so the admin can
3180 : get their sorry ass fired.
3181 : ***************************************************************************/
3182 :
3183 4 : static bool check_usershare_stat(const char *fname,
3184 : const SMB_STRUCT_STAT *psbuf)
3185 : {
3186 4 : if (!S_ISREG(psbuf->st_ex_mode)) {
3187 0 : DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3188 : "not a regular file\n",
3189 : fname, (unsigned int)psbuf->st_ex_uid ));
3190 0 : return false;
3191 : }
3192 :
3193 : /* Ensure this doesn't have the other write bit set. */
3194 4 : if (psbuf->st_ex_mode & S_IWOTH) {
3195 0 : DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3196 : "public write. Refusing to allow as a usershare file.\n",
3197 : fname, (unsigned int)psbuf->st_ex_uid ));
3198 0 : return false;
3199 : }
3200 :
3201 : /* Should be 10k or less. */
3202 4 : if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
3203 0 : DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3204 : "too large (%u) to be a user share file.\n",
3205 : fname, (unsigned int)psbuf->st_ex_uid,
3206 : (unsigned int)psbuf->st_ex_size ));
3207 0 : return false;
3208 : }
3209 :
3210 4 : return true;
3211 : }
3212 :
3213 : /***************************************************************************
3214 : Parse the contents of a usershare file.
3215 : ***************************************************************************/
3216 :
3217 4 : enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
3218 : SMB_STRUCT_STAT *psbuf,
3219 : const char *servicename,
3220 : int snum,
3221 : char **lines,
3222 : int numlines,
3223 : char **pp_sharepath,
3224 : char **pp_comment,
3225 : char **pp_cp_servicename,
3226 : struct security_descriptor **ppsd,
3227 : bool *pallow_guest)
3228 : {
3229 4 : const char **prefixallowlist = lp_usershare_prefix_allow_list();
3230 4 : const char **prefixdenylist = lp_usershare_prefix_deny_list();
3231 0 : int us_vers;
3232 0 : DIR *dp;
3233 0 : SMB_STRUCT_STAT sbuf;
3234 4 : char *sharepath = NULL;
3235 4 : char *comment = NULL;
3236 :
3237 4 : *pp_sharepath = NULL;
3238 4 : *pp_comment = NULL;
3239 :
3240 4 : *pallow_guest = false;
3241 :
3242 4 : if (numlines < 4) {
3243 0 : return USERSHARE_MALFORMED_FILE;
3244 : }
3245 :
3246 4 : if (strcmp(lines[0], "#VERSION 1") == 0) {
3247 0 : us_vers = 1;
3248 4 : } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3249 4 : us_vers = 2;
3250 4 : if (numlines < 5) {
3251 0 : return USERSHARE_MALFORMED_FILE;
3252 : }
3253 : } else {
3254 0 : return USERSHARE_BAD_VERSION;
3255 : }
3256 :
3257 4 : if (strncmp(lines[1], "path=", 5) != 0) {
3258 0 : return USERSHARE_MALFORMED_PATH;
3259 : }
3260 :
3261 4 : sharepath = talloc_strdup(ctx, &lines[1][5]);
3262 4 : if (!sharepath) {
3263 0 : return USERSHARE_POSIX_ERR;
3264 : }
3265 4 : trim_string(sharepath, " ", " ");
3266 :
3267 4 : if (strncmp(lines[2], "comment=", 8) != 0) {
3268 0 : return USERSHARE_MALFORMED_COMMENT_DEF;
3269 : }
3270 :
3271 4 : comment = talloc_strdup(ctx, &lines[2][8]);
3272 4 : if (!comment) {
3273 0 : return USERSHARE_POSIX_ERR;
3274 : }
3275 4 : trim_string(comment, " ", " ");
3276 4 : trim_char(comment, '"', '"');
3277 :
3278 4 : if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3279 0 : return USERSHARE_MALFORMED_ACL_DEF;
3280 : }
3281 :
3282 4 : if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3283 0 : return USERSHARE_ACL_ERR;
3284 : }
3285 :
3286 4 : if (us_vers == 2) {
3287 4 : if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3288 0 : return USERSHARE_MALFORMED_ACL_DEF;
3289 : }
3290 4 : if (lines[4][9] == 'y') {
3291 0 : *pallow_guest = true;
3292 : }
3293 :
3294 : /* Backwards compatible extension to file version #2. */
3295 4 : if (numlines > 5) {
3296 4 : if (strncmp(lines[5], "sharename=", 10) != 0) {
3297 0 : return USERSHARE_MALFORMED_SHARENAME_DEF;
3298 : }
3299 4 : if (!strequal(&lines[5][10], servicename)) {
3300 0 : return USERSHARE_BAD_SHARENAME;
3301 : }
3302 4 : *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3303 4 : if (!*pp_cp_servicename) {
3304 0 : return USERSHARE_POSIX_ERR;
3305 : }
3306 : }
3307 : }
3308 :
3309 4 : if (*pp_cp_servicename == NULL) {
3310 0 : *pp_cp_servicename = talloc_strdup(ctx, servicename);
3311 0 : if (!*pp_cp_servicename) {
3312 0 : return USERSHARE_POSIX_ERR;
3313 : }
3314 : }
3315 :
3316 4 : if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3317 : /* Path didn't change, no checks needed. */
3318 0 : *pp_sharepath = sharepath;
3319 0 : *pp_comment = comment;
3320 0 : return USERSHARE_OK;
3321 : }
3322 :
3323 : /* The path *must* be absolute. */
3324 4 : if (sharepath[0] != '/') {
3325 0 : DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3326 : servicename, sharepath));
3327 0 : return USERSHARE_PATH_NOT_ABSOLUTE;
3328 : }
3329 :
3330 : /* If there is a usershare prefix deny list ensure one of these paths
3331 : doesn't match the start of the user given path. */
3332 4 : if (prefixdenylist) {
3333 : int i;
3334 0 : for ( i=0; prefixdenylist[i]; i++ ) {
3335 0 : DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3336 : servicename, i, prefixdenylist[i], sharepath ));
3337 0 : if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3338 0 : DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3339 : "usershare prefix deny list entries.\n",
3340 : servicename, sharepath));
3341 0 : return USERSHARE_PATH_IS_DENIED;
3342 : }
3343 : }
3344 : }
3345 :
3346 : /* If there is a usershare prefix allow list ensure one of these paths
3347 : does match the start of the user given path. */
3348 :
3349 4 : if (prefixallowlist) {
3350 : int i;
3351 4 : for ( i=0; prefixallowlist[i]; i++ ) {
3352 4 : DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3353 : servicename, i, prefixallowlist[i], sharepath ));
3354 4 : if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3355 4 : break;
3356 : }
3357 : }
3358 4 : if (prefixallowlist[i] == NULL) {
3359 0 : DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3360 : "usershare prefix allow list entries.\n",
3361 : servicename, sharepath));
3362 0 : return USERSHARE_PATH_NOT_ALLOWED;
3363 : }
3364 : }
3365 :
3366 : /* Ensure this is pointing to a directory. */
3367 4 : dp = opendir(sharepath);
3368 :
3369 4 : if (!dp) {
3370 0 : DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3371 : servicename, sharepath));
3372 0 : return USERSHARE_PATH_NOT_DIRECTORY;
3373 : }
3374 :
3375 : /* Ensure the owner of the usershare file has permission to share
3376 : this directory. */
3377 :
3378 4 : if (sys_stat(sharepath, &sbuf, false) == -1) {
3379 0 : DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3380 : servicename, sharepath, strerror(errno) ));
3381 0 : closedir(dp);
3382 0 : return USERSHARE_POSIX_ERR;
3383 : }
3384 :
3385 4 : closedir(dp);
3386 :
3387 4 : if (!S_ISDIR(sbuf.st_ex_mode)) {
3388 0 : DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3389 : servicename, sharepath ));
3390 0 : return USERSHARE_PATH_NOT_DIRECTORY;
3391 : }
3392 :
3393 : /* Check if sharing is restricted to owner-only. */
3394 : /* psbuf is the stat of the usershare definition file,
3395 : sbuf is the stat of the target directory to be shared. */
3396 :
3397 4 : if (lp_usershare_owner_only()) {
3398 : /* root can share anything. */
3399 4 : if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3400 0 : return USERSHARE_PATH_NOT_ALLOWED;
3401 : }
3402 : }
3403 :
3404 4 : *pp_sharepath = sharepath;
3405 4 : *pp_comment = comment;
3406 4 : return USERSHARE_OK;
3407 : }
3408 :
3409 : /***************************************************************************
3410 : Deal with a usershare file.
3411 : Returns:
3412 : >= 0 - snum
3413 : -1 - Bad name, invalid contents.
3414 : - service name already existed and not a usershare, problem
3415 : with permissions to share directory etc.
3416 : ***************************************************************************/
3417 :
3418 10 : static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3419 : {
3420 0 : SMB_STRUCT_STAT sbuf;
3421 0 : SMB_STRUCT_STAT lsbuf;
3422 10 : char *fname = NULL;
3423 10 : char *sharepath = NULL;
3424 10 : char *comment = NULL;
3425 10 : char *cp_service_name = NULL;
3426 10 : char **lines = NULL;
3427 10 : int numlines = 0;
3428 10 : int fd = -1;
3429 10 : int iService = -1;
3430 10 : TALLOC_CTX *ctx = talloc_stackframe();
3431 10 : struct security_descriptor *psd = NULL;
3432 10 : bool guest_ok = false;
3433 10 : char *canon_name = NULL;
3434 10 : bool added_service = false;
3435 10 : int ret = -1;
3436 0 : NTSTATUS status;
3437 :
3438 : /* Ensure share name doesn't contain invalid characters. */
3439 10 : if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3440 0 : DEBUG(0,("process_usershare_file: share name %s contains "
3441 : "invalid characters (any of %s)\n",
3442 : file_name, INVALID_SHARENAME_CHARS ));
3443 0 : goto out;
3444 : }
3445 :
3446 10 : canon_name = canonicalize_servicename(ctx, file_name);
3447 10 : if (!canon_name) {
3448 0 : goto out;
3449 : }
3450 :
3451 10 : fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3452 10 : if (!fname) {
3453 0 : goto out;
3454 : }
3455 :
3456 : /* Minimize the race condition by doing an lstat before we
3457 : open and fstat. Ensure this isn't a symlink link. */
3458 :
3459 10 : if (sys_lstat(fname, &lsbuf, false) != 0) {
3460 8 : if (errno == ENOENT) {
3461 : /* Unknown share requested. Just ignore. */
3462 8 : goto out;
3463 : }
3464 : /* Only log messages for meaningful problems. */
3465 0 : DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3466 : fname, strerror(errno) ));
3467 0 : goto out;
3468 : }
3469 :
3470 : /* This must be a regular file, not a symlink, directory or
3471 : other strange filetype. */
3472 2 : if (!check_usershare_stat(fname, &lsbuf)) {
3473 0 : goto out;
3474 : }
3475 :
3476 : {
3477 0 : TDB_DATA data;
3478 :
3479 2 : status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3480 : canon_name, &data);
3481 :
3482 2 : iService = -1;
3483 :
3484 2 : if (NT_STATUS_IS_OK(status) &&
3485 0 : (data.dptr != NULL) &&
3486 0 : (data.dsize == sizeof(iService))) {
3487 0 : memcpy(&iService, data.dptr, sizeof(iService));
3488 : }
3489 : }
3490 :
3491 2 : if (iService != -1 &&
3492 0 : timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3493 : &lsbuf.st_ex_mtime) == 0) {
3494 : /* Nothing changed - Mark valid and return. */
3495 0 : DEBUG(10,("process_usershare_file: service %s not changed.\n",
3496 : canon_name ));
3497 0 : ServicePtrs[iService]->usershare = USERSHARE_VALID;
3498 0 : ret = iService;
3499 0 : goto out;
3500 : }
3501 :
3502 : /* Try and open the file read only - no symlinks allowed. */
3503 : #ifdef O_NOFOLLOW
3504 2 : fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3505 : #else
3506 : fd = open(fname, O_RDONLY, 0);
3507 : #endif
3508 :
3509 2 : if (fd == -1) {
3510 0 : DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3511 : fname, strerror(errno) ));
3512 0 : goto out;
3513 : }
3514 :
3515 : /* Now fstat to be *SURE* it's a regular file. */
3516 2 : if (sys_fstat(fd, &sbuf, false) != 0) {
3517 0 : close(fd);
3518 0 : DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3519 : fname, strerror(errno) ));
3520 0 : goto out;
3521 : }
3522 :
3523 : /* Is it the same dev/inode as was lstated ? */
3524 2 : if (!check_same_stat(&lsbuf, &sbuf)) {
3525 0 : close(fd);
3526 0 : DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3527 : "Symlink spoofing going on ?\n", fname ));
3528 0 : goto out;
3529 : }
3530 :
3531 : /* This must be a regular file, not a symlink, directory or
3532 : other strange filetype. */
3533 2 : if (!check_usershare_stat(fname, &sbuf)) {
3534 0 : close(fd);
3535 0 : goto out;
3536 : }
3537 :
3538 2 : lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3539 :
3540 2 : close(fd);
3541 2 : if (lines == NULL) {
3542 0 : DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3543 : fname, (unsigned int)sbuf.st_ex_uid ));
3544 0 : goto out;
3545 : }
3546 :
3547 2 : if (parse_usershare_file(ctx, &sbuf, file_name,
3548 : iService, lines, numlines, &sharepath,
3549 : &comment, &cp_service_name,
3550 : &psd, &guest_ok) != USERSHARE_OK) {
3551 0 : goto out;
3552 : }
3553 :
3554 : /* Everything ok - add the service possibly using a template. */
3555 2 : if (iService < 0) {
3556 2 : const struct loadparm_service *sp = &sDefault;
3557 2 : if (snum_template != -1) {
3558 0 : sp = ServicePtrs[snum_template];
3559 : }
3560 :
3561 2 : if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3562 0 : DEBUG(0, ("process_usershare_file: Failed to add "
3563 : "new service %s\n", cp_service_name));
3564 0 : goto out;
3565 : }
3566 :
3567 2 : added_service = true;
3568 :
3569 : /* Read only is controlled by usershare ACL below. */
3570 2 : ServicePtrs[iService]->read_only = false;
3571 : }
3572 :
3573 : /* Write the ACL of the new/modified share. */
3574 2 : status = set_share_security(canon_name, psd);
3575 2 : if (!NT_STATUS_IS_OK(status)) {
3576 0 : DEBUG(0, ("process_usershare_file: Failed to set share "
3577 : "security for user share %s\n",
3578 : canon_name ));
3579 0 : goto out;
3580 : }
3581 :
3582 : /* If from a template it may be marked invalid. */
3583 2 : ServicePtrs[iService]->valid = true;
3584 :
3585 : /* Set the service as a valid usershare. */
3586 2 : ServicePtrs[iService]->usershare = USERSHARE_VALID;
3587 :
3588 : /* Set guest access. */
3589 2 : if (lp_usershare_allow_guests()) {
3590 2 : ServicePtrs[iService]->guest_ok = guest_ok;
3591 : }
3592 :
3593 : /* And note when it was loaded. */
3594 2 : ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3595 2 : lpcfg_string_set(ServicePtrs[iService], &ServicePtrs[iService]->path,
3596 : sharepath);
3597 2 : lpcfg_string_set(ServicePtrs[iService],
3598 2 : &ServicePtrs[iService]->comment, comment);
3599 :
3600 2 : ret = iService;
3601 :
3602 10 : out:
3603 :
3604 10 : if (ret == -1 && iService != -1 && added_service) {
3605 0 : lp_remove_service(iService);
3606 : }
3607 :
3608 10 : TALLOC_FREE(lines);
3609 10 : TALLOC_FREE(ctx);
3610 10 : return ret;
3611 : }
3612 :
3613 : /***************************************************************************
3614 : Checks if a usershare entry has been modified since last load.
3615 : ***************************************************************************/
3616 :
3617 4 : static bool usershare_exists(int iService, struct timespec *last_mod)
3618 : {
3619 0 : SMB_STRUCT_STAT lsbuf;
3620 4 : const char *usersharepath = Globals.usershare_path;
3621 0 : char *fname;
3622 :
3623 4 : fname = talloc_asprintf(talloc_tos(),
3624 : "%s/%s",
3625 : usersharepath,
3626 4 : ServicePtrs[iService]->szService);
3627 4 : if (fname == NULL) {
3628 0 : return false;
3629 : }
3630 :
3631 4 : if (sys_lstat(fname, &lsbuf, false) != 0) {
3632 0 : TALLOC_FREE(fname);
3633 0 : return false;
3634 : }
3635 :
3636 4 : if (!S_ISREG(lsbuf.st_ex_mode)) {
3637 0 : TALLOC_FREE(fname);
3638 0 : return false;
3639 : }
3640 :
3641 4 : TALLOC_FREE(fname);
3642 4 : *last_mod = lsbuf.st_ex_mtime;
3643 4 : return true;
3644 : }
3645 :
3646 10 : static bool usershare_directory_is_root(uid_t uid)
3647 : {
3648 10 : if (uid == 0) {
3649 0 : return true;
3650 : }
3651 :
3652 10 : if (uid_wrapper_enabled()) {
3653 10 : return true;
3654 : }
3655 :
3656 0 : return false;
3657 : }
3658 :
3659 : /***************************************************************************
3660 : Load a usershare service by name. Returns a valid servicenumber or -1.
3661 : ***************************************************************************/
3662 :
3663 1435 : int load_usershare_service(const char *servicename)
3664 : {
3665 10 : SMB_STRUCT_STAT sbuf;
3666 1435 : const char *usersharepath = Globals.usershare_path;
3667 1435 : int max_user_shares = Globals.usershare_max_shares;
3668 1435 : int snum_template = -1;
3669 :
3670 1435 : if (servicename[0] == '\0') {
3671 : /* Invalid service name. */
3672 0 : return -1;
3673 : }
3674 :
3675 1435 : if (*usersharepath == 0 || max_user_shares == 0) {
3676 1415 : return -1;
3677 : }
3678 :
3679 10 : if (sys_stat(usersharepath, &sbuf, false) != 0) {
3680 0 : DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3681 : usersharepath, strerror(errno) ));
3682 0 : return -1;
3683 : }
3684 :
3685 10 : if (!S_ISDIR(sbuf.st_ex_mode)) {
3686 0 : DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3687 : usersharepath ));
3688 0 : return -1;
3689 : }
3690 :
3691 : /*
3692 : * This directory must be owned by root, and have the 't' bit set.
3693 : * It also must not be writable by "other".
3694 : */
3695 :
3696 : #ifdef S_ISVTX
3697 10 : if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
3698 10 : !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3699 : #else
3700 : if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
3701 : (sbuf.st_ex_mode & S_IWOTH)) {
3702 : #endif
3703 0 : DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3704 : "or does not have the sticky bit 't' set or is writable by anyone.\n",
3705 : usersharepath ));
3706 0 : return -1;
3707 : }
3708 :
3709 : /* Ensure the template share exists if it's set. */
3710 10 : if (Globals.usershare_template_share[0]) {
3711 : /* We can't use lp_servicenumber here as we are recommending that
3712 : template shares have -valid=false set. */
3713 0 : for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3714 0 : if (ServicePtrs[snum_template]->szService &&
3715 0 : strequal(ServicePtrs[snum_template]->szService,
3716 0 : Globals.usershare_template_share)) {
3717 0 : break;
3718 : }
3719 : }
3720 :
3721 0 : if (snum_template == -1) {
3722 0 : DEBUG(0,("load_usershare_service: usershare template share %s "
3723 : "does not exist.\n",
3724 : Globals.usershare_template_share ));
3725 0 : return -1;
3726 : }
3727 : }
3728 :
3729 10 : return process_usershare_file(usersharepath, servicename, snum_template);
3730 : }
3731 :
3732 : /***************************************************************************
3733 : Load all user defined shares from the user share directory.
3734 : We only do this if we're enumerating the share list.
3735 : This is the function that can delete usershares that have
3736 : been removed.
3737 : ***************************************************************************/
3738 :
3739 204 : int load_usershare_shares(struct smbd_server_connection *sconn,
3740 : bool (*snumused) (struct smbd_server_connection *, int))
3741 : {
3742 0 : DIR *dp;
3743 0 : SMB_STRUCT_STAT sbuf;
3744 0 : struct dirent *de;
3745 204 : int num_usershares = 0;
3746 204 : int max_user_shares = Globals.usershare_max_shares;
3747 0 : unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3748 204 : unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3749 204 : unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3750 0 : int iService;
3751 204 : int snum_template = -1;
3752 204 : const char *usersharepath = Globals.usershare_path;
3753 204 : int ret = lp_numservices();
3754 0 : TALLOC_CTX *tmp_ctx;
3755 :
3756 204 : if (max_user_shares == 0 || *usersharepath == '\0') {
3757 185 : return lp_numservices();
3758 : }
3759 :
3760 19 : if (sys_stat(usersharepath, &sbuf, false) != 0) {
3761 0 : DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3762 : usersharepath, strerror(errno) ));
3763 0 : return ret;
3764 : }
3765 :
3766 : /*
3767 : * This directory must be owned by root, and have the 't' bit set.
3768 : * It also must not be writable by "other".
3769 : */
3770 :
3771 : #ifdef S_ISVTX
3772 19 : if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3773 : #else
3774 : if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3775 : #endif
3776 19 : DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3777 : "or does not have the sticky bit 't' set or is writable by anyone.\n",
3778 : usersharepath ));
3779 19 : return ret;
3780 : }
3781 :
3782 : /* Ensure the template share exists if it's set. */
3783 0 : if (Globals.usershare_template_share[0]) {
3784 : /* We can't use lp_servicenumber here as we are recommending that
3785 : template shares have -valid=false set. */
3786 0 : for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3787 0 : if (ServicePtrs[snum_template]->szService &&
3788 0 : strequal(ServicePtrs[snum_template]->szService,
3789 0 : Globals.usershare_template_share)) {
3790 0 : break;
3791 : }
3792 : }
3793 :
3794 0 : if (snum_template == -1) {
3795 0 : DEBUG(0,("load_usershare_shares: usershare template share %s "
3796 : "does not exist.\n",
3797 : Globals.usershare_template_share ));
3798 0 : return ret;
3799 : }
3800 : }
3801 :
3802 : /* Mark all existing usershares as pending delete. */
3803 0 : for (iService = iNumServices - 1; iService >= 0; iService--) {
3804 0 : if (VALID(iService) && ServicePtrs[iService]->usershare) {
3805 0 : ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3806 : }
3807 : }
3808 :
3809 0 : dp = opendir(usersharepath);
3810 0 : if (!dp) {
3811 0 : DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3812 : usersharepath, strerror(errno) ));
3813 0 : return ret;
3814 : }
3815 :
3816 0 : for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3817 0 : (de = readdir(dp));
3818 0 : num_dir_entries++ ) {
3819 0 : int r;
3820 0 : const char *n = de->d_name;
3821 :
3822 : /* Ignore . and .. */
3823 0 : if (*n == '.') {
3824 0 : if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3825 0 : continue;
3826 : }
3827 : }
3828 :
3829 0 : if (n[0] == ':') {
3830 : /* Temporary file used when creating a share. */
3831 0 : num_tmp_dir_entries++;
3832 : }
3833 :
3834 : /* Allow 20% tmp entries. */
3835 0 : if (num_tmp_dir_entries > allowed_tmp_entries) {
3836 0 : DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3837 : "in directory %s\n",
3838 : num_tmp_dir_entries, usersharepath));
3839 0 : break;
3840 : }
3841 :
3842 0 : r = process_usershare_file(usersharepath, n, snum_template);
3843 0 : if (r == 0) {
3844 : /* Update the services count. */
3845 0 : num_usershares++;
3846 0 : if (num_usershares >= max_user_shares) {
3847 0 : DEBUG(0,("load_usershare_shares: max user shares reached "
3848 : "on file %s in directory %s\n",
3849 : n, usersharepath ));
3850 0 : break;
3851 : }
3852 0 : } else if (r == -1) {
3853 0 : num_bad_dir_entries++;
3854 : }
3855 :
3856 : /* Allow 20% bad entries. */
3857 0 : if (num_bad_dir_entries > allowed_bad_entries) {
3858 0 : DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3859 : "in directory %s\n",
3860 : num_bad_dir_entries, usersharepath));
3861 0 : break;
3862 : }
3863 :
3864 : /* Allow 20% bad entries. */
3865 0 : if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3866 0 : DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3867 : "in directory %s\n",
3868 : num_dir_entries, usersharepath));
3869 0 : break;
3870 : }
3871 : }
3872 :
3873 0 : closedir(dp);
3874 :
3875 : /* Sweep through and delete any non-refreshed usershares that are
3876 : not currently in use. */
3877 0 : tmp_ctx = talloc_stackframe();
3878 0 : for (iService = iNumServices - 1; iService >= 0; iService--) {
3879 0 : if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3880 0 : const struct loadparm_substitution *lp_sub =
3881 0 : loadparm_s3_global_substitution();
3882 0 : char *servname;
3883 :
3884 0 : if (snumused && snumused(sconn, iService)) {
3885 0 : continue;
3886 : }
3887 :
3888 0 : servname = lp_servicename(tmp_ctx, lp_sub, iService);
3889 :
3890 : /* Remove from the share ACL db. */
3891 0 : DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3892 : servname ));
3893 0 : delete_share_security(servname);
3894 0 : free_service_byindex(iService);
3895 : }
3896 : }
3897 0 : talloc_free(tmp_ctx);
3898 :
3899 0 : return lp_numservices();
3900 : }
3901 :
3902 : /********************************************************
3903 : Destroy global resources allocated in this file
3904 : ********************************************************/
3905 :
3906 16982 : void gfree_loadparm(void)
3907 : {
3908 9 : int i;
3909 :
3910 16982 : free_file_list();
3911 :
3912 : /* Free resources allocated to services */
3913 :
3914 28612 : for ( i = 0; i < iNumServices; i++ ) {
3915 11630 : if ( VALID(i) ) {
3916 11630 : free_service_byindex(i);
3917 : }
3918 : }
3919 :
3920 16982 : TALLOC_FREE( ServicePtrs );
3921 16982 : iNumServices = 0;
3922 :
3923 : /* Now release all resources allocated to global
3924 : parameters and the default service */
3925 :
3926 16982 : free_global_parameters();
3927 16982 : }
3928 :
3929 :
3930 : /***************************************************************************
3931 : Allow client apps to specify that they are a client
3932 : ***************************************************************************/
3933 18865 : static void lp_set_in_client(bool b)
3934 : {
3935 18865 : in_client = b;
3936 18857 : }
3937 :
3938 :
3939 : /***************************************************************************
3940 : Determine if we're running in a client app
3941 : ***************************************************************************/
3942 49106 : static bool lp_is_in_client(void)
3943 : {
3944 49106 : return in_client;
3945 : }
3946 :
3947 3993 : static void lp_enforce_ad_dc_settings(void)
3948 : {
3949 3993 : lp_do_parameter(GLOBAL_SECTION_SNUM, "passdb backend", "samba_dsdb");
3950 3993 : lp_do_parameter(GLOBAL_SECTION_SNUM,
3951 : "winbindd:use external pipes", "true");
3952 3993 : lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:default", "external");
3953 3993 : lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:svcctl", "embedded");
3954 3993 : lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:srvsvc", "embedded");
3955 3993 : lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:eventlog", "embedded");
3956 3993 : lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:ntsvcs", "embedded");
3957 3993 : lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:winreg", "embedded");
3958 3993 : lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:spoolss", "embedded");
3959 3993 : lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_daemon:spoolssd", "embedded");
3960 3993 : lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:tcpip", "no");
3961 3993 : }
3962 :
3963 : /***************************************************************************
3964 : Load the services array from the services file. Return true on success,
3965 : false on failure.
3966 : ***************************************************************************/
3967 :
3968 49106 : static bool lp_load_ex(const char *pszFname,
3969 : bool global_only,
3970 : bool save_defaults,
3971 : bool add_ipc,
3972 : bool reinit_globals,
3973 : bool allow_include_registry,
3974 : bool load_all_shares)
3975 : {
3976 49106 : char *n2 = NULL;
3977 125 : bool bRetval;
3978 49106 : TALLOC_CTX *frame = talloc_stackframe();
3979 125 : struct loadparm_context *lp_ctx;
3980 125 : int max_protocol, min_protocol;
3981 :
3982 49106 : DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3983 :
3984 49106 : bInGlobalSection = true;
3985 49106 : bGlobalOnly = global_only;
3986 49106 : bAllowIncludeRegistry = allow_include_registry;
3987 49106 : sDefault = _sDefault;
3988 :
3989 49106 : lp_ctx = setup_lp_context(talloc_tos());
3990 :
3991 49106 : loadparm_s3_init_globals(lp_ctx, reinit_globals);
3992 :
3993 49106 : free_file_list();
3994 :
3995 49106 : if (save_defaults) {
3996 2035 : init_locals();
3997 2035 : lp_save_defaults();
3998 : }
3999 :
4000 49106 : if (!reinit_globals) {
4001 2422 : free_param_opts(&Globals.param_opt);
4002 2422 : apply_lp_set_cmdline();
4003 : }
4004 :
4005 49106 : lp_do_parameter(-1, "idmap config * : backend", Globals.idmap_backend);
4006 :
4007 : /* We get sections first, so have to start 'behind' to make up */
4008 49106 : iServiceIndex = -1;
4009 :
4010 49106 : if (lp_config_backend_is_file()) {
4011 49106 : n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4012 : get_current_user_info_domain(),
4013 : pszFname);
4014 49106 : if (!n2) {
4015 0 : smb_panic("lp_load_ex: out of memory");
4016 : }
4017 :
4018 49106 : add_to_file_list(NULL, &file_lists, pszFname, n2);
4019 :
4020 49106 : bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
4021 49106 : TALLOC_FREE(n2);
4022 :
4023 : /* finish up the last section */
4024 49106 : DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4025 49106 : if (bRetval) {
4026 48890 : if (iServiceIndex >= 0) {
4027 26903 : bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
4028 : }
4029 : }
4030 :
4031 49106 : if (lp_config_backend_is_registry()) {
4032 0 : bool ok;
4033 : /* config backend changed to registry in config file */
4034 : /*
4035 : * We need to use this extra global variable here to
4036 : * survive restart: init_globals uses this as a default
4037 : * for config_backend. Otherwise, init_globals would
4038 : * send us into an endless loop here.
4039 : */
4040 :
4041 0 : config_backend = CONFIG_BACKEND_REGISTRY;
4042 : /* start over */
4043 0 : DEBUG(1, ("lp_load_ex: changing to config backend "
4044 : "registry\n"));
4045 0 : loadparm_s3_init_globals(lp_ctx, true);
4046 :
4047 0 : TALLOC_FREE(lp_ctx);
4048 :
4049 0 : lp_kill_all_services();
4050 0 : ok = lp_load_ex(pszFname, global_only, save_defaults,
4051 : add_ipc, reinit_globals,
4052 : allow_include_registry,
4053 : load_all_shares);
4054 0 : TALLOC_FREE(frame);
4055 0 : return ok;
4056 : }
4057 0 : } else if (lp_config_backend_is_registry()) {
4058 0 : bRetval = process_registry_globals();
4059 : } else {
4060 0 : DEBUG(0, ("Illegal config backend given: %d\n",
4061 : lp_config_backend()));
4062 0 : bRetval = false;
4063 : }
4064 :
4065 49106 : if (bRetval && lp_registry_shares()) {
4066 28275 : if (load_all_shares) {
4067 86 : bRetval = process_registry_shares();
4068 : } else {
4069 28189 : bRetval = reload_registry_shares();
4070 : }
4071 : }
4072 :
4073 : {
4074 125 : const struct loadparm_substitution *lp_sub =
4075 49106 : loadparm_s3_global_substitution();
4076 49106 : char *serv = lp_auto_services(talloc_tos(), lp_sub);
4077 49106 : lp_add_auto_services(serv);
4078 49106 : TALLOC_FREE(serv);
4079 : }
4080 :
4081 49106 : if (add_ipc) {
4082 : /* When 'restrict anonymous = 2' guest connections to ipc$
4083 : are denied */
4084 23303 : lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4085 23303 : if ( lp_enable_asu_support() ) {
4086 0 : lp_add_ipc("ADMIN$", false);
4087 : }
4088 : }
4089 :
4090 49106 : set_allowed_client_auth();
4091 :
4092 49106 : if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
4093 0 : DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4094 : lp_password_server()));
4095 : }
4096 :
4097 49106 : b_loaded = true;
4098 :
4099 : /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4100 : /* if we_are_a_wins_server is true and we are in the client */
4101 49106 : if (lp_is_in_client() && Globals.we_are_a_wins_server) {
4102 1325 : lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4103 : }
4104 :
4105 49106 : init_iconv();
4106 :
4107 49106 : fault_configure(smb_panic_s3);
4108 :
4109 : /*
4110 : * We run this check once the whole smb.conf is parsed, to
4111 : * force some settings for the standard way a AD DC is
4112 : * operated. We may change these as our code evolves, which
4113 : * is why we force these settings.
4114 : */
4115 49106 : if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4116 3993 : lp_enforce_ad_dc_settings();
4117 : }
4118 :
4119 49106 : bAllowIncludeRegistry = true;
4120 :
4121 : /* Check if command line max protocol < min protocol, if so
4122 : * report a warning to the user.
4123 : */
4124 49106 : max_protocol = lp_client_max_protocol();
4125 49106 : min_protocol = lp_client_min_protocol();
4126 49106 : if (max_protocol < min_protocol) {
4127 0 : const char *max_protocolp, *min_protocolp;
4128 0 : max_protocolp = lpcfg_get_smb_protocol(max_protocol);
4129 0 : min_protocolp = lpcfg_get_smb_protocol(min_protocol);
4130 0 : DBG_ERR("Max protocol %s is less than min protocol %s.\n",
4131 : max_protocolp, min_protocolp);
4132 : }
4133 :
4134 49106 : TALLOC_FREE(frame);
4135 48981 : return (bRetval);
4136 : }
4137 :
4138 47071 : static bool lp_load(const char *pszFname,
4139 : bool global_only,
4140 : bool save_defaults,
4141 : bool add_ipc,
4142 : bool reinit_globals)
4143 : {
4144 47071 : return lp_load_ex(pszFname,
4145 : global_only,
4146 : save_defaults,
4147 : add_ipc,
4148 : reinit_globals,
4149 : true, /* allow_include_registry */
4150 : false); /* load_all_shares*/
4151 : }
4152 :
4153 3 : bool lp_load_initial_only(const char *pszFname)
4154 : {
4155 3 : return lp_load_ex(pszFname,
4156 : true, /* global only */
4157 : true, /* save_defaults */
4158 : false, /* add_ipc */
4159 : true, /* reinit_globals */
4160 : false, /* allow_include_registry */
4161 : false); /* load_all_shares*/
4162 : }
4163 :
4164 : /**
4165 : * most common lp_load wrapper, loading only the globals
4166 : *
4167 : * If this is used in a daemon or client utility it should be called
4168 : * after processing popt.
4169 : */
4170 21346 : bool lp_load_global(const char *file_name)
4171 : {
4172 21346 : return lp_load(file_name,
4173 : true, /* global_only */
4174 : false, /* save_defaults */
4175 : false, /* add_ipc */
4176 : true); /* reinit_globals */
4177 : }
4178 :
4179 : /**
4180 : * The typical lp_load wrapper with shares, loads global and
4181 : * shares, including IPC, but does not force immediate
4182 : * loading of all shares from registry.
4183 : */
4184 23303 : bool lp_load_with_shares(const char *file_name)
4185 : {
4186 23303 : return lp_load(file_name,
4187 : false, /* global_only */
4188 : false, /* save_defaults */
4189 : true, /* add_ipc */
4190 : true); /* reinit_globals */
4191 : }
4192 :
4193 : /**
4194 : * lp_load wrapper, especially for clients
4195 : */
4196 18707 : bool lp_load_client(const char *file_name)
4197 : {
4198 18707 : lp_set_in_client(true);
4199 :
4200 18707 : return lp_load_global(file_name);
4201 : }
4202 :
4203 : /**
4204 : * lp_load wrapper, loading only globals, but intended
4205 : * for subsequent calls, not reinitializing the globals
4206 : * to default values
4207 : */
4208 158 : bool lp_load_global_no_reinit(const char *file_name)
4209 : {
4210 158 : return lp_load(file_name,
4211 : true, /* global_only */
4212 : false, /* save_defaults */
4213 : false, /* add_ipc */
4214 : false); /* reinit_globals */
4215 : }
4216 :
4217 : /**
4218 : * lp_load wrapper, loading globals and shares,
4219 : * intended for subsequent calls, i.e. not reinitializing
4220 : * the globals to default values.
4221 : */
4222 2264 : bool lp_load_no_reinit(const char *file_name)
4223 : {
4224 2264 : return lp_load(file_name,
4225 : false, /* global_only */
4226 : false, /* save_defaults */
4227 : false, /* add_ipc */
4228 : false); /* reinit_globals */
4229 : }
4230 :
4231 :
4232 : /**
4233 : * lp_load wrapper, especially for clients, no reinitialization
4234 : */
4235 158 : bool lp_load_client_no_reinit(const char *file_name)
4236 : {
4237 158 : lp_set_in_client(true);
4238 :
4239 158 : return lp_load_global_no_reinit(file_name);
4240 : }
4241 :
4242 2032 : bool lp_load_with_registry_shares(const char *pszFname)
4243 : {
4244 2032 : return lp_load_ex(pszFname,
4245 : false, /* global_only */
4246 : true, /* save_defaults */
4247 : false, /* add_ipc */
4248 : true, /* reinit_globals */
4249 : true, /* allow_include_registry */
4250 : true); /* load_all_shares*/
4251 : }
4252 :
4253 : /***************************************************************************
4254 : Return the max number of services.
4255 : ***************************************************************************/
4256 :
4257 2470 : int lp_numservices(void)
4258 : {
4259 2470 : return (iNumServices);
4260 : }
4261 :
4262 : /***************************************************************************
4263 : Display the contents of the services array in human-readable form.
4264 : ***************************************************************************/
4265 :
4266 520 : void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4267 : {
4268 0 : int iService;
4269 0 : struct loadparm_context *lp_ctx;
4270 :
4271 520 : if (show_defaults)
4272 0 : defaults_saved = false;
4273 :
4274 520 : lp_ctx = setup_lp_context(talloc_tos());
4275 520 : if (lp_ctx == NULL) {
4276 0 : return;
4277 : }
4278 :
4279 520 : lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
4280 :
4281 520 : lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
4282 :
4283 766 : for (iService = 0; iService < maxtoprint; iService++) {
4284 246 : fprintf(f,"\n");
4285 246 : lp_dump_one(f, show_defaults, iService);
4286 : }
4287 520 : TALLOC_FREE(lp_ctx);
4288 : }
4289 :
4290 : /***************************************************************************
4291 : Display the contents of one service in human-readable form.
4292 : ***************************************************************************/
4293 :
4294 246 : void lp_dump_one(FILE * f, bool show_defaults, int snum)
4295 : {
4296 246 : if (VALID(snum)) {
4297 246 : if (ServicePtrs[snum]->szService[0] == '\0')
4298 0 : return;
4299 246 : lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
4300 : flags_list, show_defaults);
4301 : }
4302 : }
4303 :
4304 : /***************************************************************************
4305 : Return the number of the service with the given name, or -1 if it doesn't
4306 : exist. Note that this is a DIFFERENT ANIMAL from the internal function
4307 : getservicebyname()! This works ONLY if all services have been loaded, and
4308 : does not copy the found service.
4309 : ***************************************************************************/
4310 :
4311 284929 : int lp_servicenumber(const char *pszServiceName)
4312 : {
4313 3431 : int iService;
4314 3431 : fstring serviceName;
4315 :
4316 284929 : if (!pszServiceName) {
4317 32 : return GLOBAL_SECTION_SNUM;
4318 : }
4319 :
4320 14376270 : for (iService = iNumServices - 1; iService >= 0; iService--) {
4321 14278277 : if (VALID(iService) && ServicePtrs[iService]->szService) {
4322 : /*
4323 : * The substitution here is used to support %U in
4324 : * service names
4325 : */
4326 14237642 : fstrcpy(serviceName, ServicePtrs[iService]->szService);
4327 14237642 : standard_sub_basic(get_current_username(),
4328 : get_current_user_info_domain(),
4329 : serviceName,sizeof(serviceName));
4330 14237642 : if (strequal(serviceName, pszServiceName)) {
4331 185170 : break;
4332 : }
4333 : }
4334 : }
4335 :
4336 284897 : if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4337 0 : struct timespec last_mod;
4338 :
4339 4 : if (!usershare_exists(iService, &last_mod)) {
4340 : /* Remove the share security tdb entry for it. */
4341 0 : delete_share_security(lp_const_servicename(iService));
4342 : /* Remove it from the array. */
4343 0 : free_service_byindex(iService);
4344 : /* Doesn't exist anymore. */
4345 0 : return GLOBAL_SECTION_SNUM;
4346 : }
4347 :
4348 : /* Has it been modified ? If so delete and reload. */
4349 4 : if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4350 : &last_mod) < 0) {
4351 : /* Remove it from the array. */
4352 0 : free_service_byindex(iService);
4353 : /* and now reload it. */
4354 0 : iService = load_usershare_service(pszServiceName);
4355 : }
4356 : }
4357 :
4358 284897 : if (iService < 0) {
4359 97993 : DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4360 97993 : return GLOBAL_SECTION_SNUM;
4361 : }
4362 :
4363 185170 : return (iService);
4364 : }
4365 :
4366 : /*******************************************************************
4367 : A useful volume label function.
4368 : ********************************************************************/
4369 :
4370 3424 : const char *volume_label(TALLOC_CTX *ctx, int snum)
4371 : {
4372 0 : const struct loadparm_substitution *lp_sub =
4373 3424 : loadparm_s3_global_substitution();
4374 0 : char *ret;
4375 3424 : const char *label = lp_volume(ctx, lp_sub, snum);
4376 3424 : size_t end = 32;
4377 :
4378 3424 : if (!*label) {
4379 3424 : label = lp_servicename(ctx, lp_sub, snum);
4380 : }
4381 :
4382 : /*
4383 : * Volume label can be a max of 32 bytes. Make sure to truncate
4384 : * it at a codepoint boundary if it's longer than 32 and contains
4385 : * multibyte characters. Windows insists on a volume label being
4386 : * a valid mb sequence, and errors out if not.
4387 : */
4388 3424 : if (strlen(label) > 32) {
4389 : /*
4390 : * A MB char can be a max of 5 bytes, thus
4391 : * we should have a valid mb character at a
4392 : * minimum position of (32-5) = 27.
4393 : */
4394 0 : while (end >= 27) {
4395 : /*
4396 : * Check if a codepoint starting from next byte
4397 : * is valid. If yes, then the current byte is the
4398 : * end of a MB or ascii sequence and the label can
4399 : * be safely truncated here. If not, keep going
4400 : * backwards till a valid codepoint is found.
4401 : */
4402 0 : size_t len = 0;
4403 0 : const char *s = &label[end];
4404 0 : codepoint_t c = next_codepoint(s, &len);
4405 0 : if (c != INVALID_CODEPOINT) {
4406 0 : break;
4407 : }
4408 0 : end--;
4409 : }
4410 : }
4411 :
4412 : /* This returns a max of 33 byte guaranteed null terminated string. */
4413 3424 : ret = talloc_strndup(ctx, label, end);
4414 3424 : if (!ret) {
4415 0 : return "";
4416 : }
4417 3424 : return ret;
4418 : }
4419 :
4420 : /*******************************************************************
4421 : Get the default server type we will announce as via nmbd.
4422 : ********************************************************************/
4423 :
4424 15244 : int lp_default_server_announce(void)
4425 : {
4426 15244 : int default_server_announce = 0;
4427 15244 : default_server_announce |= SV_TYPE_WORKSTATION;
4428 15244 : default_server_announce |= SV_TYPE_SERVER;
4429 15244 : default_server_announce |= SV_TYPE_SERVER_UNIX;
4430 :
4431 : /* note that the flag should be set only if we have a
4432 : printer service but nmbd doesn't actually load the
4433 : services so we can't tell --jerry */
4434 :
4435 15244 : default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4436 :
4437 15244 : default_server_announce |= SV_TYPE_SERVER_NT;
4438 15244 : default_server_announce |= SV_TYPE_NT;
4439 :
4440 15244 : switch (lp_server_role()) {
4441 7029 : case ROLE_DOMAIN_MEMBER:
4442 7029 : default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4443 7029 : break;
4444 4958 : case ROLE_DOMAIN_PDC:
4445 : case ROLE_IPA_DC:
4446 4958 : default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4447 4958 : break;
4448 0 : case ROLE_DOMAIN_BDC:
4449 0 : default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4450 0 : break;
4451 3257 : case ROLE_STANDALONE:
4452 : default:
4453 3257 : break;
4454 : }
4455 15244 : if (lp_time_server())
4456 15226 : default_server_announce |= SV_TYPE_TIME_SOURCE;
4457 :
4458 15244 : if (lp_host_msdfs())
4459 15244 : default_server_announce |= SV_TYPE_DFS_SERVER;
4460 :
4461 15244 : return default_server_announce;
4462 : }
4463 :
4464 : /***********************************************************
4465 : If we are PDC then prefer us as DMB
4466 : ************************************************************/
4467 :
4468 237 : bool lp_domain_master(void)
4469 : {
4470 237 : if (Globals._domain_master == Auto)
4471 317 : return (lp_server_role() == ROLE_DOMAIN_PDC ||
4472 154 : lp_server_role() == ROLE_IPA_DC);
4473 :
4474 74 : return (bool)Globals._domain_master;
4475 : }
4476 :
4477 : /***********************************************************
4478 : If we are PDC then prefer us as DMB
4479 : ************************************************************/
4480 :
4481 2550163 : static bool lp_domain_master_true_or_auto(void)
4482 : {
4483 2550163 : if (Globals._domain_master) /* auto or yes */
4484 2550163 : return true;
4485 :
4486 0 : return false;
4487 : }
4488 :
4489 : /***********************************************************
4490 : If we are DMB then prefer us as LMB
4491 : ************************************************************/
4492 :
4493 39 : bool lp_preferred_master(void)
4494 : {
4495 39 : int preferred_master = lp__preferred_master();
4496 :
4497 39 : if (preferred_master == Auto)
4498 39 : return (lp_local_master() && lp_domain_master());
4499 :
4500 0 : return (bool)preferred_master;
4501 : }
4502 :
4503 : /*******************************************************************
4504 : Remove a service.
4505 : ********************************************************************/
4506 :
4507 0 : void lp_remove_service(int snum)
4508 : {
4509 0 : ServicePtrs[snum]->valid = false;
4510 0 : }
4511 :
4512 6133 : const char *lp_printername(TALLOC_CTX *ctx,
4513 : const struct loadparm_substitution *lp_sub,
4514 : int snum)
4515 : {
4516 6133 : const char *ret = lp__printername(ctx, lp_sub, snum);
4517 :
4518 6133 : if (ret == NULL || *ret == '\0') {
4519 6133 : ret = lp_const_servicename(snum);
4520 : }
4521 :
4522 6133 : return ret;
4523 : }
4524 :
4525 :
4526 : /***********************************************************
4527 : Allow daemons such as winbindd to fix their logfile name.
4528 : ************************************************************/
4529 :
4530 0 : void lp_set_logfile(const char *name)
4531 : {
4532 0 : lpcfg_string_set(Globals.ctx, &Globals.logfile, name);
4533 0 : debug_set_logfile(name);
4534 0 : }
4535 :
4536 : /*******************************************************************
4537 : Return the max print jobs per queue.
4538 : ********************************************************************/
4539 :
4540 668 : int lp_maxprintjobs(int snum)
4541 : {
4542 668 : int maxjobs = lp_max_print_jobs(snum);
4543 :
4544 668 : if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4545 0 : maxjobs = PRINT_MAX_JOBID - 1;
4546 :
4547 668 : return maxjobs;
4548 : }
4549 :
4550 42 : const char *lp_printcapname(void)
4551 : {
4552 42 : const char *printcap_name = lp_printcap_name();
4553 :
4554 42 : if ((printcap_name != NULL) &&
4555 42 : (printcap_name[0] != '\0'))
4556 42 : return printcap_name;
4557 :
4558 0 : if (sDefault.printing == PRINT_CUPS) {
4559 0 : return "cups";
4560 : }
4561 :
4562 0 : if (sDefault.printing == PRINT_BSD)
4563 0 : return "/etc/printcap";
4564 :
4565 0 : return PRINTCAP_NAME;
4566 : }
4567 :
4568 : static uint32_t spoolss_state;
4569 :
4570 9637 : bool lp_disable_spoolss( void )
4571 : {
4572 9637 : if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4573 29 : spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4574 :
4575 9637 : return spoolss_state == SVCCTL_STOPPED ? true : false;
4576 : }
4577 :
4578 0 : void lp_set_spoolss_state( uint32_t state )
4579 : {
4580 0 : SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4581 :
4582 0 : spoolss_state = state;
4583 0 : }
4584 :
4585 24 : uint32_t lp_get_spoolss_state( void )
4586 : {
4587 24 : return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4588 : }
4589 :
4590 : /*******************************************************************
4591 : Turn off sendfile if we find the underlying OS doesn't support it.
4592 : ********************************************************************/
4593 :
4594 0 : void set_use_sendfile(int snum, bool val)
4595 : {
4596 0 : if (LP_SNUM_OK(snum))
4597 0 : ServicePtrs[snum]->_use_sendfile = val;
4598 : else
4599 0 : sDefault._use_sendfile = val;
4600 0 : }
4601 :
4602 476 : void lp_set_mangling_method(const char *new_method)
4603 : {
4604 476 : lpcfg_string_set(Globals.ctx, &Globals.mangling_method, new_method);
4605 476 : }
4606 :
4607 : /*******************************************************************
4608 : Global state for POSIX pathname processing.
4609 : ********************************************************************/
4610 :
4611 : static bool posix_pathnames;
4612 :
4613 676911 : bool lp_posix_pathnames(void)
4614 : {
4615 676911 : return posix_pathnames;
4616 : }
4617 :
4618 : /*******************************************************************
4619 : Change everything needed to ensure POSIX pathname processing (currently
4620 : not much).
4621 : ********************************************************************/
4622 :
4623 476 : void lp_set_posix_pathnames(void)
4624 : {
4625 476 : posix_pathnames = true;
4626 476 : }
4627 :
4628 : /*******************************************************************
4629 : Global state for POSIX lock processing - CIFS unix extensions.
4630 : ********************************************************************/
4631 :
4632 : bool posix_default_lock_was_set;
4633 : static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4634 :
4635 408952 : enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4636 : {
4637 408952 : if (posix_default_lock_was_set) {
4638 0 : return posix_cifsx_locktype;
4639 : } else {
4640 408952 : return (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
4641 408952 : POSIX_LOCK : WINDOWS_LOCK;
4642 : }
4643 : }
4644 :
4645 : /*******************************************************************
4646 : ********************************************************************/
4647 :
4648 0 : void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4649 : {
4650 0 : posix_default_lock_was_set = true;
4651 0 : posix_cifsx_locktype = val;
4652 0 : }
4653 :
4654 2128120 : int lp_min_receive_file_size(void)
4655 : {
4656 2128120 : int min_receivefile_size = lp_min_receivefile_size();
4657 :
4658 2128120 : if (min_receivefile_size < 0) {
4659 0 : return 0;
4660 : }
4661 2107819 : return min_receivefile_size;
4662 : }
4663 :
4664 : /*******************************************************************
4665 : Safe wide links checks.
4666 : This helper function always verify the validity of wide links,
4667 : even after a configuration file reload.
4668 : ********************************************************************/
4669 :
4670 48026 : void widelinks_warning(int snum)
4671 : {
4672 48026 : if (lp_allow_insecure_wide_links()) {
4673 38883 : return;
4674 : }
4675 :
4676 9143 : if (lp_wide_links(snum)) {
4677 0 : if (lp_smb1_unix_extensions()) {
4678 0 : DBG_ERR("Share '%s' has wide links and SMB1 unix "
4679 : "extensions enabled. "
4680 : "These parameters are incompatible. "
4681 : "Wide links will be disabled for this share.\n",
4682 : lp_const_servicename(snum));
4683 : }
4684 : }
4685 : }
4686 :
4687 56634 : bool lp_widelinks(int snum)
4688 : {
4689 : /* wide links is always incompatible with unix extensions */
4690 56634 : if (lp_smb1_unix_extensions()) {
4691 : /*
4692 : * Unless we have "allow insecure widelinks"
4693 : * turned on.
4694 : */
4695 56634 : if (!lp_allow_insecure_wide_links()) {
4696 11981 : return false;
4697 : }
4698 : }
4699 :
4700 43779 : return lp_wide_links(snum);
4701 : }
4702 :
4703 2550163 : int lp_server_role(void)
4704 : {
4705 2553577 : return lp_find_server_role(lp__server_role(),
4706 : lp__security(),
4707 2550163 : lp__domain_logons(),
4708 2546749 : lp_domain_master_true_or_auto());
4709 : }
4710 :
4711 120180 : int lp_security(void)
4712 : {
4713 120180 : return lp_find_security(lp__server_role(),
4714 : lp__security());
4715 : }
4716 :
4717 65470 : int lp_client_max_protocol(void)
4718 : {
4719 65470 : int client_max_protocol = lp__client_max_protocol();
4720 65470 : if (client_max_protocol == PROTOCOL_DEFAULT) {
4721 51087 : return PROTOCOL_LATEST;
4722 : }
4723 14383 : return client_max_protocol;
4724 : }
4725 :
4726 1579 : int lp_client_ipc_min_protocol(void)
4727 : {
4728 1579 : int client_ipc_min_protocol = lp__client_ipc_min_protocol();
4729 1579 : if (client_ipc_min_protocol == PROTOCOL_DEFAULT) {
4730 1579 : client_ipc_min_protocol = lp_client_min_protocol();
4731 : }
4732 1579 : if (client_ipc_min_protocol < PROTOCOL_NT1) {
4733 1126 : return PROTOCOL_NT1;
4734 : }
4735 453 : return client_ipc_min_protocol;
4736 : }
4737 :
4738 1579 : int lp_client_ipc_max_protocol(void)
4739 : {
4740 1579 : int client_ipc_max_protocol = lp__client_ipc_max_protocol();
4741 1579 : if (client_ipc_max_protocol == PROTOCOL_DEFAULT) {
4742 1579 : return PROTOCOL_LATEST;
4743 : }
4744 0 : if (client_ipc_max_protocol < PROTOCOL_NT1) {
4745 0 : return PROTOCOL_NT1;
4746 : }
4747 0 : return client_ipc_max_protocol;
4748 : }
4749 :
4750 3778 : int lp_client_ipc_signing(void)
4751 : {
4752 3778 : int client_ipc_signing = lp__client_ipc_signing();
4753 3778 : if (client_ipc_signing == SMB_SIGNING_DEFAULT) {
4754 3778 : return SMB_SIGNING_REQUIRED;
4755 : }
4756 0 : return client_ipc_signing;
4757 : }
4758 :
4759 148 : enum credentials_use_kerberos lp_client_use_kerberos(void)
4760 : {
4761 148 : if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
4762 0 : return CRED_USE_KERBEROS_REQUIRED;
4763 : }
4764 :
4765 148 : return lp__client_use_kerberos();
4766 : }
4767 :
4768 :
4769 12 : int lp_rpc_low_port(void)
4770 : {
4771 12 : return Globals.rpc_low_port;
4772 : }
4773 :
4774 48 : int lp_rpc_high_port(void)
4775 : {
4776 48 : return Globals.rpc_high_port;
4777 : }
4778 :
4779 : /*
4780 : * Do not allow LanMan auth if unless NTLMv1 is also allowed
4781 : *
4782 : * This also ensures it is disabled if NTLM is totally disabled
4783 : */
4784 55807 : bool lp_lanman_auth(void)
4785 : {
4786 55807 : enum ntlm_auth_level ntlm_auth_level = lp_ntlm_auth();
4787 :
4788 55807 : if (ntlm_auth_level == NTLM_AUTH_ON) {
4789 43950 : return lp__lanman_auth();
4790 : } else {
4791 11851 : return false;
4792 : }
4793 : }
4794 :
4795 802710 : struct loadparm_global * get_globals(void)
4796 : {
4797 802710 : return &Globals;
4798 : }
4799 :
4800 802706 : unsigned int * get_flags(void)
4801 : {
4802 802706 : if (flags_list == NULL) {
4803 38992 : flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());
4804 : }
4805 :
4806 802706 : return flags_list;
4807 : }
4808 :
4809 401 : enum samba_weak_crypto lp_weak_crypto(void)
4810 : {
4811 401 : if (Globals.weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) {
4812 51 : Globals.weak_crypto = SAMBA_WEAK_CRYPTO_DISALLOWED;
4813 :
4814 51 : if (samba_gnutls_weak_crypto_allowed()) {
4815 50 : Globals.weak_crypto = SAMBA_WEAK_CRYPTO_ALLOWED;
4816 : }
4817 : }
4818 :
4819 401 : return Globals.weak_crypto;
4820 : }
4821 :
4822 466 : uint32_t lp_get_async_dns_timeout(void)
4823 : {
4824 : /*
4825 : * Clamp minimum async dns timeout to 1 second
4826 : * as per the man page.
4827 : */
4828 466 : return MAX(Globals.async_dns_timeout, 1);
4829 : }
|