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