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