s3:vfs: add SMB_VFS_READDIR_ATTR()
[Samba.git] / source3 / param / loadparm.c
blobda50e3a58247acf0af9e5c89123779a27e2b6426
1 /*
2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12 Copyright (C) Michael Adam 2008
13 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14 Copyright (C) Andrew Bartlett 2011
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 3 of the License, or
19 (at your option) any later version.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
31 * Load parameters.
33 * This module provides suitable callback functions for the params
34 * module. It builds the internal table of service details which is
35 * then used by the rest of the server.
37 * To add a parameter:
39 * 1) add it to the global or service structure definition
40 * 2) add it to the parm_table
41 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42 * 4) If it's a global then initialise it in init_globals. If a local
43 * (ie. service) parameter then initialise it in the sDefault structure
46 * Notes:
47 * The configuration file is processed sequentially for speed. It is NOT
48 * accessed randomly as happens in 'real' Windows. For this reason, there
49 * is a fair bit of sequence-dependent code here - ie., code which assumes
50 * that certain things happen before others. In particular, the code which
51 * happens at the boundary between sections is delicately poised, so be
52 * careful!
56 #include "includes.h"
57 #include "system/filesys.h"
58 #include "util_tdb.h"
59 #include "lib/param/loadparm.h"
60 #include "lib/param/param.h"
61 #include "printing.h"
62 #include "lib/smbconf/smbconf.h"
63 #include "lib/smbconf/smbconf_init.h"
65 #include "ads.h"
66 #include "../librpc/gen_ndr/svcctl.h"
67 #include "intl.h"
68 #include "../libcli/smb/smb_signing.h"
69 #include "dbwrap/dbwrap.h"
70 #include "dbwrap/dbwrap_rbt.h"
71 #include "../lib/util/bitmap.h"
73 #ifdef HAVE_SYS_SYSCTL_H
74 #include <sys/sysctl.h>
75 #endif
77 #ifdef HAVE_HTTPCONNECTENCRYPT
78 #include <cups/http.h>
79 #endif
81 bool bLoaded = false;
83 extern userdom_struct current_user_info;
85 /* the special value for the include parameter
86 * to be interpreted not as a file name but to
87 * trigger loading of the global smb.conf options
88 * from registry. */
89 #ifndef INCLUDE_REGISTRY_NAME
90 #define INCLUDE_REGISTRY_NAME "registry"
91 #endif
93 static bool in_client = false; /* Not in the client by default */
94 static struct smbconf_csn conf_last_csn;
96 static int config_backend = CONFIG_BACKEND_FILE;
98 /* some helpful bits */
99 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
100 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
102 #define USERSHARE_VALID 1
103 #define USERSHARE_PENDING_DELETE 2
105 static bool defaults_saved = false;
107 #include "lib/param/param_global.h"
109 static struct loadparm_global Globals;
111 /* This is a default service used to prime a services structure */
112 static struct loadparm_service sDefault =
114 .valid = true,
115 .autoloaded = false,
116 .usershare = 0,
117 .usershare_last_mod = {0, 0},
118 .szService = NULL,
119 .path = NULL,
120 .username = NULL,
121 .invalid_users = NULL,
122 .valid_users = NULL,
123 .admin_users = NULL,
124 .szCopy = NULL,
125 .szInclude = NULL,
126 .preexec = NULL,
127 .postexec = NULL,
128 .root_preexec = NULL,
129 .root_postexec = NULL,
130 .cups_options = NULL,
131 .print_command = NULL,
132 .lpq_command = NULL,
133 .lprm_command = NULL,
134 .lppause_command = NULL,
135 .lpresume_command = NULL,
136 .queuepause_command = NULL,
137 .queueresume_command = NULL,
138 ._printername = NULL,
139 .printjob_username = NULL,
140 .dont_descend = NULL,
141 .hosts_allow = NULL,
142 .hosts_deny = NULL,
143 .magic_script = NULL,
144 .magic_output = NULL,
145 .veto_files = NULL,
146 .hide_files = NULL,
147 .veto_oplock_files = NULL,
148 .comment = NULL,
149 .force_user = NULL,
150 .force_group = NULL,
151 .read_list = NULL,
152 .write_list = NULL,
153 .volume = NULL,
154 .fstype = NULL,
155 .vfs_objects = NULL,
156 .msdfs_proxy = NULL,
157 .aio_write_behind = NULL,
158 .dfree_command = NULL,
159 .min_print_space = 0,
160 .iMaxPrintJobs = 1000,
161 .max_reported_print_jobs = 0,
162 .write_cache_size = 0,
163 .create_mask = 0744,
164 .force_create_mode = 0,
165 .directory_mask = 0755,
166 .force_directory_mode = 0,
167 .max_connections = 0,
168 .default_case = CASE_LOWER,
169 .printing = DEFAULT_PRINTING,
170 .oplock_contention_limit = 2,
171 .csc_policy = 0,
172 .block_size = 1024,
173 .dfree_cache_time = 0,
174 .preexec_close = false,
175 .root_preexec_close = false,
176 .case_sensitive = Auto,
177 .preserve_case = true,
178 .short_preserve_case = true,
179 .hide_dot_files = true,
180 .hide_special_files = false,
181 .hide_unreadable = false,
182 .hide_unwriteable_files = false,
183 .browseable = true,
184 .access_based_share_enum = false,
185 .bAvailable = true,
186 .read_only = true,
187 .guest_only = false,
188 .administrative_share = false,
189 .guest_ok = false,
190 .printable = false,
191 .print_notify_backchannel = false,
192 .map_system = false,
193 .map_hidden = false,
194 .map_archive = true,
195 .store_dos_attributes = false,
196 .dmapi_support = false,
197 .locking = true,
198 .strict_locking = Auto,
199 .posix_locking = true,
200 .oplocks = true,
201 .kernel_oplocks = false,
202 .level2_oplocks = true,
203 .only_user = false,
204 .mangled_names = true,
205 .bWidelinks = false,
206 .follow_symlinks = true,
207 .sync_always = false,
208 .strict_allocate = false,
209 .strict_rename = false,
210 .strict_sync = false,
211 .mangling_char = '~',
212 .copymap = NULL,
213 .delete_readonly = false,
214 .fake_oplocks = false,
215 .delete_veto_files = false,
216 .dos_filemode = false,
217 .dos_filetimes = true,
218 .dos_filetime_resolution = false,
219 .fake_directory_create_times = false,
220 .blocking_locks = true,
221 .inherit_permissions = false,
222 .inherit_acls = false,
223 .inherit_owner = false,
224 .msdfs_root = false,
225 .use_client_driver = false,
226 .default_devmode = true,
227 .force_printername = false,
228 .nt_acl_support = true,
229 .force_unknown_acl_user = false,
230 ._use_sendfile = false,
231 .profile_acls = false,
232 .map_acl_inherit = false,
233 .afs_share = false,
234 .ea_support = false,
235 .acl_check_permissions = true,
236 .acl_map_full_control = true,
237 .acl_group_control = false,
238 .acl_allow_execute_always = false,
239 .change_notify = true,
240 .kernel_change_notify = true,
241 .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
242 .aio_read_size = 0,
243 .aio_write_size = 0,
244 .map_readonly = MAP_READONLY_YES,
245 .directory_name_cache_size = 100,
246 .smb_encrypt = SMB_SIGNING_DEFAULT,
247 .kernel_share_modes = true,
248 .durable_handles = true,
249 .param_opt = NULL,
250 .dummy = ""
253 /* local variables */
254 static struct loadparm_service **ServicePtrs = NULL;
255 static int iNumServices = 0;
256 static int iServiceIndex = 0;
257 static struct db_context *ServiceHash;
258 static bool bInGlobalSection = true;
259 static bool bGlobalOnly = false;
260 static struct file_lists *file_lists = NULL;
261 static unsigned int *flags_list = NULL;
263 static void set_allowed_client_auth(void);
265 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
266 static void free_param_opts(struct parmlist_entry **popts);
268 /* this is used to prevent lots of mallocs of size 1 */
269 static const char null_string[] = "";
272 Free a string value.
275 static void string_free(char **s)
277 if (!s || !(*s))
278 return;
279 if (*s == null_string)
280 *s = NULL;
281 TALLOC_FREE(*s);
285 Set a string value, deallocating any existing space, and allocing the space
286 for the string
289 static bool string_set(TALLOC_CTX *mem_ctx, char **dest,const char *src)
291 string_free(dest);
293 if (!src) {
294 src = "";
297 (*dest) = talloc_strdup(mem_ctx, src);
298 if ((*dest) == NULL) {
299 DEBUG(0,("Out of memory in string_init\n"));
300 return false;
303 return true;
307 * Function to return the default value for the maximum number of open
308 * file descriptors permitted. This function tries to consult the
309 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
310 * the smaller of those.
312 static int max_open_files(void)
314 int sysctl_max = MAX_OPEN_FILES;
315 int rlimit_max = MAX_OPEN_FILES;
317 #ifdef HAVE_SYSCTLBYNAME
319 size_t size = sizeof(sysctl_max);
320 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
323 #endif
325 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
327 struct rlimit rl;
329 ZERO_STRUCT(rl);
331 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
332 rlimit_max = rl.rlim_cur;
334 #if defined(RLIM_INFINITY)
335 if(rl.rlim_cur == RLIM_INFINITY)
336 rlimit_max = MAX_OPEN_FILES;
337 #endif
339 #endif
341 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
342 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
343 "minimum Windows limit (%d)\n",
344 sysctl_max,
345 MIN_OPEN_FILES_WINDOWS));
346 sysctl_max = MIN_OPEN_FILES_WINDOWS;
349 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
350 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
351 "minimum Windows limit (%d)\n",
352 rlimit_max,
353 MIN_OPEN_FILES_WINDOWS));
354 rlimit_max = MIN_OPEN_FILES_WINDOWS;
357 return MIN(sysctl_max, rlimit_max);
361 * Common part of freeing allocated data for one parameter.
363 static void free_one_parameter_common(void *parm_ptr,
364 struct parm_struct parm)
366 if ((parm.type == P_STRING) ||
367 (parm.type == P_USTRING))
369 string_free((char**)parm_ptr);
370 } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
371 TALLOC_FREE(*((char***)parm_ptr));
376 * Free the allocated data for one parameter for a share
377 * given as a service struct.
379 static void free_one_parameter(struct loadparm_service *service,
380 struct parm_struct parm)
382 void *parm_ptr;
384 if (parm.p_class != P_LOCAL) {
385 return;
388 parm_ptr = lp_parm_ptr(service, &parm);
390 free_one_parameter_common(parm_ptr, parm);
394 * Free the allocated parameter data of a share given
395 * as a service struct.
397 static void free_parameters(struct loadparm_service *service)
399 uint32_t i;
401 for (i=0; parm_table[i].label; i++) {
402 free_one_parameter(service, parm_table[i]);
407 * Free the allocated data for one parameter for a given share
408 * specified by an snum.
410 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
412 void *parm_ptr;
414 if (snum < 0) {
415 parm_ptr = lp_parm_ptr(NULL, &parm);
416 } else if (parm.p_class != P_LOCAL) {
417 return;
418 } else {
419 parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
422 free_one_parameter_common(parm_ptr, parm);
426 * Free the allocated parameter data for a share specified
427 * by an snum.
429 static void free_parameters_by_snum(int snum)
431 uint32_t i;
433 for (i=0; parm_table[i].label; i++) {
434 free_one_parameter_by_snum(snum, parm_table[i]);
439 * Free the allocated global parameters.
441 static void free_global_parameters(void)
443 free_param_opts(&Globals.param_opt);
444 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
445 TALLOC_FREE(Globals.ctx);
448 struct lp_stored_option {
449 struct lp_stored_option *prev, *next;
450 const char *label;
451 const char *value;
454 static struct lp_stored_option *stored_options;
457 save options set by lp_set_cmdline() into a list. This list is
458 re-applied when we do a globals reset, so that cmdline set options
459 are sticky across reloads of smb.conf
461 bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
463 struct lp_stored_option *entry, *entry_next;
464 for (entry = stored_options; entry != NULL; entry = entry_next) {
465 entry_next = entry->next;
466 if (strcmp(pszParmName, entry->label) == 0) {
467 DLIST_REMOVE(stored_options, entry);
468 talloc_free(entry);
469 break;
473 entry = talloc(NULL, struct lp_stored_option);
474 if (!entry) {
475 return false;
478 entry->label = talloc_strdup(entry, pszParmName);
479 if (!entry->label) {
480 talloc_free(entry);
481 return false;
484 entry->value = talloc_strdup(entry, pszParmValue);
485 if (!entry->value) {
486 talloc_free(entry);
487 return false;
490 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
492 return true;
495 static bool apply_lp_set_cmdline(void)
497 struct lp_stored_option *entry = NULL;
498 for (entry = stored_options; entry != NULL; entry = entry->next) {
499 if (!lp_set_cmdline_helper(entry->label, entry->value)) {
500 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
501 entry->label, entry->value));
502 return false;
505 return true;
508 /***************************************************************************
509 Initialise the global parameter structure.
510 ***************************************************************************/
512 static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
514 static bool done_init = false;
515 char *s = NULL;
516 int i;
518 /* If requested to initialize only once and we've already done it... */
519 if (!reinit_globals && done_init) {
520 /* ... then we have nothing more to do */
521 return;
524 if (!done_init) {
525 /* The logfile can be set before this is invoked. Free it if so. */
526 if (Globals.logfile != NULL) {
527 string_free(&Globals.logfile);
528 Globals.logfile = NULL;
530 done_init = true;
531 } else {
532 free_global_parameters();
535 /* This memset and the free_global_parameters() above will
536 * wipe out smb.conf options set with lp_set_cmdline(). The
537 * apply_lp_set_cmdline() call puts these values back in the
538 * table once the defaults are set */
539 ZERO_STRUCT(Globals);
541 Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
543 /* Initialize the flags list if necessary */
544 if (flags_list == NULL) {
545 get_flags();
548 for (i = 0; parm_table[i].label; i++) {
549 if ((parm_table[i].type == P_STRING ||
550 parm_table[i].type == P_USTRING))
552 string_set(Globals.ctx, (char **)lp_parm_ptr(NULL, &parm_table[i]), "");
557 string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
558 string_set(Globals.ctx, &sDefault.printjob_username, "%U");
560 init_printer_values(lp_ctx, Globals.ctx, &sDefault);
562 sDefault.ntvfs_handler = str_list_make_v3_const(NULL, "unixuid default", NULL);
564 DEBUG(3, ("Initialising global parameters\n"));
566 /* Must manually force to upper case here, as this does not go via the handler */
567 string_set(Globals.ctx, &Globals.netbios_name, myhostname_upper());
569 string_set(Globals.ctx, &Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE());
570 string_set(Globals.ctx, &Globals.private_dir, get_dyn_PRIVATE_DIR());
572 /* use the new 'hash2' method by default, with a prefix of 1 */
573 string_set(Globals.ctx, &Globals.mangling_method, "hash2");
574 Globals.mangle_prefix = 1;
576 string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
578 /* using UTF8 by default allows us to support all chars */
579 string_set(Globals.ctx, &Globals.unix_charset, DEFAULT_UNIX_CHARSET);
581 /* Use codepage 850 as a default for the dos character set */
582 string_set(Globals.ctx, &Globals.dos_charset, DEFAULT_DOS_CHARSET);
585 * Allow the default PASSWD_CHAT to be overridden in local.h.
587 string_set(Globals.ctx, &Globals.passwd_chat, DEFAULT_PASSWD_CHAT);
589 string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
591 string_set(Globals.ctx, &Globals.passwd_program, "");
592 string_set(Globals.ctx, &Globals.lock_directory, get_dyn_LOCKDIR());
593 string_set(Globals.ctx, &Globals.state_directory, get_dyn_STATEDIR());
594 string_set(Globals.ctx, &Globals.cache_directory, get_dyn_CACHEDIR());
595 string_set(Globals.ctx, &Globals.pid_directory, get_dyn_PIDDIR());
596 string_set(Globals.ctx, &Globals.nbt_client_socket_address, "0.0.0.0");
598 * By default support explicit binding to broadcast
599 * addresses.
601 Globals.nmbd_bind_explicit_broadcast = true;
603 s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
604 if (s == NULL) {
605 smb_panic("init_globals: ENOMEM");
607 string_set(Globals.ctx, &Globals.server_string, s);
608 TALLOC_FREE(s);
609 #ifdef DEVELOPER
610 string_set(Globals.ctx, &Globals.panic_action, "/bin/sleep 999999999");
611 #endif
613 string_set(Globals.ctx, &Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
615 string_set(Globals.ctx, &Globals.logon_drive, "");
616 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
617 string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
618 string_set(Globals.ctx, &Globals.logon_path, "\\\\%N\\%U\\profile");
620 Globals.name_resolve_order = str_list_make_v3_const(NULL, "lmhosts wins host bcast", NULL);
621 string_set(Globals.ctx, &Globals.password_server, "*");
623 Globals.algorithmic_rid_base = BASE_RID;
625 Globals.load_printers = true;
626 Globals.printcap_cache_time = 750; /* 12.5 minutes */
628 Globals.config_backend = config_backend;
629 Globals._server_role = ROLE_AUTO;
631 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
632 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
633 Globals.max_xmit = 0x4104;
634 Globals.max_mux = 50; /* This is *needed* for profile support. */
635 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
636 Globals._disable_spoolss = false;
637 Globals.max_smbd_processes = 0;/* no limit specified */
638 Globals.username_level = 0;
639 Globals.deadtime = 0;
640 Globals.getwd_cache = true;
641 Globals.large_readwrite = true;
642 Globals.max_log_size = 5000;
643 Globals.max_open_files = max_open_files();
644 Globals.server_max_protocol = PROTOCOL_SMB3_00;
645 Globals.server_min_protocol = PROTOCOL_LANMAN1;
646 Globals._client_max_protocol = PROTOCOL_DEFAULT;
647 Globals.client_min_protocol = PROTOCOL_CORE;
648 Globals._security = SEC_AUTO;
649 Globals.encrypt_passwords = true;
650 Globals.client_schannel = Auto;
651 Globals.winbind_sealed_pipes = true;
652 Globals.require_strong_key = true;
653 Globals.server_schannel = Auto;
654 Globals.read_raw = true;
655 Globals.write_raw = true;
656 Globals.null_passwords = false;
657 Globals.old_password_allowed_period = 60;
658 Globals.obey_pam_restrictions = false;
659 Globals.syslog = 1;
660 Globals.syslog_only = false;
661 Globals.timestamp_logs = true;
662 string_set(Globals.ctx, &Globals.log_level, "0");
663 Globals.debug_prefix_timestamp = false;
664 Globals.debug_hires_timestamp = true;
665 Globals.debug_pid = false;
666 Globals.debug_uid = false;
667 Globals.debug_class = false;
668 Globals.enable_core_files = true;
669 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
670 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
671 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
672 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
673 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
674 Globals.lm_interval = 60;
675 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
676 Globals.nis_homedir = false;
677 #ifdef WITH_NISPLUS_HOME
678 string_set(Globals.ctx, &Globals.homedir_map, "auto_home.org_dir");
679 #else
680 string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
681 #endif
682 #endif
683 Globals.time_server = false;
684 Globals.bind_interfaces_only = false;
685 Globals.unix_password_sync = false;
686 Globals.pam_password_change = false;
687 Globals.passwd_chat_debug = false;
688 Globals.passwd_chat_timeout = 2; /* 2 second default. */
689 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
690 Globals.nt_status_support = true; /* Use NT status by default. */
691 Globals.smbd_profiling_level = 0;
692 Globals.stat_cache = true; /* use stat cache by default */
693 Globals.max_stat_cache_size = 256; /* 256k by default */
694 Globals.restrict_anonymous = 0;
695 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
696 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
697 Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
698 Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
699 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 */
700 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
702 Globals.map_to_guest = 0; /* By Default, "Never" */
703 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
704 Globals.enhanced_browsing = true;
705 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
706 #ifdef MMAP_BLACKLIST
707 Globals.use_mmap = false;
708 #else
709 Globals.use_mmap = true;
710 #endif
711 Globals.unicode = true;
712 Globals.unix_extensions = true;
713 Globals.reset_on_zero_vc = false;
714 Globals.log_writeable_files_on_exit = false;
715 Globals.create_krb5_conf = true;
716 Globals.winbindMaxDomainConnections = 1;
718 /* hostname lookups can be very expensive and are broken on
719 a large number of sites (tridge) */
720 Globals.hostname_lookups = false;
722 string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
723 string_set(Globals.ctx, &Globals.ldap_suffix, "");
724 string_set(Globals.ctx, &Globals.szLdapMachineSuffix, "");
725 string_set(Globals.ctx, &Globals.szLdapUserSuffix, "");
726 string_set(Globals.ctx, &Globals.szLdapGroupSuffix, "");
727 string_set(Globals.ctx, &Globals.szLdapIdmapSuffix, "");
729 string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
730 Globals.ldap_ssl = LDAP_SSL_START_TLS;
731 Globals.ldap_ssl_ads = false;
732 Globals.ldap_deref = -1;
733 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
734 Globals.ldap_delete_dn = false;
735 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
736 Globals.ldap_follow_referral = Auto;
737 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
738 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
739 Globals.ldap_page_size = LDAP_PAGE_SIZE;
741 Globals.ldap_debug_level = 0;
742 Globals.ldap_debug_threshold = 10;
744 Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
746 /* This is what we tell the afs client. in reality we set the token
747 * to never expire, though, when this runs out the afs client will
748 * forget the token. Set to 0 to get NEVERDATE.*/
749 Globals.afs_token_lifetime = 604800;
750 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
752 /* these parameters are set to defaults that are more appropriate
753 for the increasing samba install base:
755 as a member of the workgroup, that will possibly become a
756 _local_ master browser (lm = true). this is opposed to a forced
757 local master browser startup (pm = true).
759 doesn't provide WINS server service by default (wsupp = false),
760 and doesn't provide domain master browser services by default, either.
764 Globals.show_add_printer_wizard = true;
765 Globals.os_level = 20;
766 Globals.local_master = true;
767 Globals._domain_master = Auto; /* depending on _domain_logons */
768 Globals._domain_logons = false;
769 Globals.browse_list = true;
770 Globals.we_are_a_wins_server = false;
771 Globals.wins_proxy = false;
773 TALLOC_FREE(Globals.init_logon_delayed_hosts);
774 Globals.init_logon_delay = 100; /* 100 ms default delay */
776 Globals.wins_dns_proxy = true;
778 Globals.allow_trusted_domains = true;
779 string_set(Globals.ctx, &Globals.szIdmapBackend, "tdb");
781 string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
782 string_set(Globals.ctx, &Globals.template_homedir, "/home/%D/%U");
783 string_set(Globals.ctx, &Globals.winbind_separator, "\\");
784 string_set(Globals.ctx, &Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
786 string_set(Globals.ctx, &Globals.cups_server, "");
787 string_set(Globals.ctx, &Globals.iprint_server, "");
789 string_set(Globals.ctx, &Globals._ctdbd_socket, "");
791 Globals.cluster_addresses = NULL;
792 Globals.clustering = false;
793 Globals.ctdb_timeout = 0;
794 Globals.ctdb_locktime_warn_threshold = 0;
796 Globals.winbind_cache_time = 300; /* 5 minutes */
797 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
798 Globals.winbind_request_timeout = 60; /* 60 seconds */
799 Globals.winbind_max_clients = 200;
800 Globals.winbind_enum_users = false;
801 Globals.winbind_enum_groups = false;
802 Globals.winbind_use_default_domain = false;
803 Globals.winbind_trusted_domains_only = false;
804 Globals.winbind_nested_groups = true;
805 Globals.winbind_expand_groups = 0;
806 Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
807 Globals.winbind_refresh_tickets = false;
808 Globals.winbind_offline_logon = false;
810 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
811 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
813 Globals.passdb_expand_explicit = false;
815 Globals.name_cache_timeout = 660; /* In seconds */
817 Globals.use_spnego = true;
818 Globals.client_use_spnego = true;
820 Globals.client_signing = SMB_SIGNING_DEFAULT;
821 Globals.server_signing = SMB_SIGNING_DEFAULT;
823 Globals.defer_sharing_violations = true;
824 Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL);
826 Globals.enable_privileges = true;
827 Globals.host_msdfs = true;
828 Globals.enable_asu_support = false;
830 /* User defined shares. */
831 s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
832 if (s == NULL) {
833 smb_panic("init_globals: ENOMEM");
835 string_set(Globals.ctx, &Globals.usershare_path, s);
836 TALLOC_FREE(s);
837 string_set(Globals.ctx, &Globals.usershare_template_share, "");
838 Globals.usershare_max_shares = 0;
839 /* By default disallow sharing of directories not owned by the sharer. */
840 Globals.usershare_owner_only = true;
841 /* By default disallow guest access to usershares. */
842 Globals.usershare_allow_guests = false;
844 Globals.keepalive = DEFAULT_KEEPALIVE;
846 /* By default no shares out of the registry */
847 Globals.registry_shares = false;
849 Globals.iminreceivefile = 0;
851 Globals.map_untrusted_to_domain = false;
852 Globals.multicast_dns_register = true;
854 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
855 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
856 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
857 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
858 Globals.smb2_leases = false;
860 string_set(Globals.ctx, &Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
862 Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
864 Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
866 Globals.tls_enabled = true;
868 string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
869 string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
870 string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
872 string_set(Globals.ctx, &Globals.share_backend, "classic");
874 Globals.iPreferredMaster = Auto;
876 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
878 string_set(Globals.ctx, &Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR());
880 string_set(Globals.ctx, &Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
882 s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
883 if (s == NULL) {
884 smb_panic("init_globals: ENOMEM");
886 Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
887 TALLOC_FREE(s);
889 s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
890 if (s == NULL) {
891 smb_panic("init_globals: ENOMEM");
893 Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
894 TALLOC_FREE(s);
896 s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
897 if (s == NULL) {
898 smb_panic("init_globals: ENOMEM");
900 Globals.spn_update_command = str_list_make_v3_const(NULL, s, NULL);
901 TALLOC_FREE(s);
903 Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
905 Globals.rndc_command = str_list_make_v3_const(NULL, "/usr/sbin/rndc", NULL);
907 Globals.cldap_port = 389;
909 Globals.dgram_port = 138;
911 Globals.nbt_port = 137;
913 Globals.krb5_port = 88;
915 Globals.kpasswd_port = 464;
917 Globals.web_port = 901;
919 /* Now put back the settings that were set with lp_set_cmdline() */
920 apply_lp_set_cmdline();
923 /* Convenience routine to setup an lp_context with additional s3 variables */
924 static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
926 struct loadparm_context *lp_ctx;
928 lp_ctx = loadparm_init_s3(mem_ctx,
929 loadparm_s3_helpers());
930 if (lp_ctx == NULL) {
931 DEBUG(0, ("loadparm_init_s3 failed\n"));
932 return NULL;
935 lp_ctx->sDefault = &sDefault;
936 lp_ctx->services = NULL; /* We do not want to access this directly */
937 lp_ctx->bInGlobalSection = bInGlobalSection;
938 lp_ctx->flags = flags_list;
940 return lp_ctx;
943 /*******************************************************************
944 Convenience routine to grab string parameters into talloced memory
945 and run standard_sub_basic on them. The buffers can be written to by
946 callers without affecting the source string.
947 ********************************************************************/
949 char *lp_string(TALLOC_CTX *ctx, const char *s)
951 char *ret;
953 /* The follow debug is useful for tracking down memory problems
954 especially if you have an inner loop that is calling a lp_*()
955 function that returns a string. Perhaps this debug should be
956 present all the time? */
958 #if 0
959 DEBUG(10, ("lp_string(%s)\n", s));
960 #endif
961 if (!s) {
962 return NULL;
965 ret = talloc_sub_basic(ctx,
966 get_current_username(),
967 current_user_info.domain,
969 if (trim_char(ret, '\"', '\"')) {
970 if (strchr(ret,'\"') != NULL) {
971 TALLOC_FREE(ret);
972 ret = talloc_sub_basic(ctx,
973 get_current_username(),
974 current_user_info.domain,
978 return ret;
982 In this section all the functions that are used to access the
983 parameters from the rest of the program are defined
986 #define FN_GLOBAL_STRING(fn_name,ptr) \
987 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
988 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
989 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
990 #define FN_GLOBAL_LIST(fn_name,ptr) \
991 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
992 #define FN_GLOBAL_BOOL(fn_name,ptr) \
993 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
994 #define FN_GLOBAL_CHAR(fn_name,ptr) \
995 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
996 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
997 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
999 #define FN_LOCAL_STRING(fn_name,val) \
1000 char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1001 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1002 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1003 #define FN_LOCAL_LIST(fn_name,val) \
1004 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1005 #define FN_LOCAL_BOOL(fn_name,val) \
1006 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1007 #define FN_LOCAL_INTEGER(fn_name,val) \
1008 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1010 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1011 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1012 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1013 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1014 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1015 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1017 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
1018 winbindMaxDomainConnections)
1020 int lp_winbind_max_domain_connections(void)
1022 if (lp_winbind_offline_logon() &&
1023 lp_winbind_max_domain_connections_int() > 1) {
1024 DEBUG(1, ("offline logons active, restricting max domain "
1025 "connections to 1\n"));
1026 return 1;
1028 return MAX(1, lp_winbind_max_domain_connections_int());
1031 int lp_smb2_max_credits(void)
1033 if (Globals.ismb2_max_credits == 0) {
1034 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1036 return Globals.ismb2_max_credits;
1038 int lp_cups_encrypt(void)
1040 int result = 0;
1041 #ifdef HAVE_HTTPCONNECTENCRYPT
1042 switch (Globals.CupsEncrypt) {
1043 case Auto:
1044 result = HTTP_ENCRYPT_REQUIRED;
1045 break;
1046 case true:
1047 result = HTTP_ENCRYPT_ALWAYS;
1048 break;
1049 case false:
1050 result = HTTP_ENCRYPT_NEVER;
1051 break;
1053 #endif
1054 return result;
1057 /* These functions remain in source3/param for now */
1059 #include "lib/param/param_functions.c"
1061 FN_LOCAL_STRING(servicename, szService)
1062 FN_LOCAL_CONST_STRING(const_servicename, szService)
1064 /* These functions cannot be auto-generated */
1065 FN_LOCAL_BOOL(autoloaded, autoloaded)
1066 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1068 /* local prototypes */
1070 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1071 static const char *get_boolean(bool bool_value);
1072 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1073 void *userdata);
1074 static bool hash_a_service(const char *name, int number);
1075 static void free_service_byindex(int iService);
1076 static void show_parameter(int parmIndex);
1077 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1080 * This is a helper function for parametrical options support. It returns a
1081 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1082 * parametrical functions are quite simple
1084 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1085 const char *option)
1087 if (snum >= iNumServices) return NULL;
1089 if (snum < 0) {
1090 return get_parametric_helper(NULL, type, option, Globals.param_opt);
1091 } else {
1092 return get_parametric_helper(ServicePtrs[snum],
1093 type, option, Globals.param_opt);
1098 #define MISSING_PARAMETER(name) \
1099 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1101 /*******************************************************************
1102 convenience routine to return enum parameters.
1103 ********************************************************************/
1104 static int lp_enum(const char *s,const struct enum_list *_enum)
1106 int i;
1108 if (!s || !*s || !_enum) {
1109 MISSING_PARAMETER(lp_enum);
1110 return (-1);
1113 for (i=0; _enum[i].name; i++) {
1114 if (strequal(_enum[i].name,s))
1115 return _enum[i].value;
1118 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1119 return (-1);
1122 #undef MISSING_PARAMETER
1124 /* Return parametric option from a given service. Type is a part of option before ':' */
1125 /* Parametric option has following syntax: 'Type: option = value' */
1126 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1128 struct parmlist_entry *data = get_parametrics(snum, type, option);
1130 if (data == NULL||data->value==NULL) {
1131 if (def) {
1132 return lp_string(ctx, def);
1133 } else {
1134 return NULL;
1138 return lp_string(ctx, data->value);
1141 /* Return parametric option from a given service. Type is a part of option before ':' */
1142 /* Parametric option has following syntax: 'Type: option = value' */
1143 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1145 struct parmlist_entry *data = get_parametrics(snum, type, option);
1147 if (data == NULL||data->value==NULL)
1148 return def;
1150 return data->value;
1154 /* Return parametric option from a given service. Type is a part of option before ':' */
1155 /* Parametric option has following syntax: 'Type: option = value' */
1157 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1159 struct parmlist_entry *data = get_parametrics(snum, type, option);
1161 if (data == NULL||data->value==NULL)
1162 return (const char **)def;
1164 if (data->list==NULL) {
1165 data->list = str_list_make_v3(NULL, data->value, NULL);
1168 return discard_const_p(const char *, data->list);
1171 /* Return parametric option from a given service. Type is a part of option before ':' */
1172 /* Parametric option has following syntax: 'Type: option = value' */
1174 int lp_parm_int(int snum, const char *type, const char *option, int def)
1176 struct parmlist_entry *data = get_parametrics(snum, type, option);
1178 if (data && data->value && *data->value)
1179 return lp_int(data->value);
1181 return def;
1184 /* Return parametric option from a given service. Type is a part of option before ':' */
1185 /* Parametric option has following syntax: 'Type: option = value' */
1187 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1189 struct parmlist_entry *data = get_parametrics(snum, type, option);
1191 if (data && data->value && *data->value)
1192 return lp_ulong(data->value);
1194 return def;
1197 /* Return parametric option from a given service. Type is a part of option before ':' */
1198 /* Parametric option has following syntax: 'Type: option = value' */
1200 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1202 struct parmlist_entry *data = get_parametrics(snum, type, option);
1204 if (data && data->value && *data->value)
1205 return lp_bool(data->value);
1207 return def;
1210 /* Return parametric option from a given service. Type is a part of option before ':' */
1211 /* Parametric option has following syntax: 'Type: option = value' */
1213 int lp_parm_enum(int snum, const char *type, const char *option,
1214 const struct enum_list *_enum, int def)
1216 struct parmlist_entry *data = get_parametrics(snum, type, option);
1218 if (data && data->value && *data->value && _enum)
1219 return lp_enum(data->value, _enum);
1221 return def;
1225 * free a param_opts structure.
1226 * param_opts handling should be moved to talloc;
1227 * then this whole functions reduces to a TALLOC_FREE().
1230 static void free_param_opts(struct parmlist_entry **popts)
1232 struct parmlist_entry *opt, *next_opt;
1234 if (*popts != NULL) {
1235 DEBUG(5, ("Freeing parametrics:\n"));
1237 opt = *popts;
1238 while (opt != NULL) {
1239 string_free(&opt->key);
1240 string_free(&opt->value);
1241 TALLOC_FREE(opt->list);
1242 next_opt = opt->next;
1243 TALLOC_FREE(opt);
1244 opt = next_opt;
1246 *popts = NULL;
1249 /***************************************************************************
1250 Free the dynamically allocated parts of a service struct.
1251 ***************************************************************************/
1253 static void free_service(struct loadparm_service *pservice)
1255 if (!pservice)
1256 return;
1258 if (pservice->szService)
1259 DEBUG(5, ("free_service: Freeing service %s\n",
1260 pservice->szService));
1262 free_parameters(pservice);
1264 string_free(&pservice->szService);
1265 TALLOC_FREE(pservice->copymap);
1267 free_param_opts(&pservice->param_opt);
1269 ZERO_STRUCTP(pservice);
1273 /***************************************************************************
1274 remove a service indexed in the ServicePtrs array from the ServiceHash
1275 and free the dynamically allocated parts
1276 ***************************************************************************/
1278 static void free_service_byindex(int idx)
1280 if ( !LP_SNUM_OK(idx) )
1281 return;
1283 ServicePtrs[idx]->valid = false;
1285 /* we have to cleanup the hash record */
1287 if (ServicePtrs[idx]->szService) {
1288 char *canon_name = canonicalize_servicename(
1289 talloc_tos(),
1290 ServicePtrs[idx]->szService );
1292 dbwrap_delete_bystring(ServiceHash, canon_name );
1293 TALLOC_FREE(canon_name);
1296 free_service(ServicePtrs[idx]);
1297 talloc_free_children(ServicePtrs[idx]);
1300 /***************************************************************************
1301 Add a new service to the services array initialising it with the given
1302 service.
1303 ***************************************************************************/
1305 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1307 int i;
1308 int num_to_alloc = iNumServices + 1;
1309 struct loadparm_service **tsp = NULL;
1311 /* it might already exist */
1312 if (name) {
1313 i = getservicebyname(name, NULL);
1314 if (i >= 0) {
1315 return (i);
1319 /* if not, then create one */
1320 i = iNumServices;
1321 tsp = talloc_realloc(NULL, ServicePtrs, struct loadparm_service *, num_to_alloc);
1322 if (tsp == NULL) {
1323 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1324 return (-1);
1326 ServicePtrs = tsp;
1327 ServicePtrs[iNumServices] = talloc_zero(NULL, struct loadparm_service);
1328 if (!ServicePtrs[iNumServices]) {
1329 DEBUG(0,("add_a_service: out of memory!\n"));
1330 return (-1);
1332 iNumServices++;
1334 ServicePtrs[i]->valid = true;
1336 copy_service(ServicePtrs[i], pservice, NULL);
1337 if (name)
1338 string_set(ServicePtrs[i], &ServicePtrs[i]->szService, name);
1340 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1341 i, ServicePtrs[i]->szService));
1343 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1344 return (-1);
1347 return (i);
1350 /***************************************************************************
1351 Convert a string to uppercase and remove whitespaces.
1352 ***************************************************************************/
1354 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1356 char *result;
1358 if ( !src ) {
1359 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1360 return NULL;
1363 result = talloc_strdup(ctx, src);
1364 SMB_ASSERT(result != NULL);
1366 if (!strlower_m(result)) {
1367 TALLOC_FREE(result);
1368 return NULL;
1370 return result;
1373 /***************************************************************************
1374 Add a name/index pair for the services array to the hash table.
1375 ***************************************************************************/
1377 static bool hash_a_service(const char *name, int idx)
1379 char *canon_name;
1381 if ( !ServiceHash ) {
1382 DEBUG(10,("hash_a_service: creating servicehash\n"));
1383 ServiceHash = db_open_rbt(NULL);
1384 if ( !ServiceHash ) {
1385 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1386 return false;
1390 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1391 idx, name));
1393 canon_name = canonicalize_servicename(talloc_tos(), name );
1395 dbwrap_store_bystring(ServiceHash, canon_name,
1396 make_tdb_data((uint8 *)&idx, sizeof(idx)),
1397 TDB_REPLACE);
1399 TALLOC_FREE(canon_name);
1401 return true;
1404 /***************************************************************************
1405 Add a new home service, with the specified home directory, defaults coming
1406 from service ifrom.
1407 ***************************************************************************/
1409 bool lp_add_home(const char *pszHomename, int iDefaultService,
1410 const char *user, const char *pszHomedir)
1412 int i;
1414 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1415 pszHomedir[0] == '\0') {
1416 return false;
1419 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1421 if (i < 0)
1422 return false;
1424 if (!(*(ServicePtrs[iDefaultService]->path))
1425 || strequal(ServicePtrs[iDefaultService]->path,
1426 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1427 string_set(ServicePtrs[i], &ServicePtrs[i]->path, pszHomedir);
1430 if (!(*(ServicePtrs[i]->comment))) {
1431 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1432 if (comment == NULL) {
1433 return false;
1435 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1436 TALLOC_FREE(comment);
1439 /* set the browseable flag from the global default */
1441 ServicePtrs[i]->browseable = sDefault.browseable;
1442 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1444 ServicePtrs[i]->autoloaded = true;
1446 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1447 user, ServicePtrs[i]->path ));
1449 return true;
1452 /***************************************************************************
1453 Add a new service, based on an old one.
1454 ***************************************************************************/
1456 int lp_add_service(const char *pszService, int iDefaultService)
1458 if (iDefaultService < 0) {
1459 return add_a_service(&sDefault, pszService);
1462 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1465 /***************************************************************************
1466 Add the IPC service.
1467 ***************************************************************************/
1469 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1471 char *comment = NULL;
1472 int i = add_a_service(&sDefault, ipc_name);
1474 if (i < 0)
1475 return false;
1477 comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1478 Globals.server_string);
1479 if (comment == NULL) {
1480 return false;
1483 string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1484 string_set(ServicePtrs[i], &ServicePtrs[i]->username, "");
1485 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1486 string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1487 ServicePtrs[i]->max_connections = 0;
1488 ServicePtrs[i]->bAvailable = true;
1489 ServicePtrs[i]->read_only = true;
1490 ServicePtrs[i]->guest_only = false;
1491 ServicePtrs[i]->administrative_share = true;
1492 ServicePtrs[i]->guest_ok = guest_ok;
1493 ServicePtrs[i]->printable = false;
1494 ServicePtrs[i]->browseable = sDefault.browseable;
1496 DEBUG(3, ("adding IPC service\n"));
1498 TALLOC_FREE(comment);
1499 return true;
1502 /***************************************************************************
1503 Add a new printer service, with defaults coming from service iFrom.
1504 ***************************************************************************/
1506 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1508 const char *comment = "From Printcap";
1509 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1511 if (i < 0)
1512 return false;
1514 /* note that we do NOT default the availability flag to true - */
1515 /* we take it from the default service passed. This allows all */
1516 /* dynamic printers to be disabled by disabling the [printers] */
1517 /* entry (if/when the 'available' keyword is implemented!). */
1519 /* the printer name is set to the service name. */
1520 string_set(ServicePtrs[i], &ServicePtrs[i]->_printername, pszPrintername);
1521 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1523 /* set the browseable flag from the gloabl default */
1524 ServicePtrs[i]->browseable = sDefault.browseable;
1526 /* Printers cannot be read_only. */
1527 ServicePtrs[i]->read_only = false;
1528 /* No oplocks on printer services. */
1529 ServicePtrs[i]->oplocks = false;
1530 /* Printer services must be printable. */
1531 ServicePtrs[i]->printable = true;
1533 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1535 return true;
1539 /***************************************************************************
1540 Check whether the given parameter name is valid.
1541 Parametric options (names containing a colon) are considered valid.
1542 ***************************************************************************/
1544 bool lp_parameter_is_valid(const char *pszParmName)
1546 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1547 (strchr(pszParmName, ':') != NULL));
1550 /***************************************************************************
1551 Check whether the given name is the name of a global parameter.
1552 Returns true for strings belonging to parameters of class
1553 P_GLOBAL, false for all other strings, also for parametric options
1554 and strings not belonging to any option.
1555 ***************************************************************************/
1557 bool lp_parameter_is_global(const char *pszParmName)
1559 int num = lpcfg_map_parameter(pszParmName);
1561 if (num >= 0) {
1562 return (parm_table[num].p_class == P_GLOBAL);
1565 return false;
1568 /**************************************************************************
1569 Check whether the given name is the canonical name of a parameter.
1570 Returns false if it is not a valid parameter Name.
1571 For parametric options, true is returned.
1572 **************************************************************************/
1574 bool lp_parameter_is_canonical(const char *parm_name)
1576 if (!lp_parameter_is_valid(parm_name)) {
1577 return false;
1580 return (lpcfg_map_parameter(parm_name) ==
1581 map_parameter_canonical(parm_name, NULL));
1584 /**************************************************************************
1585 Determine the canonical name for a parameter.
1586 Indicate when it is an inverse (boolean) synonym instead of a
1587 "usual" synonym.
1588 **************************************************************************/
1590 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1591 bool *inverse)
1593 int num;
1595 if (!lp_parameter_is_valid(parm_name)) {
1596 *canon_parm = NULL;
1597 return false;
1600 num = map_parameter_canonical(parm_name, inverse);
1601 if (num < 0) {
1602 /* parametric option */
1603 *canon_parm = parm_name;
1604 } else {
1605 *canon_parm = parm_table[num].label;
1608 return true;
1612 /**************************************************************************
1613 Determine the canonical name for a parameter.
1614 Turn the value given into the inverse boolean expression when
1615 the synonym is an invers boolean synonym.
1617 Return true if parm_name is a valid parameter name and
1618 in case it is an invers boolean synonym, if the val string could
1619 successfully be converted to the reverse bool.
1620 Return false in all other cases.
1621 **************************************************************************/
1623 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1624 const char *val,
1625 const char **canon_parm,
1626 const char **canon_val)
1628 int num;
1629 bool inverse;
1631 if (!lp_parameter_is_valid(parm_name)) {
1632 *canon_parm = NULL;
1633 *canon_val = NULL;
1634 return false;
1637 num = map_parameter_canonical(parm_name, &inverse);
1638 if (num < 0) {
1639 /* parametric option */
1640 *canon_parm = parm_name;
1641 *canon_val = val;
1642 } else {
1643 *canon_parm = parm_table[num].label;
1644 if (inverse) {
1645 if (!lp_invert_boolean(val, canon_val)) {
1646 *canon_val = NULL;
1647 return false;
1649 } else {
1650 *canon_val = val;
1654 return true;
1657 /***************************************************************************
1658 Map a parameter's string representation to the index of the canonical
1659 form of the parameter (it might be a synonym).
1660 Returns -1 if the parameter string is not recognised.
1661 ***************************************************************************/
1663 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1665 int parm_num, canon_num;
1666 bool loc_inverse = false;
1668 parm_num = lpcfg_map_parameter(pszParmName);
1669 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
1670 /* invalid, parametric or no canidate for synonyms ... */
1671 goto done;
1674 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1675 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1676 parm_num = canon_num;
1677 goto done;
1681 done:
1682 if (inverse != NULL) {
1683 *inverse = loc_inverse;
1685 return parm_num;
1688 /***************************************************************************
1689 return true if parameter number parm1 is a synonym of parameter
1690 number parm2 (parm2 being the principal name).
1691 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1692 false otherwise.
1693 ***************************************************************************/
1695 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1697 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1698 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1699 (parm_table[parm1].flags & FLAG_HIDE) &&
1700 !(parm_table[parm2].flags & FLAG_HIDE))
1702 if (inverse != NULL) {
1703 if ((parm_table[parm1].type == P_BOOLREV) &&
1704 (parm_table[parm2].type == P_BOOL))
1706 *inverse = true;
1707 } else {
1708 *inverse = false;
1711 return true;
1713 return false;
1716 /***************************************************************************
1717 Show one parameter's name, type, [values,] and flags.
1718 (helper functions for show_parameter_list)
1719 ***************************************************************************/
1721 static void show_parameter(int parmIndex)
1723 int enumIndex, flagIndex;
1724 int parmIndex2;
1725 bool hadFlag;
1726 bool hadSyn;
1727 bool inverse;
1728 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1729 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1730 "P_ENUM", "P_SEP"};
1731 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
1732 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
1733 FLAG_HIDE};
1734 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
1735 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
1736 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
1738 printf("%s=%s", parm_table[parmIndex].label,
1739 type[parm_table[parmIndex].type]);
1740 if (parm_table[parmIndex].type == P_ENUM) {
1741 printf(",");
1742 for (enumIndex=0;
1743 parm_table[parmIndex].enum_list[enumIndex].name;
1744 enumIndex++)
1746 printf("%s%s",
1747 enumIndex ? "|" : "",
1748 parm_table[parmIndex].enum_list[enumIndex].name);
1751 printf(",");
1752 hadFlag = false;
1753 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1754 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1755 printf("%s%s",
1756 hadFlag ? "|" : "",
1757 flag_names[flagIndex]);
1758 hadFlag = true;
1762 /* output synonyms */
1763 hadSyn = false;
1764 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1765 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1766 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1767 parm_table[parmIndex2].label);
1768 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1769 if (!hadSyn) {
1770 printf(" (synonyms: ");
1771 hadSyn = true;
1772 } else {
1773 printf(", ");
1775 printf("%s%s", parm_table[parmIndex2].label,
1776 inverse ? "[i]" : "");
1779 if (hadSyn) {
1780 printf(")");
1783 printf("\n");
1786 /***************************************************************************
1787 Show all parameter's name, type, [values,] and flags.
1788 ***************************************************************************/
1790 void show_parameter_list(void)
1792 int classIndex, parmIndex;
1793 const char *section_names[] = { "local", "global", NULL};
1795 for (classIndex=0; section_names[classIndex]; classIndex++) {
1796 printf("[%s]\n", section_names[classIndex]);
1797 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
1798 if (parm_table[parmIndex].p_class == classIndex) {
1799 show_parameter(parmIndex);
1805 /***************************************************************************
1806 Get the standard string representation of a boolean value ("yes" or "no")
1807 ***************************************************************************/
1809 static const char *get_boolean(bool bool_value)
1811 static const char *yes_str = "yes";
1812 static const char *no_str = "no";
1814 return (bool_value ? yes_str : no_str);
1817 /***************************************************************************
1818 Provide the string of the negated boolean value associated to the boolean
1819 given as a string. Returns false if the passed string does not correctly
1820 represent a boolean.
1821 ***************************************************************************/
1823 bool lp_invert_boolean(const char *str, const char **inverse_str)
1825 bool val;
1827 if (!set_boolean(str, &val)) {
1828 return false;
1831 *inverse_str = get_boolean(!val);
1832 return true;
1835 /***************************************************************************
1836 Provide the canonical string representation of a boolean value given
1837 as a string. Return true on success, false if the string given does
1838 not correctly represent a boolean.
1839 ***************************************************************************/
1841 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
1843 bool val;
1845 if (!set_boolean(str, &val)) {
1846 return false;
1849 *canon_str = get_boolean(val);
1850 return true;
1853 /***************************************************************************
1854 Find a service by name. Otherwise works like get_service.
1855 ***************************************************************************/
1857 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
1859 int iService = -1;
1860 char *canon_name;
1861 TDB_DATA data;
1862 NTSTATUS status;
1864 if (ServiceHash == NULL) {
1865 return -1;
1868 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
1870 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
1871 &data);
1873 if (NT_STATUS_IS_OK(status) &&
1874 (data.dptr != NULL) &&
1875 (data.dsize == sizeof(iService)))
1877 iService = *(int *)data.dptr;
1880 TALLOC_FREE(canon_name);
1882 if ((iService != -1) && (LP_SNUM_OK(iService))
1883 && (pserviceDest != NULL)) {
1884 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1887 return (iService);
1890 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
1891 struct loadparm_service *lp_service(const char *pszServiceName)
1893 int iService = getservicebyname(pszServiceName, NULL);
1894 if (iService == -1 || !LP_SNUM_OK(iService)) {
1895 return NULL;
1897 return ServicePtrs[iService];
1900 struct loadparm_service *lp_servicebynum(int snum)
1902 if ((snum == -1) || !LP_SNUM_OK(snum)) {
1903 return NULL;
1905 return ServicePtrs[snum];
1908 struct loadparm_service *lp_default_loadparm_service()
1910 return &sDefault;
1913 static struct smbconf_ctx *lp_smbconf_ctx(void)
1915 sbcErr err;
1916 static struct smbconf_ctx *conf_ctx = NULL;
1918 if (conf_ctx == NULL) {
1919 err = smbconf_init(NULL, &conf_ctx, "registry:");
1920 if (!SBC_ERROR_IS_OK(err)) {
1921 DEBUG(1, ("error initializing registry configuration: "
1922 "%s\n", sbcErrorString(err)));
1923 conf_ctx = NULL;
1927 return conf_ctx;
1930 static bool process_smbconf_service(struct smbconf_service *service)
1932 uint32_t count;
1933 bool ret;
1935 if (service == NULL) {
1936 return false;
1939 ret = lp_do_section(service->name, NULL);
1940 if (ret != true) {
1941 return false;
1943 for (count = 0; count < service->num_params; count++) {
1945 if (!bInGlobalSection && bGlobalOnly) {
1946 ret = true;
1947 } else {
1948 const char *pszParmName = service->param_names[count];
1949 const char *pszParmValue = service->param_values[count];
1951 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
1953 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1954 pszParmName, pszParmValue);
1957 if (ret != true) {
1958 return false;
1961 if (iServiceIndex >= 0) {
1962 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
1964 return true;
1968 * load a service from registry and activate it
1970 bool process_registry_service(const char *service_name)
1972 sbcErr err;
1973 struct smbconf_service *service = NULL;
1974 TALLOC_CTX *mem_ctx = talloc_stackframe();
1975 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
1976 bool ret = false;
1978 if (conf_ctx == NULL) {
1979 goto done;
1982 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
1984 if (!smbconf_share_exists(conf_ctx, service_name)) {
1986 * Registry does not contain data for this service (yet),
1987 * but make sure lp_load doesn't return false.
1989 ret = true;
1990 goto done;
1993 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
1994 if (!SBC_ERROR_IS_OK(err)) {
1995 goto done;
1998 ret = process_smbconf_service(service);
1999 if (!ret) {
2000 goto done;
2003 /* store the csn */
2004 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2006 done:
2007 TALLOC_FREE(mem_ctx);
2008 return ret;
2012 * process_registry_globals
2014 static bool process_registry_globals(void)
2016 bool ret;
2018 add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2020 if (!bInGlobalSection && bGlobalOnly) {
2021 ret = true;
2022 } else {
2023 const char *pszParmName = "registry shares";
2024 const char *pszParmValue = "yes";
2026 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2028 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2029 pszParmName, pszParmValue);
2032 if (!ret) {
2033 return ret;
2036 return process_registry_service(GLOBAL_NAME);
2039 bool process_registry_shares(void)
2041 sbcErr err;
2042 uint32_t count;
2043 struct smbconf_service **service = NULL;
2044 uint32_t num_shares = 0;
2045 TALLOC_CTX *mem_ctx = talloc_stackframe();
2046 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2047 bool ret = false;
2049 if (conf_ctx == NULL) {
2050 goto done;
2053 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2054 if (!SBC_ERROR_IS_OK(err)) {
2055 goto done;
2058 ret = true;
2060 for (count = 0; count < num_shares; count++) {
2061 if (strequal(service[count]->name, GLOBAL_NAME)) {
2062 continue;
2064 ret = process_smbconf_service(service[count]);
2065 if (!ret) {
2066 goto done;
2070 /* store the csn */
2071 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2073 done:
2074 TALLOC_FREE(mem_ctx);
2075 return ret;
2079 * reload those shares from registry that are already
2080 * activated in the services array.
2082 static bool reload_registry_shares(void)
2084 int i;
2085 bool ret = true;
2087 for (i = 0; i < iNumServices; i++) {
2088 if (!VALID(i)) {
2089 continue;
2092 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2093 continue;
2096 ret = process_registry_service(ServicePtrs[i]->szService);
2097 if (!ret) {
2098 goto done;
2102 done:
2103 return ret;
2107 #define MAX_INCLUDE_DEPTH 100
2109 static uint8_t include_depth;
2112 * Free the file lists
2114 static void free_file_list(void)
2116 struct file_lists *f;
2117 struct file_lists *next;
2119 f = file_lists;
2120 while( f ) {
2121 next = f->next;
2122 TALLOC_FREE( f );
2123 f = next;
2125 file_lists = NULL;
2130 * Utility function for outsiders to check if we're running on registry.
2132 bool lp_config_backend_is_registry(void)
2134 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2138 * Utility function to check if the config backend is FILE.
2140 bool lp_config_backend_is_file(void)
2142 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2145 /*******************************************************************
2146 Check if a config file has changed date.
2147 ********************************************************************/
2149 bool lp_file_list_changed(void)
2151 struct file_lists *f = file_lists;
2153 DEBUG(6, ("lp_file_list_changed()\n"));
2155 while (f) {
2156 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2157 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2159 if (conf_ctx == NULL) {
2160 return false;
2162 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2163 NULL))
2165 DEBUGADD(6, ("registry config changed\n"));
2166 return true;
2168 } else {
2169 time_t mod_time;
2170 char *n2 = NULL;
2172 n2 = talloc_sub_basic(talloc_tos(),
2173 get_current_username(),
2174 current_user_info.domain,
2175 f->name);
2176 if (!n2) {
2177 return false;
2179 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2180 f->name, n2, ctime(&f->modtime)));
2182 mod_time = file_modtime(n2);
2184 if (mod_time &&
2185 ((f->modtime != mod_time) ||
2186 (f->subfname == NULL) ||
2187 (strcmp(n2, f->subfname) != 0)))
2189 DEBUGADD(6,
2190 ("file %s modified: %s\n", n2,
2191 ctime(&mod_time)));
2192 f->modtime = mod_time;
2193 TALLOC_FREE(f->subfname);
2194 f->subfname = talloc_strdup(f, n2);
2195 if (f->subfname == NULL) {
2196 smb_panic("talloc_strdup failed");
2198 TALLOC_FREE(n2);
2199 return true;
2201 TALLOC_FREE(n2);
2203 f = f->next;
2205 return false;
2210 * Initialize iconv conversion descriptors.
2212 * This is called the first time it is needed, and also called again
2213 * every time the configuration is reloaded, because the charset or
2214 * codepage might have changed.
2216 static void init_iconv(void)
2218 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2219 lp_unix_charset(),
2220 true, global_iconv_handle);
2223 /***************************************************************************
2224 Handle the include operation.
2225 ***************************************************************************/
2226 static bool bAllowIncludeRegistry = true;
2228 bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2229 const char *pszParmValue, char **ptr)
2231 char *fname;
2233 if (include_depth >= MAX_INCLUDE_DEPTH) {
2234 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2235 include_depth));
2236 return false;
2239 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2240 if (!bAllowIncludeRegistry) {
2241 return true;
2243 if (lp_ctx->bInGlobalSection) {
2244 bool ret;
2245 include_depth++;
2246 ret = process_registry_globals();
2247 include_depth--;
2248 return ret;
2249 } else {
2250 DEBUG(1, ("\"include = registry\" only effective "
2251 "in %s section\n", GLOBAL_NAME));
2252 return false;
2256 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2257 current_user_info.domain,
2258 pszParmValue);
2260 add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2262 if (service == NULL) {
2263 string_set(Globals.ctx, ptr, fname);
2264 } else {
2265 string_set(service, ptr, fname);
2268 if (file_exist(fname)) {
2269 bool ret;
2270 include_depth++;
2271 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2272 include_depth--;
2273 TALLOC_FREE(fname);
2274 return ret;
2277 DEBUG(2, ("Can't find include file %s\n", fname));
2278 TALLOC_FREE(fname);
2279 return true;
2282 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2284 char *config_option = NULL;
2285 const char *range = NULL;
2286 bool ret = false;
2288 SMB_ASSERT(low != NULL);
2289 SMB_ASSERT(high != NULL);
2291 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2292 domain_name = "*";
2295 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2296 domain_name);
2297 if (config_option == NULL) {
2298 DEBUG(0, ("out of memory\n"));
2299 return false;
2302 range = lp_parm_const_string(-1, config_option, "range", NULL);
2303 if (range == NULL) {
2304 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2305 goto done;
2308 if (sscanf(range, "%u - %u", low, high) != 2) {
2309 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2310 range, domain_name));
2311 goto done;
2314 ret = true;
2316 done:
2317 talloc_free(config_option);
2318 return ret;
2322 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2324 return lp_idmap_range("*", low, high);
2327 const char *lp_idmap_backend(const char *domain_name)
2329 char *config_option = NULL;
2330 const char *backend = NULL;
2332 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2333 domain_name = "*";
2336 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2337 domain_name);
2338 if (config_option == NULL) {
2339 DEBUG(0, ("out of memory\n"));
2340 return false;
2343 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2344 if (backend == NULL) {
2345 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2346 goto done;
2349 done:
2350 talloc_free(config_option);
2351 return backend;
2354 const char *lp_idmap_default_backend(void)
2356 return lp_idmap_backend("*");
2359 /***************************************************************************
2360 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2361 ***************************************************************************/
2363 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2365 const char *suffix_string;
2367 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2368 Globals.ldap_suffix );
2369 if ( !suffix_string ) {
2370 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2371 return "";
2374 return suffix_string;
2377 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2379 if (Globals.szLdapMachineSuffix[0])
2380 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
2382 return lp_string(ctx, Globals.ldap_suffix);
2385 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2387 if (Globals.szLdapUserSuffix[0])
2388 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
2390 return lp_string(ctx, Globals.ldap_suffix);
2393 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2395 if (Globals.szLdapGroupSuffix[0])
2396 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
2398 return lp_string(ctx, Globals.ldap_suffix);
2401 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2403 if (Globals.szLdapIdmapSuffix[0])
2404 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
2406 return lp_string(ctx, Globals.ldap_suffix);
2410 return the parameter pointer for a parameter
2412 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2414 if (service == NULL) {
2415 if (parm->p_class == P_LOCAL)
2416 return (void *)(((char *)&sDefault)+parm->offset);
2417 else if (parm->p_class == P_GLOBAL)
2418 return (void *)(((char *)&Globals)+parm->offset);
2419 else return NULL;
2420 } else {
2421 return (void *)(((char *)service) + parm->offset);
2425 /***************************************************************************
2426 Process a parameter for a particular service number. If snum < 0
2427 then assume we are in the globals.
2428 ***************************************************************************/
2430 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2432 TALLOC_CTX *frame = talloc_stackframe();
2433 struct loadparm_context *lp_ctx;
2434 bool ok;
2436 lp_ctx = setup_lp_context(frame);
2437 if (lp_ctx == NULL) {
2438 TALLOC_FREE(frame);
2439 return false;
2442 if (snum < 0) {
2443 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2444 } else {
2445 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2446 pszParmName, pszParmValue);
2449 TALLOC_FREE(frame);
2451 return ok;
2454 /***************************************************************************
2455 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2456 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2457 ***************************************************************************/
2459 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2461 int parmnum, i;
2462 parmnum = lpcfg_map_parameter(pszParmName);
2463 if (parmnum >= 0) {
2464 flags_list[parmnum] &= ~FLAG_CMDLINE;
2465 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2466 return false;
2468 flags_list[parmnum] |= FLAG_CMDLINE;
2470 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2471 * be grouped in the table, so we don't have to search the
2472 * whole table */
2473 for (i=parmnum-1;
2474 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2475 && parm_table[i].p_class == parm_table[parmnum].p_class;
2476 i--) {
2477 flags_list[i] |= FLAG_CMDLINE;
2479 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2480 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2481 flags_list[i] |= FLAG_CMDLINE;
2484 return true;
2487 /* it might be parametric */
2488 if (strchr(pszParmName, ':') != NULL) {
2489 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2490 return true;
2493 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2494 return false;
2497 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2499 bool ret;
2500 TALLOC_CTX *frame = talloc_stackframe();
2501 struct loadparm_context *lp_ctx;
2503 lp_ctx = setup_lp_context(frame);
2504 if (lp_ctx == NULL) {
2505 TALLOC_FREE(frame);
2506 return false;
2509 ret = lpcfg_set_cmdline(lp_ctx, pszParmName, pszParmValue);
2511 TALLOC_FREE(frame);
2512 return ret;
2515 /***************************************************************************
2516 Process a parameter.
2517 ***************************************************************************/
2519 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2520 void *userdata)
2522 if (!bInGlobalSection && bGlobalOnly)
2523 return true;
2525 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2527 if (bInGlobalSection) {
2528 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2529 } else {
2530 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2531 pszParmName, pszParmValue);
2535 /***************************************************************************
2536 Initialize any local variables in the sDefault table, after parsing a
2537 [globals] section.
2538 ***************************************************************************/
2540 static void init_locals(void)
2543 * We run this check once the [globals] is parsed, to force
2544 * the VFS objects and other per-share settings we need for
2545 * the standard way a AD DC is operated. We may change these
2546 * as our code evolves, which is why we force these settings.
2548 * We can't do this at the end of lp_load_ex(), as by that
2549 * point the services have been loaded and they will already
2550 * have "" as their vfs objects.
2552 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2553 const char **vfs_objects = lp_vfs_objects(-1);
2554 if (!vfs_objects || !vfs_objects[0]) {
2555 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2556 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2557 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2558 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2559 } else {
2560 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2564 lp_do_parameter(-1, "map hidden", "no");
2565 lp_do_parameter(-1, "map system", "no");
2566 lp_do_parameter(-1, "map readonly", "no");
2567 lp_do_parameter(-1, "map archive", "no");
2568 lp_do_parameter(-1, "store dos attributes", "yes");
2572 /***************************************************************************
2573 Process a new section (service). At this stage all sections are services.
2574 Later we'll have special sections that permit server parameters to be set.
2575 Returns true on success, false on failure.
2576 ***************************************************************************/
2578 bool lp_do_section(const char *pszSectionName, void *userdata)
2580 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2581 bool bRetval;
2582 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2583 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2584 bRetval = false;
2586 /* if we were in a global section then do the local inits */
2587 if (bInGlobalSection && !isglobal)
2588 init_locals();
2590 /* if we've just struck a global section, note the fact. */
2591 bInGlobalSection = isglobal;
2592 if (lp_ctx != NULL) {
2593 lp_ctx->bInGlobalSection = isglobal;
2596 /* check for multiple global sections */
2597 if (bInGlobalSection) {
2598 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2599 return true;
2602 if (!bInGlobalSection && bGlobalOnly)
2603 return true;
2605 /* if we have a current service, tidy it up before moving on */
2606 bRetval = true;
2608 if (iServiceIndex >= 0)
2609 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2611 /* if all is still well, move to the next record in the services array */
2612 if (bRetval) {
2613 /* We put this here to avoid an odd message order if messages are */
2614 /* issued by the post-processing of a previous section. */
2615 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2617 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2618 if (iServiceIndex < 0) {
2619 DEBUG(0, ("Failed to add a new service\n"));
2620 return false;
2622 /* Clean all parametric options for service */
2623 /* They will be added during parsing again */
2624 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2627 return bRetval;
2630 /***************************************************************************
2631 Display the contents of a parameter of a single services record.
2632 ***************************************************************************/
2634 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2636 bool result = false;
2637 struct loadparm_context *lp_ctx;
2639 lp_ctx = setup_lp_context(talloc_tos());
2640 if (lp_ctx == NULL) {
2641 return false;
2644 if (isGlobal) {
2645 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2646 } else {
2647 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2649 TALLOC_FREE(lp_ctx);
2650 return result;
2653 #if 0
2654 /***************************************************************************
2655 Display the contents of a single copy structure.
2656 ***************************************************************************/
2657 static void dump_copy_map(bool *pcopymap)
2659 int i;
2660 if (!pcopymap)
2661 return;
2663 printf("\n\tNon-Copied parameters:\n");
2665 for (i = 0; parm_table[i].label; i++)
2666 if (parm_table[i].p_class == P_LOCAL &&
2667 parm_table[i].ptr && !pcopymap[i] &&
2668 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2670 printf("\t\t%s\n", parm_table[i].label);
2673 #endif
2675 /***************************************************************************
2676 Return TRUE if the passed service number is within range.
2677 ***************************************************************************/
2679 bool lp_snum_ok(int iService)
2681 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2684 /***************************************************************************
2685 Auto-load some home services.
2686 ***************************************************************************/
2688 static void lp_add_auto_services(char *str)
2690 char *s;
2691 char *p;
2692 int homes;
2693 char *saveptr;
2695 if (!str)
2696 return;
2698 s = talloc_strdup(talloc_tos(), str);
2699 if (!s) {
2700 smb_panic("talloc_strdup failed");
2701 return;
2704 homes = lp_servicenumber(HOMES_NAME);
2706 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
2707 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
2708 char *home;
2710 if (lp_servicenumber(p) >= 0)
2711 continue;
2713 home = get_user_home_dir(talloc_tos(), p);
2715 if (home && home[0] && homes >= 0)
2716 lp_add_home(p, homes, p, home);
2718 TALLOC_FREE(home);
2720 TALLOC_FREE(s);
2723 /***************************************************************************
2724 Auto-load one printer.
2725 ***************************************************************************/
2727 void lp_add_one_printer(const char *name, const char *comment,
2728 const char *location, void *pdata)
2730 int printers = lp_servicenumber(PRINTERS_NAME);
2731 int i;
2733 if (lp_servicenumber(name) < 0) {
2734 lp_add_printer(name, printers);
2735 if ((i = lp_servicenumber(name)) >= 0) {
2736 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
2737 ServicePtrs[i]->autoloaded = true;
2742 /***************************************************************************
2743 Have we loaded a services file yet?
2744 ***************************************************************************/
2746 bool lp_loaded(void)
2748 return (bLoaded);
2751 /***************************************************************************
2752 Unload unused services.
2753 ***************************************************************************/
2755 void lp_killunused(struct smbd_server_connection *sconn,
2756 bool (*snumused) (struct smbd_server_connection *, int))
2758 int i;
2759 for (i = 0; i < iNumServices; i++) {
2760 if (!VALID(i))
2761 continue;
2763 /* don't kill autoloaded or usershare services */
2764 if ( ServicePtrs[i]->autoloaded ||
2765 ServicePtrs[i]->usershare == USERSHARE_VALID) {
2766 continue;
2769 if (!snumused || !snumused(sconn, i)) {
2770 free_service_byindex(i);
2776 * Kill all except autoloaded and usershare services - convenience wrapper
2778 void lp_kill_all_services(void)
2780 lp_killunused(NULL, NULL);
2783 /***************************************************************************
2784 Unload a service.
2785 ***************************************************************************/
2787 void lp_killservice(int iServiceIn)
2789 if (VALID(iServiceIn)) {
2790 free_service_byindex(iServiceIn);
2794 /***************************************************************************
2795 Save the curent values of all global and sDefault parameters into the
2796 defaults union. This allows testparm to show only the
2797 changed (ie. non-default) parameters.
2798 ***************************************************************************/
2800 static void lp_save_defaults(void)
2802 int i;
2803 struct parmlist_entry * parm;
2804 for (i = 0; parm_table[i].label; i++) {
2805 if (!(flags_list[i] & FLAG_CMDLINE)) {
2806 flags_list[i] |= FLAG_DEFAULT;
2809 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
2810 && parm_table[i].p_class == parm_table[i - 1].p_class)
2811 continue;
2812 switch (parm_table[i].type) {
2813 case P_LIST:
2814 case P_CMDLIST:
2815 parm_table[i].def.lvalue = str_list_copy(
2816 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
2817 break;
2818 case P_STRING:
2819 case P_USTRING:
2820 parm_table[i].def.svalue = talloc_strdup(Globals.ctx, *(char **)lp_parm_ptr(NULL, &parm_table[i]));
2821 if (parm_table[i].def.svalue == NULL) {
2822 smb_panic("talloc_strdup failed");
2824 break;
2825 case P_BOOL:
2826 case P_BOOLREV:
2827 parm_table[i].def.bvalue =
2828 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
2829 break;
2830 case P_CHAR:
2831 parm_table[i].def.cvalue =
2832 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
2833 break;
2834 case P_INTEGER:
2835 case P_OCTAL:
2836 case P_ENUM:
2837 case P_BYTES:
2838 parm_table[i].def.ivalue =
2839 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
2840 break;
2841 case P_SEP:
2842 break;
2846 for (parm=Globals.param_opt; parm; parm=parm->next) {
2847 if (!(parm->priority & FLAG_CMDLINE)) {
2848 parm->priority |= FLAG_DEFAULT;
2852 for (parm=sDefault.param_opt; parm; parm=parm->next) {
2853 if (!(parm->priority & FLAG_CMDLINE)) {
2854 parm->priority |= FLAG_DEFAULT;
2858 defaults_saved = true;
2861 /***********************************************************
2862 If we should send plaintext/LANMAN passwords in the clinet
2863 ************************************************************/
2865 static void set_allowed_client_auth(void)
2867 if (Globals.client_ntlmv2_auth) {
2868 Globals.client_lanman_auth = false;
2870 if (!Globals.client_lanman_auth) {
2871 Globals.client_plaintext_auth = false;
2875 /***************************************************************************
2876 JRA.
2877 The following code allows smbd to read a user defined share file.
2878 Yes, this is my intent. Yes, I'm comfortable with that...
2880 THE FOLLOWING IS SECURITY CRITICAL CODE.
2882 It washes your clothes, it cleans your house, it guards you while you sleep...
2883 Do not f%^k with it....
2884 ***************************************************************************/
2886 #define MAX_USERSHARE_FILE_SIZE (10*1024)
2888 /***************************************************************************
2889 Check allowed stat state of a usershare file.
2890 Ensure we print out who is dicking with us so the admin can
2891 get their sorry ass fired.
2892 ***************************************************************************/
2894 static bool check_usershare_stat(const char *fname,
2895 const SMB_STRUCT_STAT *psbuf)
2897 if (!S_ISREG(psbuf->st_ex_mode)) {
2898 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2899 "not a regular file\n",
2900 fname, (unsigned int)psbuf->st_ex_uid ));
2901 return false;
2904 /* Ensure this doesn't have the other write bit set. */
2905 if (psbuf->st_ex_mode & S_IWOTH) {
2906 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
2907 "public write. Refusing to allow as a usershare file.\n",
2908 fname, (unsigned int)psbuf->st_ex_uid ));
2909 return false;
2912 /* Should be 10k or less. */
2913 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
2914 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2915 "too large (%u) to be a user share file.\n",
2916 fname, (unsigned int)psbuf->st_ex_uid,
2917 (unsigned int)psbuf->st_ex_size ));
2918 return false;
2921 return true;
2924 /***************************************************************************
2925 Parse the contents of a usershare file.
2926 ***************************************************************************/
2928 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
2929 SMB_STRUCT_STAT *psbuf,
2930 const char *servicename,
2931 int snum,
2932 char **lines,
2933 int numlines,
2934 char **pp_sharepath,
2935 char **pp_comment,
2936 char **pp_cp_servicename,
2937 struct security_descriptor **ppsd,
2938 bool *pallow_guest)
2940 const char **prefixallowlist = lp_usershare_prefix_allow_list();
2941 const char **prefixdenylist = lp_usershare_prefix_deny_list();
2942 int us_vers;
2943 DIR *dp;
2944 SMB_STRUCT_STAT sbuf;
2945 char *sharepath = NULL;
2946 char *comment = NULL;
2948 *pp_sharepath = NULL;
2949 *pp_comment = NULL;
2951 *pallow_guest = false;
2953 if (numlines < 4) {
2954 return USERSHARE_MALFORMED_FILE;
2957 if (strcmp(lines[0], "#VERSION 1") == 0) {
2958 us_vers = 1;
2959 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
2960 us_vers = 2;
2961 if (numlines < 5) {
2962 return USERSHARE_MALFORMED_FILE;
2964 } else {
2965 return USERSHARE_BAD_VERSION;
2968 if (strncmp(lines[1], "path=", 5) != 0) {
2969 return USERSHARE_MALFORMED_PATH;
2972 sharepath = talloc_strdup(ctx, &lines[1][5]);
2973 if (!sharepath) {
2974 return USERSHARE_POSIX_ERR;
2976 trim_string(sharepath, " ", " ");
2978 if (strncmp(lines[2], "comment=", 8) != 0) {
2979 return USERSHARE_MALFORMED_COMMENT_DEF;
2982 comment = talloc_strdup(ctx, &lines[2][8]);
2983 if (!comment) {
2984 return USERSHARE_POSIX_ERR;
2986 trim_string(comment, " ", " ");
2987 trim_char(comment, '"', '"');
2989 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
2990 return USERSHARE_MALFORMED_ACL_DEF;
2993 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
2994 return USERSHARE_ACL_ERR;
2997 if (us_vers == 2) {
2998 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
2999 return USERSHARE_MALFORMED_ACL_DEF;
3001 if (lines[4][9] == 'y') {
3002 *pallow_guest = true;
3005 /* Backwards compatible extension to file version #2. */
3006 if (numlines > 5) {
3007 if (strncmp(lines[5], "sharename=", 10) != 0) {
3008 return USERSHARE_MALFORMED_SHARENAME_DEF;
3010 if (!strequal(&lines[5][10], servicename)) {
3011 return USERSHARE_BAD_SHARENAME;
3013 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3014 if (!*pp_cp_servicename) {
3015 return USERSHARE_POSIX_ERR;
3020 if (*pp_cp_servicename == NULL) {
3021 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3022 if (!*pp_cp_servicename) {
3023 return USERSHARE_POSIX_ERR;
3027 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3028 /* Path didn't change, no checks needed. */
3029 *pp_sharepath = sharepath;
3030 *pp_comment = comment;
3031 return USERSHARE_OK;
3034 /* The path *must* be absolute. */
3035 if (sharepath[0] != '/') {
3036 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3037 servicename, sharepath));
3038 return USERSHARE_PATH_NOT_ABSOLUTE;
3041 /* If there is a usershare prefix deny list ensure one of these paths
3042 doesn't match the start of the user given path. */
3043 if (prefixdenylist) {
3044 int i;
3045 for ( i=0; prefixdenylist[i]; i++ ) {
3046 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3047 servicename, i, prefixdenylist[i], sharepath ));
3048 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3049 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3050 "usershare prefix deny list entries.\n",
3051 servicename, sharepath));
3052 return USERSHARE_PATH_IS_DENIED;
3057 /* If there is a usershare prefix allow list ensure one of these paths
3058 does match the start of the user given path. */
3060 if (prefixallowlist) {
3061 int i;
3062 for ( i=0; prefixallowlist[i]; i++ ) {
3063 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3064 servicename, i, prefixallowlist[i], sharepath ));
3065 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3066 break;
3069 if (prefixallowlist[i] == NULL) {
3070 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3071 "usershare prefix allow list entries.\n",
3072 servicename, sharepath));
3073 return USERSHARE_PATH_NOT_ALLOWED;
3077 /* Ensure this is pointing to a directory. */
3078 dp = opendir(sharepath);
3080 if (!dp) {
3081 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3082 servicename, sharepath));
3083 return USERSHARE_PATH_NOT_DIRECTORY;
3086 /* Ensure the owner of the usershare file has permission to share
3087 this directory. */
3089 if (sys_stat(sharepath, &sbuf, false) == -1) {
3090 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3091 servicename, sharepath, strerror(errno) ));
3092 closedir(dp);
3093 return USERSHARE_POSIX_ERR;
3096 closedir(dp);
3098 if (!S_ISDIR(sbuf.st_ex_mode)) {
3099 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3100 servicename, sharepath ));
3101 return USERSHARE_PATH_NOT_DIRECTORY;
3104 /* Check if sharing is restricted to owner-only. */
3105 /* psbuf is the stat of the usershare definition file,
3106 sbuf is the stat of the target directory to be shared. */
3108 if (lp_usershare_owner_only()) {
3109 /* root can share anything. */
3110 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3111 return USERSHARE_PATH_NOT_ALLOWED;
3115 *pp_sharepath = sharepath;
3116 *pp_comment = comment;
3117 return USERSHARE_OK;
3120 /***************************************************************************
3121 Deal with a usershare file.
3122 Returns:
3123 >= 0 - snum
3124 -1 - Bad name, invalid contents.
3125 - service name already existed and not a usershare, problem
3126 with permissions to share directory etc.
3127 ***************************************************************************/
3129 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3131 SMB_STRUCT_STAT sbuf;
3132 SMB_STRUCT_STAT lsbuf;
3133 char *fname = NULL;
3134 char *sharepath = NULL;
3135 char *comment = NULL;
3136 char *cp_service_name = NULL;
3137 char **lines = NULL;
3138 int numlines = 0;
3139 int fd = -1;
3140 int iService = -1;
3141 TALLOC_CTX *ctx = talloc_stackframe();
3142 struct security_descriptor *psd = NULL;
3143 bool guest_ok = false;
3144 char *canon_name = NULL;
3145 bool added_service = false;
3146 int ret = -1;
3148 /* Ensure share name doesn't contain invalid characters. */
3149 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3150 DEBUG(0,("process_usershare_file: share name %s contains "
3151 "invalid characters (any of %s)\n",
3152 file_name, INVALID_SHARENAME_CHARS ));
3153 goto out;
3156 canon_name = canonicalize_servicename(ctx, file_name);
3157 if (!canon_name) {
3158 goto out;
3161 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3162 if (!fname) {
3163 goto out;
3166 /* Minimize the race condition by doing an lstat before we
3167 open and fstat. Ensure this isn't a symlink link. */
3169 if (sys_lstat(fname, &lsbuf, false) != 0) {
3170 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3171 fname, strerror(errno) ));
3172 goto out;
3175 /* This must be a regular file, not a symlink, directory or
3176 other strange filetype. */
3177 if (!check_usershare_stat(fname, &lsbuf)) {
3178 goto out;
3182 TDB_DATA data;
3183 NTSTATUS status;
3185 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3186 canon_name, &data);
3188 iService = -1;
3190 if (NT_STATUS_IS_OK(status) &&
3191 (data.dptr != NULL) &&
3192 (data.dsize == sizeof(iService))) {
3193 memcpy(&iService, data.dptr, sizeof(iService));
3197 if (iService != -1 &&
3198 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3199 &lsbuf.st_ex_mtime) == 0) {
3200 /* Nothing changed - Mark valid and return. */
3201 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3202 canon_name ));
3203 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3204 ret = iService;
3205 goto out;
3208 /* Try and open the file read only - no symlinks allowed. */
3209 #ifdef O_NOFOLLOW
3210 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3211 #else
3212 fd = open(fname, O_RDONLY, 0);
3213 #endif
3215 if (fd == -1) {
3216 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3217 fname, strerror(errno) ));
3218 goto out;
3221 /* Now fstat to be *SURE* it's a regular file. */
3222 if (sys_fstat(fd, &sbuf, false) != 0) {
3223 close(fd);
3224 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3225 fname, strerror(errno) ));
3226 goto out;
3229 /* Is it the same dev/inode as was lstated ? */
3230 if (!check_same_stat(&lsbuf, &sbuf)) {
3231 close(fd);
3232 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3233 "Symlink spoofing going on ?\n", fname ));
3234 goto out;
3237 /* This must be a regular file, not a symlink, directory or
3238 other strange filetype. */
3239 if (!check_usershare_stat(fname, &sbuf)) {
3240 close(fd);
3241 goto out;
3244 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3246 close(fd);
3247 if (lines == NULL) {
3248 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3249 fname, (unsigned int)sbuf.st_ex_uid ));
3250 goto out;
3253 if (parse_usershare_file(ctx, &sbuf, file_name,
3254 iService, lines, numlines, &sharepath,
3255 &comment, &cp_service_name,
3256 &psd, &guest_ok) != USERSHARE_OK) {
3257 goto out;
3260 /* Everything ok - add the service possibly using a template. */
3261 if (iService < 0) {
3262 const struct loadparm_service *sp = &sDefault;
3263 if (snum_template != -1) {
3264 sp = ServicePtrs[snum_template];
3267 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3268 DEBUG(0, ("process_usershare_file: Failed to add "
3269 "new service %s\n", cp_service_name));
3270 goto out;
3273 added_service = true;
3275 /* Read only is controlled by usershare ACL below. */
3276 ServicePtrs[iService]->read_only = false;
3279 /* Write the ACL of the new/modified share. */
3280 if (!set_share_security(canon_name, psd)) {
3281 DEBUG(0, ("process_usershare_file: Failed to set share "
3282 "security for user share %s\n",
3283 canon_name ));
3284 goto out;
3287 /* If from a template it may be marked invalid. */
3288 ServicePtrs[iService]->valid = true;
3290 /* Set the service as a valid usershare. */
3291 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3293 /* Set guest access. */
3294 if (lp_usershare_allow_guests()) {
3295 ServicePtrs[iService]->guest_ok = guest_ok;
3298 /* And note when it was loaded. */
3299 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3300 string_set(ServicePtrs[iService], &ServicePtrs[iService]->path, sharepath);
3301 string_set(ServicePtrs[iService], &ServicePtrs[iService]->comment, comment);
3303 ret = iService;
3305 out:
3307 if (ret == -1 && iService != -1 && added_service) {
3308 lp_remove_service(iService);
3311 TALLOC_FREE(lines);
3312 TALLOC_FREE(ctx);
3313 return ret;
3316 /***************************************************************************
3317 Checks if a usershare entry has been modified since last load.
3318 ***************************************************************************/
3320 static bool usershare_exists(int iService, struct timespec *last_mod)
3322 SMB_STRUCT_STAT lsbuf;
3323 const char *usersharepath = Globals.usershare_path;
3324 char *fname;
3326 fname = talloc_asprintf(talloc_tos(),
3327 "%s/%s",
3328 usersharepath,
3329 ServicePtrs[iService]->szService);
3330 if (fname == NULL) {
3331 return false;
3334 if (sys_lstat(fname, &lsbuf, false) != 0) {
3335 TALLOC_FREE(fname);
3336 return false;
3339 if (!S_ISREG(lsbuf.st_ex_mode)) {
3340 TALLOC_FREE(fname);
3341 return false;
3344 TALLOC_FREE(fname);
3345 *last_mod = lsbuf.st_ex_mtime;
3346 return true;
3349 /***************************************************************************
3350 Load a usershare service by name. Returns a valid servicenumber or -1.
3351 ***************************************************************************/
3353 int load_usershare_service(const char *servicename)
3355 SMB_STRUCT_STAT sbuf;
3356 const char *usersharepath = Globals.usershare_path;
3357 int max_user_shares = Globals.usershare_max_shares;
3358 int snum_template = -1;
3360 if (*usersharepath == 0 || max_user_shares == 0) {
3361 return -1;
3364 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3365 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3366 usersharepath, strerror(errno) ));
3367 return -1;
3370 if (!S_ISDIR(sbuf.st_ex_mode)) {
3371 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3372 usersharepath ));
3373 return -1;
3377 * This directory must be owned by root, and have the 't' bit set.
3378 * It also must not be writable by "other".
3381 #ifdef S_ISVTX
3382 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3383 #else
3384 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3385 #endif
3386 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3387 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3388 usersharepath ));
3389 return -1;
3392 /* Ensure the template share exists if it's set. */
3393 if (Globals.usershare_template_share[0]) {
3394 /* We can't use lp_servicenumber here as we are recommending that
3395 template shares have -valid=false set. */
3396 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3397 if (ServicePtrs[snum_template]->szService &&
3398 strequal(ServicePtrs[snum_template]->szService,
3399 Globals.usershare_template_share)) {
3400 break;
3404 if (snum_template == -1) {
3405 DEBUG(0,("load_usershare_service: usershare template share %s "
3406 "does not exist.\n",
3407 Globals.usershare_template_share ));
3408 return -1;
3412 return process_usershare_file(usersharepath, servicename, snum_template);
3415 /***************************************************************************
3416 Load all user defined shares from the user share directory.
3417 We only do this if we're enumerating the share list.
3418 This is the function that can delete usershares that have
3419 been removed.
3420 ***************************************************************************/
3422 int load_usershare_shares(struct smbd_server_connection *sconn,
3423 bool (*snumused) (struct smbd_server_connection *, int))
3425 DIR *dp;
3426 SMB_STRUCT_STAT sbuf;
3427 struct dirent *de;
3428 int num_usershares = 0;
3429 int max_user_shares = Globals.usershare_max_shares;
3430 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3431 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3432 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3433 int iService;
3434 int snum_template = -1;
3435 const char *usersharepath = Globals.usershare_path;
3436 int ret = lp_numservices();
3437 TALLOC_CTX *tmp_ctx;
3439 if (max_user_shares == 0 || *usersharepath == '\0') {
3440 return lp_numservices();
3443 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3444 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3445 usersharepath, strerror(errno) ));
3446 return ret;
3450 * This directory must be owned by root, and have the 't' bit set.
3451 * It also must not be writable by "other".
3454 #ifdef S_ISVTX
3455 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3456 #else
3457 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3458 #endif
3459 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3460 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3461 usersharepath ));
3462 return ret;
3465 /* Ensure the template share exists if it's set. */
3466 if (Globals.usershare_template_share[0]) {
3467 /* We can't use lp_servicenumber here as we are recommending that
3468 template shares have -valid=false set. */
3469 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3470 if (ServicePtrs[snum_template]->szService &&
3471 strequal(ServicePtrs[snum_template]->szService,
3472 Globals.usershare_template_share)) {
3473 break;
3477 if (snum_template == -1) {
3478 DEBUG(0,("load_usershare_shares: usershare template share %s "
3479 "does not exist.\n",
3480 Globals.usershare_template_share ));
3481 return ret;
3485 /* Mark all existing usershares as pending delete. */
3486 for (iService = iNumServices - 1; iService >= 0; iService--) {
3487 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3488 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3492 dp = opendir(usersharepath);
3493 if (!dp) {
3494 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3495 usersharepath, strerror(errno) ));
3496 return ret;
3499 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3500 (de = readdir(dp));
3501 num_dir_entries++ ) {
3502 int r;
3503 const char *n = de->d_name;
3505 /* Ignore . and .. */
3506 if (*n == '.') {
3507 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3508 continue;
3512 if (n[0] == ':') {
3513 /* Temporary file used when creating a share. */
3514 num_tmp_dir_entries++;
3517 /* Allow 20% tmp entries. */
3518 if (num_tmp_dir_entries > allowed_tmp_entries) {
3519 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3520 "in directory %s\n",
3521 num_tmp_dir_entries, usersharepath));
3522 break;
3525 r = process_usershare_file(usersharepath, n, snum_template);
3526 if (r == 0) {
3527 /* Update the services count. */
3528 num_usershares++;
3529 if (num_usershares >= max_user_shares) {
3530 DEBUG(0,("load_usershare_shares: max user shares reached "
3531 "on file %s in directory %s\n",
3532 n, usersharepath ));
3533 break;
3535 } else if (r == -1) {
3536 num_bad_dir_entries++;
3539 /* Allow 20% bad entries. */
3540 if (num_bad_dir_entries > allowed_bad_entries) {
3541 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3542 "in directory %s\n",
3543 num_bad_dir_entries, usersharepath));
3544 break;
3547 /* Allow 20% bad entries. */
3548 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3549 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3550 "in directory %s\n",
3551 num_dir_entries, usersharepath));
3552 break;
3556 closedir(dp);
3558 /* Sweep through and delete any non-refreshed usershares that are
3559 not currently in use. */
3560 tmp_ctx = talloc_stackframe();
3561 for (iService = iNumServices - 1; iService >= 0; iService--) {
3562 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3563 char *servname;
3565 if (snumused && snumused(sconn, iService)) {
3566 continue;
3569 servname = lp_servicename(tmp_ctx, iService);
3571 /* Remove from the share ACL db. */
3572 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3573 servname ));
3574 delete_share_security(servname);
3575 free_service_byindex(iService);
3578 talloc_free(tmp_ctx);
3580 return lp_numservices();
3583 /********************************************************
3584 Destroy global resources allocated in this file
3585 ********************************************************/
3587 void gfree_loadparm(void)
3589 int i;
3591 free_file_list();
3593 /* Free resources allocated to services */
3595 for ( i = 0; i < iNumServices; i++ ) {
3596 if ( VALID(i) ) {
3597 free_service_byindex(i);
3601 TALLOC_FREE( ServicePtrs );
3602 iNumServices = 0;
3604 /* Now release all resources allocated to global
3605 parameters and the default service */
3607 free_global_parameters();
3611 /***************************************************************************
3612 Allow client apps to specify that they are a client
3613 ***************************************************************************/
3614 static void lp_set_in_client(bool b)
3616 in_client = b;
3620 /***************************************************************************
3621 Determine if we're running in a client app
3622 ***************************************************************************/
3623 static bool lp_is_in_client(void)
3625 return in_client;
3628 /***************************************************************************
3629 Load the services array from the services file. Return true on success,
3630 false on failure.
3631 ***************************************************************************/
3633 static bool lp_load_ex(const char *pszFname,
3634 bool global_only,
3635 bool save_defaults,
3636 bool add_ipc,
3637 bool initialize_globals,
3638 bool allow_include_registry,
3639 bool load_all_shares)
3641 char *n2 = NULL;
3642 bool bRetval;
3643 TALLOC_CTX *frame = talloc_stackframe();
3644 struct loadparm_context *lp_ctx;
3646 bRetval = false;
3648 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3650 bInGlobalSection = true;
3651 bGlobalOnly = global_only;
3652 bAllowIncludeRegistry = allow_include_registry;
3654 lp_ctx = setup_lp_context(talloc_tos());
3656 init_globals(lp_ctx, initialize_globals);
3658 free_file_list();
3660 if (save_defaults) {
3661 init_locals();
3662 lp_save_defaults();
3665 if (!initialize_globals) {
3666 free_param_opts(&Globals.param_opt);
3667 apply_lp_set_cmdline();
3670 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
3672 /* We get sections first, so have to start 'behind' to make up */
3673 iServiceIndex = -1;
3675 if (lp_config_backend_is_file()) {
3676 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
3677 current_user_info.domain,
3678 pszFname);
3679 if (!n2) {
3680 smb_panic("lp_load_ex: out of memory");
3683 add_to_file_list(NULL, &file_lists, pszFname, n2);
3685 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
3686 TALLOC_FREE(n2);
3688 /* finish up the last section */
3689 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3690 if (bRetval) {
3691 if (iServiceIndex >= 0) {
3692 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
3696 if (lp_config_backend_is_registry()) {
3697 bool ok;
3698 /* config backend changed to registry in config file */
3700 * We need to use this extra global variable here to
3701 * survive restart: init_globals uses this as a default
3702 * for config_backend. Otherwise, init_globals would
3703 * send us into an endless loop here.
3706 config_backend = CONFIG_BACKEND_REGISTRY;
3707 /* start over */
3708 DEBUG(1, ("lp_load_ex: changing to config backend "
3709 "registry\n"));
3710 init_globals(lp_ctx, true);
3712 TALLOC_FREE(lp_ctx);
3714 lp_kill_all_services();
3715 ok = lp_load_ex(pszFname, global_only, save_defaults,
3716 add_ipc, initialize_globals,
3717 allow_include_registry,
3718 load_all_shares);
3719 TALLOC_FREE(frame);
3720 return ok;
3722 } else if (lp_config_backend_is_registry()) {
3723 bRetval = process_registry_globals();
3724 } else {
3725 DEBUG(0, ("Illegal config backend given: %d\n",
3726 lp_config_backend()));
3727 bRetval = false;
3730 if (bRetval && lp_registry_shares()) {
3731 if (load_all_shares) {
3732 bRetval = process_registry_shares();
3733 } else {
3734 bRetval = reload_registry_shares();
3739 char *serv = lp_auto_services(talloc_tos());
3740 lp_add_auto_services(serv);
3741 TALLOC_FREE(serv);
3744 if (add_ipc) {
3745 /* When 'restrict anonymous = 2' guest connections to ipc$
3746 are denied */
3747 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3748 if ( lp_enable_asu_support() ) {
3749 lp_add_ipc("ADMIN$", false);
3753 set_allowed_client_auth();
3755 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
3756 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
3757 lp_password_server()));
3760 bLoaded = true;
3762 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
3763 /* if we_are_a_wins_server is true and we are in the client */
3764 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
3765 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
3768 init_iconv();
3770 fault_configure(smb_panic_s3);
3773 * We run this check once the whole smb.conf is parsed, to
3774 * force some settings for the standard way a AD DC is
3775 * operated. We may changed these as our code evolves, which
3776 * is why we force these settings.
3778 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3779 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
3781 lp_do_parameter(-1, "winbindd:use external pipes", "true");
3783 lp_do_parameter(-1, "rpc_server:default", "external");
3784 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
3785 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
3786 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
3787 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
3788 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
3789 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
3790 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
3791 lp_do_parameter(-1, "rpc_server:tcpip", "no");
3794 bAllowIncludeRegistry = true;
3796 TALLOC_FREE(frame);
3797 return (bRetval);
3800 bool lp_load(const char *pszFname,
3801 bool global_only,
3802 bool save_defaults,
3803 bool add_ipc,
3804 bool initialize_globals)
3806 return lp_load_ex(pszFname,
3807 global_only,
3808 save_defaults,
3809 add_ipc,
3810 initialize_globals,
3811 true, /* allow_include_registry */
3812 false); /* load_all_shares*/
3815 bool lp_load_initial_only(const char *pszFname)
3817 return lp_load_ex(pszFname,
3818 true, /* global only */
3819 false, /* save_defaults */
3820 false, /* add_ipc */
3821 true, /* initialize_globals */
3822 false, /* allow_include_registry */
3823 false); /* load_all_shares*/
3827 * most common lp_load wrapper, loading only the globals
3829 bool lp_load_global(const char *file_name)
3831 return lp_load_ex(file_name,
3832 true, /* global_only */
3833 false, /* save_defaults */
3834 false, /* add_ipc */
3835 true, /* initialize_globals */
3836 true, /* allow_include_registry */
3837 false); /* load_all_shares*/
3841 * lp_load wrapper, especially for clients
3843 bool lp_load_client(const char *file_name)
3845 lp_set_in_client(true);
3847 return lp_load_global(file_name);
3851 * lp_load wrapper, loading only globals, but intended
3852 * for subsequent calls, not reinitializing the globals
3853 * to default values
3855 bool lp_load_global_no_reinit(const char *file_name)
3857 return lp_load_ex(file_name,
3858 true, /* global_only */
3859 false, /* save_defaults */
3860 false, /* add_ipc */
3861 false, /* initialize_globals */
3862 true, /* allow_include_registry */
3863 false); /* load_all_shares*/
3867 * lp_load wrapper, especially for clients, no reinitialization
3869 bool lp_load_client_no_reinit(const char *file_name)
3871 lp_set_in_client(true);
3873 return lp_load_global_no_reinit(file_name);
3876 bool lp_load_with_registry_shares(const char *pszFname,
3877 bool global_only,
3878 bool save_defaults,
3879 bool add_ipc,
3880 bool initialize_globals)
3882 return lp_load_ex(pszFname,
3883 global_only,
3884 save_defaults,
3885 add_ipc,
3886 initialize_globals,
3887 true, /* allow_include_registry */
3888 true); /* load_all_shares*/
3891 /***************************************************************************
3892 Return the max number of services.
3893 ***************************************************************************/
3895 int lp_numservices(void)
3897 return (iNumServices);
3900 /***************************************************************************
3901 Display the contents of the services array in human-readable form.
3902 ***************************************************************************/
3904 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
3906 int iService;
3907 struct loadparm_context *lp_ctx;
3909 if (show_defaults)
3910 defaults_saved = false;
3912 lp_ctx = setup_lp_context(talloc_tos());
3913 if (lp_ctx == NULL) {
3914 return;
3917 lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
3919 lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
3921 for (iService = 0; iService < maxtoprint; iService++) {
3922 fprintf(f,"\n");
3923 lp_dump_one(f, show_defaults, iService);
3927 /***************************************************************************
3928 Display the contents of one service in human-readable form.
3929 ***************************************************************************/
3931 void lp_dump_one(FILE * f, bool show_defaults, int snum)
3933 if (VALID(snum)) {
3934 if (ServicePtrs[snum]->szService[0] == '\0')
3935 return;
3936 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
3937 flags_list, show_defaults);
3941 /***************************************************************************
3942 Return the number of the service with the given name, or -1 if it doesn't
3943 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3944 getservicebyname()! This works ONLY if all services have been loaded, and
3945 does not copy the found service.
3946 ***************************************************************************/
3948 int lp_servicenumber(const char *pszServiceName)
3950 int iService;
3951 fstring serviceName;
3953 if (!pszServiceName) {
3954 return GLOBAL_SECTION_SNUM;
3957 for (iService = iNumServices - 1; iService >= 0; iService--) {
3958 if (VALID(iService) && ServicePtrs[iService]->szService) {
3960 * The substitution here is used to support %U in
3961 * service names
3963 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3964 standard_sub_basic(get_current_username(),
3965 current_user_info.domain,
3966 serviceName,sizeof(serviceName));
3967 if (strequal(serviceName, pszServiceName)) {
3968 break;
3973 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
3974 struct timespec last_mod;
3976 if (!usershare_exists(iService, &last_mod)) {
3977 /* Remove the share security tdb entry for it. */
3978 delete_share_security(lp_servicename(talloc_tos(), iService));
3979 /* Remove it from the array. */
3980 free_service_byindex(iService);
3981 /* Doesn't exist anymore. */
3982 return GLOBAL_SECTION_SNUM;
3985 /* Has it been modified ? If so delete and reload. */
3986 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3987 &last_mod) < 0) {
3988 /* Remove it from the array. */
3989 free_service_byindex(iService);
3990 /* and now reload it. */
3991 iService = load_usershare_service(pszServiceName);
3995 if (iService < 0) {
3996 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3997 return GLOBAL_SECTION_SNUM;
4000 return (iService);
4003 /*******************************************************************
4004 A useful volume label function.
4005 ********************************************************************/
4007 const char *volume_label(TALLOC_CTX *ctx, int snum)
4009 char *ret;
4010 const char *label = lp_volume(ctx, snum);
4011 if (!*label) {
4012 label = lp_servicename(ctx, snum);
4015 /* This returns a 33 byte guarenteed null terminated string. */
4016 ret = talloc_strndup(ctx, label, 32);
4017 if (!ret) {
4018 return "";
4020 return ret;
4023 /*******************************************************************
4024 Get the default server type we will announce as via nmbd.
4025 ********************************************************************/
4027 int lp_default_server_announce(void)
4029 int default_server_announce = 0;
4030 default_server_announce |= SV_TYPE_WORKSTATION;
4031 default_server_announce |= SV_TYPE_SERVER;
4032 default_server_announce |= SV_TYPE_SERVER_UNIX;
4034 /* note that the flag should be set only if we have a
4035 printer service but nmbd doesn't actually load the
4036 services so we can't tell --jerry */
4038 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4040 default_server_announce |= SV_TYPE_SERVER_NT;
4041 default_server_announce |= SV_TYPE_NT;
4043 switch (lp_server_role()) {
4044 case ROLE_DOMAIN_MEMBER:
4045 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4046 break;
4047 case ROLE_DOMAIN_PDC:
4048 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4049 break;
4050 case ROLE_DOMAIN_BDC:
4051 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4052 break;
4053 case ROLE_STANDALONE:
4054 default:
4055 break;
4057 if (lp_time_server())
4058 default_server_announce |= SV_TYPE_TIME_SOURCE;
4060 if (lp_host_msdfs())
4061 default_server_announce |= SV_TYPE_DFS_SERVER;
4063 return default_server_announce;
4066 /***********************************************************
4067 If we are PDC then prefer us as DMB
4068 ************************************************************/
4070 bool lp_domain_master(void)
4072 if (Globals._domain_master == Auto)
4073 return (lp_server_role() == ROLE_DOMAIN_PDC);
4075 return (bool)Globals._domain_master;
4078 /***********************************************************
4079 If we are PDC then prefer us as DMB
4080 ************************************************************/
4082 static bool lp_domain_master_true_or_auto(void)
4084 if (Globals._domain_master) /* auto or yes */
4085 return true;
4087 return false;
4090 /***********************************************************
4091 If we are DMB then prefer us as LMB
4092 ************************************************************/
4094 bool lp_preferred_master(void)
4096 if (Globals.iPreferredMaster == Auto)
4097 return (lp_local_master() && lp_domain_master());
4099 return (bool)Globals.iPreferredMaster;
4102 /*******************************************************************
4103 Remove a service.
4104 ********************************************************************/
4106 void lp_remove_service(int snum)
4108 ServicePtrs[snum]->valid = false;
4111 const char *lp_printername(TALLOC_CTX *ctx, int snum)
4113 const char *ret = lp__printername(ctx, snum);
4114 if (ret == NULL || *ret == '\0') {
4115 ret = lp_const_servicename(snum);
4118 return ret;
4122 /***********************************************************
4123 Allow daemons such as winbindd to fix their logfile name.
4124 ************************************************************/
4126 void lp_set_logfile(const char *name)
4128 string_set(Globals.ctx, &Globals.logfile, name);
4129 debug_set_logfile(name);
4132 /*******************************************************************
4133 Return the max print jobs per queue.
4134 ********************************************************************/
4136 int lp_maxprintjobs(int snum)
4138 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4139 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4140 maxjobs = PRINT_MAX_JOBID - 1;
4142 return maxjobs;
4145 const char *lp_printcapname(void)
4147 if ((Globals.szPrintcapname != NULL) &&
4148 (Globals.szPrintcapname[0] != '\0'))
4149 return Globals.szPrintcapname;
4151 if (sDefault.printing == PRINT_CUPS) {
4152 return "cups";
4155 if (sDefault.printing == PRINT_BSD)
4156 return "/etc/printcap";
4158 return PRINTCAP_NAME;
4161 static uint32 spoolss_state;
4163 bool lp_disable_spoolss( void )
4165 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4166 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4168 return spoolss_state == SVCCTL_STOPPED ? true : false;
4171 void lp_set_spoolss_state( uint32 state )
4173 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4175 spoolss_state = state;
4178 uint32 lp_get_spoolss_state( void )
4180 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4183 /*******************************************************************
4184 Ensure we don't use sendfile if server smb signing is active.
4185 ********************************************************************/
4187 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
4189 bool sign_active = false;
4191 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4192 if (get_Protocol() < PROTOCOL_NT1) {
4193 return false;
4195 if (signing_state) {
4196 sign_active = smb_signing_is_active(signing_state);
4198 return (lp__use_sendfile(snum) &&
4199 (get_remote_arch() != RA_WIN95) &&
4200 !sign_active);
4203 /*******************************************************************
4204 Turn off sendfile if we find the underlying OS doesn't support it.
4205 ********************************************************************/
4207 void set_use_sendfile(int snum, bool val)
4209 if (LP_SNUM_OK(snum))
4210 ServicePtrs[snum]->_use_sendfile = val;
4211 else
4212 sDefault._use_sendfile = val;
4215 /*******************************************************************
4216 Turn off storing DOS attributes if this share doesn't support it.
4217 ********************************************************************/
4219 void set_store_dos_attributes(int snum, bool val)
4221 if (!LP_SNUM_OK(snum))
4222 return;
4223 ServicePtrs[(snum)]->store_dos_attributes = val;
4226 void lp_set_mangling_method(const char *new_method)
4228 string_set(Globals.ctx, &Globals.mangling_method, new_method);
4231 /*******************************************************************
4232 Global state for POSIX pathname processing.
4233 ********************************************************************/
4235 static bool posix_pathnames;
4237 bool lp_posix_pathnames(void)
4239 return posix_pathnames;
4242 /*******************************************************************
4243 Change everything needed to ensure POSIX pathname processing (currently
4244 not much).
4245 ********************************************************************/
4247 void lp_set_posix_pathnames(void)
4249 posix_pathnames = true;
4252 /*******************************************************************
4253 Global state for POSIX lock processing - CIFS unix extensions.
4254 ********************************************************************/
4256 bool posix_default_lock_was_set;
4257 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4259 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4261 if (posix_default_lock_was_set) {
4262 return posix_cifsx_locktype;
4263 } else {
4264 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
4268 /*******************************************************************
4269 ********************************************************************/
4271 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4273 posix_default_lock_was_set = true;
4274 posix_cifsx_locktype = val;
4277 int lp_min_receive_file_size(void)
4279 if (Globals.iminreceivefile < 0) {
4280 return 0;
4282 return Globals.iminreceivefile;
4285 /*******************************************************************
4286 Safe wide links checks.
4287 This helper function always verify the validity of wide links,
4288 even after a configuration file reload.
4289 ********************************************************************/
4291 static bool lp_widelinks_internal(int snum)
4293 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
4294 sDefault.bWidelinks);
4297 void widelinks_warning(int snum)
4299 if (lp_allow_insecure_wide_links()) {
4300 return;
4303 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
4304 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4305 "These parameters are incompatible. "
4306 "Wide links will be disabled for this share.\n",
4307 lp_servicename(talloc_tos(), snum) ));
4311 bool lp_widelinks(int snum)
4313 /* wide links is always incompatible with unix extensions */
4314 if (lp_unix_extensions()) {
4316 * Unless we have "allow insecure widelinks"
4317 * turned on.
4319 if (!lp_allow_insecure_wide_links()) {
4320 return false;
4324 return lp_widelinks_internal(snum);
4327 int lp_server_role(void)
4329 return lp_find_server_role(lp__server_role(),
4330 lp__security(),
4331 lp__domain_logons(),
4332 lp_domain_master_true_or_auto());
4335 int lp_security(void)
4337 return lp_find_security(lp__server_role(),
4338 lp__security());
4341 int lp_client_max_protocol(void)
4343 int client_max_protocol = lp__client_max_protocol();
4344 if (client_max_protocol == PROTOCOL_DEFAULT) {
4345 return PROTOCOL_NT1;
4347 return client_max_protocol;
4350 int lp_winbindd_max_protocol(void)
4352 int client_max_protocol = lp__client_max_protocol();
4353 if (client_max_protocol == PROTOCOL_DEFAULT) {
4354 return PROTOCOL_LATEST;
4356 return client_max_protocol;
4359 struct loadparm_global * get_globals(void)
4361 return &Globals;
4364 unsigned int * get_flags(void)
4366 if (flags_list == NULL) {
4367 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());
4370 return flags_list;