netlogon_creds_cli: Simplify netlogon_creds_cli_delete
[Samba.git] / source3 / param / loadparm.c
blob42e579efcfd603cddd0483636e9f8ee6e03f84ea
1 /*
2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
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
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.
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.
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/>.
31 * Load parameters.
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.
37 * To add a parameter:
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
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!
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"
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 #include "libcli/auth/ntlm_check.h"
76 #ifdef HAVE_SYS_SYSCTL_H
77 #include <sys/sysctl.h>
78 #endif
80 bool bLoaded = false;
82 extern userdom_struct current_user_info;
84 /* the special value for the include parameter
85 * to be interpreted not as a file name but to
86 * trigger loading of the global smb.conf options
87 * from registry. */
88 #ifndef INCLUDE_REGISTRY_NAME
89 #define INCLUDE_REGISTRY_NAME "registry"
90 #endif
92 static bool in_client = false; /* Not in the client by default */
93 static struct smbconf_csn conf_last_csn;
95 static int config_backend = CONFIG_BACKEND_FILE;
97 /* some helpful bits */
98 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && \
99 (ServicePtrs != NULL) && \
100 (ServicePtrs[(i)] != NULL) && ServicePtrs[(i)]->valid)
101 #define VALID(i) ((ServicePtrs != NULL) && (ServicePtrs[i]!= NULL) && \
102 ServicePtrs[i]->valid)
104 #define USERSHARE_VALID 1
105 #define USERSHARE_PENDING_DELETE 2
107 static bool defaults_saved = false;
109 #include "lib/param/param_global.h"
111 static struct loadparm_global Globals;
113 /* This is a default service used to prime a services structure */
114 static struct loadparm_service sDefault =
116 .valid = true,
117 .autoloaded = false,
118 .usershare = 0,
119 .usershare_last_mod = {0, 0},
120 .szService = NULL,
121 .path = 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 .mangled_names = MANGLED_NAMES_YES,
206 .wide_links = false,
207 .follow_symlinks = true,
208 .sync_always = false,
209 .strict_allocate = false,
210 .strict_rename = false,
211 .strict_sync = true,
212 .mangling_char = '~',
213 .copymap = NULL,
214 .delete_readonly = false,
215 .fake_oplocks = false,
216 .delete_veto_files = false,
217 .dos_filemode = false,
218 .dos_filetimes = true,
219 .dos_filetime_resolution = false,
220 .fake_directory_create_times = false,
221 .blocking_locks = true,
222 .inherit_permissions = false,
223 .inherit_acls = false,
224 .inherit_owner = false,
225 .msdfs_root = false,
226 .msdfs_shuffle_referrals = false,
227 .use_client_driver = false,
228 .default_devmode = true,
229 .force_printername = false,
230 .nt_acl_support = true,
231 .force_unknown_acl_user = false,
232 ._use_sendfile = false,
233 .profile_acls = false,
234 .map_acl_inherit = false,
235 .afs_share = false,
236 .ea_support = false,
237 .acl_check_permissions = true,
238 .acl_map_full_control = true,
239 .acl_group_control = false,
240 .acl_allow_execute_always = false,
241 .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
242 .aio_read_size = 0,
243 .aio_write_size = 0,
244 .map_readonly = MAP_READONLY_YES,
245 .directory_name_cache_size = 100,
246 .smb_encrypt = SMB_SIGNING_DEFAULT,
247 .kernel_share_modes = true,
248 .durable_handles = true,
249 .param_opt = NULL,
250 .dummy = ""
253 /* local variables */
254 static struct loadparm_service **ServicePtrs = NULL;
255 static int iNumServices = 0;
256 static int iServiceIndex = 0;
257 static struct db_context *ServiceHash;
258 static bool bInGlobalSection = true;
259 static bool bGlobalOnly = false;
260 static struct file_lists *file_lists = NULL;
261 static unsigned int *flags_list = NULL;
263 static void set_allowed_client_auth(void);
265 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
266 static void free_param_opts(struct parmlist_entry **popts);
269 * Function to return the default value for the maximum number of open
270 * file descriptors permitted. This function tries to consult the
271 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
272 * the smaller of those.
274 static int max_open_files(void)
276 int sysctl_max = MAX_OPEN_FILES;
277 int rlimit_max = MAX_OPEN_FILES;
279 #ifdef HAVE_SYSCTLBYNAME
281 size_t size = sizeof(sysctl_max);
282 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
285 #endif
287 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
289 struct rlimit rl;
291 ZERO_STRUCT(rl);
293 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
294 rlimit_max = rl.rlim_cur;
296 #if defined(RLIM_INFINITY)
297 if(rl.rlim_cur == RLIM_INFINITY)
298 rlimit_max = MAX_OPEN_FILES;
299 #endif
301 #endif
303 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
304 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
305 "minimum Windows limit (%d)\n",
306 sysctl_max,
307 MIN_OPEN_FILES_WINDOWS));
308 sysctl_max = MIN_OPEN_FILES_WINDOWS;
311 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
312 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
313 "minimum Windows limit (%d)\n",
314 rlimit_max,
315 MIN_OPEN_FILES_WINDOWS));
316 rlimit_max = MIN_OPEN_FILES_WINDOWS;
319 return MIN(sysctl_max, rlimit_max);
323 * Common part of freeing allocated data for one parameter.
325 static void free_one_parameter_common(void *parm_ptr,
326 struct parm_struct parm)
328 if ((parm.type == P_STRING) ||
329 (parm.type == P_USTRING))
331 lpcfg_string_free((char**)parm_ptr);
332 } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
333 TALLOC_FREE(*((char***)parm_ptr));
338 * Free the allocated data for one parameter for a share
339 * given as a service struct.
341 static void free_one_parameter(struct loadparm_service *service,
342 struct parm_struct parm)
344 void *parm_ptr;
346 if (parm.p_class != P_LOCAL) {
347 return;
350 parm_ptr = lp_parm_ptr(service, &parm);
352 free_one_parameter_common(parm_ptr, parm);
356 * Free the allocated parameter data of a share given
357 * as a service struct.
359 static void free_parameters(struct loadparm_service *service)
361 uint32_t i;
363 for (i=0; parm_table[i].label; i++) {
364 free_one_parameter(service, parm_table[i]);
369 * Free the allocated data for one parameter for a given share
370 * specified by an snum.
372 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
374 void *parm_ptr;
376 if (snum < 0) {
377 parm_ptr = lp_parm_ptr(NULL, &parm);
378 } else if (parm.p_class != P_LOCAL) {
379 return;
380 } else {
381 parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
384 free_one_parameter_common(parm_ptr, parm);
388 * Free the allocated parameter data for a share specified
389 * by an snum.
391 static void free_parameters_by_snum(int snum)
393 uint32_t i;
395 for (i=0; parm_table[i].label; i++) {
396 free_one_parameter_by_snum(snum, parm_table[i]);
401 * Free the allocated global parameters.
403 static void free_global_parameters(void)
405 uint32_t i;
406 struct parm_struct *parm;
408 free_param_opts(&Globals.param_opt);
409 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
411 /* Reset references in the defaults because the context is going to be freed */
412 for (i=0; parm_table[i].label; i++) {
413 parm = &parm_table[i];
414 if ((parm->type == P_STRING) ||
415 (parm->type == P_USTRING)) {
416 if ((parm->def.svalue != NULL) &&
417 (*(parm->def.svalue) != '\0')) {
418 if (talloc_parent(parm->def.svalue) == Globals.ctx) {
419 parm->def.svalue = NULL;
424 TALLOC_FREE(Globals.ctx);
427 struct lp_stored_option {
428 struct lp_stored_option *prev, *next;
429 const char *label;
430 const char *value;
433 static struct lp_stored_option *stored_options;
436 save options set by lp_set_cmdline() into a list. This list is
437 re-applied when we do a globals reset, so that cmdline set options
438 are sticky across reloads of smb.conf
440 bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
442 struct lp_stored_option *entry, *entry_next;
443 for (entry = stored_options; entry != NULL; entry = entry_next) {
444 entry_next = entry->next;
445 if (strcmp(pszParmName, entry->label) == 0) {
446 DLIST_REMOVE(stored_options, entry);
447 talloc_free(entry);
448 break;
452 entry = talloc(NULL, struct lp_stored_option);
453 if (!entry) {
454 return false;
457 entry->label = talloc_strdup(entry, pszParmName);
458 if (!entry->label) {
459 talloc_free(entry);
460 return false;
463 entry->value = talloc_strdup(entry, pszParmValue);
464 if (!entry->value) {
465 talloc_free(entry);
466 return false;
469 DLIST_ADD_END(stored_options, entry);
471 return true;
474 static bool apply_lp_set_cmdline(void)
476 struct lp_stored_option *entry = NULL;
477 for (entry = stored_options; entry != NULL; entry = entry->next) {
478 if (!lp_set_cmdline_helper(entry->label, entry->value)) {
479 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
480 entry->label, entry->value));
481 return false;
484 return true;
487 /***************************************************************************
488 Initialise the global parameter structure.
489 ***************************************************************************/
491 static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
493 static bool done_init = false;
494 char *s = NULL;
495 int i;
497 /* If requested to initialize only once and we've already done it... */
498 if (!reinit_globals && done_init) {
499 /* ... then we have nothing more to do */
500 return;
503 if (!done_init) {
504 /* The logfile can be set before this is invoked. Free it if so. */
505 lpcfg_string_free(&Globals.logfile);
506 done_init = true;
507 } else {
508 free_global_parameters();
511 /* This memset and the free_global_parameters() above will
512 * wipe out smb.conf options set with lp_set_cmdline(). The
513 * apply_lp_set_cmdline() call puts these values back in the
514 * table once the defaults are set */
515 ZERO_STRUCT(Globals);
517 Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
519 /* Initialize the flags list if necessary */
520 if (flags_list == NULL) {
521 get_flags();
524 for (i = 0; parm_table[i].label; i++) {
525 if ((parm_table[i].type == P_STRING ||
526 parm_table[i].type == P_USTRING))
528 lpcfg_string_set(
529 Globals.ctx,
530 (char **)lp_parm_ptr(NULL, &parm_table[i]),
531 "");
536 lpcfg_string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
537 lpcfg_string_set(Globals.ctx, &sDefault.printjob_username, "%U");
539 init_printer_values(lp_ctx, Globals.ctx, &sDefault);
541 sDefault.ntvfs_handler = str_list_make_v3_const(NULL, "unixuid default", NULL);
543 DEBUG(3, ("Initialising global parameters\n"));
545 /* Must manually force to upper case here, as this does not go via the handler */
546 lpcfg_string_set(Globals.ctx, &Globals.netbios_name,
547 myhostname_upper());
549 lpcfg_string_set(Globals.ctx, &Globals.smb_passwd_file,
550 get_dyn_SMB_PASSWD_FILE());
551 lpcfg_string_set(Globals.ctx, &Globals.private_dir,
552 get_dyn_PRIVATE_DIR());
553 lpcfg_string_set(Globals.ctx, &Globals.binddns_dir,
554 get_dyn_BINDDNS_DIR());
556 /* use the new 'hash2' method by default, with a prefix of 1 */
557 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, "hash2");
558 Globals.mangle_prefix = 1;
560 lpcfg_string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
562 /* using UTF8 by default allows us to support all chars */
563 lpcfg_string_set(Globals.ctx, &Globals.unix_charset,
564 DEFAULT_UNIX_CHARSET);
566 /* Use codepage 850 as a default for the dos character set */
567 lpcfg_string_set(Globals.ctx, &Globals.dos_charset,
568 DEFAULT_DOS_CHARSET);
571 * Allow the default PASSWD_CHAT to be overridden in local.h.
573 lpcfg_string_set(Globals.ctx, &Globals.passwd_chat,
574 DEFAULT_PASSWD_CHAT);
576 lpcfg_string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
578 lpcfg_string_set(Globals.ctx, &Globals.passwd_program, "");
579 lpcfg_string_set(Globals.ctx, &Globals.lock_directory,
580 get_dyn_LOCKDIR());
581 lpcfg_string_set(Globals.ctx, &Globals.state_directory,
582 get_dyn_STATEDIR());
583 lpcfg_string_set(Globals.ctx, &Globals.cache_directory,
584 get_dyn_CACHEDIR());
585 lpcfg_string_set(Globals.ctx, &Globals.pid_directory,
586 get_dyn_PIDDIR());
587 lpcfg_string_set(Globals.ctx, &Globals.nbt_client_socket_address,
588 "0.0.0.0");
590 * By default support explicit binding to broadcast
591 * addresses.
593 Globals.nmbd_bind_explicit_broadcast = true;
595 s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
596 if (s == NULL) {
597 smb_panic("init_globals: ENOMEM");
599 lpcfg_string_set(Globals.ctx, &Globals.server_string, s);
600 TALLOC_FREE(s);
601 #ifdef DEVELOPER
602 lpcfg_string_set(Globals.ctx, &Globals.panic_action,
603 "/bin/sleep 999999999");
604 #endif
606 lpcfg_string_set(Globals.ctx, &Globals.socket_options,
607 DEFAULT_SOCKET_OPTIONS);
609 lpcfg_string_set(Globals.ctx, &Globals.logon_drive, "");
610 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
611 lpcfg_string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
612 lpcfg_string_set(Globals.ctx, &Globals.logon_path,
613 "\\\\%N\\%U\\profile");
615 Globals.name_resolve_order =
616 str_list_make_v3_const(Globals.ctx,
617 DEFAULT_NAME_RESOLVE_ORDER,
618 NULL);
619 lpcfg_string_set(Globals.ctx, &Globals.password_server, "*");
621 Globals.algorithmic_rid_base = BASE_RID;
623 Globals.load_printers = true;
624 Globals.printcap_cache_time = 750; /* 12.5 minutes */
626 Globals.config_backend = config_backend;
627 Globals._server_role = ROLE_AUTO;
629 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
630 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
631 Globals.max_xmit = 0x4104;
632 Globals.max_mux = 50; /* This is *needed* for profile support. */
633 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
634 Globals._disable_spoolss = false;
635 Globals.max_smbd_processes = 0;/* no limit specified */
636 Globals.username_level = 0;
637 Globals.deadtime = 0;
638 Globals.getwd_cache = true;
639 Globals.large_readwrite = true;
640 Globals.max_log_size = 5000;
641 Globals.max_open_files = max_open_files();
642 Globals.server_max_protocol = PROTOCOL_SMB3_11;
643 Globals.server_min_protocol = PROTOCOL_LANMAN1;
644 Globals._client_max_protocol = PROTOCOL_DEFAULT;
645 Globals.client_min_protocol = PROTOCOL_CORE;
646 Globals._client_ipc_max_protocol = PROTOCOL_DEFAULT;
647 Globals._client_ipc_min_protocol = PROTOCOL_DEFAULT;
648 Globals._security = SEC_AUTO;
649 Globals.encrypt_passwords = true;
650 Globals.client_schannel = Auto;
651 Globals.winbind_sealed_pipes = true;
652 Globals.require_strong_key = true;
653 Globals.server_schannel = Auto;
654 Globals.read_raw = true;
655 Globals.write_raw = true;
656 Globals.null_passwords = false;
657 Globals.old_password_allowed_period = 60;
658 Globals.obey_pam_restrictions = false;
659 Globals.syslog = 1;
660 Globals.syslog_only = false;
661 Globals.timestamp_logs = true;
662 lpcfg_string_set(Globals.ctx, &Globals.log_level, "0");
663 Globals.debug_prefix_timestamp = false;
664 Globals.debug_hires_timestamp = true;
665 Globals.debug_pid = false;
666 Globals.debug_uid = false;
667 Globals.debug_class = false;
668 Globals.enable_core_files = true;
669 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
670 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
671 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
672 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
673 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
674 Globals.lm_interval = 60;
675 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
676 Globals.nis_homedir = false;
677 #ifdef WITH_NISPLUS_HOME
678 lpcfg_string_set(Globals.ctx, &Globals.homedir_map,
679 "auto_home.org_dir");
680 #else
681 lpcfg_string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
682 #endif
683 #endif
684 Globals.time_server = false;
685 Globals.bind_interfaces_only = false;
686 Globals.unix_password_sync = false;
687 Globals.pam_password_change = false;
688 Globals.passwd_chat_debug = false;
689 Globals.passwd_chat_timeout = 2; /* 2 second default. */
690 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
691 Globals.nt_status_support = true; /* Use NT status by default. */
692 Globals.smbd_profiling_level = 0;
693 Globals.stat_cache = true; /* use stat cache by default */
694 Globals.max_stat_cache_size = 256; /* 256k by default */
695 Globals.restrict_anonymous = 0;
696 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
697 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
698 Globals._lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
699 Globals.ntlm_auth = NTLM_AUTH_NTLMV2_ONLY; /* Do NOT use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
700 Globals.raw_ntlmv2_auth = false; /* Reject NTLMv2 without NTLMSSP */
701 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 */
702 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
704 Globals.allow_dcerpc_auth_level_connect = false; /* we don't allow this by default */
706 Globals.map_to_guest = 0; /* By Default, "Never" */
707 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
708 Globals.enhanced_browsing = true;
709 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
710 #ifdef MMAP_BLACKLIST
711 Globals.use_mmap = false;
712 #else
713 Globals.use_mmap = true;
714 #endif
715 Globals.unicode = true;
716 Globals.unix_extensions = true;
717 Globals.reset_on_zero_vc = false;
718 Globals.log_writeable_files_on_exit = false;
719 Globals.create_krb5_conf = true;
720 Globals.include_system_krb5_conf = true;
721 Globals._winbind_max_domain_connections = 1;
723 /* hostname lookups can be very expensive and are broken on
724 a large number of sites (tridge) */
725 Globals.hostname_lookups = false;
727 Globals.change_notify = true,
728 Globals.kernel_change_notify = true,
730 lpcfg_string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
731 lpcfg_string_set(Globals.ctx, &Globals.ldap_suffix, "");
732 lpcfg_string_set(Globals.ctx, &Globals._ldap_machine_suffix, "");
733 lpcfg_string_set(Globals.ctx, &Globals._ldap_user_suffix, "");
734 lpcfg_string_set(Globals.ctx, &Globals._ldap_group_suffix, "");
735 lpcfg_string_set(Globals.ctx, &Globals._ldap_idmap_suffix, "");
737 lpcfg_string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
738 Globals.ldap_ssl = LDAP_SSL_START_TLS;
739 Globals.ldap_ssl_ads = false;
740 Globals.ldap_deref = -1;
741 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
742 Globals.ldap_delete_dn = false;
743 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
744 Globals.ldap_follow_referral = Auto;
745 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
746 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
747 Globals.ldap_page_size = LDAP_PAGE_SIZE;
749 Globals.ldap_debug_level = 0;
750 Globals.ldap_debug_threshold = 10;
752 Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
754 Globals.ldap_server_require_strong_auth =
755 LDAP_SERVER_REQUIRE_STRONG_AUTH_YES;
757 /* This is what we tell the afs client. in reality we set the token
758 * to never expire, though, when this runs out the afs client will
759 * forget the token. Set to 0 to get NEVERDATE.*/
760 Globals.afs_token_lifetime = 604800;
761 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
763 /* these parameters are set to defaults that are more appropriate
764 for the increasing samba install base:
766 as a member of the workgroup, that will possibly become a
767 _local_ master browser (lm = true). this is opposed to a forced
768 local master browser startup (pm = true).
770 doesn't provide WINS server service by default (wsupp = false),
771 and doesn't provide domain master browser services by default, either.
775 Globals.show_add_printer_wizard = true;
776 Globals.os_level = 20;
777 Globals.local_master = true;
778 Globals._domain_master = Auto; /* depending on _domain_logons */
779 Globals._domain_logons = false;
780 Globals.browse_list = true;
781 Globals.we_are_a_wins_server = false;
782 Globals.wins_proxy = false;
784 TALLOC_FREE(Globals.init_logon_delayed_hosts);
785 Globals.init_logon_delay = 100; /* 100 ms default delay */
787 Globals.wins_dns_proxy = true;
789 Globals.allow_trusted_domains = true;
790 lpcfg_string_set(Globals.ctx, &Globals.idmap_backend, "tdb");
792 lpcfg_string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
793 lpcfg_string_set(Globals.ctx, &Globals.template_homedir,
794 "/home/%D/%U");
795 lpcfg_string_set(Globals.ctx, &Globals.winbind_separator, "\\");
796 lpcfg_string_set(Globals.ctx, &Globals.winbindd_socket_directory,
797 dyn_WINBINDD_SOCKET_DIR);
799 lpcfg_string_set(Globals.ctx, &Globals.cups_server, "");
800 lpcfg_string_set(Globals.ctx, &Globals.iprint_server, "");
802 lpcfg_string_set(Globals.ctx, &Globals._ctdbd_socket, "");
804 Globals.cluster_addresses = NULL;
805 Globals.clustering = false;
806 Globals.ctdb_timeout = 0;
807 Globals.ctdb_locktime_warn_threshold = 0;
809 Globals.winbind_cache_time = 300; /* 5 minutes */
810 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
811 Globals.winbind_request_timeout = 60; /* 60 seconds */
812 Globals.winbind_max_clients = 200;
813 Globals.winbind_enum_users = false;
814 Globals.winbind_enum_groups = false;
815 Globals.winbind_use_default_domain = false;
816 Globals.winbind_trusted_domains_only = false;
817 Globals.winbind_nested_groups = true;
818 Globals.winbind_expand_groups = 0;
819 Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
820 Globals.winbind_refresh_tickets = false;
821 Globals.winbind_offline_logon = false;
823 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
824 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
826 Globals.passdb_expand_explicit = false;
828 Globals.name_cache_timeout = 660; /* In seconds */
830 Globals.use_spnego = true;
831 Globals.client_use_spnego = true;
833 Globals.client_signing = SMB_SIGNING_DEFAULT;
834 Globals._client_ipc_signing = SMB_SIGNING_DEFAULT;
835 Globals.server_signing = SMB_SIGNING_DEFAULT;
837 Globals.defer_sharing_violations = true;
838 Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL);
840 Globals.enable_privileges = true;
841 Globals.host_msdfs = true;
842 Globals.enable_asu_support = false;
844 /* User defined shares. */
845 s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
846 if (s == NULL) {
847 smb_panic("init_globals: ENOMEM");
849 lpcfg_string_set(Globals.ctx, &Globals.usershare_path, s);
850 TALLOC_FREE(s);
851 lpcfg_string_set(Globals.ctx, &Globals.usershare_template_share, "");
852 Globals.usershare_max_shares = 0;
853 /* By default disallow sharing of directories not owned by the sharer. */
854 Globals.usershare_owner_only = true;
855 /* By default disallow guest access to usershares. */
856 Globals.usershare_allow_guests = false;
858 Globals.keepalive = DEFAULT_KEEPALIVE;
860 /* By default no shares out of the registry */
861 Globals.registry_shares = false;
863 Globals.min_receivefile_size = 0;
865 Globals.map_untrusted_to_domain = Auto;
866 Globals.multicast_dns_register = true;
868 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
869 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
870 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
871 Globals.smb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
872 Globals.smb2_leases = true;
874 lpcfg_string_set(Globals.ctx, &Globals.ncalrpc_dir,
875 get_dyn_NCALRPCDIR());
877 Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
879 Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
881 Globals.tls_enabled = true;
882 Globals.tls_verify_peer = TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE;
884 lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
885 lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
886 lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
887 lpcfg_string_set(Globals.ctx, &Globals.tls_priority,
888 "NORMAL:-VERS-SSL3.0");
890 lpcfg_string_set(Globals.ctx, &Globals.share_backend, "classic");
892 Globals._preferred_master = Auto;
894 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
896 lpcfg_string_set(Globals.ctx, &Globals.ntp_signd_socket_directory,
897 get_dyn_NTP_SIGND_SOCKET_DIR());
899 s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
900 if (s == NULL) {
901 smb_panic("init_globals: ENOMEM");
903 Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
904 TALLOC_FREE(s);
906 #ifdef MIT_KDC_PATH
907 Globals.mit_kdc_command = str_list_make_v3_const(NULL, MIT_KDC_PATH, NULL);
908 #endif
910 s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
911 if (s == NULL) {
912 smb_panic("init_globals: ENOMEM");
914 Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
915 TALLOC_FREE(s);
917 s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
918 if (s == NULL) {
919 smb_panic("init_globals: ENOMEM");
921 Globals.spn_update_command = str_list_make_v3_const(NULL, s, NULL);
922 TALLOC_FREE(s);
924 Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
926 Globals.rndc_command = str_list_make_v3_const(NULL, "/usr/sbin/rndc", NULL);
928 Globals.cldap_port = 389;
930 Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
932 Globals.nbt_port = NBT_NAME_SERVICE_PORT;
934 Globals.krb5_port = 88;
936 Globals.kpasswd_port = 464;
938 Globals.web_port = 901;
940 Globals.aio_max_threads = 100;
942 lpcfg_string_set(Globals.ctx,
943 &Globals.rpc_server_dynamic_port_range,
944 "49152-65535");
945 Globals.rpc_low_port = SERVER_TCP_LOW_PORT;
946 Globals.rpc_high_port = SERVER_TCP_HIGH_PORT;
948 /* Now put back the settings that were set with lp_set_cmdline() */
949 apply_lp_set_cmdline();
952 /* Convenience routine to setup an lp_context with additional s3 variables */
953 static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
955 struct loadparm_context *lp_ctx;
957 lp_ctx = loadparm_init_s3(mem_ctx,
958 loadparm_s3_helpers());
959 if (lp_ctx == NULL) {
960 DEBUG(0, ("loadparm_init_s3 failed\n"));
961 return NULL;
964 lp_ctx->sDefault = &sDefault;
965 lp_ctx->services = NULL; /* We do not want to access this directly */
966 lp_ctx->bInGlobalSection = bInGlobalSection;
967 lp_ctx->flags = flags_list;
969 return lp_ctx;
972 /*******************************************************************
973 Convenience routine to grab string parameters into talloced memory
974 and run standard_sub_basic on them. The buffers can be written to by
975 callers without affecting the source string.
976 ********************************************************************/
978 char *lp_string(TALLOC_CTX *ctx, const char *s)
980 char *ret;
982 /* The follow debug is useful for tracking down memory problems
983 especially if you have an inner loop that is calling a lp_*()
984 function that returns a string. Perhaps this debug should be
985 present all the time? */
987 #if 0
988 DEBUG(10, ("lp_string(%s)\n", s));
989 #endif
990 if (!s) {
991 return NULL;
994 ret = talloc_sub_basic(ctx,
995 get_current_username(),
996 current_user_info.domain,
998 if (trim_char(ret, '\"', '\"')) {
999 if (strchr(ret,'\"') != NULL) {
1000 TALLOC_FREE(ret);
1001 ret = talloc_sub_basic(ctx,
1002 get_current_username(),
1003 current_user_info.domain,
1007 return ret;
1011 In this section all the functions that are used to access the
1012 parameters from the rest of the program are defined
1015 #define FN_GLOBAL_STRING(fn_name,ptr) \
1016 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1017 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1018 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1019 #define FN_GLOBAL_LIST(fn_name,ptr) \
1020 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1021 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1022 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1023 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1024 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1025 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1026 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1028 #define FN_LOCAL_STRING(fn_name,val) \
1029 char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1030 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1031 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1032 #define FN_LOCAL_LIST(fn_name,val) \
1033 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1034 #define FN_LOCAL_BOOL(fn_name,val) \
1035 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1036 #define FN_LOCAL_INTEGER(fn_name,val) \
1037 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1039 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1040 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1041 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1042 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1043 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1044 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1046 int lp_winbind_max_domain_connections(void)
1048 if (lp_winbind_offline_logon() &&
1049 lp__winbind_max_domain_connections() > 1) {
1050 DEBUG(1, ("offline logons active, restricting max domain "
1051 "connections to 1\n"));
1052 return 1;
1054 return MAX(1, lp__winbind_max_domain_connections());
1057 /* These functions remain in source3/param for now */
1059 #include "lib/param/param_functions.c"
1061 FN_LOCAL_STRING(servicename, szService)
1062 FN_LOCAL_CONST_STRING(const_servicename, szService)
1064 /* These functions cannot be auto-generated */
1065 FN_LOCAL_BOOL(autoloaded, autoloaded)
1066 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1068 /* local prototypes */
1070 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1071 static const char *get_boolean(bool bool_value);
1072 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1073 void *userdata);
1074 static bool hash_a_service(const char *name, int number);
1075 static void free_service_byindex(int iService);
1076 static void show_parameter(int parmIndex);
1077 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1078 static bool lp_parameter_value_is_valid(const char *parm_name, const char *val);
1081 * This is a helper function for parametrical options support. It returns a
1082 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1083 * parametrical functions are quite simple
1085 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1086 const char *option)
1088 if (snum >= iNumServices) return NULL;
1090 if (snum < 0) {
1091 return get_parametric_helper(NULL, type, option, Globals.param_opt);
1092 } else {
1093 return get_parametric_helper(ServicePtrs[snum],
1094 type, option, Globals.param_opt);
1098 static void discard_whitespace(char *str)
1100 size_t len = strlen(str);
1101 size_t i = 0;
1103 while (i < len) {
1104 if (isspace(str[i])) {
1105 memmove(&str[i], &str[i+1], len-i);
1106 len -= 1;
1107 continue;
1109 i += 1;
1114 * @brief Go through all global parametric parameters
1116 * @param regex_str A regular expression to scan param for
1117 * @param max_matches Max number of submatches the regexp expects
1118 * @param cb Function to call on match. Should return true
1119 * when it wants wi_scan_global_parametrics to stop
1120 * scanning
1121 * @param private_data Anonymous pointer passed to cb
1123 * @return 0: success, regcomp/regexec return value on error.
1124 * See "man regexec" for possible errors
1127 int lp_wi_scan_global_parametrics(
1128 const char *regex_str, size_t max_matches,
1129 bool (*cb)(const char *string, regmatch_t matches[],
1130 void *private_data),
1131 void *private_data)
1133 struct parmlist_entry *data;
1134 regex_t regex;
1135 int ret;
1137 ret = regcomp(&regex, regex_str, REG_ICASE);
1138 if (ret != 0) {
1139 return ret;
1142 for (data = Globals.param_opt; data != NULL; data = data->next) {
1143 size_t keylen = strlen(data->key);
1144 char key[keylen+1];
1145 regmatch_t matches[max_matches];
1146 bool stop;
1148 memcpy(key, data->key, sizeof(key));
1149 discard_whitespace(key);
1151 ret = regexec(&regex, key, max_matches, matches, 0);
1152 if (ret == REG_NOMATCH) {
1153 continue;
1155 if (ret != 0) {
1156 goto fail;
1159 stop = cb(key, matches, private_data);
1160 if (stop) {
1161 break;
1165 ret = 0;
1166 fail:
1167 regfree(&regex);
1168 return ret;
1172 #define MISSING_PARAMETER(name) \
1173 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1175 /*******************************************************************
1176 convenience routine to return enum parameters.
1177 ********************************************************************/
1178 static int lp_enum(const char *s,const struct enum_list *_enum)
1180 int i;
1182 if (!s || !*s || !_enum) {
1183 MISSING_PARAMETER(lp_enum);
1184 return (-1);
1187 for (i=0; _enum[i].name; i++) {
1188 if (strequal(_enum[i].name,s))
1189 return _enum[i].value;
1192 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1193 return (-1);
1196 #undef MISSING_PARAMETER
1198 /* Return parametric option from a given service. Type is a part of option before ':' */
1199 /* Parametric option has following syntax: 'Type: option = value' */
1200 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1202 struct parmlist_entry *data = get_parametrics(snum, type, option);
1204 if (data == NULL||data->value==NULL) {
1205 if (def) {
1206 return lp_string(ctx, def);
1207 } else {
1208 return NULL;
1212 return lp_string(ctx, data->value);
1215 /* Return parametric option from a given service. Type is a part of option before ':' */
1216 /* Parametric option has following syntax: 'Type: option = value' */
1217 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1219 struct parmlist_entry *data = get_parametrics(snum, type, option);
1221 if (data == NULL||data->value==NULL)
1222 return def;
1224 return data->value;
1228 /* Return parametric option from a given service. Type is a part of option before ':' */
1229 /* Parametric option has following syntax: 'Type: option = value' */
1231 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1233 struct parmlist_entry *data = get_parametrics(snum, type, option);
1235 if (data == NULL||data->value==NULL)
1236 return (const char **)def;
1238 if (data->list==NULL) {
1239 data->list = str_list_make_v3(NULL, data->value, NULL);
1242 return discard_const_p(const char *, data->list);
1245 /* Return parametric option from a given service. Type is a part of option before ':' */
1246 /* Parametric option has following syntax: 'Type: option = value' */
1248 int lp_parm_int(int snum, const char *type, const char *option, int def)
1250 struct parmlist_entry *data = get_parametrics(snum, type, option);
1252 if (data && data->value && *data->value)
1253 return lp_int(data->value);
1255 return def;
1258 /* Return parametric option from a given service. Type is a part of option before ':' */
1259 /* Parametric option has following syntax: 'Type: option = value' */
1261 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1263 struct parmlist_entry *data = get_parametrics(snum, type, option);
1265 if (data && data->value && *data->value)
1266 return lp_ulong(data->value);
1268 return def;
1271 /* Return parametric option from a given service. Type is a part of option before ':' */
1272 /* Parametric option has following syntax: 'Type: option = value' */
1274 unsigned long long lp_parm_ulonglong(int snum, const char *type,
1275 const char *option, unsigned long long def)
1277 struct parmlist_entry *data = get_parametrics(snum, type, option);
1279 if (data && data->value && *data->value) {
1280 return lp_ulonglong(data->value);
1283 return def;
1286 /* Return parametric option from a given service. Type is a part of option
1287 * before ':' */
1288 /* Parametric option has following syntax: 'Type: option = value' */
1290 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1292 struct parmlist_entry *data = get_parametrics(snum, type, option);
1294 if (data && data->value && *data->value)
1295 return lp_bool(data->value);
1297 return def;
1300 /* Return parametric option from a given service. Type is a part of option before ':' */
1301 /* Parametric option has following syntax: 'Type: option = value' */
1303 int lp_parm_enum(int snum, const char *type, const char *option,
1304 const struct enum_list *_enum, int def)
1306 struct parmlist_entry *data = get_parametrics(snum, type, option);
1308 if (data && data->value && *data->value && _enum)
1309 return lp_enum(data->value, _enum);
1311 return def;
1315 * free a param_opts structure.
1316 * param_opts handling should be moved to talloc;
1317 * then this whole functions reduces to a TALLOC_FREE().
1320 static void free_param_opts(struct parmlist_entry **popts)
1322 struct parmlist_entry *opt, *next_opt;
1324 if (*popts != NULL) {
1325 DEBUG(5, ("Freeing parametrics:\n"));
1327 opt = *popts;
1328 while (opt != NULL) {
1329 lpcfg_string_free(&opt->key);
1330 lpcfg_string_free(&opt->value);
1331 TALLOC_FREE(opt->list);
1332 next_opt = opt->next;
1333 TALLOC_FREE(opt);
1334 opt = next_opt;
1336 *popts = NULL;
1339 /***************************************************************************
1340 Free the dynamically allocated parts of a service struct.
1341 ***************************************************************************/
1343 static void free_service(struct loadparm_service *pservice)
1345 if (!pservice)
1346 return;
1348 if (pservice->szService)
1349 DEBUG(5, ("free_service: Freeing service %s\n",
1350 pservice->szService));
1352 free_parameters(pservice);
1354 lpcfg_string_free(&pservice->szService);
1355 TALLOC_FREE(pservice->copymap);
1357 free_param_opts(&pservice->param_opt);
1359 ZERO_STRUCTP(pservice);
1363 /***************************************************************************
1364 remove a service indexed in the ServicePtrs array from the ServiceHash
1365 and free the dynamically allocated parts
1366 ***************************************************************************/
1368 static void free_service_byindex(int idx)
1370 if ( !LP_SNUM_OK(idx) )
1371 return;
1373 ServicePtrs[idx]->valid = false;
1375 /* we have to cleanup the hash record */
1377 if (ServicePtrs[idx]->szService) {
1378 char *canon_name = canonicalize_servicename(
1379 talloc_tos(),
1380 ServicePtrs[idx]->szService );
1382 dbwrap_delete_bystring(ServiceHash, canon_name );
1383 TALLOC_FREE(canon_name);
1386 free_service(ServicePtrs[idx]);
1387 TALLOC_FREE(ServicePtrs[idx]);
1390 /***************************************************************************
1391 Add a new service to the services array initialising it with the given
1392 service.
1393 ***************************************************************************/
1395 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1397 int i;
1398 struct loadparm_service **tsp = NULL;
1400 /* it might already exist */
1401 if (name) {
1402 i = getservicebyname(name, NULL);
1403 if (i >= 0) {
1404 return (i);
1408 /* Re use empty slots if any before allocating new one.*/
1409 for (i=0; i < iNumServices; i++) {
1410 if (ServicePtrs[i] == NULL) {
1411 break;
1414 if (i == iNumServices) {
1415 /* if not, then create one */
1416 tsp = talloc_realloc(NULL, ServicePtrs,
1417 struct loadparm_service *,
1418 iNumServices + 1);
1419 if (tsp == NULL) {
1420 DEBUG(0, ("add_a_service: failed to enlarge "
1421 "ServicePtrs!\n"));
1422 return (-1);
1424 ServicePtrs = tsp;
1425 iNumServices++;
1427 ServicePtrs[i] = talloc_zero(ServicePtrs, struct loadparm_service);
1428 if (!ServicePtrs[i]) {
1429 DEBUG(0,("add_a_service: out of memory!\n"));
1430 return (-1);
1433 ServicePtrs[i]->valid = true;
1435 copy_service(ServicePtrs[i], pservice, NULL);
1436 if (name)
1437 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->szService,
1438 name);
1440 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1441 i, ServicePtrs[i]->szService));
1443 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1444 return (-1);
1447 return (i);
1450 /***************************************************************************
1451 Convert a string to uppercase and remove whitespaces.
1452 ***************************************************************************/
1454 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1456 char *result;
1458 if ( !src ) {
1459 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1460 return NULL;
1463 result = talloc_strdup(ctx, src);
1464 SMB_ASSERT(result != NULL);
1466 if (!strlower_m(result)) {
1467 TALLOC_FREE(result);
1468 return NULL;
1470 return result;
1473 /***************************************************************************
1474 Add a name/index pair for the services array to the hash table.
1475 ***************************************************************************/
1477 static bool hash_a_service(const char *name, int idx)
1479 char *canon_name;
1481 if ( !ServiceHash ) {
1482 DEBUG(10,("hash_a_service: creating servicehash\n"));
1483 ServiceHash = db_open_rbt(NULL);
1484 if ( !ServiceHash ) {
1485 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1486 return false;
1490 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1491 idx, name));
1493 canon_name = canonicalize_servicename(talloc_tos(), name );
1495 dbwrap_store_bystring(ServiceHash, canon_name,
1496 make_tdb_data((uint8_t *)&idx, sizeof(idx)),
1497 TDB_REPLACE);
1499 TALLOC_FREE(canon_name);
1501 return true;
1504 /***************************************************************************
1505 Add a new home service, with the specified home directory, defaults coming
1506 from service ifrom.
1507 ***************************************************************************/
1509 bool lp_add_home(const char *pszHomename, int iDefaultService,
1510 const char *user, const char *pszHomedir)
1512 int i;
1514 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1515 pszHomedir[0] == '\0') {
1516 return false;
1519 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1521 if (i < 0)
1522 return false;
1524 if (!(*(ServicePtrs[iDefaultService]->path))
1525 || strequal(ServicePtrs[iDefaultService]->path,
1526 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1527 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
1528 pszHomedir);
1531 if (!(*(ServicePtrs[i]->comment))) {
1532 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1533 if (comment == NULL) {
1534 return false;
1536 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment,
1537 comment);
1538 TALLOC_FREE(comment);
1541 /* set the browseable flag from the global default */
1543 ServicePtrs[i]->browseable = sDefault.browseable;
1544 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1546 ServicePtrs[i]->autoloaded = true;
1548 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1549 user, ServicePtrs[i]->path ));
1551 return true;
1554 /***************************************************************************
1555 Add a new service, based on an old one.
1556 ***************************************************************************/
1558 int lp_add_service(const char *pszService, int iDefaultService)
1560 if (iDefaultService < 0) {
1561 return add_a_service(&sDefault, pszService);
1564 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1567 /***************************************************************************
1568 Add the IPC service.
1569 ***************************************************************************/
1571 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1573 char *comment = NULL;
1574 int i = add_a_service(&sDefault, ipc_name);
1576 if (i < 0)
1577 return false;
1579 comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1580 Globals.server_string);
1581 if (comment == NULL) {
1582 return false;
1585 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1586 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1587 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1588 ServicePtrs[i]->max_connections = 0;
1589 ServicePtrs[i]->available = true;
1590 ServicePtrs[i]->read_only = true;
1591 ServicePtrs[i]->guest_only = false;
1592 ServicePtrs[i]->administrative_share = true;
1593 ServicePtrs[i]->guest_ok = guest_ok;
1594 ServicePtrs[i]->printable = false;
1595 ServicePtrs[i]->browseable = sDefault.browseable;
1596 ServicePtrs[i]->autoloaded = true;
1598 DEBUG(3, ("adding IPC service\n"));
1600 TALLOC_FREE(comment);
1601 return true;
1604 /***************************************************************************
1605 Add a new printer service, with defaults coming from service iFrom.
1606 ***************************************************************************/
1608 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1610 const char *comment = "From Printcap";
1611 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1613 if (i < 0)
1614 return false;
1616 /* note that we do NOT default the availability flag to true - */
1617 /* we take it from the default service passed. This allows all */
1618 /* dynamic printers to be disabled by disabling the [printers] */
1619 /* entry (if/when the 'available' keyword is implemented!). */
1621 /* the printer name is set to the service name. */
1622 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->_printername,
1623 pszPrintername);
1624 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1626 /* set the browseable flag from the gloabl default */
1627 ServicePtrs[i]->browseable = sDefault.browseable;
1629 /* Printers cannot be read_only. */
1630 ServicePtrs[i]->read_only = false;
1631 /* No oplocks on printer services. */
1632 ServicePtrs[i]->oplocks = false;
1633 /* Printer services must be printable. */
1634 ServicePtrs[i]->printable = true;
1636 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1638 return true;
1642 /***************************************************************************
1643 Check whether the given parameter name is valid.
1644 Parametric options (names containing a colon) are considered valid.
1645 ***************************************************************************/
1647 bool lp_parameter_is_valid(const char *pszParmName)
1649 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1650 (strchr(pszParmName, ':') != NULL));
1653 /***************************************************************************
1654 Check whether the given name is the name of a global parameter.
1655 Returns true for strings belonging to parameters of class
1656 P_GLOBAL, false for all other strings, also for parametric options
1657 and strings not belonging to any option.
1658 ***************************************************************************/
1660 bool lp_parameter_is_global(const char *pszParmName)
1662 int num = lpcfg_map_parameter(pszParmName);
1664 if (num >= 0) {
1665 return (parm_table[num].p_class == P_GLOBAL);
1668 return false;
1671 /**************************************************************************
1672 Determine the canonical name for a parameter.
1673 Indicate when it is an inverse (boolean) synonym instead of a
1674 "usual" synonym.
1675 **************************************************************************/
1677 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1678 bool *inverse)
1680 int num;
1682 if (!lp_parameter_is_valid(parm_name)) {
1683 *canon_parm = NULL;
1684 return false;
1687 num = map_parameter_canonical(parm_name, inverse);
1688 if (num < 0) {
1689 /* parametric option */
1690 *canon_parm = parm_name;
1691 } else {
1692 *canon_parm = parm_table[num].label;
1695 return true;
1699 /**************************************************************************
1700 Determine the canonical name for a parameter.
1701 Turn the value given into the inverse boolean expression when
1702 the synonym is an invers boolean synonym.
1704 Return true if
1705 - parm_name is a valid parameter name and
1706 - val is a valid value for this parameter and
1707 - in case the parameter is an inverse boolean synonym, if the val
1708 string could successfully be converted to the reverse bool.
1709 Return false in all other cases.
1710 **************************************************************************/
1712 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1713 const char *val,
1714 const char **canon_parm,
1715 const char **canon_val)
1717 int num;
1718 bool inverse;
1719 bool ret;
1721 if (!lp_parameter_is_valid(parm_name)) {
1722 *canon_parm = NULL;
1723 *canon_val = NULL;
1724 return false;
1727 num = map_parameter_canonical(parm_name, &inverse);
1728 if (num < 0) {
1729 /* parametric option */
1730 *canon_parm = parm_name;
1731 *canon_val = val;
1732 return true;
1735 *canon_parm = parm_table[num].label;
1736 if (inverse) {
1737 if (!lp_invert_boolean(val, canon_val)) {
1738 *canon_val = NULL;
1739 return false;
1741 } else {
1742 *canon_val = val;
1745 ret = lp_parameter_value_is_valid(*canon_parm, *canon_val);
1747 return ret;
1750 /***************************************************************************
1751 Map a parameter's string representation to the index of the canonical
1752 form of the parameter (it might be a synonym).
1753 Returns -1 if the parameter string is not recognised.
1754 ***************************************************************************/
1756 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1758 int parm_num, canon_num;
1759 bool loc_inverse = false;
1761 parm_num = lpcfg_map_parameter(pszParmName);
1762 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) {
1763 /* invalid, parametric or no canidate for synonyms ... */
1764 goto done;
1767 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1768 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1769 parm_num = canon_num;
1770 goto done;
1774 done:
1775 if (inverse != NULL) {
1776 *inverse = loc_inverse;
1778 return parm_num;
1781 /***************************************************************************
1782 return true if parameter number parm1 is a synonym of parameter
1783 number parm2 (parm2 being the principal name).
1784 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1785 false otherwise.
1786 ***************************************************************************/
1788 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1790 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1791 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1792 (parm_table[parm1].flags & FLAG_SYNONYM) &&
1793 !(parm_table[parm2].flags & FLAG_SYNONYM))
1795 if (inverse != NULL) {
1796 if ((parm_table[parm1].type == P_BOOLREV) &&
1797 (parm_table[parm2].type == P_BOOL))
1799 *inverse = true;
1800 } else {
1801 *inverse = false;
1804 return true;
1806 return false;
1809 /***************************************************************************
1810 Show one parameter's name, type, [values,] and flags.
1811 (helper functions for show_parameter_list)
1812 ***************************************************************************/
1814 static void show_parameter(int parmIndex)
1816 int enumIndex, flagIndex;
1817 int parmIndex2;
1818 bool hadFlag;
1819 bool hadSyn;
1820 bool inverse;
1821 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1822 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1823 "P_ENUM", "P_BYTES", "P_CMDLIST" };
1824 unsigned flags[] = { FLAG_DEPRECATED, FLAG_SYNONYM };
1825 const char *flag_names[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL};
1827 printf("%s=%s", parm_table[parmIndex].label,
1828 type[parm_table[parmIndex].type]);
1829 if (parm_table[parmIndex].type == P_ENUM) {
1830 printf(",");
1831 for (enumIndex=0;
1832 parm_table[parmIndex].enum_list[enumIndex].name;
1833 enumIndex++)
1835 printf("%s%s",
1836 enumIndex ? "|" : "",
1837 parm_table[parmIndex].enum_list[enumIndex].name);
1840 printf(",");
1841 hadFlag = false;
1842 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1843 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1844 printf("%s%s",
1845 hadFlag ? "|" : "",
1846 flag_names[flagIndex]);
1847 hadFlag = true;
1851 /* output synonyms */
1852 hadSyn = false;
1853 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1854 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1855 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1856 parm_table[parmIndex2].label);
1857 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1858 if (!hadSyn) {
1859 printf(" (synonyms: ");
1860 hadSyn = true;
1861 } else {
1862 printf(", ");
1864 printf("%s%s", parm_table[parmIndex2].label,
1865 inverse ? "[i]" : "");
1868 if (hadSyn) {
1869 printf(")");
1872 printf("\n");
1876 * Check the value for a P_ENUM
1878 static bool check_enum_parameter(struct parm_struct *parm, const char *value)
1880 int i;
1882 for (i = 0; parm->enum_list[i].name; i++) {
1883 if (strwicmp(value, parm->enum_list[i].name) == 0) {
1884 return true;
1887 return false;
1890 /**************************************************************************
1891 Check whether the given value is valid for the given parameter name.
1892 **************************************************************************/
1894 static bool lp_parameter_value_is_valid(const char *parm_name, const char *val)
1896 bool ret = false, tmp_bool;
1897 int num = lpcfg_map_parameter(parm_name), tmp_int;
1898 uint64_t tmp_int64 = 0;
1899 struct parm_struct *parm;
1901 /* parametric options (parameter names containing a colon) cannot
1902 be checked and are therefore considered valid. */
1903 if (strchr(parm_name, ':') != NULL) {
1904 return true;
1907 if (num >= 0) {
1908 parm = &parm_table[num];
1909 switch (parm->type) {
1910 case P_BOOL:
1911 case P_BOOLREV:
1912 ret = set_boolean(val, &tmp_bool);
1913 break;
1915 case P_INTEGER:
1916 ret = (sscanf(val, "%d", &tmp_int) == 1);
1917 break;
1919 case P_OCTAL:
1920 ret = (sscanf(val, "%o", &tmp_int) == 1);
1921 break;
1923 case P_ENUM:
1924 ret = check_enum_parameter(parm, val);
1925 break;
1927 case P_BYTES:
1928 if (conv_str_size_error(val, &tmp_int64) &&
1929 tmp_int64 <= INT_MAX) {
1930 ret = true;
1932 break;
1934 case P_CHAR:
1935 case P_LIST:
1936 case P_STRING:
1937 case P_USTRING:
1938 case P_CMDLIST:
1939 ret = true;
1940 break;
1943 return ret;
1946 /***************************************************************************
1947 Show all parameter's name, type, [values,] and flags.
1948 ***************************************************************************/
1950 void show_parameter_list(void)
1952 int classIndex, parmIndex;
1953 const char *section_names[] = { "local", "global", NULL};
1955 for (classIndex=0; section_names[classIndex]; classIndex++) {
1956 printf("[%s]\n", section_names[classIndex]);
1957 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
1958 if (parm_table[parmIndex].p_class == classIndex) {
1959 show_parameter(parmIndex);
1965 /***************************************************************************
1966 Get the standard string representation of a boolean value ("yes" or "no")
1967 ***************************************************************************/
1969 static const char *get_boolean(bool bool_value)
1971 static const char *yes_str = "yes";
1972 static const char *no_str = "no";
1974 return (bool_value ? yes_str : no_str);
1977 /***************************************************************************
1978 Provide the string of the negated boolean value associated to the boolean
1979 given as a string. Returns false if the passed string does not correctly
1980 represent a boolean.
1981 ***************************************************************************/
1983 bool lp_invert_boolean(const char *str, const char **inverse_str)
1985 bool val;
1987 if (!set_boolean(str, &val)) {
1988 return false;
1991 *inverse_str = get_boolean(!val);
1992 return true;
1995 /***************************************************************************
1996 Provide the canonical string representation of a boolean value given
1997 as a string. Return true on success, false if the string given does
1998 not correctly represent a boolean.
1999 ***************************************************************************/
2001 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2003 bool val;
2005 if (!set_boolean(str, &val)) {
2006 return false;
2009 *canon_str = get_boolean(val);
2010 return true;
2013 /***************************************************************************
2014 Find a service by name. Otherwise works like get_service.
2015 ***************************************************************************/
2017 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2019 int iService = -1;
2020 char *canon_name;
2021 TDB_DATA data;
2022 NTSTATUS status;
2024 if (ServiceHash == NULL) {
2025 return -1;
2028 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2030 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2031 &data);
2033 if (NT_STATUS_IS_OK(status) &&
2034 (data.dptr != NULL) &&
2035 (data.dsize == sizeof(iService)))
2037 memcpy(&iService, data.dptr, sizeof(iService));
2040 TALLOC_FREE(canon_name);
2042 if ((iService != -1) && (LP_SNUM_OK(iService))
2043 && (pserviceDest != NULL)) {
2044 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2047 return (iService);
2050 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2051 struct loadparm_service *lp_service(const char *pszServiceName)
2053 int iService = getservicebyname(pszServiceName, NULL);
2054 if (iService == -1 || !LP_SNUM_OK(iService)) {
2055 return NULL;
2057 return ServicePtrs[iService];
2060 struct loadparm_service *lp_servicebynum(int snum)
2062 if ((snum == -1) || !LP_SNUM_OK(snum)) {
2063 return NULL;
2065 return ServicePtrs[snum];
2068 struct loadparm_service *lp_default_loadparm_service()
2070 return &sDefault;
2073 static struct smbconf_ctx *lp_smbconf_ctx(void)
2075 sbcErr err;
2076 static struct smbconf_ctx *conf_ctx = NULL;
2078 if (conf_ctx == NULL) {
2079 err = smbconf_init(NULL, &conf_ctx, "registry:");
2080 if (!SBC_ERROR_IS_OK(err)) {
2081 DEBUG(1, ("error initializing registry configuration: "
2082 "%s\n", sbcErrorString(err)));
2083 conf_ctx = NULL;
2087 return conf_ctx;
2090 static bool process_smbconf_service(struct smbconf_service *service)
2092 uint32_t count;
2093 bool ret;
2095 if (service == NULL) {
2096 return false;
2099 ret = lp_do_section(service->name, NULL);
2100 if (ret != true) {
2101 return false;
2103 for (count = 0; count < service->num_params; count++) {
2105 if (!bInGlobalSection && bGlobalOnly) {
2106 ret = true;
2107 } else {
2108 const char *pszParmName = service->param_names[count];
2109 const char *pszParmValue = service->param_values[count];
2111 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2113 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2114 pszParmName, pszParmValue);
2117 if (ret != true) {
2118 return false;
2121 if (iServiceIndex >= 0) {
2122 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2124 return true;
2128 * load a service from registry and activate it
2130 bool process_registry_service(const char *service_name)
2132 sbcErr err;
2133 struct smbconf_service *service = NULL;
2134 TALLOC_CTX *mem_ctx = talloc_stackframe();
2135 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2136 bool ret = false;
2138 if (conf_ctx == NULL) {
2139 goto done;
2142 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2144 if (!smbconf_share_exists(conf_ctx, service_name)) {
2146 * Registry does not contain data for this service (yet),
2147 * but make sure lp_load doesn't return false.
2149 ret = true;
2150 goto done;
2153 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2154 if (!SBC_ERROR_IS_OK(err)) {
2155 goto done;
2158 ret = process_smbconf_service(service);
2159 if (!ret) {
2160 goto done;
2163 /* store the csn */
2164 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2166 done:
2167 TALLOC_FREE(mem_ctx);
2168 return ret;
2172 * process_registry_globals
2174 static bool process_registry_globals(void)
2176 bool ret;
2178 add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2180 if (!bInGlobalSection && bGlobalOnly) {
2181 ret = true;
2182 } else {
2183 const char *pszParmName = "registry shares";
2184 const char *pszParmValue = "yes";
2186 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2188 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2189 pszParmName, pszParmValue);
2192 if (!ret) {
2193 return ret;
2196 return process_registry_service(GLOBAL_NAME);
2199 bool process_registry_shares(void)
2201 sbcErr err;
2202 uint32_t count;
2203 struct smbconf_service **service = NULL;
2204 uint32_t num_shares = 0;
2205 TALLOC_CTX *mem_ctx = talloc_stackframe();
2206 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2207 bool ret = false;
2209 if (conf_ctx == NULL) {
2210 goto done;
2213 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2214 if (!SBC_ERROR_IS_OK(err)) {
2215 goto done;
2218 ret = true;
2220 for (count = 0; count < num_shares; count++) {
2221 if (strequal(service[count]->name, GLOBAL_NAME)) {
2222 continue;
2224 ret = process_smbconf_service(service[count]);
2225 if (!ret) {
2226 goto done;
2230 /* store the csn */
2231 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2233 done:
2234 TALLOC_FREE(mem_ctx);
2235 return ret;
2239 * reload those shares from registry that are already
2240 * activated in the services array.
2242 static bool reload_registry_shares(void)
2244 int i;
2245 bool ret = true;
2247 for (i = 0; i < iNumServices; i++) {
2248 if (!VALID(i)) {
2249 continue;
2252 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2253 continue;
2256 ret = process_registry_service(ServicePtrs[i]->szService);
2257 if (!ret) {
2258 goto done;
2262 done:
2263 return ret;
2267 #define MAX_INCLUDE_DEPTH 100
2269 static uint8_t include_depth;
2272 * Free the file lists
2274 static void free_file_list(void)
2276 struct file_lists *f;
2277 struct file_lists *next;
2279 f = file_lists;
2280 while( f ) {
2281 next = f->next;
2282 TALLOC_FREE( f );
2283 f = next;
2285 file_lists = NULL;
2290 * Utility function for outsiders to check if we're running on registry.
2292 bool lp_config_backend_is_registry(void)
2294 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2298 * Utility function to check if the config backend is FILE.
2300 bool lp_config_backend_is_file(void)
2302 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2305 /*******************************************************************
2306 Check if a config file has changed date.
2307 ********************************************************************/
2309 bool lp_file_list_changed(void)
2311 struct file_lists *f = file_lists;
2313 DEBUG(6, ("lp_file_list_changed()\n"));
2315 while (f) {
2316 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2317 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2319 if (conf_ctx == NULL) {
2320 return false;
2322 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2323 NULL))
2325 DEBUGADD(6, ("registry config changed\n"));
2326 return true;
2328 } else {
2329 time_t mod_time;
2330 char *n2 = NULL;
2332 n2 = talloc_sub_basic(talloc_tos(),
2333 get_current_username(),
2334 current_user_info.domain,
2335 f->name);
2336 if (!n2) {
2337 return false;
2339 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2340 f->name, n2, ctime(&f->modtime)));
2342 mod_time = file_modtime(n2);
2344 if (mod_time &&
2345 ((f->modtime != mod_time) ||
2346 (f->subfname == NULL) ||
2347 (strcmp(n2, f->subfname) != 0)))
2349 DEBUGADD(6,
2350 ("file %s modified: %s\n", n2,
2351 ctime(&mod_time)));
2352 f->modtime = mod_time;
2353 TALLOC_FREE(f->subfname);
2354 f->subfname = talloc_strdup(f, n2);
2355 if (f->subfname == NULL) {
2356 smb_panic("talloc_strdup failed");
2358 TALLOC_FREE(n2);
2359 return true;
2361 TALLOC_FREE(n2);
2363 f = f->next;
2365 return false;
2370 * Initialize iconv conversion descriptors.
2372 * This is called the first time it is needed, and also called again
2373 * every time the configuration is reloaded, because the charset or
2374 * codepage might have changed.
2376 static void init_iconv(void)
2378 struct smb_iconv_handle *ret = NULL;
2380 ret = reinit_iconv_handle(NULL,
2381 lp_dos_charset(),
2382 lp_unix_charset());
2383 if (ret == NULL) {
2384 smb_panic("reinit_iconv_handle failed");
2388 /***************************************************************************
2389 Handle the include operation.
2390 ***************************************************************************/
2391 static bool bAllowIncludeRegistry = true;
2393 bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2394 const char *pszParmValue, char **ptr)
2396 char *fname;
2398 if (include_depth >= MAX_INCLUDE_DEPTH) {
2399 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2400 include_depth));
2401 return false;
2404 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2405 if (!bAllowIncludeRegistry) {
2406 return true;
2408 if (lp_ctx->bInGlobalSection) {
2409 bool ret;
2410 include_depth++;
2411 ret = process_registry_globals();
2412 include_depth--;
2413 return ret;
2414 } else {
2415 DEBUG(1, ("\"include = registry\" only effective "
2416 "in %s section\n", GLOBAL_NAME));
2417 return false;
2421 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2422 current_user_info.domain,
2423 pszParmValue);
2425 add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2427 if (service == NULL) {
2428 lpcfg_string_set(Globals.ctx, ptr, fname);
2429 } else {
2430 lpcfg_string_set(service, ptr, fname);
2433 if (file_exist(fname)) {
2434 bool ret;
2435 include_depth++;
2436 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2437 include_depth--;
2438 TALLOC_FREE(fname);
2439 return ret;
2442 DEBUG(2, ("Can't find include file %s\n", fname));
2443 TALLOC_FREE(fname);
2444 return true;
2447 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2449 char *config_option = NULL;
2450 const char *range = NULL;
2451 bool ret = false;
2453 SMB_ASSERT(low != NULL);
2454 SMB_ASSERT(high != NULL);
2456 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2457 domain_name = "*";
2460 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2461 domain_name);
2462 if (config_option == NULL) {
2463 DEBUG(0, ("out of memory\n"));
2464 return false;
2467 range = lp_parm_const_string(-1, config_option, "range", NULL);
2468 if (range == NULL) {
2469 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2470 goto done;
2473 if (sscanf(range, "%u - %u", low, high) != 2) {
2474 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2475 range, domain_name));
2476 goto done;
2479 ret = true;
2481 done:
2482 talloc_free(config_option);
2483 return ret;
2487 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2489 return lp_idmap_range("*", low, high);
2492 const char *lp_idmap_backend(const char *domain_name)
2494 char *config_option = NULL;
2495 const char *backend = NULL;
2497 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2498 domain_name = "*";
2501 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2502 domain_name);
2503 if (config_option == NULL) {
2504 DEBUG(0, ("out of memory\n"));
2505 return false;
2508 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2509 if (backend == NULL) {
2510 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2511 goto done;
2514 done:
2515 talloc_free(config_option);
2516 return backend;
2519 const char *lp_idmap_default_backend(void)
2521 return lp_idmap_backend("*");
2524 /***************************************************************************
2525 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2526 ***************************************************************************/
2528 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2530 const char *suffix_string;
2532 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2533 Globals.ldap_suffix );
2534 if ( !suffix_string ) {
2535 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2536 return "";
2539 return suffix_string;
2542 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2544 if (Globals._ldap_machine_suffix[0])
2545 return append_ldap_suffix(ctx, Globals._ldap_machine_suffix);
2547 return lp_string(ctx, Globals.ldap_suffix);
2550 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2552 if (Globals._ldap_user_suffix[0])
2553 return append_ldap_suffix(ctx, Globals._ldap_user_suffix);
2555 return lp_string(ctx, Globals.ldap_suffix);
2558 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2560 if (Globals._ldap_group_suffix[0])
2561 return append_ldap_suffix(ctx, Globals._ldap_group_suffix);
2563 return lp_string(ctx, Globals.ldap_suffix);
2566 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2568 if (Globals._ldap_idmap_suffix[0])
2569 return append_ldap_suffix(ctx, Globals._ldap_idmap_suffix);
2571 return lp_string(ctx, Globals.ldap_suffix);
2575 return the parameter pointer for a parameter
2577 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2579 if (service == NULL) {
2580 if (parm->p_class == P_LOCAL)
2581 return (void *)(((char *)&sDefault)+parm->offset);
2582 else if (parm->p_class == P_GLOBAL)
2583 return (void *)(((char *)&Globals)+parm->offset);
2584 else return NULL;
2585 } else {
2586 return (void *)(((char *)service) + parm->offset);
2590 /***************************************************************************
2591 Process a parameter for a particular service number. If snum < 0
2592 then assume we are in the globals.
2593 ***************************************************************************/
2595 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2597 TALLOC_CTX *frame = talloc_stackframe();
2598 struct loadparm_context *lp_ctx;
2599 bool ok;
2601 lp_ctx = setup_lp_context(frame);
2602 if (lp_ctx == NULL) {
2603 TALLOC_FREE(frame);
2604 return false;
2607 if (snum < 0) {
2608 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2609 } else {
2610 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2611 pszParmName, pszParmValue);
2614 TALLOC_FREE(frame);
2616 return ok;
2619 /***************************************************************************
2620 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2621 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2622 ***************************************************************************/
2624 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2626 int parmnum, i;
2627 parmnum = lpcfg_map_parameter(pszParmName);
2628 if (parmnum >= 0) {
2629 flags_list[parmnum] &= ~FLAG_CMDLINE;
2630 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2631 return false;
2633 flags_list[parmnum] |= FLAG_CMDLINE;
2635 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2636 * be grouped in the table, so we don't have to search the
2637 * whole table */
2638 for (i=parmnum-1;
2639 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2640 && parm_table[i].p_class == parm_table[parmnum].p_class;
2641 i--) {
2642 flags_list[i] |= FLAG_CMDLINE;
2644 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2645 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2646 flags_list[i] |= FLAG_CMDLINE;
2649 return true;
2652 /* it might be parametric */
2653 if (strchr(pszParmName, ':') != NULL) {
2654 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2655 return true;
2658 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2659 return false;
2662 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2664 bool ret;
2665 TALLOC_CTX *frame = talloc_stackframe();
2666 struct loadparm_context *lp_ctx;
2668 lp_ctx = setup_lp_context(frame);
2669 if (lp_ctx == NULL) {
2670 TALLOC_FREE(frame);
2671 return false;
2674 ret = lpcfg_set_cmdline(lp_ctx, pszParmName, pszParmValue);
2676 TALLOC_FREE(frame);
2677 return ret;
2680 /***************************************************************************
2681 Process a parameter.
2682 ***************************************************************************/
2684 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2685 void *userdata)
2687 if (!bInGlobalSection && bGlobalOnly)
2688 return true;
2690 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2692 if (bInGlobalSection) {
2693 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2694 } else {
2695 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2696 pszParmName, pszParmValue);
2700 /***************************************************************************
2701 Initialize any local variables in the sDefault table, after parsing a
2702 [globals] section.
2703 ***************************************************************************/
2705 static void init_locals(void)
2708 * We run this check once the [globals] is parsed, to force
2709 * the VFS objects and other per-share settings we need for
2710 * the standard way a AD DC is operated. We may change these
2711 * as our code evolves, which is why we force these settings.
2713 * We can't do this at the end of lp_load_ex(), as by that
2714 * point the services have been loaded and they will already
2715 * have "" as their vfs objects.
2717 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2718 const char **vfs_objects = lp_vfs_objects(-1);
2719 if (!vfs_objects || !vfs_objects[0]) {
2720 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2721 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2722 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2723 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2724 } else {
2725 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2729 lp_do_parameter(-1, "map hidden", "no");
2730 lp_do_parameter(-1, "map system", "no");
2731 lp_do_parameter(-1, "map readonly", "no");
2732 lp_do_parameter(-1, "map archive", "no");
2733 lp_do_parameter(-1, "store dos attributes", "yes");
2737 /***************************************************************************
2738 Process a new section (service). At this stage all sections are services.
2739 Later we'll have special sections that permit server parameters to be set.
2740 Returns true on success, false on failure.
2741 ***************************************************************************/
2743 bool lp_do_section(const char *pszSectionName, void *userdata)
2745 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2746 bool bRetval;
2747 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2748 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2749 bRetval = false;
2751 /* if we were in a global section then do the local inits */
2752 if (bInGlobalSection && !isglobal)
2753 init_locals();
2755 /* if we've just struck a global section, note the fact. */
2756 bInGlobalSection = isglobal;
2757 if (lp_ctx != NULL) {
2758 lp_ctx->bInGlobalSection = isglobal;
2761 /* check for multiple global sections */
2762 if (bInGlobalSection) {
2763 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2764 return true;
2767 if (!bInGlobalSection && bGlobalOnly)
2768 return true;
2770 /* if we have a current service, tidy it up before moving on */
2771 bRetval = true;
2773 if (iServiceIndex >= 0)
2774 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2776 /* if all is still well, move to the next record in the services array */
2777 if (bRetval) {
2778 /* We put this here to avoid an odd message order if messages are */
2779 /* issued by the post-processing of a previous section. */
2780 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2782 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2783 if (iServiceIndex < 0) {
2784 DEBUG(0, ("Failed to add a new service\n"));
2785 return false;
2787 /* Clean all parametric options for service */
2788 /* They will be added during parsing again */
2789 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2792 return bRetval;
2795 /***************************************************************************
2796 Display the contents of a parameter of a single services record.
2797 ***************************************************************************/
2799 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2801 bool result = false;
2802 struct loadparm_context *lp_ctx;
2804 lp_ctx = setup_lp_context(talloc_tos());
2805 if (lp_ctx == NULL) {
2806 return false;
2809 if (isGlobal) {
2810 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2811 } else {
2812 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2814 TALLOC_FREE(lp_ctx);
2815 return result;
2818 #if 0
2819 /***************************************************************************
2820 Display the contents of a single copy structure.
2821 ***************************************************************************/
2822 static void dump_copy_map(bool *pcopymap)
2824 int i;
2825 if (!pcopymap)
2826 return;
2828 printf("\n\tNon-Copied parameters:\n");
2830 for (i = 0; parm_table[i].label; i++)
2831 if (parm_table[i].p_class == P_LOCAL &&
2832 parm_table[i].ptr && !pcopymap[i] &&
2833 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2835 printf("\t\t%s\n", parm_table[i].label);
2838 #endif
2840 /***************************************************************************
2841 Return TRUE if the passed service number is within range.
2842 ***************************************************************************/
2844 bool lp_snum_ok(int iService)
2846 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->available);
2849 /***************************************************************************
2850 Auto-load some home services.
2851 ***************************************************************************/
2853 static void lp_add_auto_services(char *str)
2855 char *s;
2856 char *p;
2857 int homes;
2858 char *saveptr;
2860 if (!str)
2861 return;
2863 s = talloc_strdup(talloc_tos(), str);
2864 if (!s) {
2865 smb_panic("talloc_strdup failed");
2866 return;
2869 homes = lp_servicenumber(HOMES_NAME);
2871 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
2872 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
2873 char *home;
2875 if (lp_servicenumber(p) >= 0)
2876 continue;
2878 home = get_user_home_dir(talloc_tos(), p);
2880 if (home && home[0] && homes >= 0)
2881 lp_add_home(p, homes, p, home);
2883 TALLOC_FREE(home);
2885 TALLOC_FREE(s);
2888 /***************************************************************************
2889 Auto-load one printer.
2890 ***************************************************************************/
2892 void lp_add_one_printer(const char *name, const char *comment,
2893 const char *location, void *pdata)
2895 int printers = lp_servicenumber(PRINTERS_NAME);
2896 int i;
2898 if (lp_servicenumber(name) < 0) {
2899 lp_add_printer(name, printers);
2900 if ((i = lp_servicenumber(name)) >= 0) {
2901 lpcfg_string_set(ServicePtrs[i],
2902 &ServicePtrs[i]->comment, comment);
2903 ServicePtrs[i]->autoloaded = true;
2908 /***************************************************************************
2909 Have we loaded a services file yet?
2910 ***************************************************************************/
2912 bool lp_loaded(void)
2914 return (bLoaded);
2917 /***************************************************************************
2918 Unload unused services.
2919 ***************************************************************************/
2921 void lp_killunused(struct smbd_server_connection *sconn,
2922 bool (*snumused) (struct smbd_server_connection *, int))
2924 int i;
2925 for (i = 0; i < iNumServices; i++) {
2926 if (!VALID(i))
2927 continue;
2929 /* don't kill autoloaded or usershare services */
2930 if ( ServicePtrs[i]->autoloaded ||
2931 ServicePtrs[i]->usershare == USERSHARE_VALID) {
2932 continue;
2935 if (!snumused || !snumused(sconn, i)) {
2936 free_service_byindex(i);
2942 * Kill all except autoloaded and usershare services - convenience wrapper
2944 void lp_kill_all_services(void)
2946 lp_killunused(NULL, NULL);
2949 /***************************************************************************
2950 Unload a service.
2951 ***************************************************************************/
2953 void lp_killservice(int iServiceIn)
2955 if (VALID(iServiceIn)) {
2956 free_service_byindex(iServiceIn);
2960 /***************************************************************************
2961 Save the curent values of all global and sDefault parameters into the
2962 defaults union. This allows testparm to show only the
2963 changed (ie. non-default) parameters.
2964 ***************************************************************************/
2966 static void lp_save_defaults(void)
2968 int i;
2969 struct parmlist_entry * parm;
2970 for (i = 0; parm_table[i].label; i++) {
2971 if (!(flags_list[i] & FLAG_CMDLINE)) {
2972 flags_list[i] |= FLAG_DEFAULT;
2975 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
2976 && parm_table[i].p_class == parm_table[i - 1].p_class)
2977 continue;
2978 switch (parm_table[i].type) {
2979 case P_LIST:
2980 case P_CMDLIST:
2981 parm_table[i].def.lvalue = str_list_copy(
2982 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
2983 break;
2984 case P_STRING:
2985 case P_USTRING:
2986 lpcfg_string_set(
2987 Globals.ctx,
2988 &parm_table[i].def.svalue,
2989 *(char **)lp_parm_ptr(
2990 NULL, &parm_table[i]));
2991 if (parm_table[i].def.svalue == NULL) {
2992 smb_panic("lpcfg_string_set() failed");
2994 break;
2995 case P_BOOL:
2996 case P_BOOLREV:
2997 parm_table[i].def.bvalue =
2998 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
2999 break;
3000 case P_CHAR:
3001 parm_table[i].def.cvalue =
3002 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3003 break;
3004 case P_INTEGER:
3005 case P_OCTAL:
3006 case P_ENUM:
3007 case P_BYTES:
3008 parm_table[i].def.ivalue =
3009 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3010 break;
3014 for (parm=Globals.param_opt; parm; parm=parm->next) {
3015 if (!(parm->priority & FLAG_CMDLINE)) {
3016 parm->priority |= FLAG_DEFAULT;
3020 for (parm=sDefault.param_opt; parm; parm=parm->next) {
3021 if (!(parm->priority & FLAG_CMDLINE)) {
3022 parm->priority |= FLAG_DEFAULT;
3026 defaults_saved = true;
3029 /***********************************************************
3030 If we should send plaintext/LANMAN passwords in the clinet
3031 ************************************************************/
3033 static void set_allowed_client_auth(void)
3035 if (Globals.client_ntlmv2_auth) {
3036 Globals.client_lanman_auth = false;
3038 if (!Globals.client_lanman_auth) {
3039 Globals.client_plaintext_auth = false;
3043 /***************************************************************************
3044 JRA.
3045 The following code allows smbd to read a user defined share file.
3046 Yes, this is my intent. Yes, I'm comfortable with that...
3048 THE FOLLOWING IS SECURITY CRITICAL CODE.
3050 It washes your clothes, it cleans your house, it guards you while you sleep...
3051 Do not f%^k with it....
3052 ***************************************************************************/
3054 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3056 /***************************************************************************
3057 Check allowed stat state of a usershare file.
3058 Ensure we print out who is dicking with us so the admin can
3059 get their sorry ass fired.
3060 ***************************************************************************/
3062 static bool check_usershare_stat(const char *fname,
3063 const SMB_STRUCT_STAT *psbuf)
3065 if (!S_ISREG(psbuf->st_ex_mode)) {
3066 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3067 "not a regular file\n",
3068 fname, (unsigned int)psbuf->st_ex_uid ));
3069 return false;
3072 /* Ensure this doesn't have the other write bit set. */
3073 if (psbuf->st_ex_mode & S_IWOTH) {
3074 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3075 "public write. Refusing to allow as a usershare file.\n",
3076 fname, (unsigned int)psbuf->st_ex_uid ));
3077 return false;
3080 /* Should be 10k or less. */
3081 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
3082 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3083 "too large (%u) to be a user share file.\n",
3084 fname, (unsigned int)psbuf->st_ex_uid,
3085 (unsigned int)psbuf->st_ex_size ));
3086 return false;
3089 return true;
3092 /***************************************************************************
3093 Parse the contents of a usershare file.
3094 ***************************************************************************/
3096 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
3097 SMB_STRUCT_STAT *psbuf,
3098 const char *servicename,
3099 int snum,
3100 char **lines,
3101 int numlines,
3102 char **pp_sharepath,
3103 char **pp_comment,
3104 char **pp_cp_servicename,
3105 struct security_descriptor **ppsd,
3106 bool *pallow_guest)
3108 const char **prefixallowlist = lp_usershare_prefix_allow_list();
3109 const char **prefixdenylist = lp_usershare_prefix_deny_list();
3110 int us_vers;
3111 DIR *dp;
3112 SMB_STRUCT_STAT sbuf;
3113 char *sharepath = NULL;
3114 char *comment = NULL;
3116 *pp_sharepath = NULL;
3117 *pp_comment = NULL;
3119 *pallow_guest = false;
3121 if (numlines < 4) {
3122 return USERSHARE_MALFORMED_FILE;
3125 if (strcmp(lines[0], "#VERSION 1") == 0) {
3126 us_vers = 1;
3127 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3128 us_vers = 2;
3129 if (numlines < 5) {
3130 return USERSHARE_MALFORMED_FILE;
3132 } else {
3133 return USERSHARE_BAD_VERSION;
3136 if (strncmp(lines[1], "path=", 5) != 0) {
3137 return USERSHARE_MALFORMED_PATH;
3140 sharepath = talloc_strdup(ctx, &lines[1][5]);
3141 if (!sharepath) {
3142 return USERSHARE_POSIX_ERR;
3144 trim_string(sharepath, " ", " ");
3146 if (strncmp(lines[2], "comment=", 8) != 0) {
3147 return USERSHARE_MALFORMED_COMMENT_DEF;
3150 comment = talloc_strdup(ctx, &lines[2][8]);
3151 if (!comment) {
3152 return USERSHARE_POSIX_ERR;
3154 trim_string(comment, " ", " ");
3155 trim_char(comment, '"', '"');
3157 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3158 return USERSHARE_MALFORMED_ACL_DEF;
3161 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3162 return USERSHARE_ACL_ERR;
3165 if (us_vers == 2) {
3166 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3167 return USERSHARE_MALFORMED_ACL_DEF;
3169 if (lines[4][9] == 'y') {
3170 *pallow_guest = true;
3173 /* Backwards compatible extension to file version #2. */
3174 if (numlines > 5) {
3175 if (strncmp(lines[5], "sharename=", 10) != 0) {
3176 return USERSHARE_MALFORMED_SHARENAME_DEF;
3178 if (!strequal(&lines[5][10], servicename)) {
3179 return USERSHARE_BAD_SHARENAME;
3181 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3182 if (!*pp_cp_servicename) {
3183 return USERSHARE_POSIX_ERR;
3188 if (*pp_cp_servicename == NULL) {
3189 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3190 if (!*pp_cp_servicename) {
3191 return USERSHARE_POSIX_ERR;
3195 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3196 /* Path didn't change, no checks needed. */
3197 *pp_sharepath = sharepath;
3198 *pp_comment = comment;
3199 return USERSHARE_OK;
3202 /* The path *must* be absolute. */
3203 if (sharepath[0] != '/') {
3204 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3205 servicename, sharepath));
3206 return USERSHARE_PATH_NOT_ABSOLUTE;
3209 /* If there is a usershare prefix deny list ensure one of these paths
3210 doesn't match the start of the user given path. */
3211 if (prefixdenylist) {
3212 int i;
3213 for ( i=0; prefixdenylist[i]; i++ ) {
3214 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3215 servicename, i, prefixdenylist[i], sharepath ));
3216 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3217 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3218 "usershare prefix deny list entries.\n",
3219 servicename, sharepath));
3220 return USERSHARE_PATH_IS_DENIED;
3225 /* If there is a usershare prefix allow list ensure one of these paths
3226 does match the start of the user given path. */
3228 if (prefixallowlist) {
3229 int i;
3230 for ( i=0; prefixallowlist[i]; i++ ) {
3231 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3232 servicename, i, prefixallowlist[i], sharepath ));
3233 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3234 break;
3237 if (prefixallowlist[i] == NULL) {
3238 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3239 "usershare prefix allow list entries.\n",
3240 servicename, sharepath));
3241 return USERSHARE_PATH_NOT_ALLOWED;
3245 /* Ensure this is pointing to a directory. */
3246 dp = opendir(sharepath);
3248 if (!dp) {
3249 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3250 servicename, sharepath));
3251 return USERSHARE_PATH_NOT_DIRECTORY;
3254 /* Ensure the owner of the usershare file has permission to share
3255 this directory. */
3257 if (sys_stat(sharepath, &sbuf, false) == -1) {
3258 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3259 servicename, sharepath, strerror(errno) ));
3260 closedir(dp);
3261 return USERSHARE_POSIX_ERR;
3264 closedir(dp);
3266 if (!S_ISDIR(sbuf.st_ex_mode)) {
3267 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3268 servicename, sharepath ));
3269 return USERSHARE_PATH_NOT_DIRECTORY;
3272 /* Check if sharing is restricted to owner-only. */
3273 /* psbuf is the stat of the usershare definition file,
3274 sbuf is the stat of the target directory to be shared. */
3276 if (lp_usershare_owner_only()) {
3277 /* root can share anything. */
3278 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3279 return USERSHARE_PATH_NOT_ALLOWED;
3283 *pp_sharepath = sharepath;
3284 *pp_comment = comment;
3285 return USERSHARE_OK;
3288 /***************************************************************************
3289 Deal with a usershare file.
3290 Returns:
3291 >= 0 - snum
3292 -1 - Bad name, invalid contents.
3293 - service name already existed and not a usershare, problem
3294 with permissions to share directory etc.
3295 ***************************************************************************/
3297 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3299 SMB_STRUCT_STAT sbuf;
3300 SMB_STRUCT_STAT lsbuf;
3301 char *fname = NULL;
3302 char *sharepath = NULL;
3303 char *comment = NULL;
3304 char *cp_service_name = NULL;
3305 char **lines = NULL;
3306 int numlines = 0;
3307 int fd = -1;
3308 int iService = -1;
3309 TALLOC_CTX *ctx = talloc_stackframe();
3310 struct security_descriptor *psd = NULL;
3311 bool guest_ok = false;
3312 char *canon_name = NULL;
3313 bool added_service = false;
3314 int ret = -1;
3316 /* Ensure share name doesn't contain invalid characters. */
3317 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3318 DEBUG(0,("process_usershare_file: share name %s contains "
3319 "invalid characters (any of %s)\n",
3320 file_name, INVALID_SHARENAME_CHARS ));
3321 goto out;
3324 canon_name = canonicalize_servicename(ctx, file_name);
3325 if (!canon_name) {
3326 goto out;
3329 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3330 if (!fname) {
3331 goto out;
3334 /* Minimize the race condition by doing an lstat before we
3335 open and fstat. Ensure this isn't a symlink link. */
3337 if (sys_lstat(fname, &lsbuf, false) != 0) {
3338 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3339 fname, strerror(errno) ));
3340 goto out;
3343 /* This must be a regular file, not a symlink, directory or
3344 other strange filetype. */
3345 if (!check_usershare_stat(fname, &lsbuf)) {
3346 goto out;
3350 TDB_DATA data;
3351 NTSTATUS status;
3353 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3354 canon_name, &data);
3356 iService = -1;
3358 if (NT_STATUS_IS_OK(status) &&
3359 (data.dptr != NULL) &&
3360 (data.dsize == sizeof(iService))) {
3361 memcpy(&iService, data.dptr, sizeof(iService));
3365 if (iService != -1 &&
3366 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3367 &lsbuf.st_ex_mtime) == 0) {
3368 /* Nothing changed - Mark valid and return. */
3369 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3370 canon_name ));
3371 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3372 ret = iService;
3373 goto out;
3376 /* Try and open the file read only - no symlinks allowed. */
3377 #ifdef O_NOFOLLOW
3378 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3379 #else
3380 fd = open(fname, O_RDONLY, 0);
3381 #endif
3383 if (fd == -1) {
3384 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3385 fname, strerror(errno) ));
3386 goto out;
3389 /* Now fstat to be *SURE* it's a regular file. */
3390 if (sys_fstat(fd, &sbuf, false) != 0) {
3391 close(fd);
3392 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3393 fname, strerror(errno) ));
3394 goto out;
3397 /* Is it the same dev/inode as was lstated ? */
3398 if (!check_same_stat(&lsbuf, &sbuf)) {
3399 close(fd);
3400 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3401 "Symlink spoofing going on ?\n", fname ));
3402 goto out;
3405 /* This must be a regular file, not a symlink, directory or
3406 other strange filetype. */
3407 if (!check_usershare_stat(fname, &sbuf)) {
3408 close(fd);
3409 goto out;
3412 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3414 close(fd);
3415 if (lines == NULL) {
3416 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3417 fname, (unsigned int)sbuf.st_ex_uid ));
3418 goto out;
3421 if (parse_usershare_file(ctx, &sbuf, file_name,
3422 iService, lines, numlines, &sharepath,
3423 &comment, &cp_service_name,
3424 &psd, &guest_ok) != USERSHARE_OK) {
3425 goto out;
3428 /* Everything ok - add the service possibly using a template. */
3429 if (iService < 0) {
3430 const struct loadparm_service *sp = &sDefault;
3431 if (snum_template != -1) {
3432 sp = ServicePtrs[snum_template];
3435 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3436 DEBUG(0, ("process_usershare_file: Failed to add "
3437 "new service %s\n", cp_service_name));
3438 goto out;
3441 added_service = true;
3443 /* Read only is controlled by usershare ACL below. */
3444 ServicePtrs[iService]->read_only = false;
3447 /* Write the ACL of the new/modified share. */
3448 if (!set_share_security(canon_name, psd)) {
3449 DEBUG(0, ("process_usershare_file: Failed to set share "
3450 "security for user share %s\n",
3451 canon_name ));
3452 goto out;
3455 /* If from a template it may be marked invalid. */
3456 ServicePtrs[iService]->valid = true;
3458 /* Set the service as a valid usershare. */
3459 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3461 /* Set guest access. */
3462 if (lp_usershare_allow_guests()) {
3463 ServicePtrs[iService]->guest_ok = guest_ok;
3466 /* And note when it was loaded. */
3467 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3468 lpcfg_string_set(ServicePtrs[iService], &ServicePtrs[iService]->path,
3469 sharepath);
3470 lpcfg_string_set(ServicePtrs[iService],
3471 &ServicePtrs[iService]->comment, comment);
3473 ret = iService;
3475 out:
3477 if (ret == -1 && iService != -1 && added_service) {
3478 lp_remove_service(iService);
3481 TALLOC_FREE(lines);
3482 TALLOC_FREE(ctx);
3483 return ret;
3486 /***************************************************************************
3487 Checks if a usershare entry has been modified since last load.
3488 ***************************************************************************/
3490 static bool usershare_exists(int iService, struct timespec *last_mod)
3492 SMB_STRUCT_STAT lsbuf;
3493 const char *usersharepath = Globals.usershare_path;
3494 char *fname;
3496 fname = talloc_asprintf(talloc_tos(),
3497 "%s/%s",
3498 usersharepath,
3499 ServicePtrs[iService]->szService);
3500 if (fname == NULL) {
3501 return false;
3504 if (sys_lstat(fname, &lsbuf, false) != 0) {
3505 TALLOC_FREE(fname);
3506 return false;
3509 if (!S_ISREG(lsbuf.st_ex_mode)) {
3510 TALLOC_FREE(fname);
3511 return false;
3514 TALLOC_FREE(fname);
3515 *last_mod = lsbuf.st_ex_mtime;
3516 return true;
3519 static bool usershare_directory_is_root(uid_t uid)
3521 if (uid == 0) {
3522 return true;
3525 if (uid_wrapper_enabled()) {
3526 return true;
3529 return false;
3532 /***************************************************************************
3533 Load a usershare service by name. Returns a valid servicenumber or -1.
3534 ***************************************************************************/
3536 int load_usershare_service(const char *servicename)
3538 SMB_STRUCT_STAT sbuf;
3539 const char *usersharepath = Globals.usershare_path;
3540 int max_user_shares = Globals.usershare_max_shares;
3541 int snum_template = -1;
3543 if (*usersharepath == 0 || max_user_shares == 0) {
3544 return -1;
3547 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3548 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3549 usersharepath, strerror(errno) ));
3550 return -1;
3553 if (!S_ISDIR(sbuf.st_ex_mode)) {
3554 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3555 usersharepath ));
3556 return -1;
3560 * This directory must be owned by root, and have the 't' bit set.
3561 * It also must not be writable by "other".
3564 #ifdef S_ISVTX
3565 if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
3566 !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3567 #else
3568 if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
3569 (sbuf.st_ex_mode & S_IWOTH)) {
3570 #endif
3571 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3572 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3573 usersharepath ));
3574 return -1;
3577 /* Ensure the template share exists if it's set. */
3578 if (Globals.usershare_template_share[0]) {
3579 /* We can't use lp_servicenumber here as we are recommending that
3580 template shares have -valid=false set. */
3581 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3582 if (ServicePtrs[snum_template]->szService &&
3583 strequal(ServicePtrs[snum_template]->szService,
3584 Globals.usershare_template_share)) {
3585 break;
3589 if (snum_template == -1) {
3590 DEBUG(0,("load_usershare_service: usershare template share %s "
3591 "does not exist.\n",
3592 Globals.usershare_template_share ));
3593 return -1;
3597 return process_usershare_file(usersharepath, servicename, snum_template);
3600 /***************************************************************************
3601 Load all user defined shares from the user share directory.
3602 We only do this if we're enumerating the share list.
3603 This is the function that can delete usershares that have
3604 been removed.
3605 ***************************************************************************/
3607 int load_usershare_shares(struct smbd_server_connection *sconn,
3608 bool (*snumused) (struct smbd_server_connection *, int))
3610 DIR *dp;
3611 SMB_STRUCT_STAT sbuf;
3612 struct dirent *de;
3613 int num_usershares = 0;
3614 int max_user_shares = Globals.usershare_max_shares;
3615 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3616 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3617 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3618 int iService;
3619 int snum_template = -1;
3620 const char *usersharepath = Globals.usershare_path;
3621 int ret = lp_numservices();
3622 TALLOC_CTX *tmp_ctx;
3624 if (max_user_shares == 0 || *usersharepath == '\0') {
3625 return lp_numservices();
3628 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3629 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3630 usersharepath, strerror(errno) ));
3631 return ret;
3635 * This directory must be owned by root, and have the 't' bit set.
3636 * It also must not be writable by "other".
3639 #ifdef S_ISVTX
3640 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3641 #else
3642 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3643 #endif
3644 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3645 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3646 usersharepath ));
3647 return ret;
3650 /* Ensure the template share exists if it's set. */
3651 if (Globals.usershare_template_share[0]) {
3652 /* We can't use lp_servicenumber here as we are recommending that
3653 template shares have -valid=false set. */
3654 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3655 if (ServicePtrs[snum_template]->szService &&
3656 strequal(ServicePtrs[snum_template]->szService,
3657 Globals.usershare_template_share)) {
3658 break;
3662 if (snum_template == -1) {
3663 DEBUG(0,("load_usershare_shares: usershare template share %s "
3664 "does not exist.\n",
3665 Globals.usershare_template_share ));
3666 return ret;
3670 /* Mark all existing usershares as pending delete. */
3671 for (iService = iNumServices - 1; iService >= 0; iService--) {
3672 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3673 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3677 dp = opendir(usersharepath);
3678 if (!dp) {
3679 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3680 usersharepath, strerror(errno) ));
3681 return ret;
3684 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3685 (de = readdir(dp));
3686 num_dir_entries++ ) {
3687 int r;
3688 const char *n = de->d_name;
3690 /* Ignore . and .. */
3691 if (*n == '.') {
3692 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3693 continue;
3697 if (n[0] == ':') {
3698 /* Temporary file used when creating a share. */
3699 num_tmp_dir_entries++;
3702 /* Allow 20% tmp entries. */
3703 if (num_tmp_dir_entries > allowed_tmp_entries) {
3704 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3705 "in directory %s\n",
3706 num_tmp_dir_entries, usersharepath));
3707 break;
3710 r = process_usershare_file(usersharepath, n, snum_template);
3711 if (r == 0) {
3712 /* Update the services count. */
3713 num_usershares++;
3714 if (num_usershares >= max_user_shares) {
3715 DEBUG(0,("load_usershare_shares: max user shares reached "
3716 "on file %s in directory %s\n",
3717 n, usersharepath ));
3718 break;
3720 } else if (r == -1) {
3721 num_bad_dir_entries++;
3724 /* Allow 20% bad entries. */
3725 if (num_bad_dir_entries > allowed_bad_entries) {
3726 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3727 "in directory %s\n",
3728 num_bad_dir_entries, usersharepath));
3729 break;
3732 /* Allow 20% bad entries. */
3733 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3734 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3735 "in directory %s\n",
3736 num_dir_entries, usersharepath));
3737 break;
3741 closedir(dp);
3743 /* Sweep through and delete any non-refreshed usershares that are
3744 not currently in use. */
3745 tmp_ctx = talloc_stackframe();
3746 for (iService = iNumServices - 1; iService >= 0; iService--) {
3747 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3748 char *servname;
3750 if (snumused && snumused(sconn, iService)) {
3751 continue;
3754 servname = lp_servicename(tmp_ctx, iService);
3756 /* Remove from the share ACL db. */
3757 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3758 servname ));
3759 delete_share_security(servname);
3760 free_service_byindex(iService);
3763 talloc_free(tmp_ctx);
3765 return lp_numservices();
3768 /********************************************************
3769 Destroy global resources allocated in this file
3770 ********************************************************/
3772 void gfree_loadparm(void)
3774 int i;
3776 free_file_list();
3778 /* Free resources allocated to services */
3780 for ( i = 0; i < iNumServices; i++ ) {
3781 if ( VALID(i) ) {
3782 free_service_byindex(i);
3786 TALLOC_FREE( ServicePtrs );
3787 iNumServices = 0;
3789 /* Now release all resources allocated to global
3790 parameters and the default service */
3792 free_global_parameters();
3796 /***************************************************************************
3797 Allow client apps to specify that they are a client
3798 ***************************************************************************/
3799 static void lp_set_in_client(bool b)
3801 in_client = b;
3805 /***************************************************************************
3806 Determine if we're running in a client app
3807 ***************************************************************************/
3808 static bool lp_is_in_client(void)
3810 return in_client;
3813 static void lp_enforce_ad_dc_settings(void)
3815 lp_do_parameter(GLOBAL_SECTION_SNUM, "passdb backend", "samba_dsdb");
3816 lp_do_parameter(GLOBAL_SECTION_SNUM,
3817 "winbindd:use external pipes", "true");
3818 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:default", "external");
3819 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:svcctl", "embedded");
3820 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:srvsvc", "embedded");
3821 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:eventlog", "embedded");
3822 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:ntsvcs", "embedded");
3823 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:winreg", "embedded");
3824 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:spoolss", "embedded");
3825 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_daemon:spoolssd", "embedded");
3826 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:tcpip", "no");
3829 /***************************************************************************
3830 Load the services array from the services file. Return true on success,
3831 false on failure.
3832 ***************************************************************************/
3834 static bool lp_load_ex(const char *pszFname,
3835 bool global_only,
3836 bool save_defaults,
3837 bool add_ipc,
3838 bool reinit_globals,
3839 bool allow_include_registry,
3840 bool load_all_shares)
3842 char *n2 = NULL;
3843 bool bRetval;
3844 TALLOC_CTX *frame = talloc_stackframe();
3845 struct loadparm_context *lp_ctx;
3847 bRetval = false;
3849 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3851 bInGlobalSection = true;
3852 bGlobalOnly = global_only;
3853 bAllowIncludeRegistry = allow_include_registry;
3855 lp_ctx = setup_lp_context(talloc_tos());
3857 init_globals(lp_ctx, reinit_globals);
3859 free_file_list();
3861 if (save_defaults) {
3862 init_locals();
3863 lp_save_defaults();
3866 if (!reinit_globals) {
3867 free_param_opts(&Globals.param_opt);
3868 apply_lp_set_cmdline();
3871 lp_do_parameter(-1, "idmap config * : backend", Globals.idmap_backend);
3873 /* We get sections first, so have to start 'behind' to make up */
3874 iServiceIndex = -1;
3876 if (lp_config_backend_is_file()) {
3877 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
3878 current_user_info.domain,
3879 pszFname);
3880 if (!n2) {
3881 smb_panic("lp_load_ex: out of memory");
3884 add_to_file_list(NULL, &file_lists, pszFname, n2);
3886 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
3887 TALLOC_FREE(n2);
3889 /* finish up the last section */
3890 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3891 if (bRetval) {
3892 if (iServiceIndex >= 0) {
3893 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
3897 if (lp_config_backend_is_registry()) {
3898 bool ok;
3899 /* config backend changed to registry in config file */
3901 * We need to use this extra global variable here to
3902 * survive restart: init_globals uses this as a default
3903 * for config_backend. Otherwise, init_globals would
3904 * send us into an endless loop here.
3907 config_backend = CONFIG_BACKEND_REGISTRY;
3908 /* start over */
3909 DEBUG(1, ("lp_load_ex: changing to config backend "
3910 "registry\n"));
3911 init_globals(lp_ctx, true);
3913 TALLOC_FREE(lp_ctx);
3915 lp_kill_all_services();
3916 ok = lp_load_ex(pszFname, global_only, save_defaults,
3917 add_ipc, reinit_globals,
3918 allow_include_registry,
3919 load_all_shares);
3920 TALLOC_FREE(frame);
3921 return ok;
3923 } else if (lp_config_backend_is_registry()) {
3924 bRetval = process_registry_globals();
3925 } else {
3926 DEBUG(0, ("Illegal config backend given: %d\n",
3927 lp_config_backend()));
3928 bRetval = false;
3931 if (bRetval && lp_registry_shares()) {
3932 if (load_all_shares) {
3933 bRetval = process_registry_shares();
3934 } else {
3935 bRetval = reload_registry_shares();
3940 char *serv = lp_auto_services(talloc_tos());
3941 lp_add_auto_services(serv);
3942 TALLOC_FREE(serv);
3945 if (add_ipc) {
3946 /* When 'restrict anonymous = 2' guest connections to ipc$
3947 are denied */
3948 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3949 if ( lp_enable_asu_support() ) {
3950 lp_add_ipc("ADMIN$", false);
3954 set_allowed_client_auth();
3956 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
3957 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
3958 lp_password_server()));
3961 bLoaded = true;
3963 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
3964 /* if we_are_a_wins_server is true and we are in the client */
3965 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
3966 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
3969 init_iconv();
3971 fault_configure(smb_panic_s3);
3974 * We run this check once the whole smb.conf is parsed, to
3975 * force some settings for the standard way a AD DC is
3976 * operated. We may change these as our code evolves, which
3977 * is why we force these settings.
3979 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3980 lp_enforce_ad_dc_settings();
3983 bAllowIncludeRegistry = true;
3985 TALLOC_FREE(frame);
3986 return (bRetval);
3989 static bool lp_load(const char *pszFname,
3990 bool global_only,
3991 bool save_defaults,
3992 bool add_ipc,
3993 bool reinit_globals)
3995 return lp_load_ex(pszFname,
3996 global_only,
3997 save_defaults,
3998 add_ipc,
3999 reinit_globals,
4000 true, /* allow_include_registry */
4001 false); /* load_all_shares*/
4004 bool lp_load_initial_only(const char *pszFname)
4006 return lp_load_ex(pszFname,
4007 true, /* global only */
4008 true, /* save_defaults */
4009 false, /* add_ipc */
4010 true, /* reinit_globals */
4011 false, /* allow_include_registry */
4012 false); /* load_all_shares*/
4016 * most common lp_load wrapper, loading only the globals
4018 * If this is used in a daemon or client utility it should be called
4019 * after processing popt.
4021 bool lp_load_global(const char *file_name)
4023 return lp_load(file_name,
4024 true, /* global_only */
4025 false, /* save_defaults */
4026 false, /* add_ipc */
4027 true); /* reinit_globals */
4031 * The typical lp_load wrapper with shares, loads global and
4032 * shares, including IPC, but does not force immediate
4033 * loading of all shares from registry.
4035 bool lp_load_with_shares(const char *file_name)
4037 return lp_load(file_name,
4038 false, /* global_only */
4039 false, /* save_defaults */
4040 true, /* add_ipc */
4041 true); /* reinit_globals */
4045 * lp_load wrapper, especially for clients
4047 bool lp_load_client(const char *file_name)
4049 lp_set_in_client(true);
4051 return lp_load_global(file_name);
4055 * lp_load wrapper, loading only globals, but intended
4056 * for subsequent calls, not reinitializing the globals
4057 * to default values
4059 bool lp_load_global_no_reinit(const char *file_name)
4061 return lp_load(file_name,
4062 true, /* global_only */
4063 false, /* save_defaults */
4064 false, /* add_ipc */
4065 false); /* reinit_globals */
4069 * lp_load wrapper, loading globals and shares,
4070 * intended for subsequent calls, i.e. not reinitializing
4071 * the globals to default values.
4073 bool lp_load_no_reinit(const char *file_name)
4075 return lp_load(file_name,
4076 false, /* global_only */
4077 false, /* save_defaults */
4078 false, /* add_ipc */
4079 false); /* reinit_globals */
4084 * lp_load wrapper, especially for clients, no reinitialization
4086 bool lp_load_client_no_reinit(const char *file_name)
4088 lp_set_in_client(true);
4090 return lp_load_global_no_reinit(file_name);
4093 bool lp_load_with_registry_shares(const char *pszFname)
4095 return lp_load_ex(pszFname,
4096 false, /* global_only */
4097 true, /* save_defaults */
4098 false, /* add_ipc */
4099 false, /* reinit_globals */
4100 true, /* allow_include_registry */
4101 true); /* load_all_shares*/
4104 /***************************************************************************
4105 Return the max number of services.
4106 ***************************************************************************/
4108 int lp_numservices(void)
4110 return (iNumServices);
4113 /***************************************************************************
4114 Display the contents of the services array in human-readable form.
4115 ***************************************************************************/
4117 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4119 int iService;
4120 struct loadparm_context *lp_ctx;
4122 if (show_defaults)
4123 defaults_saved = false;
4125 lp_ctx = setup_lp_context(talloc_tos());
4126 if (lp_ctx == NULL) {
4127 return;
4130 lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
4132 lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
4134 for (iService = 0; iService < maxtoprint; iService++) {
4135 fprintf(f,"\n");
4136 lp_dump_one(f, show_defaults, iService);
4140 /***************************************************************************
4141 Display the contents of one service in human-readable form.
4142 ***************************************************************************/
4144 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4146 if (VALID(snum)) {
4147 if (ServicePtrs[snum]->szService[0] == '\0')
4148 return;
4149 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
4150 flags_list, show_defaults);
4154 /***************************************************************************
4155 Return the number of the service with the given name, or -1 if it doesn't
4156 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4157 getservicebyname()! This works ONLY if all services have been loaded, and
4158 does not copy the found service.
4159 ***************************************************************************/
4161 int lp_servicenumber(const char *pszServiceName)
4163 int iService;
4164 fstring serviceName;
4166 if (!pszServiceName) {
4167 return GLOBAL_SECTION_SNUM;
4170 for (iService = iNumServices - 1; iService >= 0; iService--) {
4171 if (VALID(iService) && ServicePtrs[iService]->szService) {
4173 * The substitution here is used to support %U in
4174 * service names
4176 fstrcpy(serviceName, ServicePtrs[iService]->szService);
4177 standard_sub_basic(get_current_username(),
4178 current_user_info.domain,
4179 serviceName,sizeof(serviceName));
4180 if (strequal(serviceName, pszServiceName)) {
4181 break;
4186 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4187 struct timespec last_mod;
4189 if (!usershare_exists(iService, &last_mod)) {
4190 /* Remove the share security tdb entry for it. */
4191 delete_share_security(lp_servicename(talloc_tos(), iService));
4192 /* Remove it from the array. */
4193 free_service_byindex(iService);
4194 /* Doesn't exist anymore. */
4195 return GLOBAL_SECTION_SNUM;
4198 /* Has it been modified ? If so delete and reload. */
4199 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4200 &last_mod) < 0) {
4201 /* Remove it from the array. */
4202 free_service_byindex(iService);
4203 /* and now reload it. */
4204 iService = load_usershare_service(pszServiceName);
4208 if (iService < 0) {
4209 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4210 return GLOBAL_SECTION_SNUM;
4213 return (iService);
4216 /*******************************************************************
4217 A useful volume label function.
4218 ********************************************************************/
4220 const char *volume_label(TALLOC_CTX *ctx, int snum)
4222 char *ret;
4223 const char *label = lp_volume(ctx, snum);
4224 if (!*label) {
4225 label = lp_servicename(ctx, snum);
4228 /* This returns a 33 byte guarenteed null terminated string. */
4229 ret = talloc_strndup(ctx, label, 32);
4230 if (!ret) {
4231 return "";
4233 return ret;
4236 /*******************************************************************
4237 Get the default server type we will announce as via nmbd.
4238 ********************************************************************/
4240 int lp_default_server_announce(void)
4242 int default_server_announce = 0;
4243 default_server_announce |= SV_TYPE_WORKSTATION;
4244 default_server_announce |= SV_TYPE_SERVER;
4245 default_server_announce |= SV_TYPE_SERVER_UNIX;
4247 /* note that the flag should be set only if we have a
4248 printer service but nmbd doesn't actually load the
4249 services so we can't tell --jerry */
4251 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4253 default_server_announce |= SV_TYPE_SERVER_NT;
4254 default_server_announce |= SV_TYPE_NT;
4256 switch (lp_server_role()) {
4257 case ROLE_DOMAIN_MEMBER:
4258 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4259 break;
4260 case ROLE_DOMAIN_PDC:
4261 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4262 break;
4263 case ROLE_DOMAIN_BDC:
4264 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4265 break;
4266 case ROLE_STANDALONE:
4267 default:
4268 break;
4270 if (lp_time_server())
4271 default_server_announce |= SV_TYPE_TIME_SOURCE;
4273 if (lp_host_msdfs())
4274 default_server_announce |= SV_TYPE_DFS_SERVER;
4276 return default_server_announce;
4279 /***********************************************************
4280 If we are PDC then prefer us as DMB
4281 ************************************************************/
4283 bool lp_domain_master(void)
4285 if (Globals._domain_master == Auto)
4286 return (lp_server_role() == ROLE_DOMAIN_PDC);
4288 return (bool)Globals._domain_master;
4291 /***********************************************************
4292 If we are PDC then prefer us as DMB
4293 ************************************************************/
4295 static bool lp_domain_master_true_or_auto(void)
4297 if (Globals._domain_master) /* auto or yes */
4298 return true;
4300 return false;
4303 /***********************************************************
4304 If we are DMB then prefer us as LMB
4305 ************************************************************/
4307 bool lp_preferred_master(void)
4309 int preferred_master = lp__preferred_master();
4311 if (preferred_master == Auto)
4312 return (lp_local_master() && lp_domain_master());
4314 return (bool)preferred_master;
4317 /*******************************************************************
4318 Remove a service.
4319 ********************************************************************/
4321 void lp_remove_service(int snum)
4323 ServicePtrs[snum]->valid = false;
4326 const char *lp_printername(TALLOC_CTX *ctx, int snum)
4328 const char *ret = lp__printername(ctx, snum);
4329 if (ret == NULL || *ret == '\0') {
4330 ret = lp_const_servicename(snum);
4333 return ret;
4337 /***********************************************************
4338 Allow daemons such as winbindd to fix their logfile name.
4339 ************************************************************/
4341 void lp_set_logfile(const char *name)
4343 lpcfg_string_set(Globals.ctx, &Globals.logfile, name);
4344 debug_set_logfile(name);
4347 /*******************************************************************
4348 Return the max print jobs per queue.
4349 ********************************************************************/
4351 int lp_maxprintjobs(int snum)
4353 int maxjobs = lp_max_print_jobs(snum);
4355 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4356 maxjobs = PRINT_MAX_JOBID - 1;
4358 return maxjobs;
4361 const char *lp_printcapname(void)
4363 const char *printcap_name = lp_printcap_name();
4365 if ((printcap_name != NULL) &&
4366 (printcap_name[0] != '\0'))
4367 return printcap_name;
4369 if (sDefault.printing == PRINT_CUPS) {
4370 return "cups";
4373 if (sDefault.printing == PRINT_BSD)
4374 return "/etc/printcap";
4376 return PRINTCAP_NAME;
4379 static uint32_t spoolss_state;
4381 bool lp_disable_spoolss( void )
4383 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4384 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4386 return spoolss_state == SVCCTL_STOPPED ? true : false;
4389 void lp_set_spoolss_state( uint32_t state )
4391 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4393 spoolss_state = state;
4396 uint32_t lp_get_spoolss_state( void )
4398 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4401 /*******************************************************************
4402 Ensure we don't use sendfile if server smb signing is active.
4403 ********************************************************************/
4405 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
4407 bool sign_active = false;
4409 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4410 if (get_Protocol() < PROTOCOL_NT1) {
4411 return false;
4413 if (signing_state) {
4414 sign_active = smb_signing_is_active(signing_state);
4416 return (lp__use_sendfile(snum) &&
4417 (get_remote_arch() != RA_WIN95) &&
4418 !sign_active);
4421 /*******************************************************************
4422 Turn off sendfile if we find the underlying OS doesn't support it.
4423 ********************************************************************/
4425 void set_use_sendfile(int snum, bool val)
4427 if (LP_SNUM_OK(snum))
4428 ServicePtrs[snum]->_use_sendfile = val;
4429 else
4430 sDefault._use_sendfile = val;
4433 void lp_set_mangling_method(const char *new_method)
4435 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, new_method);
4438 /*******************************************************************
4439 Global state for POSIX pathname processing.
4440 ********************************************************************/
4442 static bool posix_pathnames;
4444 bool lp_posix_pathnames(void)
4446 return posix_pathnames;
4449 /*******************************************************************
4450 Change everything needed to ensure POSIX pathname processing (currently
4451 not much).
4452 ********************************************************************/
4454 void lp_set_posix_pathnames(void)
4456 posix_pathnames = true;
4459 /*******************************************************************
4460 Global state for POSIX lock processing - CIFS unix extensions.
4461 ********************************************************************/
4463 bool posix_default_lock_was_set;
4464 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4466 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4468 if (posix_default_lock_was_set) {
4469 return posix_cifsx_locktype;
4470 } else {
4471 return (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
4472 POSIX_LOCK : WINDOWS_LOCK;
4476 /*******************************************************************
4477 ********************************************************************/
4479 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4481 posix_default_lock_was_set = true;
4482 posix_cifsx_locktype = val;
4485 int lp_min_receive_file_size(void)
4487 int min_receivefile_size = lp_min_receivefile_size();
4489 if (min_receivefile_size < 0) {
4490 return 0;
4492 return min_receivefile_size;
4495 /*******************************************************************
4496 Safe wide links checks.
4497 This helper function always verify the validity of wide links,
4498 even after a configuration file reload.
4499 ********************************************************************/
4501 void widelinks_warning(int snum)
4503 if (lp_allow_insecure_wide_links()) {
4504 return;
4507 if (lp_unix_extensions() && lp_wide_links(snum)) {
4508 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4509 "These parameters are incompatible. "
4510 "Wide links will be disabled for this share.\n",
4511 lp_servicename(talloc_tos(), snum) ));
4515 bool lp_widelinks(int snum)
4517 /* wide links is always incompatible with unix extensions */
4518 if (lp_unix_extensions()) {
4520 * Unless we have "allow insecure widelinks"
4521 * turned on.
4523 if (!lp_allow_insecure_wide_links()) {
4524 return false;
4528 return lp_wide_links(snum);
4531 int lp_server_role(void)
4533 return lp_find_server_role(lp__server_role(),
4534 lp__security(),
4535 lp__domain_logons(),
4536 lp_domain_master_true_or_auto());
4539 int lp_security(void)
4541 return lp_find_security(lp__server_role(),
4542 lp__security());
4545 int lp_client_max_protocol(void)
4547 int client_max_protocol = lp__client_max_protocol();
4548 if (client_max_protocol == PROTOCOL_DEFAULT) {
4549 return PROTOCOL_LATEST;
4551 return client_max_protocol;
4554 int lp_client_ipc_min_protocol(void)
4556 int client_ipc_min_protocol = lp__client_ipc_min_protocol();
4557 if (client_ipc_min_protocol == PROTOCOL_DEFAULT) {
4558 client_ipc_min_protocol = lp_client_min_protocol();
4560 if (client_ipc_min_protocol < PROTOCOL_NT1) {
4561 return PROTOCOL_NT1;
4563 return client_ipc_min_protocol;
4566 int lp_client_ipc_max_protocol(void)
4568 int client_ipc_max_protocol = lp__client_ipc_max_protocol();
4569 if (client_ipc_max_protocol == PROTOCOL_DEFAULT) {
4570 return PROTOCOL_LATEST;
4572 if (client_ipc_max_protocol < PROTOCOL_NT1) {
4573 return PROTOCOL_NT1;
4575 return client_ipc_max_protocol;
4578 int lp_client_ipc_signing(void)
4580 int client_ipc_signing = lp__client_ipc_signing();
4581 if (client_ipc_signing == SMB_SIGNING_DEFAULT) {
4582 return SMB_SIGNING_REQUIRED;
4584 return client_ipc_signing;
4587 int lp_rpc_low_port(void)
4589 return Globals.rpc_low_port;
4592 int lp_rpc_high_port(void)
4594 return Globals.rpc_high_port;
4598 * Do not allow LanMan auth if unless NTLMv1 is also allowed
4600 * This also ensures it is disabled if NTLM is totally disabled
4602 bool lp_lanman_auth(void)
4604 enum ntlm_auth_level ntlm_auth_level = lp_ntlm_auth();
4606 if (ntlm_auth_level == NTLM_AUTH_ON) {
4607 return lp__lanman_auth();
4608 } else {
4609 return false;
4613 struct loadparm_global * get_globals(void)
4615 return &Globals;
4618 unsigned int * get_flags(void)
4620 if (flags_list == NULL) {
4621 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());
4624 return flags_list;