smbstatus: add server_id to notifies
[Samba.git] / source3 / param / loadparm.c
blob43838575f3bfed7de35536a1555d233db75a4fce
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 #define LOADPARM_SUBSTITUTION_INTERNALS 1
57 #include "includes.h"
58 #include "system/filesys.h"
59 #include "util_tdb.h"
60 #include "lib/param/loadparm.h"
61 #include "lib/param/param.h"
62 #include "printing.h"
63 #include "lib/smbconf/smbconf.h"
64 #include "lib/smbconf/smbconf_init.h"
66 #include "include/smb_ldap.h"
67 #include "../librpc/gen_ndr/svcctl.h"
68 #include "intl.h"
69 #include "../libcli/smb/smb_signing.h"
70 #include "dbwrap/dbwrap.h"
71 #include "dbwrap/dbwrap_rbt.h"
72 #include "../lib/util/bitmap.h"
73 #include "librpc/gen_ndr/nbt.h"
74 #include "librpc/gen_ndr/dns.h"
75 #include "source4/lib/tls/tls.h"
76 #include "libcli/auth/ntlm_check.h"
77 #include "lib/crypto/gnutls_helpers.h"
78 #include "lib/util/string_wrappers.h"
79 #include "auth/credentials/credentials.h"
80 #include "source3/lib/substitute.h"
82 #ifdef HAVE_SYS_SYSCTL_H
83 #include <sys/sysctl.h>
84 #endif
86 bool bLoaded = false;
88 extern userdom_struct current_user_info;
90 /* the special value for the include parameter
91 * to be interpreted not as a file name but to
92 * trigger loading of the global smb.conf options
93 * from registry. */
94 #ifndef INCLUDE_REGISTRY_NAME
95 #define INCLUDE_REGISTRY_NAME "registry"
96 #endif
98 static bool in_client = false; /* Not in the client by default */
99 static struct smbconf_csn conf_last_csn;
101 static int config_backend = CONFIG_BACKEND_FILE;
103 /* some helpful bits */
104 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && \
105 (ServicePtrs != NULL) && \
106 (ServicePtrs[(i)] != NULL) && ServicePtrs[(i)]->valid)
107 #define VALID(i) ((ServicePtrs != NULL) && (ServicePtrs[i]!= NULL) && \
108 ServicePtrs[i]->valid)
110 #define USERSHARE_VALID 1
111 #define USERSHARE_PENDING_DELETE 2
113 static bool defaults_saved = false;
115 #include "lib/param/param_global.h"
117 static struct loadparm_global Globals;
119 /* This is a default service used to prime a services structure */
120 static const struct loadparm_service _sDefault =
122 .valid = true,
123 .autoloaded = false,
124 .usershare = 0,
125 .usershare_last_mod = {0, 0},
126 .szService = NULL,
127 .path = NULL,
128 .invalid_users = NULL,
129 .valid_users = NULL,
130 .admin_users = NULL,
131 .copy = NULL,
132 .include = NULL,
133 .preexec = NULL,
134 .postexec = NULL,
135 .root_preexec = NULL,
136 .root_postexec = NULL,
137 .cups_options = NULL,
138 .print_command = NULL,
139 .lpq_command = NULL,
140 .lprm_command = NULL,
141 .lppause_command = NULL,
142 .lpresume_command = NULL,
143 .queuepause_command = NULL,
144 .queueresume_command = NULL,
145 ._printername = NULL,
146 .printjob_username = NULL,
147 .dont_descend = NULL,
148 .hosts_allow = NULL,
149 .hosts_deny = NULL,
150 .magic_script = NULL,
151 .magic_output = NULL,
152 .veto_files = NULL,
153 .hide_files = NULL,
154 .veto_oplock_files = NULL,
155 .comment = NULL,
156 .force_user = NULL,
157 .force_group = NULL,
158 .read_list = NULL,
159 .write_list = NULL,
160 .volume = NULL,
161 .fstype = NULL,
162 .vfs_objects = NULL,
163 .msdfs_proxy = NULL,
164 .aio_write_behind = NULL,
165 .dfree_command = NULL,
166 .min_print_space = 0,
167 .max_print_jobs = 1000,
168 .max_reported_print_jobs = 0,
169 .create_mask = 0744,
170 .force_create_mode = 0,
171 .directory_mask = 0755,
172 .force_directory_mode = 0,
173 .max_connections = 0,
174 .default_case = CASE_LOWER,
175 .printing = DEFAULT_PRINTING,
176 .csc_policy = 0,
177 .block_size = 1024,
178 .dfree_cache_time = 0,
179 .preexec_close = false,
180 .root_preexec_close = false,
181 .case_sensitive = Auto,
182 .preserve_case = true,
183 .short_preserve_case = true,
184 .hide_dot_files = true,
185 .hide_special_files = false,
186 .hide_unreadable = false,
187 .hide_unwriteable_files = false,
188 .browseable = true,
189 .access_based_share_enum = false,
190 .available = true,
191 .read_only = true,
192 .spotlight = false,
193 .guest_only = false,
194 .administrative_share = false,
195 .guest_ok = false,
196 .printable = false,
197 .print_notify_backchannel = false,
198 .map_system = false,
199 .map_hidden = false,
200 .map_archive = true,
201 .store_dos_attributes = true,
202 .smbd_max_xattr_size = 65536,
203 .dmapi_support = false,
204 .locking = true,
205 .strict_locking = Auto,
206 .posix_locking = true,
207 .oplocks = true,
208 .kernel_oplocks = false,
209 .level2_oplocks = true,
210 .mangled_names = MANGLED_NAMES_ILLEGAL,
211 .wide_links = false,
212 .follow_symlinks = true,
213 .sync_always = false,
214 .strict_allocate = false,
215 .strict_rename = false,
216 .strict_sync = true,
217 .mangling_char = '~',
218 .copymap = NULL,
219 .delete_readonly = false,
220 .fake_oplocks = false,
221 .delete_veto_files = false,
222 .dos_filemode = false,
223 .dos_filetimes = true,
224 .dos_filetime_resolution = false,
225 .fake_directory_create_times = false,
226 .blocking_locks = true,
227 .inherit_permissions = false,
228 .inherit_acls = false,
229 .inherit_owner = false,
230 .msdfs_root = false,
231 .msdfs_shuffle_referrals = false,
232 .use_client_driver = false,
233 .default_devmode = true,
234 .force_printername = false,
235 .nt_acl_support = true,
236 .force_unknown_acl_user = false,
237 ._use_sendfile = false,
238 .map_acl_inherit = false,
239 .afs_share = false,
240 .ea_support = true,
241 .acl_check_permissions = true,
242 .acl_map_full_control = true,
243 .acl_group_control = false,
244 .acl_allow_execute_always = false,
245 .acl_flag_inherited_canonicalization = true,
246 .aio_read_size = 1,
247 .aio_write_size = 1,
248 .map_readonly = MAP_READONLY_NO,
249 .directory_name_cache_size = 100,
250 .server_smb_encrypt = SMB_ENCRYPTION_DEFAULT,
251 .kernel_share_modes = false,
252 .durable_handles = true,
253 .check_parent_directory_delete_on_close = false,
254 .param_opt = NULL,
255 .smbd_search_ask_sharemode = true,
256 .smbd_getinfo_ask_sharemode = true,
257 .spotlight_backend = SPOTLIGHT_BACKEND_NOINDEX,
258 .honor_change_notify_privilege = false,
259 .volume_serial_number = -1,
260 .dummy = ""
264 * This is a copy of the default service structure. Service options in the
265 * global section would otherwise overwrite the initial default values.
267 static struct loadparm_service sDefault;
269 /* local variables */
270 static struct loadparm_service **ServicePtrs = NULL;
271 static int iNumServices = 0;
272 static int iServiceIndex = 0;
273 static struct db_context *ServiceHash;
274 static bool bInGlobalSection = true;
275 static bool bGlobalOnly = false;
276 static struct file_lists *file_lists = NULL;
277 static unsigned int *flags_list = NULL;
279 static void set_allowed_client_auth(void);
281 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
282 static void free_param_opts(struct parmlist_entry **popts);
285 * Function to return the default value for the maximum number of open
286 * file descriptors permitted. This function tries to consult the
287 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
288 * the smaller of those.
290 static int max_open_files(void)
292 int sysctl_max = MAX_OPEN_FILES;
293 int rlimit_max = MAX_OPEN_FILES;
295 #ifdef HAVE_SYSCTLBYNAME
297 size_t size = sizeof(sysctl_max);
298 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
301 #endif
303 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
305 struct rlimit rl;
307 ZERO_STRUCT(rl);
309 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
310 rlimit_max = rl.rlim_cur;
312 #if defined(RLIM_INFINITY)
313 if(rl.rlim_cur == RLIM_INFINITY)
314 rlimit_max = MAX_OPEN_FILES;
315 #endif
317 #endif
319 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
320 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
321 "minimum Windows limit (%d)\n",
322 sysctl_max,
323 MIN_OPEN_FILES_WINDOWS));
324 sysctl_max = MIN_OPEN_FILES_WINDOWS;
327 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
328 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
329 "minimum Windows limit (%d)\n",
330 rlimit_max,
331 MIN_OPEN_FILES_WINDOWS));
332 rlimit_max = MIN_OPEN_FILES_WINDOWS;
335 return MIN(sysctl_max, rlimit_max);
339 * Common part of freeing allocated data for one parameter.
341 static void free_one_parameter_common(void *parm_ptr,
342 struct parm_struct parm)
344 if ((parm.type == P_STRING) ||
345 (parm.type == P_USTRING))
347 lpcfg_string_free((char**)parm_ptr);
348 } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
349 TALLOC_FREE(*((char***)parm_ptr));
354 * Free the allocated data for one parameter for a share
355 * given as a service struct.
357 static void free_one_parameter(struct loadparm_service *service,
358 struct parm_struct parm)
360 void *parm_ptr;
362 if (parm.p_class != P_LOCAL) {
363 return;
366 parm_ptr = lp_parm_ptr(service, &parm);
368 free_one_parameter_common(parm_ptr, parm);
372 * Free the allocated parameter data of a share given
373 * as a service struct.
375 static void free_parameters(struct loadparm_service *service)
377 uint32_t i;
379 for (i=0; parm_table[i].label; i++) {
380 free_one_parameter(service, parm_table[i]);
385 * Free the allocated data for one parameter for a given share
386 * specified by an snum.
388 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
390 void *parm_ptr;
392 if (snum < 0) {
393 parm_ptr = lp_parm_ptr(NULL, &parm);
394 } else if (parm.p_class != P_LOCAL) {
395 return;
396 } else {
397 parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
400 free_one_parameter_common(parm_ptr, parm);
404 * Free the allocated parameter data for a share specified
405 * by an snum.
407 static void free_parameters_by_snum(int snum)
409 uint32_t i;
411 for (i=0; parm_table[i].label; i++) {
412 free_one_parameter_by_snum(snum, parm_table[i]);
417 * Free the allocated global parameters.
419 static void free_global_parameters(void)
421 uint32_t i;
422 struct parm_struct *parm;
424 free_param_opts(&Globals.param_opt);
425 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
427 /* Reset references in the defaults because the context is going to be freed */
428 for (i=0; parm_table[i].label; i++) {
429 parm = &parm_table[i];
430 if ((parm->type == P_STRING) ||
431 (parm->type == P_USTRING)) {
432 if ((parm->def.svalue != NULL) &&
433 (*(parm->def.svalue) != '\0')) {
434 if (talloc_parent(parm->def.svalue) == Globals.ctx) {
435 parm->def.svalue = NULL;
440 TALLOC_FREE(Globals.ctx);
443 struct lp_stored_option {
444 struct lp_stored_option *prev, *next;
445 const char *label;
446 const char *value;
449 static struct lp_stored_option *stored_options;
452 save options set by lp_set_cmdline() into a list. This list is
453 re-applied when we do a globals reset, so that cmdline set options
454 are sticky across reloads of smb.conf
456 bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
458 struct lp_stored_option *entry, *entry_next;
459 for (entry = stored_options; entry != NULL; entry = entry_next) {
460 entry_next = entry->next;
461 if (strcmp(pszParmName, entry->label) == 0) {
462 DLIST_REMOVE(stored_options, entry);
463 talloc_free(entry);
464 break;
468 entry = talloc(NULL, struct lp_stored_option);
469 if (!entry) {
470 return false;
473 entry->label = talloc_strdup(entry, pszParmName);
474 if (!entry->label) {
475 talloc_free(entry);
476 return false;
479 entry->value = talloc_strdup(entry, pszParmValue);
480 if (!entry->value) {
481 talloc_free(entry);
482 return false;
485 DLIST_ADD_END(stored_options, entry);
487 return true;
490 static bool apply_lp_set_cmdline(void)
492 struct lp_stored_option *entry = NULL;
493 for (entry = stored_options; entry != NULL; entry = entry->next) {
494 if (!lp_set_cmdline_helper(entry->label, entry->value)) {
495 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
496 entry->label, entry->value));
497 return false;
500 return true;
503 /***************************************************************************
504 Initialise the global parameter structure.
505 ***************************************************************************/
507 static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
509 static bool done_init = false;
510 char *s = NULL;
511 int i;
513 /* If requested to initialize only once and we've already done it... */
514 if (!reinit_globals && done_init) {
515 /* ... then we have nothing more to do */
516 return;
519 if (!done_init) {
520 /* The logfile can be set before this is invoked. Free it if so. */
521 lpcfg_string_free(&Globals.logfile);
522 done_init = true;
523 } else {
524 free_global_parameters();
527 /* This memset and the free_global_parameters() above will
528 * wipe out smb.conf options set with lp_set_cmdline(). The
529 * apply_lp_set_cmdline() call puts these values back in the
530 * table once the defaults are set */
531 ZERO_STRUCT(Globals);
533 Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
535 /* Initialize the flags list if necessary */
536 if (flags_list == NULL) {
537 get_flags();
540 for (i = 0; parm_table[i].label; i++) {
541 if ((parm_table[i].type == P_STRING ||
542 parm_table[i].type == P_USTRING))
544 lpcfg_string_set(
545 Globals.ctx,
546 (char **)lp_parm_ptr(NULL, &parm_table[i]),
547 "");
552 lpcfg_string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
553 lpcfg_string_set(Globals.ctx, &sDefault.printjob_username, "%U");
555 init_printer_values(lp_ctx, Globals.ctx, &sDefault);
557 sDefault.ntvfs_handler = str_list_make_v3_const(Globals.ctx, "unixuid default", NULL);
559 DEBUG(3, ("Initialising global parameters\n"));
561 /* Must manually force to upper case here, as this does not go via the handler */
562 lpcfg_string_set(Globals.ctx, &Globals.netbios_name,
563 myhostname_upper());
565 lpcfg_string_set(Globals.ctx, &Globals.smb_passwd_file,
566 get_dyn_SMB_PASSWD_FILE());
567 lpcfg_string_set(Globals.ctx, &Globals.private_dir,
568 get_dyn_PRIVATE_DIR());
569 lpcfg_string_set(Globals.ctx, &Globals.binddns_dir,
570 get_dyn_BINDDNS_DIR());
572 /* use the new 'hash2' method by default, with a prefix of 1 */
573 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, "hash2");
574 Globals.mangle_prefix = 1;
576 lpcfg_string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
578 /* using UTF8 by default allows us to support all chars */
579 lpcfg_string_set(Globals.ctx, &Globals.unix_charset,
580 DEFAULT_UNIX_CHARSET);
582 /* Use codepage 850 as a default for the dos character set */
583 lpcfg_string_set(Globals.ctx, &Globals.dos_charset,
584 DEFAULT_DOS_CHARSET);
587 * Allow the default PASSWD_CHAT to be overridden in local.h.
589 lpcfg_string_set(Globals.ctx, &Globals.passwd_chat,
590 DEFAULT_PASSWD_CHAT);
592 lpcfg_string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
594 lpcfg_string_set(Globals.ctx, &Globals.passwd_program, "");
595 lpcfg_string_set(Globals.ctx, &Globals.lock_directory,
596 get_dyn_LOCKDIR());
597 lpcfg_string_set(Globals.ctx, &Globals.state_directory,
598 get_dyn_STATEDIR());
599 lpcfg_string_set(Globals.ctx, &Globals.cache_directory,
600 get_dyn_CACHEDIR());
601 lpcfg_string_set(Globals.ctx, &Globals.pid_directory,
602 get_dyn_PIDDIR());
603 lpcfg_string_set(Globals.ctx, &Globals.nbt_client_socket_address,
604 "0.0.0.0");
606 * By default support explicit binding to broadcast
607 * addresses.
609 Globals.nmbd_bind_explicit_broadcast = true;
611 s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
612 if (s == NULL) {
613 smb_panic("init_globals: ENOMEM");
615 lpcfg_string_set(Globals.ctx, &Globals.server_string, s);
616 TALLOC_FREE(s);
617 #ifdef DEVELOPER
618 lpcfg_string_set(Globals.ctx, &Globals.panic_action,
619 "/bin/sleep 999999999");
620 #endif
622 lpcfg_string_set(Globals.ctx, &Globals.socket_options,
623 DEFAULT_SOCKET_OPTIONS);
625 lpcfg_string_set(Globals.ctx, &Globals.logon_drive, "");
626 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
627 lpcfg_string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
628 lpcfg_string_set(Globals.ctx, &Globals.logon_path,
629 "\\\\%N\\%U\\profile");
631 Globals.name_resolve_order =
632 str_list_make_v3_const(Globals.ctx,
633 DEFAULT_NAME_RESOLVE_ORDER,
634 NULL);
635 lpcfg_string_set(Globals.ctx, &Globals.password_server, "*");
637 Globals.algorithmic_rid_base = BASE_RID;
639 Globals.load_printers = true;
640 Globals.printcap_cache_time = 750; /* 12.5 minutes */
642 Globals.config_backend = config_backend;
643 Globals._server_role = ROLE_AUTO;
645 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
646 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
647 Globals.max_xmit = 0x4104;
648 Globals.max_mux = 50; /* This is *needed* for profile support. */
649 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
650 Globals._disable_spoolss = false;
651 Globals.max_smbd_processes = 0;/* no limit specified */
652 Globals.username_level = 0;
653 Globals.deadtime = 10080;
654 Globals.getwd_cache = true;
655 Globals.large_readwrite = true;
656 Globals.max_log_size = 5000;
657 Globals.max_open_files = max_open_files();
658 Globals.server_max_protocol = PROTOCOL_SMB3_11;
659 Globals.server_min_protocol = PROTOCOL_SMB2_02;
660 Globals._client_max_protocol = PROTOCOL_DEFAULT;
661 Globals.client_min_protocol = PROTOCOL_SMB2_02;
662 Globals._client_ipc_max_protocol = PROTOCOL_DEFAULT;
663 Globals._client_ipc_min_protocol = PROTOCOL_DEFAULT;
664 Globals._security = SEC_AUTO;
665 Globals.encrypt_passwords = true;
666 Globals.client_schannel = true;
667 Globals.winbind_sealed_pipes = true;
668 Globals.require_strong_key = true;
669 Globals.server_schannel = true;
670 Globals.read_raw = true;
671 Globals.write_raw = true;
672 Globals.null_passwords = false;
673 Globals.old_password_allowed_period = 60;
674 Globals.obey_pam_restrictions = false;
675 Globals.syslog = 1;
676 Globals.syslog_only = false;
677 Globals.timestamp_logs = true;
678 lpcfg_string_set(Globals.ctx, &Globals.log_level, "0");
679 Globals.debug_prefix_timestamp = false;
680 Globals.debug_hires_timestamp = true;
681 Globals.debug_syslog_format = false;
682 Globals.debug_pid = false;
683 Globals.debug_uid = false;
684 Globals.debug_class = false;
685 Globals.enable_core_files = true;
686 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
687 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
688 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
689 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
690 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
691 Globals.lm_interval = 60;
692 Globals.time_server = false;
693 Globals.bind_interfaces_only = false;
694 Globals.unix_password_sync = false;
695 Globals.pam_password_change = false;
696 Globals.passwd_chat_debug = false;
697 Globals.passwd_chat_timeout = 2; /* 2 second default. */
698 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
699 Globals.nt_status_support = true; /* Use NT status by default. */
700 Globals.smbd_profiling_level = 0;
701 Globals.stat_cache = true; /* use stat cache by default */
702 Globals.max_stat_cache_size = 512; /* 512k by default */
703 Globals.restrict_anonymous = 0;
704 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
705 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
706 Globals._lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
707 Globals.ntlm_auth = NTLM_AUTH_NTLMV2_ONLY; /* Do NOT use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
708 Globals.nt_hash_store = NT_HASH_STORE_ALWAYS; /* Fill in NT hash when setting password */
709 Globals.raw_ntlmv2_auth = false; /* Reject NTLMv2 without NTLMSSP */
710 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 */
711 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
713 Globals.allow_dcerpc_auth_level_connect = false; /* we don't allow this by default */
715 Globals.map_to_guest = 0; /* By Default, "Never" */
716 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
717 Globals.enhanced_browsing = true;
718 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
719 Globals.use_mmap = true;
720 Globals.unicode = true;
721 Globals.smb1_unix_extensions = true;
722 Globals.reset_on_zero_vc = false;
723 Globals.log_writeable_files_on_exit = false;
724 Globals.create_krb5_conf = true;
725 Globals.include_system_krb5_conf = true;
726 Globals._winbind_max_domain_connections = 1;
728 /* hostname lookups can be very expensive and are broken on
729 a large number of sites (tridge) */
730 Globals.hostname_lookups = false;
732 Globals.change_notify = true,
733 Globals.kernel_change_notify = true,
735 lpcfg_string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
736 lpcfg_string_set(Globals.ctx, &Globals.ldap_suffix, "");
737 lpcfg_string_set(Globals.ctx, &Globals._ldap_machine_suffix, "");
738 lpcfg_string_set(Globals.ctx, &Globals._ldap_user_suffix, "");
739 lpcfg_string_set(Globals.ctx, &Globals._ldap_group_suffix, "");
740 lpcfg_string_set(Globals.ctx, &Globals._ldap_idmap_suffix, "");
742 lpcfg_string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
743 Globals.ldap_ssl = LDAP_SSL_START_TLS;
744 Globals.ldap_deref = -1;
745 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
746 Globals.ldap_delete_dn = false;
747 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
748 Globals.ldap_follow_referral = Auto;
749 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
750 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
751 Globals.ldap_page_size = LDAP_PAGE_SIZE;
753 Globals.ldap_debug_level = 0;
754 Globals.ldap_debug_threshold = 10;
756 Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
758 Globals.ldap_server_require_strong_auth =
759 LDAP_SERVER_REQUIRE_STRONG_AUTH_YES;
761 /* This is what we tell the afs client. in reality we set the token
762 * to never expire, though, when this runs out the afs client will
763 * forget the token. Set to 0 to get NEVERDATE.*/
764 Globals.afs_token_lifetime = 604800;
765 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
767 /* these parameters are set to defaults that are more appropriate
768 for the increasing samba install base:
770 as a member of the workgroup, that will possibly become a
771 _local_ master browser (lm = true). this is opposed to a forced
772 local master browser startup (pm = true).
774 doesn't provide WINS server service by default (wsupp = false),
775 and doesn't provide domain master browser services by default, either.
779 Globals.show_add_printer_wizard = true;
780 Globals.os_level = 20;
781 Globals.local_master = true;
782 Globals._domain_master = Auto; /* depending on _domain_logons */
783 Globals._domain_logons = false;
784 Globals.browse_list = true;
785 Globals.we_are_a_wins_server = false;
786 Globals.wins_proxy = false;
788 TALLOC_FREE(Globals.init_logon_delayed_hosts);
789 Globals.init_logon_delay = 100; /* 100 ms default delay */
791 Globals.wins_dns_proxy = true;
792 Globals.dns_port = DNS_SERVICE_PORT;
794 Globals.allow_trusted_domains = true;
795 lpcfg_string_set(Globals.ctx, &Globals.idmap_backend, "tdb");
797 lpcfg_string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
798 lpcfg_string_set(Globals.ctx, &Globals.template_homedir,
799 "/home/%D/%U");
800 lpcfg_string_set(Globals.ctx, &Globals.winbind_separator, "\\");
801 lpcfg_string_set(Globals.ctx, &Globals.winbindd_socket_directory,
802 dyn_WINBINDD_SOCKET_DIR);
804 lpcfg_string_set(Globals.ctx, &Globals.cups_server, "");
805 lpcfg_string_set(Globals.ctx, &Globals.iprint_server, "");
807 lpcfg_string_set(Globals.ctx, &Globals._ctdbd_socket, "");
809 Globals.cluster_addresses = NULL;
810 Globals.clustering = false;
811 Globals.ctdb_timeout = 0;
812 Globals.ctdb_locktime_warn_threshold = 0;
814 Globals.winbind_cache_time = 300; /* 5 minutes */
815 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
816 Globals.winbind_request_timeout = 60; /* 60 seconds */
817 Globals.winbind_max_clients = 200;
818 Globals.winbind_enum_users = false;
819 Globals.winbind_enum_groups = false;
820 Globals.winbind_use_default_domain = false;
821 Globals.winbind_nested_groups = true;
822 Globals.winbind_expand_groups = 0;
823 Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
824 Globals.winbind_refresh_tickets = false;
825 Globals.winbind_offline_logon = false;
826 Globals.winbind_scan_trusted_domains = false;
828 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
829 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
831 Globals.passdb_expand_explicit = false;
833 Globals.name_cache_timeout = 660; /* In seconds */
835 Globals.client_use_spnego = true;
837 Globals.client_signing = SMB_SIGNING_DEFAULT;
838 Globals._client_ipc_signing = SMB_SIGNING_DEFAULT;
839 Globals.server_signing = SMB_SIGNING_DEFAULT;
841 Globals.defer_sharing_violations = true;
842 Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL);
844 Globals.enable_privileges = true;
845 Globals.host_msdfs = true;
846 Globals.enable_asu_support = false;
848 /* User defined shares. */
849 s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
850 if (s == NULL) {
851 smb_panic("init_globals: ENOMEM");
853 lpcfg_string_set(Globals.ctx, &Globals.usershare_path, s);
854 TALLOC_FREE(s);
855 lpcfg_string_set(Globals.ctx, &Globals.usershare_template_share, "");
856 Globals.usershare_max_shares = 0;
857 /* By default disallow sharing of directories not owned by the sharer. */
858 Globals.usershare_owner_only = true;
859 /* By default disallow guest access to usershares. */
860 Globals.usershare_allow_guests = false;
862 Globals.keepalive = DEFAULT_KEEPALIVE;
864 /* By default no shares out of the registry */
865 Globals.registry_shares = false;
867 Globals.min_receivefile_size = 0;
869 Globals.multicast_dns_register = true;
871 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
872 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
873 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
874 Globals.smb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
875 Globals.smb2_leases = true;
876 Globals.server_multi_channel_support = true;
878 lpcfg_string_set(Globals.ctx, &Globals.ncalrpc_dir,
879 get_dyn_NCALRPCDIR());
881 Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
883 Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
885 Globals.tls_enabled = true;
886 Globals.tls_verify_peer = TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE;
888 lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
889 lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
890 lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
891 lpcfg_string_set(Globals.ctx,
892 &Globals.tls_priority,
893 "NORMAL:-VERS-SSL3.0");
895 Globals._preferred_master = Auto;
897 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
898 Globals.dns_zone_scavenging = false;
900 lpcfg_string_set(Globals.ctx, &Globals.ntp_signd_socket_directory,
901 get_dyn_NTP_SIGND_SOCKET_DIR());
903 s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
904 if (s == NULL) {
905 smb_panic("init_globals: ENOMEM");
907 Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
908 TALLOC_FREE(s);
910 #ifdef MIT_KDC_PATH
911 Globals.mit_kdc_command = str_list_make_v3_const(NULL, MIT_KDC_PATH, NULL);
912 #endif
914 s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
915 if (s == NULL) {
916 smb_panic("init_globals: ENOMEM");
918 Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
919 TALLOC_FREE(s);
921 s = talloc_asprintf(talloc_tos(), "%s/samba-gpupdate", get_dyn_SCRIPTSBINDIR());
922 if (s == NULL) {
923 smb_panic("init_globals: ENOMEM");
925 Globals.gpo_update_command = str_list_make_v3_const(NULL, s, NULL);
926 TALLOC_FREE(s);
928 Globals.apply_group_policies = false;
930 s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
931 if (s == NULL) {
932 smb_panic("init_globals: ENOMEM");
934 Globals.spn_update_command = str_list_make_v3_const(NULL, s, NULL);
935 TALLOC_FREE(s);
937 Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
939 Globals.cldap_port = 389;
941 Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
943 Globals.nbt_port = NBT_NAME_SERVICE_PORT;
945 Globals.krb5_port = 88;
947 Globals.kpasswd_port = 464;
949 Globals.kdc_enable_fast = true;
951 Globals.aio_max_threads = 100;
953 lpcfg_string_set(Globals.ctx,
954 &Globals.rpc_server_dynamic_port_range,
955 "49152-65535");
956 Globals.rpc_low_port = SERVER_TCP_LOW_PORT;
957 Globals.rpc_high_port = SERVER_TCP_HIGH_PORT;
958 Globals.prefork_children = 4;
959 Globals.prefork_backoff_increment = 10;
960 Globals.prefork_maximum_backoff = 120;
962 Globals.ldap_max_anonymous_request_size = 256000;
963 Globals.ldap_max_authenticated_request_size = 16777216;
964 Globals.ldap_max_search_request_size = 256000;
966 /* Async DNS query timeout (in seconds). */
967 Globals.async_dns_timeout = 10;
969 Globals.client_smb_encrypt = SMB_ENCRYPTION_DEFAULT;
971 Globals._client_use_kerberos = CRED_USE_KERBEROS_DESIRED;
973 Globals.client_protection = CRED_CLIENT_PROTECTION_DEFAULT;
975 Globals.winbind_use_krb5_enterprise_principals = true;
977 Globals.client_smb3_signing_algorithms =
978 str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
979 Globals.server_smb3_signing_algorithms =
980 str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
982 Globals.client_smb3_encryption_algorithms =
983 str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
984 Globals.server_smb3_encryption_algorithms =
985 str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
987 Globals.min_domain_uid = 1000;
990 * By default allow smbd and winbindd to start samba-dcerpcd as
991 * a named-pipe helper.
993 Globals.rpc_start_on_demand_helpers = true;
995 /* Now put back the settings that were set with lp_set_cmdline() */
996 apply_lp_set_cmdline();
999 /* Convenience routine to setup an lp_context with additional s3 variables */
1000 static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
1002 struct loadparm_context *lp_ctx;
1004 lp_ctx = loadparm_init_s3(mem_ctx,
1005 loadparm_s3_helpers());
1006 if (lp_ctx == NULL) {
1007 DEBUG(0, ("loadparm_init_s3 failed\n"));
1008 return NULL;
1011 lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
1012 if (lp_ctx->sDefault == NULL) {
1013 DBG_ERR("talloc_zero failed\n");
1014 TALLOC_FREE(lp_ctx);
1015 return NULL;
1018 *lp_ctx->sDefault = _sDefault;
1019 lp_ctx->services = NULL; /* We do not want to access this directly */
1020 lp_ctx->bInGlobalSection = bInGlobalSection;
1021 lp_ctx->flags = flags_list;
1023 return lp_ctx;
1026 /*******************************************************************
1027 Convenience routine to grab string parameters into talloced memory
1028 and run standard_sub_basic on them. The buffers can be written to by
1029 callers without affecting the source string.
1030 ********************************************************************/
1032 static char *loadparm_s3_global_substitution_fn(
1033 TALLOC_CTX *mem_ctx,
1034 const struct loadparm_substitution *lp_sub,
1035 const char *s,
1036 void *private_data)
1038 char *ret;
1040 /* The follow debug is useful for tracking down memory problems
1041 especially if you have an inner loop that is calling a lp_*()
1042 function that returns a string. Perhaps this debug should be
1043 present all the time? */
1045 #if 0
1046 DEBUG(10, ("lp_string(%s)\n", s));
1047 #endif
1048 if (!s) {
1049 return NULL;
1052 ret = talloc_sub_basic(mem_ctx,
1053 get_current_username(),
1054 current_user_info.domain,
1056 if (trim_char(ret, '\"', '\"')) {
1057 if (strchr(ret,'\"') != NULL) {
1058 TALLOC_FREE(ret);
1059 ret = talloc_sub_basic(mem_ctx,
1060 get_current_username(),
1061 current_user_info.domain,
1065 return ret;
1068 static const struct loadparm_substitution s3_global_substitution = {
1069 .substituted_string_fn = loadparm_s3_global_substitution_fn,
1072 const struct loadparm_substitution *loadparm_s3_global_substitution(void)
1074 return &s3_global_substitution;
1078 In this section all the functions that are used to access the
1079 parameters from the rest of the program are defined
1082 #define FN_GLOBAL_SUBSTITUTED_STRING(fn_name,ptr) \
1083 char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub) \
1084 {return lpcfg_substituted_string(ctx, lp_sub, *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : "");}
1085 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1086 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1087 #define FN_GLOBAL_LIST(fn_name,ptr) \
1088 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1089 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1090 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1091 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1092 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1093 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1094 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1096 #define FN_LOCAL_SUBSTITUTED_STRING(fn_name,val) \
1097 char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub, int i) \
1098 {return lpcfg_substituted_string((ctx), lp_sub, (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1099 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1100 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1101 #define FN_LOCAL_LIST(fn_name,val) \
1102 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1103 #define FN_LOCAL_BOOL(fn_name,val) \
1104 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1105 #define FN_LOCAL_INTEGER(fn_name,val) \
1106 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1108 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1109 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1110 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1111 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1112 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1113 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1115 int lp_winbind_max_domain_connections(void)
1117 if (lp_winbind_offline_logon() &&
1118 lp__winbind_max_domain_connections() > 1) {
1119 DEBUG(1, ("offline logons active, restricting max domain "
1120 "connections to 1\n"));
1121 return 1;
1123 return MAX(1, lp__winbind_max_domain_connections());
1126 /* These functions remain in source3/param for now */
1128 #include "lib/param/param_functions.c"
1130 FN_LOCAL_SUBSTITUTED_STRING(servicename, szService)
1131 FN_LOCAL_CONST_STRING(const_servicename, szService)
1133 /* These functions cannot be auto-generated */
1134 FN_LOCAL_BOOL(autoloaded, autoloaded)
1135 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1137 /* local prototypes */
1139 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1140 static const char *get_boolean(bool bool_value);
1141 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1142 void *userdata);
1143 static bool hash_a_service(const char *name, int number);
1144 static void free_service_byindex(int iService);
1145 static void show_parameter(int parmIndex);
1146 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1147 static bool lp_parameter_value_is_valid(const char *parm_name, const char *val);
1150 * This is a helper function for parametrical options support. It returns a
1151 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1152 * parametrical functions are quite simple
1154 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1155 const char *option)
1157 if (snum >= iNumServices) return NULL;
1159 if (snum < 0) {
1160 return get_parametric_helper(NULL, type, option, Globals.param_opt);
1161 } else {
1162 return get_parametric_helper(ServicePtrs[snum],
1163 type, option, Globals.param_opt);
1167 static void discard_whitespace(char *str)
1169 size_t len = strlen(str);
1170 size_t i = 0;
1172 while (i < len) {
1173 if (isspace(str[i])) {
1174 memmove(&str[i], &str[i+1], len-i);
1175 len -= 1;
1176 continue;
1178 i += 1;
1183 * @brief Go through all global parametric parameters
1185 * @param regex_str A regular expression to scan param for
1186 * @param max_matches Max number of submatches the regexp expects
1187 * @param cb Function to call on match. Should return true
1188 * when it wants wi_scan_global_parametrics to stop
1189 * scanning
1190 * @param private_data Anonymous pointer passed to cb
1192 * @return 0: success, regcomp/regexec return value on error.
1193 * See "man regexec" for possible errors
1196 int lp_wi_scan_global_parametrics(
1197 const char *regex_str, size_t max_matches,
1198 bool (*cb)(const char *string, regmatch_t matches[],
1199 void *private_data),
1200 void *private_data)
1202 struct parmlist_entry *data;
1203 regex_t regex;
1204 int ret;
1206 ret = regcomp(&regex, regex_str, REG_ICASE);
1207 if (ret != 0) {
1208 return ret;
1211 for (data = Globals.param_opt; data != NULL; data = data->next) {
1212 size_t keylen = strlen(data->key);
1213 char key[keylen+1];
1214 regmatch_t matches[max_matches];
1215 bool stop;
1217 memcpy(key, data->key, sizeof(key));
1218 discard_whitespace(key);
1220 ret = regexec(&regex, key, max_matches, matches, 0);
1221 if (ret == REG_NOMATCH) {
1222 continue;
1224 if (ret != 0) {
1225 goto fail;
1228 stop = cb(key, matches, private_data);
1229 if (stop) {
1230 break;
1234 ret = 0;
1235 fail:
1236 regfree(&regex);
1237 return ret;
1241 #define MISSING_PARAMETER(name) \
1242 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1244 /*******************************************************************
1245 convenience routine to return enum parameters.
1246 ********************************************************************/
1247 static int lp_enum(const char *s,const struct enum_list *_enum)
1249 int i;
1251 if (!s || !*s || !_enum) {
1252 MISSING_PARAMETER(lp_enum);
1253 return (-1);
1256 for (i=0; _enum[i].name; i++) {
1257 if (strequal(_enum[i].name,s))
1258 return _enum[i].value;
1261 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1262 return (-1);
1265 #undef MISSING_PARAMETER
1267 /* Return parametric option from a given service. Type is a part of option before ':' */
1268 /* Parametric option has following syntax: 'Type: option = value' */
1269 char *lp_parm_substituted_string(TALLOC_CTX *mem_ctx,
1270 const struct loadparm_substitution *lp_sub,
1271 int snum,
1272 const char *type,
1273 const char *option,
1274 const char *def)
1276 struct parmlist_entry *data = get_parametrics(snum, type, option);
1278 SMB_ASSERT(lp_sub != NULL);
1280 if (data == NULL||data->value==NULL) {
1281 if (def) {
1282 return lpcfg_substituted_string(mem_ctx, lp_sub, def);
1283 } else {
1284 return NULL;
1288 return lpcfg_substituted_string(mem_ctx, lp_sub, data->value);
1291 /* Return parametric option from a given service. Type is a part of option before ':' */
1292 /* Parametric option has following syntax: 'Type: option = value' */
1293 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1295 struct parmlist_entry *data = get_parametrics(snum, type, option);
1297 if (data == NULL||data->value==NULL)
1298 return def;
1300 return data->value;
1304 /* Return parametric option from a given service. Type is a part of option before ':' */
1305 /* Parametric option has following syntax: 'Type: option = value' */
1307 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1309 struct parmlist_entry *data = get_parametrics(snum, type, option);
1311 if (data == NULL||data->value==NULL)
1312 return (const char **)def;
1314 if (data->list==NULL) {
1315 data->list = str_list_make_v3(NULL, data->value, NULL);
1318 return discard_const_p(const char *, data->list);
1321 /* Return parametric option from a given service. Type is a part of option before ':' */
1322 /* Parametric option has following syntax: 'Type: option = value' */
1324 int lp_parm_int(int snum, const char *type, const char *option, int def)
1326 struct parmlist_entry *data = get_parametrics(snum, type, option);
1328 if (data && data->value && *data->value)
1329 return lp_int(data->value);
1331 return def;
1334 /* Return parametric option from a given service. Type is a part of option before ':' */
1335 /* Parametric option has following syntax: 'Type: option = value' */
1337 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1339 struct parmlist_entry *data = get_parametrics(snum, type, option);
1341 if (data && data->value && *data->value)
1342 return lp_ulong(data->value);
1344 return def;
1347 /* Return parametric option from a given service. Type is a part of option before ':' */
1348 /* Parametric option has following syntax: 'Type: option = value' */
1350 unsigned long long lp_parm_ulonglong(int snum, const char *type,
1351 const char *option, unsigned long long def)
1353 struct parmlist_entry *data = get_parametrics(snum, type, option);
1355 if (data && data->value && *data->value) {
1356 return lp_ulonglong(data->value);
1359 return def;
1362 /* Return parametric option from a given service. Type is a part of option
1363 * before ':' */
1364 /* Parametric option has following syntax: 'Type: option = value' */
1366 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1368 struct parmlist_entry *data = get_parametrics(snum, type, option);
1370 if (data && data->value && *data->value)
1371 return lp_bool(data->value);
1373 return def;
1376 /* Return parametric option from a given service. Type is a part of option before ':' */
1377 /* Parametric option has following syntax: 'Type: option = value' */
1379 int lp_parm_enum(int snum, const char *type, const char *option,
1380 const struct enum_list *_enum, int def)
1382 struct parmlist_entry *data = get_parametrics(snum, type, option);
1384 if (data && data->value && *data->value && _enum)
1385 return lp_enum(data->value, _enum);
1387 return def;
1391 * free a param_opts structure.
1392 * param_opts handling should be moved to talloc;
1393 * then this whole functions reduces to a TALLOC_FREE().
1396 static void free_param_opts(struct parmlist_entry **popts)
1398 struct parmlist_entry *opt, *next_opt;
1400 if (*popts != NULL) {
1401 DEBUG(5, ("Freeing parametrics:\n"));
1403 opt = *popts;
1404 while (opt != NULL) {
1405 lpcfg_string_free(&opt->key);
1406 lpcfg_string_free(&opt->value);
1407 TALLOC_FREE(opt->list);
1408 next_opt = opt->next;
1409 TALLOC_FREE(opt);
1410 opt = next_opt;
1412 *popts = NULL;
1415 /***************************************************************************
1416 Free the dynamically allocated parts of a service struct.
1417 ***************************************************************************/
1419 static void free_service(struct loadparm_service *pservice)
1421 if (!pservice)
1422 return;
1424 if (pservice->szService)
1425 DEBUG(5, ("free_service: Freeing service %s\n",
1426 pservice->szService));
1428 free_parameters(pservice);
1430 lpcfg_string_free(&pservice->szService);
1431 TALLOC_FREE(pservice->copymap);
1433 free_param_opts(&pservice->param_opt);
1435 ZERO_STRUCTP(pservice);
1439 /***************************************************************************
1440 remove a service indexed in the ServicePtrs array from the ServiceHash
1441 and free the dynamically allocated parts
1442 ***************************************************************************/
1444 static void free_service_byindex(int idx)
1446 if ( !LP_SNUM_OK(idx) )
1447 return;
1449 ServicePtrs[idx]->valid = false;
1451 /* we have to cleanup the hash record */
1453 if (ServicePtrs[idx]->szService) {
1454 char *canon_name = canonicalize_servicename(
1455 talloc_tos(),
1456 ServicePtrs[idx]->szService );
1458 dbwrap_delete_bystring(ServiceHash, canon_name );
1459 TALLOC_FREE(canon_name);
1462 free_service(ServicePtrs[idx]);
1463 TALLOC_FREE(ServicePtrs[idx]);
1466 /***************************************************************************
1467 Add a new service to the services array initialising it with the given
1468 service.
1469 ***************************************************************************/
1471 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1473 int i;
1474 struct loadparm_service **tsp = NULL;
1476 /* it might already exist */
1477 if (name) {
1478 i = getservicebyname(name, NULL);
1479 if (i >= 0) {
1480 return (i);
1484 /* Re use empty slots if any before allocating new one.*/
1485 for (i=0; i < iNumServices; i++) {
1486 if (ServicePtrs[i] == NULL) {
1487 break;
1490 if (i == iNumServices) {
1491 /* if not, then create one */
1492 tsp = talloc_realloc(NULL, ServicePtrs,
1493 struct loadparm_service *,
1494 iNumServices + 1);
1495 if (tsp == NULL) {
1496 DEBUG(0, ("add_a_service: failed to enlarge "
1497 "ServicePtrs!\n"));
1498 return (-1);
1500 ServicePtrs = tsp;
1501 iNumServices++;
1503 ServicePtrs[i] = talloc_zero(ServicePtrs, struct loadparm_service);
1504 if (!ServicePtrs[i]) {
1505 DEBUG(0,("add_a_service: out of memory!\n"));
1506 return (-1);
1509 ServicePtrs[i]->valid = true;
1511 copy_service(ServicePtrs[i], pservice, NULL);
1512 if (name)
1513 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->szService,
1514 name);
1516 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1517 i, ServicePtrs[i]->szService));
1519 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1520 return (-1);
1523 return (i);
1526 /***************************************************************************
1527 Convert a string to uppercase and remove whitespaces.
1528 ***************************************************************************/
1530 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1532 char *result;
1534 if ( !src ) {
1535 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1536 return NULL;
1539 result = talloc_strdup(ctx, src);
1540 SMB_ASSERT(result != NULL);
1542 if (!strlower_m(result)) {
1543 TALLOC_FREE(result);
1544 return NULL;
1546 return result;
1549 /***************************************************************************
1550 Add a name/index pair for the services array to the hash table.
1551 ***************************************************************************/
1553 static bool hash_a_service(const char *name, int idx)
1555 char *canon_name;
1557 if ( !ServiceHash ) {
1558 DEBUG(10,("hash_a_service: creating servicehash\n"));
1559 ServiceHash = db_open_rbt(NULL);
1560 if ( !ServiceHash ) {
1561 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1562 return false;
1566 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1567 idx, name));
1569 canon_name = canonicalize_servicename(talloc_tos(), name );
1571 dbwrap_store_bystring(ServiceHash, canon_name,
1572 make_tdb_data((uint8_t *)&idx, sizeof(idx)),
1573 TDB_REPLACE);
1575 TALLOC_FREE(canon_name);
1577 return true;
1580 /***************************************************************************
1581 Add a new home service, with the specified home directory, defaults coming
1582 from service ifrom.
1583 ***************************************************************************/
1585 bool lp_add_home(const char *pszHomename, int iDefaultService,
1586 const char *user, const char *pszHomedir)
1588 const struct loadparm_substitution *lp_sub =
1589 loadparm_s3_global_substitution();
1590 int i;
1591 char *global_path;
1593 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1594 pszHomedir[0] == '\0') {
1595 return false;
1598 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1600 if (i < 0)
1601 return false;
1603 global_path = lp_path(talloc_tos(), lp_sub, GLOBAL_SECTION_SNUM);
1604 if (!(*(ServicePtrs[iDefaultService]->path))
1605 || strequal(ServicePtrs[iDefaultService]->path, global_path)) {
1606 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
1607 pszHomedir);
1609 TALLOC_FREE(global_path);
1611 if (!(*(ServicePtrs[i]->comment))) {
1612 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1613 if (comment == NULL) {
1614 return false;
1616 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment,
1617 comment);
1618 TALLOC_FREE(comment);
1621 /* set the browseable flag from the global default */
1623 ServicePtrs[i]->browseable = sDefault.browseable;
1624 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1626 ServicePtrs[i]->autoloaded = true;
1628 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1629 user, ServicePtrs[i]->path ));
1631 return true;
1634 /***************************************************************************
1635 Add a new service, based on an old one.
1636 ***************************************************************************/
1638 int lp_add_service(const char *pszService, int iDefaultService)
1640 if (iDefaultService < 0) {
1641 return add_a_service(&sDefault, pszService);
1644 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1647 /***************************************************************************
1648 Add the IPC service.
1649 ***************************************************************************/
1651 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1653 char *comment = NULL;
1654 int i = add_a_service(&sDefault, ipc_name);
1656 if (i < 0)
1657 return false;
1659 comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1660 Globals.server_string);
1661 if (comment == NULL) {
1662 return false;
1665 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1666 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1667 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1668 ServicePtrs[i]->max_connections = 0;
1669 ServicePtrs[i]->available = true;
1670 ServicePtrs[i]->read_only = true;
1671 ServicePtrs[i]->guest_only = false;
1672 ServicePtrs[i]->administrative_share = true;
1673 ServicePtrs[i]->guest_ok = guest_ok;
1674 ServicePtrs[i]->printable = false;
1675 ServicePtrs[i]->browseable = sDefault.browseable;
1676 ServicePtrs[i]->autoloaded = false;
1678 DEBUG(3, ("adding IPC service\n"));
1680 TALLOC_FREE(comment);
1681 return true;
1684 /***************************************************************************
1685 Add a new printer service, with defaults coming from service iFrom.
1686 ***************************************************************************/
1688 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1690 const char *comment = "From Printcap";
1691 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1693 if (i < 0)
1694 return false;
1696 /* note that we do NOT default the availability flag to true - */
1697 /* we take it from the default service passed. This allows all */
1698 /* dynamic printers to be disabled by disabling the [printers] */
1699 /* entry (if/when the 'available' keyword is implemented!). */
1701 /* the printer name is set to the service name. */
1702 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->_printername,
1703 pszPrintername);
1704 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1706 /* set the browseable flag from the gloabl default */
1707 ServicePtrs[i]->browseable = sDefault.browseable;
1709 /* Printers cannot be read_only. */
1710 ServicePtrs[i]->read_only = false;
1711 /* No oplocks on printer services. */
1712 ServicePtrs[i]->oplocks = false;
1713 /* Printer services must be printable. */
1714 ServicePtrs[i]->printable = true;
1716 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1718 return true;
1722 /***************************************************************************
1723 Check whether the given parameter name is valid.
1724 Parametric options (names containing a colon) are considered valid.
1725 ***************************************************************************/
1727 bool lp_parameter_is_valid(const char *pszParmName)
1729 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1730 (strchr(pszParmName, ':') != NULL));
1733 /***************************************************************************
1734 Check whether the given name is the name of a global parameter.
1735 Returns true for strings belonging to parameters of class
1736 P_GLOBAL, false for all other strings, also for parametric options
1737 and strings not belonging to any option.
1738 ***************************************************************************/
1740 bool lp_parameter_is_global(const char *pszParmName)
1742 int num = lpcfg_map_parameter(pszParmName);
1744 if (num >= 0) {
1745 return (parm_table[num].p_class == P_GLOBAL);
1748 return false;
1751 /**************************************************************************
1752 Determine the canonical name for a parameter.
1753 Indicate when it is an inverse (boolean) synonym instead of a
1754 "usual" synonym.
1755 **************************************************************************/
1757 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1758 bool *inverse)
1760 int num;
1762 if (!lp_parameter_is_valid(parm_name)) {
1763 *canon_parm = NULL;
1764 return false;
1767 num = map_parameter_canonical(parm_name, inverse);
1768 if (num < 0) {
1769 /* parametric option */
1770 *canon_parm = parm_name;
1771 } else {
1772 *canon_parm = parm_table[num].label;
1775 return true;
1779 /**************************************************************************
1780 Determine the canonical name for a parameter.
1781 Turn the value given into the inverse boolean expression when
1782 the synonym is an invers boolean synonym.
1784 Return true if
1785 - parm_name is a valid parameter name and
1786 - val is a valid value for this parameter and
1787 - in case the parameter is an inverse boolean synonym, if the val
1788 string could successfully be converted to the reverse bool.
1789 Return false in all other cases.
1790 **************************************************************************/
1792 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1793 const char *val,
1794 const char **canon_parm,
1795 const char **canon_val)
1797 int num;
1798 bool inverse;
1799 bool ret;
1801 if (!lp_parameter_is_valid(parm_name)) {
1802 *canon_parm = NULL;
1803 *canon_val = NULL;
1804 return false;
1807 num = map_parameter_canonical(parm_name, &inverse);
1808 if (num < 0) {
1809 /* parametric option */
1810 *canon_parm = parm_name;
1811 *canon_val = val;
1812 return true;
1815 *canon_parm = parm_table[num].label;
1816 if (inverse) {
1817 if (!lp_invert_boolean(val, canon_val)) {
1818 *canon_val = NULL;
1819 return false;
1821 } else {
1822 *canon_val = val;
1825 ret = lp_parameter_value_is_valid(*canon_parm, *canon_val);
1827 return ret;
1830 /***************************************************************************
1831 Map a parameter's string representation to the index of the canonical
1832 form of the parameter (it might be a synonym).
1833 Returns -1 if the parameter string is not recognised.
1834 ***************************************************************************/
1836 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1838 int parm_num, canon_num;
1839 bool loc_inverse = false;
1841 parm_num = lpcfg_map_parameter(pszParmName);
1842 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) {
1843 /* invalid, parametric or no canidate for synonyms ... */
1844 goto done;
1847 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1848 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1849 parm_num = canon_num;
1850 goto done;
1854 done:
1855 if (inverse != NULL) {
1856 *inverse = loc_inverse;
1858 return parm_num;
1861 /***************************************************************************
1862 return true if parameter number parm1 is a synonym of parameter
1863 number parm2 (parm2 being the principal name).
1864 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1865 false otherwise.
1866 ***************************************************************************/
1868 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1870 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1871 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1872 (parm_table[parm1].flags & FLAG_SYNONYM) &&
1873 !(parm_table[parm2].flags & FLAG_SYNONYM))
1875 if (inverse != NULL) {
1876 if ((parm_table[parm1].type == P_BOOLREV) &&
1877 (parm_table[parm2].type == P_BOOL))
1879 *inverse = true;
1880 } else {
1881 *inverse = false;
1884 return true;
1886 return false;
1889 /***************************************************************************
1890 Show one parameter's name, type, [values,] and flags.
1891 (helper functions for show_parameter_list)
1892 ***************************************************************************/
1894 static void show_parameter(int parmIndex)
1896 size_t enumIndex, flagIndex;
1897 size_t parmIndex2;
1898 bool hadFlag;
1899 bool hadSyn;
1900 bool inverse;
1901 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1902 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1903 "P_ENUM", "P_BYTES", "P_CMDLIST" };
1904 unsigned flags[] = { FLAG_DEPRECATED, FLAG_SYNONYM };
1905 const char *flag_names[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL};
1907 printf("%s=%s", parm_table[parmIndex].label,
1908 type[parm_table[parmIndex].type]);
1909 if (parm_table[parmIndex].type == P_ENUM) {
1910 printf(",");
1911 for (enumIndex=0;
1912 parm_table[parmIndex].enum_list[enumIndex].name;
1913 enumIndex++)
1915 printf("%s%s",
1916 enumIndex ? "|" : "",
1917 parm_table[parmIndex].enum_list[enumIndex].name);
1920 printf(",");
1921 hadFlag = false;
1922 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1923 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1924 printf("%s%s",
1925 hadFlag ? "|" : "",
1926 flag_names[flagIndex]);
1927 hadFlag = true;
1931 /* output synonyms */
1932 hadSyn = false;
1933 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1934 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1935 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1936 parm_table[parmIndex2].label);
1937 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1938 if (!hadSyn) {
1939 printf(" (synonyms: ");
1940 hadSyn = true;
1941 } else {
1942 printf(", ");
1944 printf("%s%s", parm_table[parmIndex2].label,
1945 inverse ? "[i]" : "");
1948 if (hadSyn) {
1949 printf(")");
1952 printf("\n");
1956 * Check the value for a P_ENUM
1958 static bool check_enum_parameter(struct parm_struct *parm, const char *value)
1960 int i;
1962 for (i = 0; parm->enum_list[i].name; i++) {
1963 if (strwicmp(value, parm->enum_list[i].name) == 0) {
1964 return true;
1967 return false;
1970 /**************************************************************************
1971 Check whether the given value is valid for the given parameter name.
1972 **************************************************************************/
1974 static bool lp_parameter_value_is_valid(const char *parm_name, const char *val)
1976 bool ret = false, tmp_bool;
1977 int num = lpcfg_map_parameter(parm_name), tmp_int;
1978 uint64_t tmp_int64 = 0;
1979 struct parm_struct *parm;
1981 /* parametric options (parameter names containing a colon) cannot
1982 be checked and are therefore considered valid. */
1983 if (strchr(parm_name, ':') != NULL) {
1984 return true;
1987 if (num >= 0) {
1988 parm = &parm_table[num];
1989 switch (parm->type) {
1990 case P_BOOL:
1991 case P_BOOLREV:
1992 ret = set_boolean(val, &tmp_bool);
1993 break;
1995 case P_INTEGER:
1996 ret = (sscanf(val, "%d", &tmp_int) == 1);
1997 break;
1999 case P_OCTAL:
2000 ret = (sscanf(val, "%o", &tmp_int) == 1);
2001 break;
2003 case P_ENUM:
2004 ret = check_enum_parameter(parm, val);
2005 break;
2007 case P_BYTES:
2008 if (conv_str_size_error(val, &tmp_int64) &&
2009 tmp_int64 <= INT_MAX) {
2010 ret = true;
2012 break;
2014 case P_CHAR:
2015 case P_LIST:
2016 case P_STRING:
2017 case P_USTRING:
2018 case P_CMDLIST:
2019 ret = true;
2020 break;
2023 return ret;
2026 /***************************************************************************
2027 Show all parameter's name, type, [values,] and flags.
2028 ***************************************************************************/
2030 void show_parameter_list(void)
2032 int classIndex, parmIndex;
2033 const char *section_names[] = { "local", "global", NULL};
2035 for (classIndex=0; section_names[classIndex]; classIndex++) {
2036 printf("[%s]\n", section_names[classIndex]);
2037 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2038 if (parm_table[parmIndex].p_class == classIndex) {
2039 show_parameter(parmIndex);
2045 /***************************************************************************
2046 Get the standard string representation of a boolean value ("yes" or "no")
2047 ***************************************************************************/
2049 static const char *get_boolean(bool bool_value)
2051 static const char *yes_str = "yes";
2052 static const char *no_str = "no";
2054 return (bool_value ? yes_str : no_str);
2057 /***************************************************************************
2058 Provide the string of the negated boolean value associated to the boolean
2059 given as a string. Returns false if the passed string does not correctly
2060 represent a boolean.
2061 ***************************************************************************/
2063 bool lp_invert_boolean(const char *str, const char **inverse_str)
2065 bool val;
2067 if (!set_boolean(str, &val)) {
2068 return false;
2071 *inverse_str = get_boolean(!val);
2072 return true;
2075 /***************************************************************************
2076 Provide the canonical string representation of a boolean value given
2077 as a string. Return true on success, false if the string given does
2078 not correctly represent a boolean.
2079 ***************************************************************************/
2081 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2083 bool val;
2085 if (!set_boolean(str, &val)) {
2086 return false;
2089 *canon_str = get_boolean(val);
2090 return true;
2093 /***************************************************************************
2094 Find a service by name. Otherwise works like get_service.
2095 ***************************************************************************/
2097 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2099 int iService = -1;
2100 char *canon_name;
2101 TDB_DATA data;
2102 NTSTATUS status;
2104 if (ServiceHash == NULL) {
2105 return -1;
2108 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2110 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2111 &data);
2113 if (NT_STATUS_IS_OK(status) &&
2114 (data.dptr != NULL) &&
2115 (data.dsize == sizeof(iService)))
2117 memcpy(&iService, data.dptr, sizeof(iService));
2120 TALLOC_FREE(canon_name);
2122 if ((iService != -1) && (LP_SNUM_OK(iService))
2123 && (pserviceDest != NULL)) {
2124 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2127 return (iService);
2130 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2131 struct loadparm_service *lp_service(const char *pszServiceName)
2133 int iService = getservicebyname(pszServiceName, NULL);
2134 if (iService == -1 || !LP_SNUM_OK(iService)) {
2135 return NULL;
2137 return ServicePtrs[iService];
2140 struct loadparm_service *lp_servicebynum(int snum)
2142 if ((snum == -1) || !LP_SNUM_OK(snum)) {
2143 return NULL;
2145 return ServicePtrs[snum];
2148 struct loadparm_service *lp_default_loadparm_service()
2150 return &sDefault;
2153 static struct smbconf_ctx *lp_smbconf_ctx(void)
2155 sbcErr err;
2156 static struct smbconf_ctx *conf_ctx = NULL;
2158 if (conf_ctx == NULL) {
2159 err = smbconf_init(NULL, &conf_ctx, "registry:");
2160 if (!SBC_ERROR_IS_OK(err)) {
2161 DEBUG(1, ("error initializing registry configuration: "
2162 "%s\n", sbcErrorString(err)));
2163 conf_ctx = NULL;
2167 return conf_ctx;
2170 static bool process_smbconf_service(struct smbconf_service *service)
2172 uint32_t count;
2173 bool ret;
2175 if (service == NULL) {
2176 return false;
2179 ret = lp_do_section(service->name, NULL);
2180 if (ret != true) {
2181 return false;
2183 for (count = 0; count < service->num_params; count++) {
2185 if (!bInGlobalSection && bGlobalOnly) {
2186 ret = true;
2187 } else {
2188 const char *pszParmName = service->param_names[count];
2189 const char *pszParmValue = service->param_values[count];
2191 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2193 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2194 pszParmName, pszParmValue);
2197 if (ret != true) {
2198 return false;
2201 if (iServiceIndex >= 0) {
2202 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2204 return true;
2208 * load a service from registry and activate it
2210 bool process_registry_service(const char *service_name)
2212 sbcErr err;
2213 struct smbconf_service *service = NULL;
2214 TALLOC_CTX *mem_ctx = talloc_stackframe();
2215 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2216 bool ret = false;
2218 if (conf_ctx == NULL) {
2219 goto done;
2222 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2224 if (!smbconf_share_exists(conf_ctx, service_name)) {
2226 * Registry does not contain data for this service (yet),
2227 * but make sure lp_load doesn't return false.
2229 ret = true;
2230 goto done;
2233 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2234 if (!SBC_ERROR_IS_OK(err)) {
2235 goto done;
2238 ret = process_smbconf_service(service);
2239 if (!ret) {
2240 goto done;
2243 /* store the csn */
2244 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2246 done:
2247 TALLOC_FREE(mem_ctx);
2248 return ret;
2252 * process_registry_globals
2254 static bool process_registry_globals(void)
2256 bool ret;
2258 add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2260 if (!bInGlobalSection && bGlobalOnly) {
2261 ret = true;
2262 } else {
2263 const char *pszParmName = "registry shares";
2264 const char *pszParmValue = "yes";
2266 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2268 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2269 pszParmName, pszParmValue);
2272 if (!ret) {
2273 return ret;
2276 return process_registry_service(GLOBAL_NAME);
2279 bool process_registry_shares(void)
2281 sbcErr err;
2282 uint32_t count;
2283 struct smbconf_service **service = NULL;
2284 uint32_t num_shares = 0;
2285 TALLOC_CTX *mem_ctx = talloc_stackframe();
2286 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2287 bool ret = false;
2289 if (conf_ctx == NULL) {
2290 goto done;
2293 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2294 if (!SBC_ERROR_IS_OK(err)) {
2295 goto done;
2298 ret = true;
2300 for (count = 0; count < num_shares; count++) {
2301 if (strequal(service[count]->name, GLOBAL_NAME)) {
2302 continue;
2304 ret = process_smbconf_service(service[count]);
2305 if (!ret) {
2306 goto done;
2310 /* store the csn */
2311 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2313 done:
2314 TALLOC_FREE(mem_ctx);
2315 return ret;
2319 * reload those shares from registry that are already
2320 * activated in the services array.
2322 static bool reload_registry_shares(void)
2324 int i;
2325 bool ret = true;
2327 for (i = 0; i < iNumServices; i++) {
2328 if (!VALID(i)) {
2329 continue;
2332 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2333 continue;
2336 ret = process_registry_service(ServicePtrs[i]->szService);
2337 if (!ret) {
2338 goto done;
2342 done:
2343 return ret;
2347 #define MAX_INCLUDE_DEPTH 100
2349 static uint8_t include_depth;
2352 * Free the file lists
2354 static void free_file_list(void)
2356 struct file_lists *f;
2357 struct file_lists *next;
2359 f = file_lists;
2360 while( f ) {
2361 next = f->next;
2362 TALLOC_FREE( f );
2363 f = next;
2365 file_lists = NULL;
2370 * Utility function for outsiders to check if we're running on registry.
2372 bool lp_config_backend_is_registry(void)
2374 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2378 * Utility function to check if the config backend is FILE.
2380 bool lp_config_backend_is_file(void)
2382 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2385 /*******************************************************************
2386 Check if a config file has changed date.
2387 ********************************************************************/
2389 bool lp_file_list_changed(void)
2391 struct file_lists *f = file_lists;
2393 DEBUG(6, ("lp_file_list_changed()\n"));
2395 while (f) {
2396 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2397 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2399 if (conf_ctx == NULL) {
2400 return false;
2402 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2403 NULL))
2405 DEBUGADD(6, ("registry config changed\n"));
2406 return true;
2408 } else {
2409 time_t mod_time;
2410 char *n2 = NULL;
2412 n2 = talloc_sub_basic(talloc_tos(),
2413 get_current_username(),
2414 current_user_info.domain,
2415 f->name);
2416 if (!n2) {
2417 return false;
2419 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2420 f->name, n2, ctime(&f->modtime)));
2422 mod_time = file_modtime(n2);
2424 if (mod_time &&
2425 ((f->modtime != mod_time) ||
2426 (f->subfname == NULL) ||
2427 (strcmp(n2, f->subfname) != 0)))
2429 DEBUGADD(6,
2430 ("file %s modified: %s\n", n2,
2431 ctime(&mod_time)));
2432 f->modtime = mod_time;
2433 TALLOC_FREE(f->subfname);
2434 f->subfname = talloc_strdup(f, n2);
2435 if (f->subfname == NULL) {
2436 smb_panic("talloc_strdup failed");
2438 TALLOC_FREE(n2);
2439 return true;
2441 TALLOC_FREE(n2);
2443 f = f->next;
2445 return false;
2450 * Initialize iconv conversion descriptors.
2452 * This is called the first time it is needed, and also called again
2453 * every time the configuration is reloaded, because the charset or
2454 * codepage might have changed.
2456 static void init_iconv(void)
2458 struct smb_iconv_handle *ret = NULL;
2460 ret = reinit_iconv_handle(NULL,
2461 lp_dos_charset(),
2462 lp_unix_charset());
2463 if (ret == NULL) {
2464 smb_panic("reinit_iconv_handle failed");
2468 /***************************************************************************
2469 Handle the include operation.
2470 ***************************************************************************/
2471 static bool bAllowIncludeRegistry = true;
2473 bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2474 const char *pszParmValue, char **ptr)
2476 char *fname;
2478 if (include_depth >= MAX_INCLUDE_DEPTH) {
2479 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2480 include_depth));
2481 return false;
2484 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2485 if (!bAllowIncludeRegistry) {
2486 return true;
2488 if (lp_ctx->bInGlobalSection) {
2489 bool ret;
2490 include_depth++;
2491 ret = process_registry_globals();
2492 include_depth--;
2493 return ret;
2494 } else {
2495 DEBUG(1, ("\"include = registry\" only effective "
2496 "in %s section\n", GLOBAL_NAME));
2497 return false;
2501 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2502 current_user_info.domain,
2503 pszParmValue);
2505 add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2507 if (service == NULL) {
2508 lpcfg_string_set(Globals.ctx, ptr, fname);
2509 } else {
2510 lpcfg_string_set(service, ptr, fname);
2513 if (file_exist(fname)) {
2514 bool ret;
2515 include_depth++;
2516 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2517 include_depth--;
2518 TALLOC_FREE(fname);
2519 return ret;
2522 DEBUG(2, ("Can't find include file %s\n", fname));
2523 TALLOC_FREE(fname);
2524 return true;
2527 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2529 char *config_option = NULL;
2530 const char *range = NULL;
2531 bool ret = false;
2533 SMB_ASSERT(low != NULL);
2534 SMB_ASSERT(high != NULL);
2536 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2537 domain_name = "*";
2540 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2541 domain_name);
2542 if (config_option == NULL) {
2543 DEBUG(0, ("out of memory\n"));
2544 return false;
2547 range = lp_parm_const_string(-1, config_option, "range", NULL);
2548 if (range == NULL) {
2549 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2550 goto done;
2553 if (sscanf(range, "%u - %u", low, high) != 2) {
2554 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2555 range, domain_name));
2556 goto done;
2559 ret = true;
2561 done:
2562 talloc_free(config_option);
2563 return ret;
2567 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2569 return lp_idmap_range("*", low, high);
2572 const char *lp_idmap_backend(const char *domain_name)
2574 char *config_option = NULL;
2575 const char *backend = NULL;
2577 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2578 domain_name = "*";
2581 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2582 domain_name);
2583 if (config_option == NULL) {
2584 DEBUG(0, ("out of memory\n"));
2585 return false;
2588 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2589 if (backend == NULL) {
2590 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2591 goto done;
2594 done:
2595 talloc_free(config_option);
2596 return backend;
2599 const char *lp_idmap_default_backend(void)
2601 return lp_idmap_backend("*");
2604 /***************************************************************************
2605 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2606 ***************************************************************************/
2608 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2610 const char *suffix_string;
2612 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2613 Globals.ldap_suffix );
2614 if ( !suffix_string ) {
2615 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2616 return "";
2619 return suffix_string;
2622 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2624 if (Globals._ldap_machine_suffix[0])
2625 return append_ldap_suffix(ctx, Globals._ldap_machine_suffix);
2627 return talloc_strdup(ctx, Globals.ldap_suffix);
2630 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2632 if (Globals._ldap_user_suffix[0])
2633 return append_ldap_suffix(ctx, Globals._ldap_user_suffix);
2635 return talloc_strdup(ctx, Globals.ldap_suffix);
2638 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2640 if (Globals._ldap_group_suffix[0])
2641 return append_ldap_suffix(ctx, Globals._ldap_group_suffix);
2643 return talloc_strdup(ctx, Globals.ldap_suffix);
2646 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2648 if (Globals._ldap_idmap_suffix[0])
2649 return append_ldap_suffix(ctx, Globals._ldap_idmap_suffix);
2651 return talloc_strdup(ctx, Globals.ldap_suffix);
2655 return the parameter pointer for a parameter
2657 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2659 if (service == NULL) {
2660 if (parm->p_class == P_LOCAL)
2661 return (void *)(((char *)&sDefault)+parm->offset);
2662 else if (parm->p_class == P_GLOBAL)
2663 return (void *)(((char *)&Globals)+parm->offset);
2664 else return NULL;
2665 } else {
2666 return (void *)(((char *)service) + parm->offset);
2670 /***************************************************************************
2671 Process a parameter for a particular service number. If snum < 0
2672 then assume we are in the globals.
2673 ***************************************************************************/
2675 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2677 TALLOC_CTX *frame = talloc_stackframe();
2678 struct loadparm_context *lp_ctx;
2679 bool ok;
2681 lp_ctx = setup_lp_context(frame);
2682 if (lp_ctx == NULL) {
2683 TALLOC_FREE(frame);
2684 return false;
2687 if (snum < 0) {
2688 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2689 } else {
2690 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2691 pszParmName, pszParmValue);
2694 TALLOC_FREE(frame);
2696 return ok;
2699 /***************************************************************************
2700 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2701 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2702 ***************************************************************************/
2704 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2706 int parmnum, i;
2707 parmnum = lpcfg_map_parameter(pszParmName);
2708 if (parmnum >= 0) {
2709 flags_list[parmnum] &= ~FLAG_CMDLINE;
2710 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2711 return false;
2713 flags_list[parmnum] |= FLAG_CMDLINE;
2715 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2716 * be grouped in the table, so we don't have to search the
2717 * whole table */
2718 for (i=parmnum-1;
2719 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2720 && parm_table[i].p_class == parm_table[parmnum].p_class;
2721 i--) {
2722 flags_list[i] |= FLAG_CMDLINE;
2724 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2725 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2726 flags_list[i] |= FLAG_CMDLINE;
2729 return true;
2732 /* it might be parametric */
2733 if (strchr(pszParmName, ':') != NULL) {
2734 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2735 return true;
2738 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2739 return false;
2742 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2744 bool ret;
2745 TALLOC_CTX *frame = talloc_stackframe();
2746 struct loadparm_context *lp_ctx;
2748 lp_ctx = setup_lp_context(frame);
2749 if (lp_ctx == NULL) {
2750 TALLOC_FREE(frame);
2751 return false;
2754 ret = lpcfg_set_cmdline(lp_ctx, pszParmName, pszParmValue);
2756 TALLOC_FREE(frame);
2757 return ret;
2760 /***************************************************************************
2761 Process a parameter.
2762 ***************************************************************************/
2764 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2765 void *userdata)
2767 if (!bInGlobalSection && bGlobalOnly)
2768 return true;
2770 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2772 if (bInGlobalSection) {
2773 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2774 } else {
2775 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2776 pszParmName, pszParmValue);
2781 static const char *ad_dc_req_vfs_mods[] = {"dfs_samba4", "acl_xattr", NULL};
2784 * check that @vfs_objects includes all vfs modules required by an AD DC.
2786 static bool check_ad_dc_required_mods(const char **vfs_objects)
2788 int i;
2789 int j;
2790 int got_req;
2792 for (i = 0; ad_dc_req_vfs_mods[i] != NULL; i++) {
2793 got_req = false;
2794 for (j = 0; vfs_objects[j] != NULL; j++) {
2795 if (!strwicmp(ad_dc_req_vfs_mods[i], vfs_objects[j])) {
2796 got_req = true;
2797 break;
2800 if (!got_req) {
2801 DEBUG(0, ("vfs objects specified without required AD "
2802 "DC module: %s\n", ad_dc_req_vfs_mods[i]));
2803 return false;
2807 DEBUG(6, ("vfs objects specified with all required AD DC modules\n"));
2808 return true;
2812 /***************************************************************************
2813 Initialize any local variables in the sDefault table, after parsing a
2814 [globals] section.
2815 ***************************************************************************/
2817 static void init_locals(void)
2820 * We run this check once the [globals] is parsed, to force
2821 * the VFS objects and other per-share settings we need for
2822 * the standard way a AD DC is operated. We may change these
2823 * as our code evolves, which is why we force these settings.
2825 * We can't do this at the end of lp_load_ex(), as by that
2826 * point the services have been loaded and they will already
2827 * have "" as their vfs objects.
2829 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2830 const char **vfs_objects = lp_vfs_objects(-1);
2831 if (vfs_objects != NULL) {
2832 /* ignore return, only warn if modules are missing */
2833 check_ad_dc_required_mods(vfs_objects);
2834 } else {
2835 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2836 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2837 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2838 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2839 } else {
2840 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2844 lp_do_parameter(-1, "map hidden", "no");
2845 lp_do_parameter(-1, "map system", "no");
2846 lp_do_parameter(-1, "map readonly", "no");
2847 lp_do_parameter(-1, "map archive", "no");
2848 lp_do_parameter(-1, "store dos attributes", "yes");
2852 /***************************************************************************
2853 Process a new section (service). At this stage all sections are services.
2854 Later we'll have special sections that permit server parameters to be set.
2855 Returns true on success, false on failure.
2856 ***************************************************************************/
2858 bool lp_do_section(const char *pszSectionName, void *userdata)
2860 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2861 bool bRetval;
2862 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2863 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2865 /* if we were in a global section then do the local inits */
2866 if (bInGlobalSection && !isglobal)
2867 init_locals();
2869 /* if we've just struck a global section, note the fact. */
2870 bInGlobalSection = isglobal;
2871 if (lp_ctx != NULL) {
2872 lp_ctx->bInGlobalSection = isglobal;
2875 /* check for multiple global sections */
2876 if (bInGlobalSection) {
2877 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2878 return true;
2881 if (!bInGlobalSection && bGlobalOnly)
2882 return true;
2884 /* if we have a current service, tidy it up before moving on */
2885 bRetval = true;
2887 if (iServiceIndex >= 0)
2888 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2890 /* if all is still well, move to the next record in the services array */
2891 if (bRetval) {
2892 /* We put this here to avoid an odd message order if messages are */
2893 /* issued by the post-processing of a previous section. */
2894 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2896 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2897 if (iServiceIndex < 0) {
2898 DEBUG(0, ("Failed to add a new service\n"));
2899 return false;
2901 /* Clean all parametric options for service */
2902 /* They will be added during parsing again */
2903 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2906 return bRetval;
2909 /***************************************************************************
2910 Display the contents of a parameter of a single services record.
2911 ***************************************************************************/
2913 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2915 bool result = false;
2916 struct loadparm_context *lp_ctx;
2918 lp_ctx = setup_lp_context(talloc_tos());
2919 if (lp_ctx == NULL) {
2920 return false;
2923 if (isGlobal) {
2924 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2925 } else {
2926 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2928 TALLOC_FREE(lp_ctx);
2929 return result;
2932 #if 0
2933 /***************************************************************************
2934 Display the contents of a single copy structure.
2935 ***************************************************************************/
2936 static void dump_copy_map(bool *pcopymap)
2938 int i;
2939 if (!pcopymap)
2940 return;
2942 printf("\n\tNon-Copied parameters:\n");
2944 for (i = 0; parm_table[i].label; i++)
2945 if (parm_table[i].p_class == P_LOCAL &&
2946 parm_table[i].ptr && !pcopymap[i] &&
2947 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2949 printf("\t\t%s\n", parm_table[i].label);
2952 #endif
2954 /***************************************************************************
2955 Return TRUE if the passed service number is within range.
2956 ***************************************************************************/
2958 bool lp_snum_ok(int iService)
2960 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->available);
2963 /***************************************************************************
2964 Auto-load some home services.
2965 ***************************************************************************/
2967 static void lp_add_auto_services(const char *str)
2969 char *s;
2970 char *p;
2971 int homes;
2972 char *saveptr;
2974 if (!str)
2975 return;
2977 s = talloc_strdup(talloc_tos(), str);
2978 if (!s) {
2979 smb_panic("talloc_strdup failed");
2980 return;
2983 homes = lp_servicenumber(HOMES_NAME);
2985 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
2986 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
2987 char *home;
2989 if (lp_servicenumber(p) >= 0)
2990 continue;
2992 home = get_user_home_dir(talloc_tos(), p);
2994 if (home && home[0] && homes >= 0)
2995 lp_add_home(p, homes, p, home);
2997 TALLOC_FREE(home);
2999 TALLOC_FREE(s);
3002 /***************************************************************************
3003 Auto-load one printer.
3004 ***************************************************************************/
3006 void lp_add_one_printer(const char *name, const char *comment,
3007 const char *location, void *pdata)
3009 int printers = lp_servicenumber(PRINTERS_NAME);
3010 int i;
3012 if (lp_servicenumber(name) < 0) {
3013 lp_add_printer(name, printers);
3014 if ((i = lp_servicenumber(name)) >= 0) {
3015 lpcfg_string_set(ServicePtrs[i],
3016 &ServicePtrs[i]->comment, comment);
3017 ServicePtrs[i]->autoloaded = true;
3022 /***************************************************************************
3023 Have we loaded a services file yet?
3024 ***************************************************************************/
3026 bool lp_loaded(void)
3028 return (bLoaded);
3031 /***************************************************************************
3032 Unload unused services.
3033 ***************************************************************************/
3035 void lp_killunused(struct smbd_server_connection *sconn,
3036 bool (*snumused) (struct smbd_server_connection *, int))
3038 int i;
3039 for (i = 0; i < iNumServices; i++) {
3040 if (!VALID(i))
3041 continue;
3043 /* don't kill autoloaded or usershare services */
3044 if ( ServicePtrs[i]->autoloaded ||
3045 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3046 continue;
3049 if (!snumused || !snumused(sconn, i)) {
3050 free_service_byindex(i);
3056 * Kill all except autoloaded and usershare services - convenience wrapper
3058 void lp_kill_all_services(void)
3060 lp_killunused(NULL, NULL);
3063 /***************************************************************************
3064 Unload a service.
3065 ***************************************************************************/
3067 void lp_killservice(int iServiceIn)
3069 if (VALID(iServiceIn)) {
3070 free_service_byindex(iServiceIn);
3074 /***************************************************************************
3075 Save the curent values of all global and sDefault parameters into the
3076 defaults union. This allows testparm to show only the
3077 changed (ie. non-default) parameters.
3078 ***************************************************************************/
3080 static void lp_save_defaults(void)
3082 int i;
3083 struct parmlist_entry * parm;
3084 for (i = 0; parm_table[i].label; i++) {
3085 if (!(flags_list[i] & FLAG_CMDLINE)) {
3086 flags_list[i] |= FLAG_DEFAULT;
3089 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3090 && parm_table[i].p_class == parm_table[i - 1].p_class)
3091 continue;
3092 switch (parm_table[i].type) {
3093 case P_LIST:
3094 case P_CMDLIST:
3095 parm_table[i].def.lvalue = str_list_copy(
3096 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3097 break;
3098 case P_STRING:
3099 case P_USTRING:
3100 lpcfg_string_set(
3101 Globals.ctx,
3102 &parm_table[i].def.svalue,
3103 *(char **)lp_parm_ptr(
3104 NULL, &parm_table[i]));
3105 if (parm_table[i].def.svalue == NULL) {
3106 smb_panic("lpcfg_string_set() failed");
3108 break;
3109 case P_BOOL:
3110 case P_BOOLREV:
3111 parm_table[i].def.bvalue =
3112 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3113 break;
3114 case P_CHAR:
3115 parm_table[i].def.cvalue =
3116 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3117 break;
3118 case P_INTEGER:
3119 case P_OCTAL:
3120 case P_ENUM:
3121 case P_BYTES:
3122 parm_table[i].def.ivalue =
3123 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3124 break;
3128 for (parm=Globals.param_opt; parm; parm=parm->next) {
3129 if (!(parm->priority & FLAG_CMDLINE)) {
3130 parm->priority |= FLAG_DEFAULT;
3134 for (parm=sDefault.param_opt; parm; parm=parm->next) {
3135 if (!(parm->priority & FLAG_CMDLINE)) {
3136 parm->priority |= FLAG_DEFAULT;
3140 defaults_saved = true;
3143 /***********************************************************
3144 If we should send plaintext/LANMAN passwords in the clinet
3145 ************************************************************/
3147 static void set_allowed_client_auth(void)
3149 if (Globals.client_ntlmv2_auth) {
3150 Globals.client_lanman_auth = false;
3152 if (!Globals.client_lanman_auth) {
3153 Globals.client_plaintext_auth = false;
3157 /***************************************************************************
3158 JRA.
3159 The following code allows smbd to read a user defined share file.
3160 Yes, this is my intent. Yes, I'm comfortable with that...
3162 THE FOLLOWING IS SECURITY CRITICAL CODE.
3164 It washes your clothes, it cleans your house, it guards you while you sleep...
3165 Do not f%^k with it....
3166 ***************************************************************************/
3168 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3170 /***************************************************************************
3171 Check allowed stat state of a usershare file.
3172 Ensure we print out who is dicking with us so the admin can
3173 get their sorry ass fired.
3174 ***************************************************************************/
3176 static bool check_usershare_stat(const char *fname,
3177 const SMB_STRUCT_STAT *psbuf)
3179 if (!S_ISREG(psbuf->st_ex_mode)) {
3180 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3181 "not a regular file\n",
3182 fname, (unsigned int)psbuf->st_ex_uid ));
3183 return false;
3186 /* Ensure this doesn't have the other write bit set. */
3187 if (psbuf->st_ex_mode & S_IWOTH) {
3188 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3189 "public write. Refusing to allow as a usershare file.\n",
3190 fname, (unsigned int)psbuf->st_ex_uid ));
3191 return false;
3194 /* Should be 10k or less. */
3195 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
3196 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3197 "too large (%u) to be a user share file.\n",
3198 fname, (unsigned int)psbuf->st_ex_uid,
3199 (unsigned int)psbuf->st_ex_size ));
3200 return false;
3203 return true;
3206 /***************************************************************************
3207 Parse the contents of a usershare file.
3208 ***************************************************************************/
3210 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
3211 SMB_STRUCT_STAT *psbuf,
3212 const char *servicename,
3213 int snum,
3214 char **lines,
3215 int numlines,
3216 char **pp_sharepath,
3217 char **pp_comment,
3218 char **pp_cp_servicename,
3219 struct security_descriptor **ppsd,
3220 bool *pallow_guest)
3222 const char **prefixallowlist = lp_usershare_prefix_allow_list();
3223 const char **prefixdenylist = lp_usershare_prefix_deny_list();
3224 int us_vers;
3225 DIR *dp;
3226 SMB_STRUCT_STAT sbuf;
3227 char *sharepath = NULL;
3228 char *comment = NULL;
3230 *pp_sharepath = NULL;
3231 *pp_comment = NULL;
3233 *pallow_guest = false;
3235 if (numlines < 4) {
3236 return USERSHARE_MALFORMED_FILE;
3239 if (strcmp(lines[0], "#VERSION 1") == 0) {
3240 us_vers = 1;
3241 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3242 us_vers = 2;
3243 if (numlines < 5) {
3244 return USERSHARE_MALFORMED_FILE;
3246 } else {
3247 return USERSHARE_BAD_VERSION;
3250 if (strncmp(lines[1], "path=", 5) != 0) {
3251 return USERSHARE_MALFORMED_PATH;
3254 sharepath = talloc_strdup(ctx, &lines[1][5]);
3255 if (!sharepath) {
3256 return USERSHARE_POSIX_ERR;
3258 trim_string(sharepath, " ", " ");
3260 if (strncmp(lines[2], "comment=", 8) != 0) {
3261 return USERSHARE_MALFORMED_COMMENT_DEF;
3264 comment = talloc_strdup(ctx, &lines[2][8]);
3265 if (!comment) {
3266 return USERSHARE_POSIX_ERR;
3268 trim_string(comment, " ", " ");
3269 trim_char(comment, '"', '"');
3271 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3272 return USERSHARE_MALFORMED_ACL_DEF;
3275 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3276 return USERSHARE_ACL_ERR;
3279 if (us_vers == 2) {
3280 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3281 return USERSHARE_MALFORMED_ACL_DEF;
3283 if (lines[4][9] == 'y') {
3284 *pallow_guest = true;
3287 /* Backwards compatible extension to file version #2. */
3288 if (numlines > 5) {
3289 if (strncmp(lines[5], "sharename=", 10) != 0) {
3290 return USERSHARE_MALFORMED_SHARENAME_DEF;
3292 if (!strequal(&lines[5][10], servicename)) {
3293 return USERSHARE_BAD_SHARENAME;
3295 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3296 if (!*pp_cp_servicename) {
3297 return USERSHARE_POSIX_ERR;
3302 if (*pp_cp_servicename == NULL) {
3303 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3304 if (!*pp_cp_servicename) {
3305 return USERSHARE_POSIX_ERR;
3309 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3310 /* Path didn't change, no checks needed. */
3311 *pp_sharepath = sharepath;
3312 *pp_comment = comment;
3313 return USERSHARE_OK;
3316 /* The path *must* be absolute. */
3317 if (sharepath[0] != '/') {
3318 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3319 servicename, sharepath));
3320 return USERSHARE_PATH_NOT_ABSOLUTE;
3323 /* If there is a usershare prefix deny list ensure one of these paths
3324 doesn't match the start of the user given path. */
3325 if (prefixdenylist) {
3326 int i;
3327 for ( i=0; prefixdenylist[i]; i++ ) {
3328 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3329 servicename, i, prefixdenylist[i], sharepath ));
3330 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3331 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3332 "usershare prefix deny list entries.\n",
3333 servicename, sharepath));
3334 return USERSHARE_PATH_IS_DENIED;
3339 /* If there is a usershare prefix allow list ensure one of these paths
3340 does match the start of the user given path. */
3342 if (prefixallowlist) {
3343 int i;
3344 for ( i=0; prefixallowlist[i]; i++ ) {
3345 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3346 servicename, i, prefixallowlist[i], sharepath ));
3347 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3348 break;
3351 if (prefixallowlist[i] == NULL) {
3352 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3353 "usershare prefix allow list entries.\n",
3354 servicename, sharepath));
3355 return USERSHARE_PATH_NOT_ALLOWED;
3359 /* Ensure this is pointing to a directory. */
3360 dp = opendir(sharepath);
3362 if (!dp) {
3363 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3364 servicename, sharepath));
3365 return USERSHARE_PATH_NOT_DIRECTORY;
3368 /* Ensure the owner of the usershare file has permission to share
3369 this directory. */
3371 if (sys_stat(sharepath, &sbuf, false) == -1) {
3372 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3373 servicename, sharepath, strerror(errno) ));
3374 closedir(dp);
3375 return USERSHARE_POSIX_ERR;
3378 closedir(dp);
3380 if (!S_ISDIR(sbuf.st_ex_mode)) {
3381 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3382 servicename, sharepath ));
3383 return USERSHARE_PATH_NOT_DIRECTORY;
3386 /* Check if sharing is restricted to owner-only. */
3387 /* psbuf is the stat of the usershare definition file,
3388 sbuf is the stat of the target directory to be shared. */
3390 if (lp_usershare_owner_only()) {
3391 /* root can share anything. */
3392 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3393 return USERSHARE_PATH_NOT_ALLOWED;
3397 *pp_sharepath = sharepath;
3398 *pp_comment = comment;
3399 return USERSHARE_OK;
3402 /***************************************************************************
3403 Deal with a usershare file.
3404 Returns:
3405 >= 0 - snum
3406 -1 - Bad name, invalid contents.
3407 - service name already existed and not a usershare, problem
3408 with permissions to share directory etc.
3409 ***************************************************************************/
3411 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3413 SMB_STRUCT_STAT sbuf;
3414 SMB_STRUCT_STAT lsbuf;
3415 char *fname = NULL;
3416 char *sharepath = NULL;
3417 char *comment = NULL;
3418 char *cp_service_name = NULL;
3419 char **lines = NULL;
3420 int numlines = 0;
3421 int fd = -1;
3422 int iService = -1;
3423 TALLOC_CTX *ctx = talloc_stackframe();
3424 struct security_descriptor *psd = NULL;
3425 bool guest_ok = false;
3426 char *canon_name = NULL;
3427 bool added_service = false;
3428 int ret = -1;
3429 NTSTATUS status;
3431 /* Ensure share name doesn't contain invalid characters. */
3432 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3433 DEBUG(0,("process_usershare_file: share name %s contains "
3434 "invalid characters (any of %s)\n",
3435 file_name, INVALID_SHARENAME_CHARS ));
3436 goto out;
3439 canon_name = canonicalize_servicename(ctx, file_name);
3440 if (!canon_name) {
3441 goto out;
3444 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3445 if (!fname) {
3446 goto out;
3449 /* Minimize the race condition by doing an lstat before we
3450 open and fstat. Ensure this isn't a symlink link. */
3452 if (sys_lstat(fname, &lsbuf, false) != 0) {
3453 if (errno == ENOENT) {
3454 /* Unknown share requested. Just ignore. */
3455 goto out;
3457 /* Only log messages for meaningful problems. */
3458 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3459 fname, strerror(errno) ));
3460 goto out;
3463 /* This must be a regular file, not a symlink, directory or
3464 other strange filetype. */
3465 if (!check_usershare_stat(fname, &lsbuf)) {
3466 goto out;
3470 TDB_DATA data;
3472 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3473 canon_name, &data);
3475 iService = -1;
3477 if (NT_STATUS_IS_OK(status) &&
3478 (data.dptr != NULL) &&
3479 (data.dsize == sizeof(iService))) {
3480 memcpy(&iService, data.dptr, sizeof(iService));
3484 if (iService != -1 &&
3485 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3486 &lsbuf.st_ex_mtime) == 0) {
3487 /* Nothing changed - Mark valid and return. */
3488 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3489 canon_name ));
3490 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3491 ret = iService;
3492 goto out;
3495 /* Try and open the file read only - no symlinks allowed. */
3496 #ifdef O_NOFOLLOW
3497 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3498 #else
3499 fd = open(fname, O_RDONLY, 0);
3500 #endif
3502 if (fd == -1) {
3503 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3504 fname, strerror(errno) ));
3505 goto out;
3508 /* Now fstat to be *SURE* it's a regular file. */
3509 if (sys_fstat(fd, &sbuf, false) != 0) {
3510 close(fd);
3511 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3512 fname, strerror(errno) ));
3513 goto out;
3516 /* Is it the same dev/inode as was lstated ? */
3517 if (!check_same_stat(&lsbuf, &sbuf)) {
3518 close(fd);
3519 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3520 "Symlink spoofing going on ?\n", fname ));
3521 goto out;
3524 /* This must be a regular file, not a symlink, directory or
3525 other strange filetype. */
3526 if (!check_usershare_stat(fname, &sbuf)) {
3527 close(fd);
3528 goto out;
3531 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3533 close(fd);
3534 if (lines == NULL) {
3535 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3536 fname, (unsigned int)sbuf.st_ex_uid ));
3537 goto out;
3540 if (parse_usershare_file(ctx, &sbuf, file_name,
3541 iService, lines, numlines, &sharepath,
3542 &comment, &cp_service_name,
3543 &psd, &guest_ok) != USERSHARE_OK) {
3544 goto out;
3547 /* Everything ok - add the service possibly using a template. */
3548 if (iService < 0) {
3549 const struct loadparm_service *sp = &sDefault;
3550 if (snum_template != -1) {
3551 sp = ServicePtrs[snum_template];
3554 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3555 DEBUG(0, ("process_usershare_file: Failed to add "
3556 "new service %s\n", cp_service_name));
3557 goto out;
3560 added_service = true;
3562 /* Read only is controlled by usershare ACL below. */
3563 ServicePtrs[iService]->read_only = false;
3566 /* Write the ACL of the new/modified share. */
3567 status = set_share_security(canon_name, psd);
3568 if (!NT_STATUS_IS_OK(status)) {
3569 DEBUG(0, ("process_usershare_file: Failed to set share "
3570 "security for user share %s\n",
3571 canon_name ));
3572 goto out;
3575 /* If from a template it may be marked invalid. */
3576 ServicePtrs[iService]->valid = true;
3578 /* Set the service as a valid usershare. */
3579 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3581 /* Set guest access. */
3582 if (lp_usershare_allow_guests()) {
3583 ServicePtrs[iService]->guest_ok = guest_ok;
3586 /* And note when it was loaded. */
3587 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3588 lpcfg_string_set(ServicePtrs[iService], &ServicePtrs[iService]->path,
3589 sharepath);
3590 lpcfg_string_set(ServicePtrs[iService],
3591 &ServicePtrs[iService]->comment, comment);
3593 ret = iService;
3595 out:
3597 if (ret == -1 && iService != -1 && added_service) {
3598 lp_remove_service(iService);
3601 TALLOC_FREE(lines);
3602 TALLOC_FREE(ctx);
3603 return ret;
3606 /***************************************************************************
3607 Checks if a usershare entry has been modified since last load.
3608 ***************************************************************************/
3610 static bool usershare_exists(int iService, struct timespec *last_mod)
3612 SMB_STRUCT_STAT lsbuf;
3613 const char *usersharepath = Globals.usershare_path;
3614 char *fname;
3616 fname = talloc_asprintf(talloc_tos(),
3617 "%s/%s",
3618 usersharepath,
3619 ServicePtrs[iService]->szService);
3620 if (fname == NULL) {
3621 return false;
3624 if (sys_lstat(fname, &lsbuf, false) != 0) {
3625 TALLOC_FREE(fname);
3626 return false;
3629 if (!S_ISREG(lsbuf.st_ex_mode)) {
3630 TALLOC_FREE(fname);
3631 return false;
3634 TALLOC_FREE(fname);
3635 *last_mod = lsbuf.st_ex_mtime;
3636 return true;
3639 static bool usershare_directory_is_root(uid_t uid)
3641 if (uid == 0) {
3642 return true;
3645 if (uid_wrapper_enabled()) {
3646 return true;
3649 return false;
3652 /***************************************************************************
3653 Load a usershare service by name. Returns a valid servicenumber or -1.
3654 ***************************************************************************/
3656 int load_usershare_service(const char *servicename)
3658 SMB_STRUCT_STAT sbuf;
3659 const char *usersharepath = Globals.usershare_path;
3660 int max_user_shares = Globals.usershare_max_shares;
3661 int snum_template = -1;
3663 if (servicename[0] == '\0') {
3664 /* Invalid service name. */
3665 return -1;
3668 if (*usersharepath == 0 || max_user_shares == 0) {
3669 return -1;
3672 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3673 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3674 usersharepath, strerror(errno) ));
3675 return -1;
3678 if (!S_ISDIR(sbuf.st_ex_mode)) {
3679 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3680 usersharepath ));
3681 return -1;
3685 * This directory must be owned by root, and have the 't' bit set.
3686 * It also must not be writable by "other".
3689 #ifdef S_ISVTX
3690 if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
3691 !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3692 #else
3693 if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
3694 (sbuf.st_ex_mode & S_IWOTH)) {
3695 #endif
3696 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3697 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3698 usersharepath ));
3699 return -1;
3702 /* Ensure the template share exists if it's set. */
3703 if (Globals.usershare_template_share[0]) {
3704 /* We can't use lp_servicenumber here as we are recommending that
3705 template shares have -valid=false set. */
3706 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3707 if (ServicePtrs[snum_template]->szService &&
3708 strequal(ServicePtrs[snum_template]->szService,
3709 Globals.usershare_template_share)) {
3710 break;
3714 if (snum_template == -1) {
3715 DEBUG(0,("load_usershare_service: usershare template share %s "
3716 "does not exist.\n",
3717 Globals.usershare_template_share ));
3718 return -1;
3722 return process_usershare_file(usersharepath, servicename, snum_template);
3725 /***************************************************************************
3726 Load all user defined shares from the user share directory.
3727 We only do this if we're enumerating the share list.
3728 This is the function that can delete usershares that have
3729 been removed.
3730 ***************************************************************************/
3732 int load_usershare_shares(struct smbd_server_connection *sconn,
3733 bool (*snumused) (struct smbd_server_connection *, int))
3735 DIR *dp;
3736 SMB_STRUCT_STAT sbuf;
3737 struct dirent *de;
3738 int num_usershares = 0;
3739 int max_user_shares = Globals.usershare_max_shares;
3740 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3741 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3742 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3743 int iService;
3744 int snum_template = -1;
3745 const char *usersharepath = Globals.usershare_path;
3746 int ret = lp_numservices();
3747 TALLOC_CTX *tmp_ctx;
3749 if (max_user_shares == 0 || *usersharepath == '\0') {
3750 return lp_numservices();
3753 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3754 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3755 usersharepath, strerror(errno) ));
3756 return ret;
3760 * This directory must be owned by root, and have the 't' bit set.
3761 * It also must not be writable by "other".
3764 #ifdef S_ISVTX
3765 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3766 #else
3767 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3768 #endif
3769 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3770 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3771 usersharepath ));
3772 return ret;
3775 /* Ensure the template share exists if it's set. */
3776 if (Globals.usershare_template_share[0]) {
3777 /* We can't use lp_servicenumber here as we are recommending that
3778 template shares have -valid=false set. */
3779 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3780 if (ServicePtrs[snum_template]->szService &&
3781 strequal(ServicePtrs[snum_template]->szService,
3782 Globals.usershare_template_share)) {
3783 break;
3787 if (snum_template == -1) {
3788 DEBUG(0,("load_usershare_shares: usershare template share %s "
3789 "does not exist.\n",
3790 Globals.usershare_template_share ));
3791 return ret;
3795 /* Mark all existing usershares as pending delete. */
3796 for (iService = iNumServices - 1; iService >= 0; iService--) {
3797 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3798 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3802 dp = opendir(usersharepath);
3803 if (!dp) {
3804 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3805 usersharepath, strerror(errno) ));
3806 return ret;
3809 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3810 (de = readdir(dp));
3811 num_dir_entries++ ) {
3812 int r;
3813 const char *n = de->d_name;
3815 /* Ignore . and .. */
3816 if (*n == '.') {
3817 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3818 continue;
3822 if (n[0] == ':') {
3823 /* Temporary file used when creating a share. */
3824 num_tmp_dir_entries++;
3827 /* Allow 20% tmp entries. */
3828 if (num_tmp_dir_entries > allowed_tmp_entries) {
3829 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3830 "in directory %s\n",
3831 num_tmp_dir_entries, usersharepath));
3832 break;
3835 r = process_usershare_file(usersharepath, n, snum_template);
3836 if (r == 0) {
3837 /* Update the services count. */
3838 num_usershares++;
3839 if (num_usershares >= max_user_shares) {
3840 DEBUG(0,("load_usershare_shares: max user shares reached "
3841 "on file %s in directory %s\n",
3842 n, usersharepath ));
3843 break;
3845 } else if (r == -1) {
3846 num_bad_dir_entries++;
3849 /* Allow 20% bad entries. */
3850 if (num_bad_dir_entries > allowed_bad_entries) {
3851 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3852 "in directory %s\n",
3853 num_bad_dir_entries, usersharepath));
3854 break;
3857 /* Allow 20% bad entries. */
3858 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3859 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3860 "in directory %s\n",
3861 num_dir_entries, usersharepath));
3862 break;
3866 closedir(dp);
3868 /* Sweep through and delete any non-refreshed usershares that are
3869 not currently in use. */
3870 tmp_ctx = talloc_stackframe();
3871 for (iService = iNumServices - 1; iService >= 0; iService--) {
3872 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3873 const struct loadparm_substitution *lp_sub =
3874 loadparm_s3_global_substitution();
3875 char *servname;
3877 if (snumused && snumused(sconn, iService)) {
3878 continue;
3881 servname = lp_servicename(tmp_ctx, lp_sub, iService);
3883 /* Remove from the share ACL db. */
3884 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3885 servname ));
3886 delete_share_security(servname);
3887 free_service_byindex(iService);
3890 talloc_free(tmp_ctx);
3892 return lp_numservices();
3895 /********************************************************
3896 Destroy global resources allocated in this file
3897 ********************************************************/
3899 void gfree_loadparm(void)
3901 int i;
3903 free_file_list();
3905 /* Free resources allocated to services */
3907 for ( i = 0; i < iNumServices; i++ ) {
3908 if ( VALID(i) ) {
3909 free_service_byindex(i);
3913 TALLOC_FREE( ServicePtrs );
3914 iNumServices = 0;
3916 /* Now release all resources allocated to global
3917 parameters and the default service */
3919 free_global_parameters();
3923 /***************************************************************************
3924 Allow client apps to specify that they are a client
3925 ***************************************************************************/
3926 static void lp_set_in_client(bool b)
3928 in_client = b;
3932 /***************************************************************************
3933 Determine if we're running in a client app
3934 ***************************************************************************/
3935 static bool lp_is_in_client(void)
3937 return in_client;
3940 static void lp_enforce_ad_dc_settings(void)
3942 lp_do_parameter(GLOBAL_SECTION_SNUM, "passdb backend", "samba_dsdb");
3943 lp_do_parameter(GLOBAL_SECTION_SNUM,
3944 "winbindd:use external pipes", "true");
3945 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:default", "external");
3946 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:svcctl", "embedded");
3947 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:srvsvc", "embedded");
3948 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:eventlog", "embedded");
3949 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:ntsvcs", "embedded");
3950 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:winreg", "embedded");
3951 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:spoolss", "embedded");
3952 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_daemon:spoolssd", "embedded");
3953 lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:tcpip", "no");
3956 /***************************************************************************
3957 Load the services array from the services file. Return true on success,
3958 false on failure.
3959 ***************************************************************************/
3961 static bool lp_load_ex(const char *pszFname,
3962 bool global_only,
3963 bool save_defaults,
3964 bool add_ipc,
3965 bool reinit_globals,
3966 bool allow_include_registry,
3967 bool load_all_shares)
3969 char *n2 = NULL;
3970 bool bRetval;
3971 TALLOC_CTX *frame = talloc_stackframe();
3972 struct loadparm_context *lp_ctx;
3973 int max_protocol, min_protocol;
3975 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3977 bInGlobalSection = true;
3978 bGlobalOnly = global_only;
3979 bAllowIncludeRegistry = allow_include_registry;
3980 sDefault = _sDefault;
3982 lp_ctx = setup_lp_context(talloc_tos());
3984 init_globals(lp_ctx, reinit_globals);
3986 free_file_list();
3988 if (save_defaults) {
3989 init_locals();
3990 lp_save_defaults();
3993 if (!reinit_globals) {
3994 free_param_opts(&Globals.param_opt);
3995 apply_lp_set_cmdline();
3998 lp_do_parameter(-1, "idmap config * : backend", Globals.idmap_backend);
4000 /* We get sections first, so have to start 'behind' to make up */
4001 iServiceIndex = -1;
4003 if (lp_config_backend_is_file()) {
4004 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4005 current_user_info.domain,
4006 pszFname);
4007 if (!n2) {
4008 smb_panic("lp_load_ex: out of memory");
4011 add_to_file_list(NULL, &file_lists, pszFname, n2);
4013 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
4014 TALLOC_FREE(n2);
4016 /* finish up the last section */
4017 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4018 if (bRetval) {
4019 if (iServiceIndex >= 0) {
4020 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
4024 if (lp_config_backend_is_registry()) {
4025 bool ok;
4026 /* config backend changed to registry in config file */
4028 * We need to use this extra global variable here to
4029 * survive restart: init_globals uses this as a default
4030 * for config_backend. Otherwise, init_globals would
4031 * send us into an endless loop here.
4034 config_backend = CONFIG_BACKEND_REGISTRY;
4035 /* start over */
4036 DEBUG(1, ("lp_load_ex: changing to config backend "
4037 "registry\n"));
4038 init_globals(lp_ctx, true);
4040 TALLOC_FREE(lp_ctx);
4042 lp_kill_all_services();
4043 ok = lp_load_ex(pszFname, global_only, save_defaults,
4044 add_ipc, reinit_globals,
4045 allow_include_registry,
4046 load_all_shares);
4047 TALLOC_FREE(frame);
4048 return ok;
4050 } else if (lp_config_backend_is_registry()) {
4051 bRetval = process_registry_globals();
4052 } else {
4053 DEBUG(0, ("Illegal config backend given: %d\n",
4054 lp_config_backend()));
4055 bRetval = false;
4058 if (bRetval && lp_registry_shares()) {
4059 if (load_all_shares) {
4060 bRetval = process_registry_shares();
4061 } else {
4062 bRetval = reload_registry_shares();
4067 const struct loadparm_substitution *lp_sub =
4068 loadparm_s3_global_substitution();
4069 char *serv = lp_auto_services(talloc_tos(), lp_sub);
4070 lp_add_auto_services(serv);
4071 TALLOC_FREE(serv);
4074 if (add_ipc) {
4075 /* When 'restrict anonymous = 2' guest connections to ipc$
4076 are denied */
4077 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4078 if ( lp_enable_asu_support() ) {
4079 lp_add_ipc("ADMIN$", false);
4083 set_allowed_client_auth();
4085 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
4086 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4087 lp_password_server()));
4090 bLoaded = true;
4092 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4093 /* if we_are_a_wins_server is true and we are in the client */
4094 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
4095 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4098 init_iconv();
4100 fault_configure(smb_panic_s3);
4103 * We run this check once the whole smb.conf is parsed, to
4104 * force some settings for the standard way a AD DC is
4105 * operated. We may change these as our code evolves, which
4106 * is why we force these settings.
4108 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4109 lp_enforce_ad_dc_settings();
4112 bAllowIncludeRegistry = true;
4114 /* Check if command line max protocol < min protocol, if so
4115 * report a warning to the user.
4117 max_protocol = lp_client_max_protocol();
4118 min_protocol = lp_client_min_protocol();
4119 if (max_protocol < min_protocol) {
4120 const char *max_protocolp, *min_protocolp;
4121 max_protocolp = lpcfg_get_smb_protocol(max_protocol);
4122 min_protocolp = lpcfg_get_smb_protocol(min_protocol);
4123 DBG_ERR("Max protocol %s is less than min protocol %s.\n",
4124 max_protocolp, min_protocolp);
4127 TALLOC_FREE(frame);
4128 return (bRetval);
4131 static bool lp_load(const char *pszFname,
4132 bool global_only,
4133 bool save_defaults,
4134 bool add_ipc,
4135 bool reinit_globals)
4137 return lp_load_ex(pszFname,
4138 global_only,
4139 save_defaults,
4140 add_ipc,
4141 reinit_globals,
4142 true, /* allow_include_registry */
4143 false); /* load_all_shares*/
4146 bool lp_load_initial_only(const char *pszFname)
4148 return lp_load_ex(pszFname,
4149 true, /* global only */
4150 true, /* save_defaults */
4151 false, /* add_ipc */
4152 true, /* reinit_globals */
4153 false, /* allow_include_registry */
4154 false); /* load_all_shares*/
4158 * most common lp_load wrapper, loading only the globals
4160 * If this is used in a daemon or client utility it should be called
4161 * after processing popt.
4163 bool lp_load_global(const char *file_name)
4165 return lp_load(file_name,
4166 true, /* global_only */
4167 false, /* save_defaults */
4168 false, /* add_ipc */
4169 true); /* reinit_globals */
4173 * The typical lp_load wrapper with shares, loads global and
4174 * shares, including IPC, but does not force immediate
4175 * loading of all shares from registry.
4177 bool lp_load_with_shares(const char *file_name)
4179 return lp_load(file_name,
4180 false, /* global_only */
4181 false, /* save_defaults */
4182 true, /* add_ipc */
4183 true); /* reinit_globals */
4187 * lp_load wrapper, especially for clients
4189 bool lp_load_client(const char *file_name)
4191 lp_set_in_client(true);
4193 return lp_load_global(file_name);
4197 * lp_load wrapper, loading only globals, but intended
4198 * for subsequent calls, not reinitializing the globals
4199 * to default values
4201 bool lp_load_global_no_reinit(const char *file_name)
4203 return lp_load(file_name,
4204 true, /* global_only */
4205 false, /* save_defaults */
4206 false, /* add_ipc */
4207 false); /* reinit_globals */
4211 * lp_load wrapper, loading globals and shares,
4212 * intended for subsequent calls, i.e. not reinitializing
4213 * the globals to default values.
4215 bool lp_load_no_reinit(const char *file_name)
4217 return lp_load(file_name,
4218 false, /* global_only */
4219 false, /* save_defaults */
4220 false, /* add_ipc */
4221 false); /* reinit_globals */
4226 * lp_load wrapper, especially for clients, no reinitialization
4228 bool lp_load_client_no_reinit(const char *file_name)
4230 lp_set_in_client(true);
4232 return lp_load_global_no_reinit(file_name);
4235 bool lp_load_with_registry_shares(const char *pszFname)
4237 return lp_load_ex(pszFname,
4238 false, /* global_only */
4239 true, /* save_defaults */
4240 false, /* add_ipc */
4241 true, /* reinit_globals */
4242 true, /* allow_include_registry */
4243 true); /* load_all_shares*/
4246 /***************************************************************************
4247 Return the max number of services.
4248 ***************************************************************************/
4250 int lp_numservices(void)
4252 return (iNumServices);
4255 /***************************************************************************
4256 Display the contents of the services array in human-readable form.
4257 ***************************************************************************/
4259 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4261 int iService;
4262 struct loadparm_context *lp_ctx;
4264 if (show_defaults)
4265 defaults_saved = false;
4267 lp_ctx = setup_lp_context(talloc_tos());
4268 if (lp_ctx == NULL) {
4269 return;
4272 lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
4274 lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
4276 for (iService = 0; iService < maxtoprint; iService++) {
4277 fprintf(f,"\n");
4278 lp_dump_one(f, show_defaults, iService);
4280 TALLOC_FREE(lp_ctx);
4283 /***************************************************************************
4284 Display the contents of one service in human-readable form.
4285 ***************************************************************************/
4287 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4289 if (VALID(snum)) {
4290 if (ServicePtrs[snum]->szService[0] == '\0')
4291 return;
4292 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
4293 flags_list, show_defaults);
4297 /***************************************************************************
4298 Return the number of the service with the given name, or -1 if it doesn't
4299 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4300 getservicebyname()! This works ONLY if all services have been loaded, and
4301 does not copy the found service.
4302 ***************************************************************************/
4304 int lp_servicenumber(const char *pszServiceName)
4306 int iService;
4307 fstring serviceName;
4309 if (!pszServiceName) {
4310 return GLOBAL_SECTION_SNUM;
4313 for (iService = iNumServices - 1; iService >= 0; iService--) {
4314 if (VALID(iService) && ServicePtrs[iService]->szService) {
4316 * The substitution here is used to support %U in
4317 * service names
4319 fstrcpy(serviceName, ServicePtrs[iService]->szService);
4320 standard_sub_basic(get_current_username(),
4321 current_user_info.domain,
4322 serviceName,sizeof(serviceName));
4323 if (strequal(serviceName, pszServiceName)) {
4324 break;
4329 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4330 struct timespec last_mod;
4332 if (!usershare_exists(iService, &last_mod)) {
4333 /* Remove the share security tdb entry for it. */
4334 delete_share_security(lp_const_servicename(iService));
4335 /* Remove it from the array. */
4336 free_service_byindex(iService);
4337 /* Doesn't exist anymore. */
4338 return GLOBAL_SECTION_SNUM;
4341 /* Has it been modified ? If so delete and reload. */
4342 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4343 &last_mod) < 0) {
4344 /* Remove it from the array. */
4345 free_service_byindex(iService);
4346 /* and now reload it. */
4347 iService = load_usershare_service(pszServiceName);
4351 if (iService < 0) {
4352 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4353 return GLOBAL_SECTION_SNUM;
4356 return (iService);
4359 /*******************************************************************
4360 A useful volume label function.
4361 ********************************************************************/
4363 const char *volume_label(TALLOC_CTX *ctx, int snum)
4365 const struct loadparm_substitution *lp_sub =
4366 loadparm_s3_global_substitution();
4367 char *ret;
4368 const char *label = lp_volume(ctx, lp_sub, snum);
4369 size_t end = 32;
4371 if (!*label) {
4372 label = lp_servicename(ctx, lp_sub, snum);
4376 * Volume label can be a max of 32 bytes. Make sure to truncate
4377 * it at a codepoint boundary if it's longer than 32 and contains
4378 * multibyte characters. Windows insists on a volume label being
4379 * a valid mb sequence, and errors out if not.
4381 if (strlen(label) > 32) {
4383 * A MB char can be a max of 5 bytes, thus
4384 * we should have a valid mb character at a
4385 * minimum position of (32-5) = 27.
4387 while (end >= 27) {
4389 * Check if a codepoint starting from next byte
4390 * is valid. If yes, then the current byte is the
4391 * end of a MB or ascii sequence and the label can
4392 * be safely truncated here. If not, keep going
4393 * backwards till a valid codepoint is found.
4395 size_t len = 0;
4396 const char *s = &label[end];
4397 codepoint_t c = next_codepoint(s, &len);
4398 if (c != INVALID_CODEPOINT) {
4399 break;
4401 end--;
4405 /* This returns a max of 33 byte guarenteed null terminated string. */
4406 ret = talloc_strndup(ctx, label, end);
4407 if (!ret) {
4408 return "";
4410 return ret;
4413 /*******************************************************************
4414 Get the default server type we will announce as via nmbd.
4415 ********************************************************************/
4417 int lp_default_server_announce(void)
4419 int default_server_announce = 0;
4420 default_server_announce |= SV_TYPE_WORKSTATION;
4421 default_server_announce |= SV_TYPE_SERVER;
4422 default_server_announce |= SV_TYPE_SERVER_UNIX;
4424 /* note that the flag should be set only if we have a
4425 printer service but nmbd doesn't actually load the
4426 services so we can't tell --jerry */
4428 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4430 default_server_announce |= SV_TYPE_SERVER_NT;
4431 default_server_announce |= SV_TYPE_NT;
4433 switch (lp_server_role()) {
4434 case ROLE_DOMAIN_MEMBER:
4435 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4436 break;
4437 case ROLE_DOMAIN_PDC:
4438 case ROLE_IPA_DC:
4439 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4440 break;
4441 case ROLE_DOMAIN_BDC:
4442 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4443 break;
4444 case ROLE_STANDALONE:
4445 default:
4446 break;
4448 if (lp_time_server())
4449 default_server_announce |= SV_TYPE_TIME_SOURCE;
4451 if (lp_host_msdfs())
4452 default_server_announce |= SV_TYPE_DFS_SERVER;
4454 return default_server_announce;
4457 /***********************************************************
4458 If we are PDC then prefer us as DMB
4459 ************************************************************/
4461 bool lp_domain_master(void)
4463 if (Globals._domain_master == Auto)
4464 return (lp_server_role() == ROLE_DOMAIN_PDC ||
4465 lp_server_role() == ROLE_IPA_DC);
4467 return (bool)Globals._domain_master;
4470 /***********************************************************
4471 If we are PDC then prefer us as DMB
4472 ************************************************************/
4474 static bool lp_domain_master_true_or_auto(void)
4476 if (Globals._domain_master) /* auto or yes */
4477 return true;
4479 return false;
4482 /***********************************************************
4483 If we are DMB then prefer us as LMB
4484 ************************************************************/
4486 bool lp_preferred_master(void)
4488 int preferred_master = lp__preferred_master();
4490 if (preferred_master == Auto)
4491 return (lp_local_master() && lp_domain_master());
4493 return (bool)preferred_master;
4496 /*******************************************************************
4497 Remove a service.
4498 ********************************************************************/
4500 void lp_remove_service(int snum)
4502 ServicePtrs[snum]->valid = false;
4505 const char *lp_printername(TALLOC_CTX *ctx,
4506 const struct loadparm_substitution *lp_sub,
4507 int snum)
4509 const char *ret = lp__printername(ctx, lp_sub, snum);
4511 if (ret == NULL || *ret == '\0') {
4512 ret = lp_const_servicename(snum);
4515 return ret;
4519 /***********************************************************
4520 Allow daemons such as winbindd to fix their logfile name.
4521 ************************************************************/
4523 void lp_set_logfile(const char *name)
4525 lpcfg_string_set(Globals.ctx, &Globals.logfile, name);
4526 debug_set_logfile(name);
4529 /*******************************************************************
4530 Return the max print jobs per queue.
4531 ********************************************************************/
4533 int lp_maxprintjobs(int snum)
4535 int maxjobs = lp_max_print_jobs(snum);
4537 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4538 maxjobs = PRINT_MAX_JOBID - 1;
4540 return maxjobs;
4543 const char *lp_printcapname(void)
4545 const char *printcap_name = lp_printcap_name();
4547 if ((printcap_name != NULL) &&
4548 (printcap_name[0] != '\0'))
4549 return printcap_name;
4551 if (sDefault.printing == PRINT_CUPS) {
4552 return "cups";
4555 if (sDefault.printing == PRINT_BSD)
4556 return "/etc/printcap";
4558 return PRINTCAP_NAME;
4561 static uint32_t spoolss_state;
4563 bool lp_disable_spoolss( void )
4565 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4566 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4568 return spoolss_state == SVCCTL_STOPPED ? true : false;
4571 void lp_set_spoolss_state( uint32_t state )
4573 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4575 spoolss_state = state;
4578 uint32_t lp_get_spoolss_state( void )
4580 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4583 /*******************************************************************
4584 Turn off sendfile if we find the underlying OS doesn't support it.
4585 ********************************************************************/
4587 void set_use_sendfile(int snum, bool val)
4589 if (LP_SNUM_OK(snum))
4590 ServicePtrs[snum]->_use_sendfile = val;
4591 else
4592 sDefault._use_sendfile = val;
4595 void lp_set_mangling_method(const char *new_method)
4597 lpcfg_string_set(Globals.ctx, &Globals.mangling_method, new_method);
4600 /*******************************************************************
4601 Global state for POSIX pathname processing.
4602 ********************************************************************/
4604 static bool posix_pathnames;
4606 bool lp_posix_pathnames(void)
4608 return posix_pathnames;
4611 /*******************************************************************
4612 Change everything needed to ensure POSIX pathname processing (currently
4613 not much).
4614 ********************************************************************/
4616 void lp_set_posix_pathnames(void)
4618 posix_pathnames = true;
4621 /*******************************************************************
4622 Global state for POSIX lock processing - CIFS unix extensions.
4623 ********************************************************************/
4625 bool posix_default_lock_was_set;
4626 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4628 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4630 if (posix_default_lock_was_set) {
4631 return posix_cifsx_locktype;
4632 } else {
4633 return (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
4634 POSIX_LOCK : WINDOWS_LOCK;
4638 /*******************************************************************
4639 ********************************************************************/
4641 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4643 posix_default_lock_was_set = true;
4644 posix_cifsx_locktype = val;
4647 int lp_min_receive_file_size(void)
4649 int min_receivefile_size = lp_min_receivefile_size();
4651 if (min_receivefile_size < 0) {
4652 return 0;
4654 return min_receivefile_size;
4657 /*******************************************************************
4658 Safe wide links checks.
4659 This helper function always verify the validity of wide links,
4660 even after a configuration file reload.
4661 ********************************************************************/
4663 void widelinks_warning(int snum)
4665 if (lp_allow_insecure_wide_links()) {
4666 return;
4669 if (lp_wide_links(snum)) {
4670 if (lp_smb1_unix_extensions()) {
4671 DBG_ERR("Share '%s' has wide links and SMB1 unix "
4672 "extensions enabled. "
4673 "These parameters are incompatible. "
4674 "Wide links will be disabled for this share.\n",
4675 lp_const_servicename(snum));
4676 } else if (lp_smb2_unix_extensions()) {
4677 DBG_ERR("Share '%s' has wide links and SMB2 unix "
4678 "extensions enabled. "
4679 "These parameters are incompatible. "
4680 "Wide links will be disabled for this share.\n",
4681 lp_const_servicename(snum));
4686 bool lp_widelinks(int snum)
4688 /* wide links is always incompatible with unix extensions */
4689 if (lp_smb1_unix_extensions() || lp_smb2_unix_extensions()) {
4691 * Unless we have "allow insecure widelinks"
4692 * turned on.
4694 if (!lp_allow_insecure_wide_links()) {
4695 return false;
4699 return lp_wide_links(snum);
4702 int lp_server_role(void)
4704 return lp_find_server_role(lp__server_role(),
4705 lp__security(),
4706 lp__domain_logons(),
4707 lp_domain_master_true_or_auto());
4710 int lp_security(void)
4712 return lp_find_security(lp__server_role(),
4713 lp__security());
4716 int lp_client_max_protocol(void)
4718 int client_max_protocol = lp__client_max_protocol();
4719 if (client_max_protocol == PROTOCOL_DEFAULT) {
4720 return PROTOCOL_LATEST;
4722 return client_max_protocol;
4725 int lp_client_ipc_min_protocol(void)
4727 int client_ipc_min_protocol = lp__client_ipc_min_protocol();
4728 if (client_ipc_min_protocol == PROTOCOL_DEFAULT) {
4729 client_ipc_min_protocol = lp_client_min_protocol();
4731 if (client_ipc_min_protocol < PROTOCOL_NT1) {
4732 return PROTOCOL_NT1;
4734 return client_ipc_min_protocol;
4737 int lp_client_ipc_max_protocol(void)
4739 int client_ipc_max_protocol = lp__client_ipc_max_protocol();
4740 if (client_ipc_max_protocol == PROTOCOL_DEFAULT) {
4741 return PROTOCOL_LATEST;
4743 if (client_ipc_max_protocol < PROTOCOL_NT1) {
4744 return PROTOCOL_NT1;
4746 return client_ipc_max_protocol;
4749 int lp_client_ipc_signing(void)
4751 int client_ipc_signing = lp__client_ipc_signing();
4752 if (client_ipc_signing == SMB_SIGNING_DEFAULT) {
4753 return SMB_SIGNING_REQUIRED;
4755 return client_ipc_signing;
4758 enum credentials_use_kerberos lp_client_use_kerberos(void)
4760 if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
4761 return CRED_USE_KERBEROS_REQUIRED;
4764 return lp__client_use_kerberos();
4768 int lp_rpc_low_port(void)
4770 return Globals.rpc_low_port;
4773 int lp_rpc_high_port(void)
4775 return Globals.rpc_high_port;
4779 * Do not allow LanMan auth if unless NTLMv1 is also allowed
4781 * This also ensures it is disabled if NTLM is totally disabled
4783 bool lp_lanman_auth(void)
4785 enum ntlm_auth_level ntlm_auth_level = lp_ntlm_auth();
4787 if (ntlm_auth_level == NTLM_AUTH_ON) {
4788 return lp__lanman_auth();
4789 } else {
4790 return false;
4794 struct loadparm_global * get_globals(void)
4796 return &Globals;
4799 unsigned int * get_flags(void)
4801 if (flags_list == NULL) {
4802 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());
4805 return flags_list;
4808 enum samba_weak_crypto lp_weak_crypto()
4810 if (Globals.weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) {
4811 Globals.weak_crypto = SAMBA_WEAK_CRYPTO_DISALLOWED;
4813 if (samba_gnutls_weak_crypto_allowed()) {
4814 Globals.weak_crypto = SAMBA_WEAK_CRYPTO_ALLOWED;
4818 return Globals.weak_crypto;
4821 uint32_t lp_get_async_dns_timeout(void)
4824 * Clamp minimum async dns timeout to 1 second
4825 * as per the man page.
4827 return MAX(Globals.async_dns_timeout, 1);
4830 /* SMB2 POSIX extensions. For now, *always* disabled. */
4831 bool lp_smb2_unix_extensions(void)
4833 return false;