source: vendor/current/source3/param/loadparm.c

Last change on this file was 989, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.7

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