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