param: use a single special handler for idmap parameters
[Samba.git] / source3 / param / loadparm.c
blobd5f7bacf1b05f6f512513e5c1cd09791f2997f20
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_sync = false,
210 .mangling_char = '~',
211 .copymap = NULL,
212 .delete_readonly = false,
213 .fake_oplocks = false,
214 .delete_veto_files = false,
215 .dos_filemode = false,
216 .dos_filetimes = true,
217 .dos_filetime_resolution = false,
218 .fake_directory_create_times = false,
219 .blocking_locks = true,
220 .inherit_permissions = false,
221 .inherit_acls = false,
222 .inherit_owner = false,
223 .msdfs_root = false,
224 .use_client_driver = false,
225 .default_devmode = true,
226 .force_printername = false,
227 .nt_acl_support = true,
228 .force_unknown_acl_user = false,
229 ._use_sendfile = false,
230 .profile_acls = false,
231 .map_acl_inherit = false,
232 .afs_share = false,
233 .ea_support = false,
234 .acl_check_permissions = true,
235 .acl_map_full_control = true,
236 .acl_group_control = false,
237 .acl_allow_execute_always = false,
238 .change_notify = true,
239 .kernel_change_notify = true,
240 .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
241 .aio_read_size = 0,
242 .aio_write_size = 0,
243 .map_readonly = MAP_READONLY_YES,
244 .directory_name_cache_size = 100,
245 .smb_encrypt = SMB_SIGNING_DEFAULT,
246 .kernel_share_modes = true,
247 .durable_handles = true,
248 .param_opt = NULL,
249 .dummy = ""
252 /* local variables */
253 static struct loadparm_service **ServicePtrs = NULL;
254 static int iNumServices = 0;
255 static int iServiceIndex = 0;
256 static struct db_context *ServiceHash;
257 static bool bInGlobalSection = true;
258 static bool bGlobalOnly = false;
259 static struct file_lists *file_lists = NULL;
261 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
263 static void set_allowed_client_auth(void);
265 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
266 static void free_param_opts(struct parmlist_entry **popts);
268 #include "lib/param/param_table.c"
270 /* this is used to prevent lots of mallocs of size 1 */
271 static const char null_string[] = "";
274 Free a string value.
277 static void string_free(char **s)
279 if (!s || !(*s))
280 return;
281 if (*s == null_string)
282 *s = NULL;
283 TALLOC_FREE(*s);
287 Set a string value, deallocating any existing space, and allocing the space
288 for the string
291 static bool string_set(TALLOC_CTX *mem_ctx, char **dest,const char *src)
293 string_free(dest);
295 if (!src) {
296 src = "";
299 (*dest) = talloc_strdup(mem_ctx, src);
300 if ((*dest) == NULL) {
301 DEBUG(0,("Out of memory in string_init\n"));
302 return false;
305 return true;
308 bool lp_string_set(char **dest, const char *src) {
309 return string_set(Globals.ctx, dest, src);
312 /***************************************************************************
313 Initialise the sDefault parameter structure for the printer values.
314 ***************************************************************************/
316 void init_printer_values(TALLOC_CTX *ctx, struct loadparm_service *pService)
318 /* choose defaults depending on the type of printing */
319 switch (pService->printing) {
320 case PRINT_BSD:
321 case PRINT_AIX:
322 case PRINT_LPRNT:
323 case PRINT_LPROS2:
324 lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
325 lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
326 lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
327 break;
329 case PRINT_LPRNG:
330 case PRINT_PLP:
331 lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
332 lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
333 lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
334 lpcfg_string_set(ctx, &pService->queuepause_command, "lpc stop '%p'");
335 lpcfg_string_set(ctx, &pService->queueresume_command, "lpc start '%p'");
336 lpcfg_string_set(ctx, &pService->lppause_command, "lpc hold '%p' %j");
337 lpcfg_string_set(ctx, &pService->lpresume_command, "lpc release '%p' %j");
338 break;
340 case PRINT_CUPS:
341 case PRINT_IPRINT:
342 /* set the lpq command to contain the destination printer
343 name only. This is used by cups_queue_get() */
344 lpcfg_string_set(ctx, &pService->lpq_command, "%p");
345 lpcfg_string_set(ctx, &pService->lprm_command, "");
346 lpcfg_string_set(ctx, &pService->print_command, "");
347 lpcfg_string_set(ctx, &pService->lppause_command, "");
348 lpcfg_string_set(ctx, &pService->lpresume_command, "");
349 lpcfg_string_set(ctx, &pService->queuepause_command, "");
350 lpcfg_string_set(ctx, &pService->queueresume_command, "");
351 break;
353 case PRINT_SYSV:
354 case PRINT_HPUX:
355 lpcfg_string_set(ctx, &pService->lpq_command, "lpstat -o%p");
356 lpcfg_string_set(ctx, &pService->lprm_command, "cancel %p-%j");
357 lpcfg_string_set(ctx, &pService->print_command, "lp -c -d%p %s; rm %s");
358 lpcfg_string_set(ctx, &pService->queuepause_command, "disable %p");
359 lpcfg_string_set(ctx, &pService->queueresume_command, "enable %p");
360 #ifndef HPUX
361 lpcfg_string_set(ctx, &pService->lppause_command, "lp -i %p-%j -H hold");
362 lpcfg_string_set(ctx, &pService->lpresume_command, "lp -i %p-%j -H resume");
363 #endif /* HPUX */
364 break;
366 case PRINT_QNX:
367 lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P%p");
368 lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P%p %j");
369 lpcfg_string_set(ctx, &pService->print_command, "lp -r -P%p %s");
370 break;
372 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
374 case PRINT_TEST:
375 case PRINT_VLP: {
376 const char *tdbfile;
377 TALLOC_CTX *tmp_ctx = talloc_new(ctx);
378 char *tmp;
380 tdbfile = talloc_asprintf(
381 tmp_ctx, "tdbfile=%s",
382 lp_parm_const_string(-1, "vlp", "tdbfile",
383 "/tmp/vlp.tdb"));
384 if (tdbfile == NULL) {
385 tdbfile="tdbfile=/tmp/vlp.tdb";
388 tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
389 tdbfile);
390 lpcfg_string_set(ctx, &pService->print_command,
391 tmp ? tmp : "vlp print %p %s");
393 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
394 tdbfile);
395 lpcfg_string_set(ctx, &pService->lpq_command,
396 tmp ? tmp : "vlp lpq %p");
398 tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
399 tdbfile);
400 lpcfg_string_set(ctx, &pService->lprm_command,
401 tmp ? tmp : "vlp lprm %p %j");
403 tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
404 tdbfile);
405 lpcfg_string_set(ctx, &pService->lppause_command,
406 tmp ? tmp : "vlp lppause %p %j");
408 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
409 tdbfile);
410 lpcfg_string_set(ctx, &pService->lpresume_command,
411 tmp ? tmp : "vlp lpresume %p %j");
413 tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
414 tdbfile);
415 lpcfg_string_set(ctx, &pService->queuepause_command,
416 tmp ? tmp : "vlp queuepause %p");
418 tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
419 tdbfile);
420 lpcfg_string_set(ctx, &pService->queueresume_command,
421 tmp ? tmp : "vlp queueresume %p");
422 TALLOC_FREE(tmp_ctx);
424 break;
426 #endif /* DEVELOPER */
431 * Function to return the default value for the maximum number of open
432 * file descriptors permitted. This function tries to consult the
433 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
434 * the smaller of those.
436 static int max_open_files(void)
438 int sysctl_max = MAX_OPEN_FILES;
439 int rlimit_max = MAX_OPEN_FILES;
441 #ifdef HAVE_SYSCTLBYNAME
443 size_t size = sizeof(sysctl_max);
444 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
447 #endif
449 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
451 struct rlimit rl;
453 ZERO_STRUCT(rl);
455 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
456 rlimit_max = rl.rlim_cur;
458 #if defined(RLIM_INFINITY)
459 if(rl.rlim_cur == RLIM_INFINITY)
460 rlimit_max = MAX_OPEN_FILES;
461 #endif
463 #endif
465 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
466 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
467 "minimum Windows limit (%d)\n",
468 sysctl_max,
469 MIN_OPEN_FILES_WINDOWS));
470 sysctl_max = MIN_OPEN_FILES_WINDOWS;
473 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
474 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
475 "minimum Windows limit (%d)\n",
476 rlimit_max,
477 MIN_OPEN_FILES_WINDOWS));
478 rlimit_max = MIN_OPEN_FILES_WINDOWS;
481 return MIN(sysctl_max, rlimit_max);
485 * Common part of freeing allocated data for one parameter.
487 static void free_one_parameter_common(void *parm_ptr,
488 struct parm_struct parm)
490 if ((parm.type == P_STRING) ||
491 (parm.type == P_USTRING))
493 string_free((char**)parm_ptr);
494 } else if (parm.type == P_LIST) {
495 TALLOC_FREE(*((char***)parm_ptr));
500 * Free the allocated data for one parameter for a share
501 * given as a service struct.
503 static void free_one_parameter(struct loadparm_service *service,
504 struct parm_struct parm)
506 void *parm_ptr;
508 if (parm.p_class != P_LOCAL) {
509 return;
512 parm_ptr = lp_parm_ptr(service, &parm);
514 free_one_parameter_common(parm_ptr, parm);
518 * Free the allocated parameter data of a share given
519 * as a service struct.
521 static void free_parameters(struct loadparm_service *service)
523 uint32_t i;
525 for (i=0; parm_table[i].label; i++) {
526 free_one_parameter(service, parm_table[i]);
531 * Free the allocated data for one parameter for a given share
532 * specified by an snum.
534 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
536 void *parm_ptr;
538 if (snum < 0) {
539 parm_ptr = lp_parm_ptr(NULL, &parm);
540 } else if (parm.p_class != P_LOCAL) {
541 return;
542 } else {
543 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
546 free_one_parameter_common(parm_ptr, parm);
550 * Free the allocated parameter data for a share specified
551 * by an snum.
553 static void free_parameters_by_snum(int snum)
555 uint32_t i;
557 for (i=0; parm_table[i].label; i++) {
558 free_one_parameter_by_snum(snum, parm_table[i]);
563 * Free the allocated global parameters.
565 static void free_global_parameters(void)
567 free_param_opts(&Globals.param_opt);
568 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
569 TALLOC_FREE(Globals.ctx);
572 struct lp_stored_option {
573 struct lp_stored_option *prev, *next;
574 const char *label;
575 const char *value;
578 static struct lp_stored_option *stored_options;
581 save options set by lp_set_cmdline() into a list. This list is
582 re-applied when we do a globals reset, so that cmdline set options
583 are sticky across reloads of smb.conf
585 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
587 struct lp_stored_option *entry, *entry_next;
588 for (entry = stored_options; entry != NULL; entry = entry_next) {
589 entry_next = entry->next;
590 if (strcmp(pszParmName, entry->label) == 0) {
591 DLIST_REMOVE(stored_options, entry);
592 talloc_free(entry);
593 break;
597 entry = talloc(NULL, struct lp_stored_option);
598 if (!entry) {
599 return false;
602 entry->label = talloc_strdup(entry, pszParmName);
603 if (!entry->label) {
604 talloc_free(entry);
605 return false;
608 entry->value = talloc_strdup(entry, pszParmValue);
609 if (!entry->value) {
610 talloc_free(entry);
611 return false;
614 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
616 return true;
619 static bool apply_lp_set_cmdline(void)
621 struct lp_stored_option *entry = NULL;
622 for (entry = stored_options; entry != NULL; entry = entry->next) {
623 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
624 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
625 entry->label, entry->value));
626 return false;
629 return true;
632 /***************************************************************************
633 Initialise the global parameter structure.
634 ***************************************************************************/
636 static void init_globals(bool reinit_globals)
638 static bool done_init = false;
639 char *s = NULL;
640 int i;
642 /* If requested to initialize only once and we've already done it... */
643 if (!reinit_globals && done_init) {
644 /* ... then we have nothing more to do */
645 return;
648 if (!done_init) {
649 /* The logfile can be set before this is invoked. Free it if so. */
650 if (Globals.logfile != NULL) {
651 string_free(&Globals.logfile);
652 Globals.logfile = NULL;
654 done_init = true;
655 } else {
656 free_global_parameters();
659 /* This memset and the free_global_parameters() above will
660 * wipe out smb.conf options set with lp_set_cmdline(). The
661 * apply_lp_set_cmdline() call puts these values back in the
662 * table once the defaults are set */
663 ZERO_STRUCT(Globals);
665 Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
667 for (i = 0; parm_table[i].label; i++) {
668 if ((parm_table[i].type == P_STRING ||
669 parm_table[i].type == P_USTRING))
671 string_set(Globals.ctx, (char **)lp_parm_ptr(NULL, &parm_table[i]), "");
676 string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
677 string_set(Globals.ctx, &sDefault.printjob_username, "%U");
679 init_printer_values(Globals.ctx, &sDefault);
681 sDefault.ntvfs_handler = (const char **)str_list_make_v3(NULL, "unixuid default", NULL);
683 DEBUG(3, ("Initialising global parameters\n"));
685 /* Must manually force to upper case here, as this does not go via the handler */
686 string_set(Globals.ctx, &Globals.netbios_name, myhostname_upper());
688 string_set(Globals.ctx, &Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE());
689 string_set(Globals.ctx, &Globals.private_dir, get_dyn_PRIVATE_DIR());
691 /* use the new 'hash2' method by default, with a prefix of 1 */
692 string_set(Globals.ctx, &Globals.mangling_method, "hash2");
693 Globals.mangle_prefix = 1;
695 string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
697 /* using UTF8 by default allows us to support all chars */
698 string_set(Globals.ctx, &Globals.unix_charset, DEFAULT_UNIX_CHARSET);
700 /* Use codepage 850 as a default for the dos character set */
701 string_set(Globals.ctx, &Globals.dos_charset, DEFAULT_DOS_CHARSET);
704 * Allow the default PASSWD_CHAT to be overridden in local.h.
706 string_set(Globals.ctx, &Globals.passwd_chat, DEFAULT_PASSWD_CHAT);
708 string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
710 string_set(Globals.ctx, &Globals.passwd_program, "");
711 string_set(Globals.ctx, &Globals.lock_directory, get_dyn_LOCKDIR());
712 string_set(Globals.ctx, &Globals.state_directory, get_dyn_STATEDIR());
713 string_set(Globals.ctx, &Globals.cache_directory, get_dyn_CACHEDIR());
714 string_set(Globals.ctx, &Globals.pid_directory, get_dyn_PIDDIR());
715 string_set(Globals.ctx, &Globals.nbt_client_socket_address, "0.0.0.0");
717 * By default support explicit binding to broadcast
718 * addresses.
720 Globals.nmbd_bind_explicit_broadcast = true;
722 s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
723 if (s == NULL) {
724 smb_panic("init_globals: ENOMEM");
726 string_set(Globals.ctx, &Globals.server_string, s);
727 TALLOC_FREE(s);
728 #ifdef DEVELOPER
729 string_set(Globals.ctx, &Globals.panic_action, "/bin/sleep 999999999");
730 #endif
732 string_set(Globals.ctx, &Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
734 string_set(Globals.ctx, &Globals.logon_drive, "");
735 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
736 string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
737 string_set(Globals.ctx, &Globals.logon_path, "\\\\%N\\%U\\profile");
739 Globals.name_resolve_order = (const char **)str_list_make_v3(NULL, "lmhosts wins host bcast", NULL);
740 string_set(Globals.ctx, &Globals.password_server, "*");
742 Globals.algorithmic_rid_base = BASE_RID;
744 Globals.load_printers = true;
745 Globals.printcap_cache_time = 750; /* 12.5 minutes */
747 Globals.config_backend = config_backend;
748 Globals._server_role = ROLE_AUTO;
750 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
751 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
752 Globals.max_xmit = 0x4104;
753 Globals.max_mux = 50; /* This is *needed* for profile support. */
754 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
755 Globals._disable_spoolss = false;
756 Globals.max_smbd_processes = 0;/* no limit specified */
757 Globals.username_level = 0;
758 Globals.deadtime = 0;
759 Globals.getwd_cache = true;
760 Globals.large_readwrite = true;
761 Globals.max_log_size = 5000;
762 Globals.max_open_files = max_open_files();
763 Globals.server_max_protocol = PROTOCOL_SMB3_00;
764 Globals.server_min_protocol = PROTOCOL_LANMAN1;
765 Globals.client_max_protocol = PROTOCOL_NT1;
766 Globals.client_min_protocol = PROTOCOL_CORE;
767 Globals._security = SEC_AUTO;
768 Globals.encrypt_passwords = true;
769 Globals.client_schannel = Auto;
770 Globals.winbind_sealed_pipes = true;
771 Globals.require_strong_key = true;
772 Globals.server_schannel = Auto;
773 Globals.read_raw = true;
774 Globals.write_raw = true;
775 Globals.null_passwords = false;
776 Globals.old_password_allowed_period = 60;
777 Globals.obey_pam_restrictions = false;
778 Globals.syslog = 1;
779 Globals.syslog_only = false;
780 Globals.timestamp_logs = true;
781 string_set(Globals.ctx, &Globals.log_level, "0");
782 Globals.debug_prefix_timestamp = false;
783 Globals.debug_hires_timestamp = true;
784 Globals.debug_pid = false;
785 Globals.debug_uid = false;
786 Globals.debug_class = false;
787 Globals.enable_core_files = true;
788 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
789 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
790 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
791 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
792 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
793 Globals.lm_interval = 60;
794 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
795 Globals.nis_homedir = false;
796 #ifdef WITH_NISPLUS_HOME
797 string_set(Globals.ctx, &Globals.homedir_map, "auto_home.org_dir");
798 #else
799 string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
800 #endif
801 #endif
802 Globals.time_server = false;
803 Globals.bind_interfaces_only = false;
804 Globals.unix_password_sync = false;
805 Globals.pam_password_change = false;
806 Globals.passwd_chat_debug = false;
807 Globals.passwd_chat_timeout = 2; /* 2 second default. */
808 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
809 Globals.nt_status_support = true; /* Use NT status by default. */
810 Globals.stat_cache = true; /* use stat cache by default */
811 Globals.max_stat_cache_size = 256; /* 256k by default */
812 Globals.restrict_anonymous = 0;
813 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
814 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
815 Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
816 Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
817 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 */
818 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
820 Globals.map_to_guest = 0; /* By Default, "Never" */
821 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
822 Globals.enhanced_browsing = true;
823 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
824 #ifdef MMAP_BLACKLIST
825 Globals.use_mmap = false;
826 #else
827 Globals.use_mmap = true;
828 #endif
829 Globals.unicode = true;
830 Globals.unix_extensions = true;
831 Globals.reset_on_zero_vc = false;
832 Globals.log_writeable_files_on_exit = false;
833 Globals.create_krb5_conf = true;
834 Globals.winbindMaxDomainConnections = 1;
836 /* hostname lookups can be very expensive and are broken on
837 a large number of sites (tridge) */
838 Globals.hostname_lookups = false;
840 string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
841 string_set(Globals.ctx, &Globals.ldap_suffix, "");
842 string_set(Globals.ctx, &Globals.szLdapMachineSuffix, "");
843 string_set(Globals.ctx, &Globals.szLdapUserSuffix, "");
844 string_set(Globals.ctx, &Globals.szLdapGroupSuffix, "");
845 string_set(Globals.ctx, &Globals.szLdapIdmapSuffix, "");
847 string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
848 Globals.ldap_ssl = LDAP_SSL_START_TLS;
849 Globals.ldap_ssl_ads = false;
850 Globals.ldap_deref = -1;
851 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
852 Globals.ldap_delete_dn = false;
853 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
854 Globals.ldap_follow_referral = Auto;
855 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
856 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
857 Globals.ldap_page_size = LDAP_PAGE_SIZE;
859 Globals.ldap_debug_level = 0;
860 Globals.ldap_debug_threshold = 10;
862 /* This is what we tell the afs client. in reality we set the token
863 * to never expire, though, when this runs out the afs client will
864 * forget the token. Set to 0 to get NEVERDATE.*/
865 Globals.afs_token_lifetime = 604800;
866 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
868 /* these parameters are set to defaults that are more appropriate
869 for the increasing samba install base:
871 as a member of the workgroup, that will possibly become a
872 _local_ master browser (lm = true). this is opposed to a forced
873 local master browser startup (pm = true).
875 doesn't provide WINS server service by default (wsupp = false),
876 and doesn't provide domain master browser services by default, either.
880 Globals.show_add_printer_wizard = true;
881 Globals.os_level = 20;
882 Globals.local_master = true;
883 Globals._domain_master = Auto; /* depending on _domain_logons */
884 Globals._domain_logons = false;
885 Globals.browse_list = true;
886 Globals.we_are_a_wins_server = false;
887 Globals.wins_proxy = false;
889 TALLOC_FREE(Globals.init_logon_delayed_hosts);
890 Globals.init_logon_delay = 100; /* 100 ms default delay */
892 Globals.wins_dns_proxy = true;
894 Globals.allow_trusted_domains = true;
895 string_set(Globals.ctx, &Globals.szIdmapBackend, "tdb");
897 string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
898 string_set(Globals.ctx, &Globals.template_homedir, "/home/%D/%U");
899 string_set(Globals.ctx, &Globals.winbind_separator, "\\");
900 string_set(Globals.ctx, &Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
902 string_set(Globals.ctx, &Globals.cups_server, "");
903 string_set(Globals.ctx, &Globals.iprint_server, "");
905 string_set(Globals.ctx, &Globals._ctdbd_socket, "");
907 Globals.cluster_addresses = NULL;
908 Globals.clustering = false;
909 Globals.ctdb_timeout = 0;
910 Globals.ctdb_locktime_warn_threshold = 0;
912 Globals.winbind_cache_time = 300; /* 5 minutes */
913 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
914 Globals.winbind_max_clients = 200;
915 Globals.winbind_enum_users = false;
916 Globals.winbind_enum_groups = false;
917 Globals.winbind_use_default_domain = false;
918 Globals.winbind_trusted_domains_only = false;
919 Globals.winbind_nested_groups = true;
920 Globals.winbind_expand_groups = 1;
921 Globals.winbind_nss_info = (const char **)str_list_make_v3(NULL, "template", NULL);
922 Globals.winbind_refresh_tickets = false;
923 Globals.winbind_offline_logon = false;
925 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
926 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
928 Globals.passdb_expand_explicit = false;
930 Globals.name_cache_timeout = 660; /* In seconds */
932 Globals.use_spnego = true;
933 Globals.client_use_spnego = true;
935 Globals.client_signing = SMB_SIGNING_DEFAULT;
936 Globals.server_signing = SMB_SIGNING_DEFAULT;
938 Globals.defer_sharing_violations = true;
939 Globals.smb_ports = (const char **)str_list_make_v3(NULL, SMB_PORTS, NULL);
941 Globals.enable_privileges = true;
942 Globals.host_msdfs = true;
943 Globals.enable_asu_support = false;
945 /* User defined shares. */
946 s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
947 if (s == NULL) {
948 smb_panic("init_globals: ENOMEM");
950 string_set(Globals.ctx, &Globals.usershare_path, s);
951 TALLOC_FREE(s);
952 string_set(Globals.ctx, &Globals.usershare_template_share, "");
953 Globals.usershare_max_shares = 0;
954 /* By default disallow sharing of directories not owned by the sharer. */
955 Globals.usershare_owner_only = true;
956 /* By default disallow guest access to usershares. */
957 Globals.usershare_allow_guests = false;
959 Globals.keepalive = DEFAULT_KEEPALIVE;
961 /* By default no shares out of the registry */
962 Globals.registry_shares = false;
964 Globals.iminreceivefile = 0;
966 Globals.map_untrusted_to_domain = false;
967 Globals.multicast_dns_register = true;
969 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
970 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
971 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
972 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
974 string_set(Globals.ctx, &Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
976 Globals.server_services = (const char **)str_list_make_v3(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbind ntp_signd kcc dnsupdate dns", NULL);
978 Globals.dcerpc_endpoint_servers = (const char **)str_list_make_v3(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
980 Globals.tls_enabled = true;
982 string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
983 string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
984 string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
986 string_set(Globals.ctx, &Globals.share_backend, "classic");
988 Globals.iPreferredMaster = Auto;
990 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
992 string_set(Globals.ctx, &Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR());
994 string_set(Globals.ctx, &Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
996 s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
997 if (s == NULL) {
998 smb_panic("init_globals: ENOMEM");
1000 Globals.samba_kcc_command = (const char **)str_list_make_v3(NULL, s, NULL);
1001 TALLOC_FREE(s);
1003 s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
1004 if (s == NULL) {
1005 smb_panic("init_globals: ENOMEM");
1007 Globals.dns_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
1008 TALLOC_FREE(s);
1010 s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
1011 if (s == NULL) {
1012 smb_panic("init_globals: ENOMEM");
1014 Globals.spn_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
1015 TALLOC_FREE(s);
1017 Globals.nsupdate_command = (const char **)str_list_make_v3(NULL, "/usr/bin/nsupdate -g", NULL);
1019 Globals.rndc_command = (const char **)str_list_make_v3(NULL, "/usr/sbin/rndc", NULL);
1021 Globals.cldap_port = 389;
1023 Globals.dgram_port = 138;
1025 Globals.nbt_port = 137;
1027 Globals.krb5_port = 88;
1029 Globals.kpasswd_port = 464;
1031 Globals.web_port = 901;
1033 /* Now put back the settings that were set with lp_set_cmdline() */
1034 apply_lp_set_cmdline();
1037 /*******************************************************************
1038 Convenience routine to grab string parameters into talloced memory
1039 and run standard_sub_basic on them. The buffers can be written to by
1040 callers without affecting the source string.
1041 ********************************************************************/
1043 char *lp_string(TALLOC_CTX *ctx, const char *s)
1045 char *ret;
1047 /* The follow debug is useful for tracking down memory problems
1048 especially if you have an inner loop that is calling a lp_*()
1049 function that returns a string. Perhaps this debug should be
1050 present all the time? */
1052 #if 0
1053 DEBUG(10, ("lp_string(%s)\n", s));
1054 #endif
1055 if (!s) {
1056 return NULL;
1059 ret = talloc_sub_basic(ctx,
1060 get_current_username(),
1061 current_user_info.domain,
1063 if (trim_char(ret, '\"', '\"')) {
1064 if (strchr(ret,'\"') != NULL) {
1065 TALLOC_FREE(ret);
1066 ret = talloc_sub_basic(ctx,
1067 get_current_username(),
1068 current_user_info.domain,
1072 return ret;
1076 In this section all the functions that are used to access the
1077 parameters from the rest of the program are defined
1080 #define FN_GLOBAL_STRING(fn_name,ptr) \
1081 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1082 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1083 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1084 #define FN_GLOBAL_LIST(fn_name,ptr) \
1085 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1086 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1087 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1088 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1089 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1090 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1091 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1093 #define FN_LOCAL_STRING(fn_name,val) \
1094 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));}
1095 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1096 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1097 #define FN_LOCAL_LIST(fn_name,val) \
1098 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1099 #define FN_LOCAL_BOOL(fn_name,val) \
1100 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1101 #define FN_LOCAL_INTEGER(fn_name,val) \
1102 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1104 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1105 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1106 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1107 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1108 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1109 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1111 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
1112 winbindMaxDomainConnections)
1114 int lp_winbind_max_domain_connections(void)
1116 if (lp_winbind_offline_logon() &&
1117 lp_winbind_max_domain_connections_int() > 1) {
1118 DEBUG(1, ("offline logons active, restricting max domain "
1119 "connections to 1\n"));
1120 return 1;
1122 return MAX(1, lp_winbind_max_domain_connections_int());
1125 int lp_smb2_max_credits(void)
1127 if (Globals.ismb2_max_credits == 0) {
1128 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1130 return Globals.ismb2_max_credits;
1132 int lp_cups_encrypt(void)
1134 int result = 0;
1135 #ifdef HAVE_HTTPCONNECTENCRYPT
1136 switch (Globals.CupsEncrypt) {
1137 case Auto:
1138 result = HTTP_ENCRYPT_REQUIRED;
1139 break;
1140 case true:
1141 result = HTTP_ENCRYPT_ALWAYS;
1142 break;
1143 case false:
1144 result = HTTP_ENCRYPT_NEVER;
1145 break;
1147 #endif
1148 return result;
1151 /* These functions remain in source3/param for now */
1153 #include "lib/param/param_functions.c"
1155 FN_LOCAL_STRING(servicename, szService)
1156 FN_LOCAL_CONST_STRING(const_servicename, szService)
1158 /* These functions cannot be auto-generated */
1159 FN_LOCAL_BOOL(autoloaded, autoloaded)
1161 /* local prototypes */
1163 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1164 static const char *get_boolean(bool bool_value);
1165 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1166 void *userdata);
1167 static bool do_section(const char *pszSectionName, void *userdata);
1168 static bool hash_a_service(const char *name, int number);
1169 static void free_service_byindex(int iService);
1170 static void show_parameter(int parmIndex);
1171 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1174 * This is a helper function for parametrical options support. It returns a
1175 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1176 * parametrical functions are quite simple
1178 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
1179 const char *option)
1181 bool global_section = false;
1182 char* param_key;
1183 struct parmlist_entry *data;
1184 TALLOC_CTX *mem_ctx = talloc_stackframe();
1186 if (service == NULL) {
1187 data = Globals.param_opt;
1188 global_section = true;
1189 } else {
1190 data = service->param_opt;
1193 param_key = talloc_asprintf(mem_ctx, "%s:%s", type, option);
1194 if (param_key == NULL) {
1195 DEBUG(0,("asprintf failed!\n"));
1196 TALLOC_FREE(mem_ctx);
1197 return NULL;
1200 while (data) {
1201 if (strwicmp(data->key, param_key) == 0) {
1202 TALLOC_FREE(mem_ctx);
1203 return data;
1205 data = data->next;
1208 if (!global_section) {
1209 /* Try to fetch the same option but from globals */
1210 /* but only if we are not already working with Globals */
1211 data = Globals.param_opt;
1212 while (data) {
1213 if (strwicmp(data->key, param_key) == 0) {
1214 TALLOC_FREE(mem_ctx);
1215 return data;
1217 data = data->next;
1221 TALLOC_FREE(mem_ctx);
1223 return NULL;
1227 * This is a helper function for parametrical options support. It returns a
1228 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1229 * parametrical functions are quite simple
1231 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1232 const char *option)
1234 if (snum >= iNumServices) return NULL;
1236 if (snum < 0) {
1237 return get_parametrics_by_service(NULL, type, option);
1238 } else {
1239 return get_parametrics_by_service(ServicePtrs[snum], type, option);
1244 #define MISSING_PARAMETER(name) \
1245 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1247 /*******************************************************************
1248 convenience routine to return enum parameters.
1249 ********************************************************************/
1250 static int lp_enum(const char *s,const struct enum_list *_enum)
1252 int i;
1254 if (!s || !*s || !_enum) {
1255 MISSING_PARAMETER(lp_enum);
1256 return (-1);
1259 for (i=0; _enum[i].name; i++) {
1260 if (strequal(_enum[i].name,s))
1261 return _enum[i].value;
1264 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1265 return (-1);
1268 #undef MISSING_PARAMETER
1270 /* Return parametric option from a given service. Type is a part of option before ':' */
1271 /* Parametric option has following syntax: 'Type: option = value' */
1272 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1274 struct parmlist_entry *data = get_parametrics(snum, type, option);
1276 if (data == NULL||data->value==NULL) {
1277 if (def) {
1278 return lp_string(ctx, def);
1279 } else {
1280 return NULL;
1284 return lp_string(ctx, data->value);
1287 /* Return parametric option from a given service. Type is a part of option before ':' */
1288 /* Parametric option has following syntax: 'Type: option = value' */
1289 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1291 struct parmlist_entry *data = get_parametrics(snum, type, option);
1293 if (data == NULL||data->value==NULL)
1294 return def;
1296 return data->value;
1299 const char *lp_parm_const_string_service(struct loadparm_service *service,
1300 const char *type, const char *option,
1301 const char *def)
1303 struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
1305 if (data == NULL||data->value==NULL)
1306 return def;
1308 return data->value;
1312 /* Return parametric option from a given service. Type is a part of option before ':' */
1313 /* Parametric option has following syntax: 'Type: option = value' */
1315 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1317 struct parmlist_entry *data = get_parametrics(snum, type, option);
1319 if (data == NULL||data->value==NULL)
1320 return (const char **)def;
1322 if (data->list==NULL) {
1323 data->list = str_list_make_v3(NULL, data->value, NULL);
1326 return (const char **)data->list;
1329 /* Return parametric option from a given service. Type is a part of option before ':' */
1330 /* Parametric option has following syntax: 'Type: option = value' */
1332 int lp_parm_int(int snum, const char *type, const char *option, int def)
1334 struct parmlist_entry *data = get_parametrics(snum, type, option);
1336 if (data && data->value && *data->value)
1337 return lp_int(data->value);
1339 return def;
1342 /* Return parametric option from a given service. Type is a part of option before ':' */
1343 /* Parametric option has following syntax: 'Type: option = value' */
1345 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1347 struct parmlist_entry *data = get_parametrics(snum, type, option);
1349 if (data && data->value && *data->value)
1350 return lp_ulong(data->value);
1352 return def;
1355 /* Return parametric option from a given service. Type is a part of option before ':' */
1356 /* Parametric option has following syntax: 'Type: option = value' */
1358 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1360 struct parmlist_entry *data = get_parametrics(snum, type, option);
1362 if (data && data->value && *data->value)
1363 return lp_bool(data->value);
1365 return def;
1368 /* Return parametric option from a given service. Type is a part of option before ':' */
1369 /* Parametric option has following syntax: 'Type: option = value' */
1371 int lp_parm_enum(int snum, const char *type, const char *option,
1372 const struct enum_list *_enum, int def)
1374 struct parmlist_entry *data = get_parametrics(snum, type, option);
1376 if (data && data->value && *data->value && _enum)
1377 return lp_enum(data->value, _enum);
1379 return def;
1383 * free a param_opts structure.
1384 * param_opts handling should be moved to talloc;
1385 * then this whole functions reduces to a TALLOC_FREE().
1388 static void free_param_opts(struct parmlist_entry **popts)
1390 struct parmlist_entry *opt, *next_opt;
1392 if (*popts != NULL) {
1393 DEBUG(5, ("Freeing parametrics:\n"));
1395 opt = *popts;
1396 while (opt != NULL) {
1397 string_free(&opt->key);
1398 string_free(&opt->value);
1399 TALLOC_FREE(opt->list);
1400 next_opt = opt->next;
1401 TALLOC_FREE(opt);
1402 opt = next_opt;
1404 *popts = NULL;
1407 /***************************************************************************
1408 Free the dynamically allocated parts of a service struct.
1409 ***************************************************************************/
1411 static void free_service(struct loadparm_service *pservice)
1413 if (!pservice)
1414 return;
1416 if (pservice->szService)
1417 DEBUG(5, ("free_service: Freeing service %s\n",
1418 pservice->szService));
1420 free_parameters(pservice);
1422 string_free(&pservice->szService);
1423 TALLOC_FREE(pservice->copymap);
1425 free_param_opts(&pservice->param_opt);
1427 ZERO_STRUCTP(pservice);
1431 /***************************************************************************
1432 remove a service indexed in the ServicePtrs array from the ServiceHash
1433 and free the dynamically allocated parts
1434 ***************************************************************************/
1436 static void free_service_byindex(int idx)
1438 if ( !LP_SNUM_OK(idx) )
1439 return;
1441 ServicePtrs[idx]->valid = false;
1443 /* we have to cleanup the hash record */
1445 if (ServicePtrs[idx]->szService) {
1446 char *canon_name = canonicalize_servicename(
1447 talloc_tos(),
1448 ServicePtrs[idx]->szService );
1450 dbwrap_delete_bystring(ServiceHash, canon_name );
1451 TALLOC_FREE(canon_name);
1454 free_service(ServicePtrs[idx]);
1455 talloc_free_children(ServicePtrs[idx]);
1458 /***************************************************************************
1459 Add a new service to the services array initialising it with the given
1460 service.
1461 ***************************************************************************/
1463 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1465 int i;
1466 int num_to_alloc = iNumServices + 1;
1467 struct loadparm_service **tsp = NULL;
1469 /* it might already exist */
1470 if (name) {
1471 i = getservicebyname(name, NULL);
1472 if (i >= 0) {
1473 return (i);
1477 /* if not, then create one */
1478 i = iNumServices;
1479 tsp = talloc_realloc(NULL, ServicePtrs, struct loadparm_service *, num_to_alloc);
1480 if (tsp == NULL) {
1481 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1482 return (-1);
1484 ServicePtrs = tsp;
1485 ServicePtrs[iNumServices] = talloc_zero(NULL, struct loadparm_service);
1486 if (!ServicePtrs[iNumServices]) {
1487 DEBUG(0,("add_a_service: out of memory!\n"));
1488 return (-1);
1490 iNumServices++;
1492 ServicePtrs[i]->valid = true;
1494 copy_service(ServicePtrs[i], pservice, NULL);
1495 if (name)
1496 string_set(ServicePtrs[i], &ServicePtrs[i]->szService, name);
1498 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1499 i, ServicePtrs[i]->szService));
1501 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1502 return (-1);
1505 return (i);
1508 /***************************************************************************
1509 Convert a string to uppercase and remove whitespaces.
1510 ***************************************************************************/
1512 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1514 char *result;
1516 if ( !src ) {
1517 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1518 return NULL;
1521 result = talloc_strdup(ctx, src);
1522 SMB_ASSERT(result != NULL);
1524 if (!strlower_m(result)) {
1525 TALLOC_FREE(result);
1526 return NULL;
1528 return result;
1531 /***************************************************************************
1532 Add a name/index pair for the services array to the hash table.
1533 ***************************************************************************/
1535 static bool hash_a_service(const char *name, int idx)
1537 char *canon_name;
1539 if ( !ServiceHash ) {
1540 DEBUG(10,("hash_a_service: creating servicehash\n"));
1541 ServiceHash = db_open_rbt(NULL);
1542 if ( !ServiceHash ) {
1543 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1544 return false;
1548 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1549 idx, name));
1551 canon_name = canonicalize_servicename(talloc_tos(), name );
1553 dbwrap_store_bystring(ServiceHash, canon_name,
1554 make_tdb_data((uint8 *)&idx, sizeof(idx)),
1555 TDB_REPLACE);
1557 TALLOC_FREE(canon_name);
1559 return true;
1562 /***************************************************************************
1563 Add a new home service, with the specified home directory, defaults coming
1564 from service ifrom.
1565 ***************************************************************************/
1567 bool lp_add_home(const char *pszHomename, int iDefaultService,
1568 const char *user, const char *pszHomedir)
1570 int i;
1572 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1573 pszHomedir[0] == '\0') {
1574 return false;
1577 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1579 if (i < 0)
1580 return false;
1582 if (!(*(ServicePtrs[iDefaultService]->path))
1583 || strequal(ServicePtrs[iDefaultService]->path,
1584 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1585 string_set(ServicePtrs[i], &ServicePtrs[i]->path, pszHomedir);
1588 if (!(*(ServicePtrs[i]->comment))) {
1589 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1590 if (comment == NULL) {
1591 return false;
1593 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1594 TALLOC_FREE(comment);
1597 /* set the browseable flag from the global default */
1599 ServicePtrs[i]->browseable = sDefault.browseable;
1600 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1602 ServicePtrs[i]->autoloaded = true;
1604 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1605 user, ServicePtrs[i]->path ));
1607 return true;
1610 /***************************************************************************
1611 Add a new service, based on an old one.
1612 ***************************************************************************/
1614 int lp_add_service(const char *pszService, int iDefaultService)
1616 if (iDefaultService < 0) {
1617 return add_a_service(&sDefault, pszService);
1620 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1623 /***************************************************************************
1624 Add the IPC service.
1625 ***************************************************************************/
1627 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1629 char *comment = NULL;
1630 int i = add_a_service(&sDefault, ipc_name);
1632 if (i < 0)
1633 return false;
1635 comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1636 Globals.server_string);
1637 if (comment == NULL) {
1638 return false;
1641 string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1642 string_set(ServicePtrs[i], &ServicePtrs[i]->username, "");
1643 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1644 string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1645 ServicePtrs[i]->max_connections = 0;
1646 ServicePtrs[i]->bAvailable = true;
1647 ServicePtrs[i]->read_only = true;
1648 ServicePtrs[i]->guest_only = false;
1649 ServicePtrs[i]->administrative_share = true;
1650 ServicePtrs[i]->guest_ok = guest_ok;
1651 ServicePtrs[i]->printable = false;
1652 ServicePtrs[i]->browseable = sDefault.browseable;
1654 DEBUG(3, ("adding IPC service\n"));
1656 TALLOC_FREE(comment);
1657 return true;
1660 /***************************************************************************
1661 Add a new printer service, with defaults coming from service iFrom.
1662 ***************************************************************************/
1664 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1666 const char *comment = "From Printcap";
1667 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1669 if (i < 0)
1670 return false;
1672 /* note that we do NOT default the availability flag to true - */
1673 /* we take it from the default service passed. This allows all */
1674 /* dynamic printers to be disabled by disabling the [printers] */
1675 /* entry (if/when the 'available' keyword is implemented!). */
1677 /* the printer name is set to the service name. */
1678 string_set(ServicePtrs[i], &ServicePtrs[i]->_printername, pszPrintername);
1679 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1681 /* set the browseable flag from the gloabl default */
1682 ServicePtrs[i]->browseable = sDefault.browseable;
1684 /* Printers cannot be read_only. */
1685 ServicePtrs[i]->read_only = false;
1686 /* No oplocks on printer services. */
1687 ServicePtrs[i]->oplocks = false;
1688 /* Printer services must be printable. */
1689 ServicePtrs[i]->printable = true;
1691 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1693 return true;
1697 /***************************************************************************
1698 Check whether the given parameter name is valid.
1699 Parametric options (names containing a colon) are considered valid.
1700 ***************************************************************************/
1702 bool lp_parameter_is_valid(const char *pszParmName)
1704 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1705 (strchr(pszParmName, ':') != NULL));
1708 /***************************************************************************
1709 Check whether the given name is the name of a global parameter.
1710 Returns true for strings belonging to parameters of class
1711 P_GLOBAL, false for all other strings, also for parametric options
1712 and strings not belonging to any option.
1713 ***************************************************************************/
1715 bool lp_parameter_is_global(const char *pszParmName)
1717 int num = lpcfg_map_parameter(pszParmName);
1719 if (num >= 0) {
1720 return (parm_table[num].p_class == P_GLOBAL);
1723 return false;
1726 /**************************************************************************
1727 Check whether the given name is the canonical name of a parameter.
1728 Returns false if it is not a valid parameter Name.
1729 For parametric options, true is returned.
1730 **************************************************************************/
1732 bool lp_parameter_is_canonical(const char *parm_name)
1734 if (!lp_parameter_is_valid(parm_name)) {
1735 return false;
1738 return (lpcfg_map_parameter(parm_name) ==
1739 map_parameter_canonical(parm_name, NULL));
1742 /**************************************************************************
1743 Determine the canonical name for a parameter.
1744 Indicate when it is an inverse (boolean) synonym instead of a
1745 "usual" synonym.
1746 **************************************************************************/
1748 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1749 bool *inverse)
1751 int num;
1753 if (!lp_parameter_is_valid(parm_name)) {
1754 *canon_parm = NULL;
1755 return false;
1758 num = map_parameter_canonical(parm_name, inverse);
1759 if (num < 0) {
1760 /* parametric option */
1761 *canon_parm = parm_name;
1762 } else {
1763 *canon_parm = parm_table[num].label;
1766 return true;
1770 /**************************************************************************
1771 Determine the canonical name for a parameter.
1772 Turn the value given into the inverse boolean expression when
1773 the synonym is an invers boolean synonym.
1775 Return true if parm_name is a valid parameter name and
1776 in case it is an invers boolean synonym, if the val string could
1777 successfully be converted to the reverse bool.
1778 Return false in all other cases.
1779 **************************************************************************/
1781 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1782 const char *val,
1783 const char **canon_parm,
1784 const char **canon_val)
1786 int num;
1787 bool inverse;
1789 if (!lp_parameter_is_valid(parm_name)) {
1790 *canon_parm = NULL;
1791 *canon_val = NULL;
1792 return false;
1795 num = map_parameter_canonical(parm_name, &inverse);
1796 if (num < 0) {
1797 /* parametric option */
1798 *canon_parm = parm_name;
1799 *canon_val = val;
1800 } else {
1801 *canon_parm = parm_table[num].label;
1802 if (inverse) {
1803 if (!lp_invert_boolean(val, canon_val)) {
1804 *canon_val = NULL;
1805 return false;
1807 } else {
1808 *canon_val = val;
1812 return true;
1815 /***************************************************************************
1816 Map a parameter's string representation to the index of the canonical
1817 form of the parameter (it might be a synonym).
1818 Returns -1 if the parameter string is not recognised.
1819 ***************************************************************************/
1821 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1823 int parm_num, canon_num;
1824 bool loc_inverse = false;
1826 parm_num = lpcfg_map_parameter(pszParmName);
1827 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
1828 /* invalid, parametric or no canidate for synonyms ... */
1829 goto done;
1832 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1833 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1834 parm_num = canon_num;
1835 goto done;
1839 done:
1840 if (inverse != NULL) {
1841 *inverse = loc_inverse;
1843 return parm_num;
1846 /***************************************************************************
1847 return true if parameter number parm1 is a synonym of parameter
1848 number parm2 (parm2 being the principal name).
1849 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1850 false otherwise.
1851 ***************************************************************************/
1853 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1855 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1856 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1857 (parm_table[parm1].flags & FLAG_HIDE) &&
1858 !(parm_table[parm2].flags & FLAG_HIDE))
1860 if (inverse != NULL) {
1861 if ((parm_table[parm1].type == P_BOOLREV) &&
1862 (parm_table[parm2].type == P_BOOL))
1864 *inverse = true;
1865 } else {
1866 *inverse = false;
1869 return true;
1871 return false;
1874 /***************************************************************************
1875 Show one parameter's name, type, [values,] and flags.
1876 (helper functions for show_parameter_list)
1877 ***************************************************************************/
1879 static void show_parameter(int parmIndex)
1881 int enumIndex, flagIndex;
1882 int parmIndex2;
1883 bool hadFlag;
1884 bool hadSyn;
1885 bool inverse;
1886 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1887 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1888 "P_ENUM", "P_SEP"};
1889 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
1890 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
1891 FLAG_HIDE};
1892 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
1893 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
1894 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
1896 printf("%s=%s", parm_table[parmIndex].label,
1897 type[parm_table[parmIndex].type]);
1898 if (parm_table[parmIndex].type == P_ENUM) {
1899 printf(",");
1900 for (enumIndex=0;
1901 parm_table[parmIndex].enum_list[enumIndex].name;
1902 enumIndex++)
1904 printf("%s%s",
1905 enumIndex ? "|" : "",
1906 parm_table[parmIndex].enum_list[enumIndex].name);
1909 printf(",");
1910 hadFlag = false;
1911 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1912 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1913 printf("%s%s",
1914 hadFlag ? "|" : "",
1915 flag_names[flagIndex]);
1916 hadFlag = true;
1920 /* output synonyms */
1921 hadSyn = false;
1922 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1923 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1924 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1925 parm_table[parmIndex2].label);
1926 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1927 if (!hadSyn) {
1928 printf(" (synonyms: ");
1929 hadSyn = true;
1930 } else {
1931 printf(", ");
1933 printf("%s%s", parm_table[parmIndex2].label,
1934 inverse ? "[i]" : "");
1937 if (hadSyn) {
1938 printf(")");
1941 printf("\n");
1944 /***************************************************************************
1945 Show all parameter's name, type, [values,] and flags.
1946 ***************************************************************************/
1948 void show_parameter_list(void)
1950 int classIndex, parmIndex;
1951 const char *section_names[] = { "local", "global", NULL};
1953 for (classIndex=0; section_names[classIndex]; classIndex++) {
1954 printf("[%s]\n", section_names[classIndex]);
1955 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
1956 if (parm_table[parmIndex].p_class == classIndex) {
1957 show_parameter(parmIndex);
1963 /***************************************************************************
1964 Get the standard string representation of a boolean value ("yes" or "no")
1965 ***************************************************************************/
1967 static const char *get_boolean(bool bool_value)
1969 static const char *yes_str = "yes";
1970 static const char *no_str = "no";
1972 return (bool_value ? yes_str : no_str);
1975 /***************************************************************************
1976 Provide the string of the negated boolean value associated to the boolean
1977 given as a string. Returns false if the passed string does not correctly
1978 represent a boolean.
1979 ***************************************************************************/
1981 bool lp_invert_boolean(const char *str, const char **inverse_str)
1983 bool val;
1985 if (!set_boolean(str, &val)) {
1986 return false;
1989 *inverse_str = get_boolean(!val);
1990 return true;
1993 /***************************************************************************
1994 Provide the canonical string representation of a boolean value given
1995 as a string. Return true on success, false if the string given does
1996 not correctly represent a boolean.
1997 ***************************************************************************/
1999 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2001 bool val;
2003 if (!set_boolean(str, &val)) {
2004 return false;
2007 *canon_str = get_boolean(val);
2008 return true;
2011 /***************************************************************************
2012 Find a service by name. Otherwise works like get_service.
2013 ***************************************************************************/
2015 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2017 int iService = -1;
2018 char *canon_name;
2019 TDB_DATA data;
2020 NTSTATUS status;
2022 if (ServiceHash == NULL) {
2023 return -1;
2026 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2028 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2029 &data);
2031 if (NT_STATUS_IS_OK(status) &&
2032 (data.dptr != NULL) &&
2033 (data.dsize == sizeof(iService)))
2035 iService = *(int *)data.dptr;
2038 TALLOC_FREE(canon_name);
2040 if ((iService != -1) && (LP_SNUM_OK(iService))
2041 && (pserviceDest != NULL)) {
2042 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2045 return (iService);
2048 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2049 struct loadparm_service *lp_service(const char *pszServiceName)
2051 int iService = getservicebyname(pszServiceName, NULL);
2052 if (iService == -1 || !LP_SNUM_OK(iService)) {
2053 return NULL;
2055 return ServicePtrs[iService];
2058 struct loadparm_service *lp_servicebynum(int snum)
2060 if ((snum == -1) || !LP_SNUM_OK(snum)) {
2061 return NULL;
2063 return ServicePtrs[snum];
2066 struct loadparm_service *lp_default_loadparm_service()
2068 return &sDefault;
2071 /***************************************************************************
2072 Check a service for consistency. Return false if the service is in any way
2073 incomplete or faulty, else true.
2074 ***************************************************************************/
2076 bool service_ok(int iService)
2078 bool bRetval;
2080 bRetval = true;
2081 if (ServicePtrs[iService]->szService[0] == '\0') {
2082 DEBUG(0, ("The following message indicates an internal error:\n"));
2083 DEBUG(0, ("No service name in service entry.\n"));
2084 bRetval = false;
2087 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2088 /* I can't see why you'd want a non-printable printer service... */
2089 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2090 if (!ServicePtrs[iService]->printable) {
2091 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2092 ServicePtrs[iService]->szService));
2093 ServicePtrs[iService]->printable = true;
2095 /* [printers] service must also be non-browsable. */
2096 if (ServicePtrs[iService]->browseable)
2097 ServicePtrs[iService]->browseable = false;
2100 if (ServicePtrs[iService]->path[0] == '\0' &&
2101 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
2102 ServicePtrs[iService]->msdfs_proxy[0] == '\0'
2104 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2105 ServicePtrs[iService]->szService));
2106 ServicePtrs[iService]->bAvailable = false;
2109 /* If a service is flagged unavailable, log the fact at level 1. */
2110 if (!ServicePtrs[iService]->bAvailable)
2111 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2112 ServicePtrs[iService]->szService));
2114 return (bRetval);
2117 static struct smbconf_ctx *lp_smbconf_ctx(void)
2119 sbcErr err;
2120 static struct smbconf_ctx *conf_ctx = NULL;
2122 if (conf_ctx == NULL) {
2123 err = smbconf_init(NULL, &conf_ctx, "registry:");
2124 if (!SBC_ERROR_IS_OK(err)) {
2125 DEBUG(1, ("error initializing registry configuration: "
2126 "%s\n", sbcErrorString(err)));
2127 conf_ctx = NULL;
2131 return conf_ctx;
2134 static bool process_smbconf_service(struct smbconf_service *service)
2136 uint32_t count;
2137 bool ret;
2139 if (service == NULL) {
2140 return false;
2143 ret = do_section(service->name, NULL);
2144 if (ret != true) {
2145 return false;
2147 for (count = 0; count < service->num_params; count++) {
2148 ret = do_parameter(service->param_names[count],
2149 service->param_values[count],
2150 NULL);
2151 if (ret != true) {
2152 return false;
2155 if (iServiceIndex >= 0) {
2156 return service_ok(iServiceIndex);
2158 return true;
2162 * load a service from registry and activate it
2164 bool process_registry_service(const char *service_name)
2166 sbcErr err;
2167 struct smbconf_service *service = NULL;
2168 TALLOC_CTX *mem_ctx = talloc_stackframe();
2169 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2170 bool ret = false;
2172 if (conf_ctx == NULL) {
2173 goto done;
2176 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2178 if (!smbconf_share_exists(conf_ctx, service_name)) {
2180 * Registry does not contain data for this service (yet),
2181 * but make sure lp_load doesn't return false.
2183 ret = true;
2184 goto done;
2187 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2188 if (!SBC_ERROR_IS_OK(err)) {
2189 goto done;
2192 ret = process_smbconf_service(service);
2193 if (!ret) {
2194 goto done;
2197 /* store the csn */
2198 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2200 done:
2201 TALLOC_FREE(mem_ctx);
2202 return ret;
2206 * process_registry_globals
2208 static bool process_registry_globals(void)
2210 bool ret;
2212 add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2214 ret = do_parameter("registry shares", "yes", NULL);
2215 if (!ret) {
2216 return ret;
2219 return process_registry_service(GLOBAL_NAME);
2222 bool process_registry_shares(void)
2224 sbcErr err;
2225 uint32_t count;
2226 struct smbconf_service **service = NULL;
2227 uint32_t num_shares = 0;
2228 TALLOC_CTX *mem_ctx = talloc_stackframe();
2229 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2230 bool ret = false;
2232 if (conf_ctx == NULL) {
2233 goto done;
2236 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2237 if (!SBC_ERROR_IS_OK(err)) {
2238 goto done;
2241 ret = true;
2243 for (count = 0; count < num_shares; count++) {
2244 if (strequal(service[count]->name, GLOBAL_NAME)) {
2245 continue;
2247 ret = process_smbconf_service(service[count]);
2248 if (!ret) {
2249 goto done;
2253 /* store the csn */
2254 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2256 done:
2257 TALLOC_FREE(mem_ctx);
2258 return ret;
2262 * reload those shares from registry that are already
2263 * activated in the services array.
2265 static bool reload_registry_shares(void)
2267 int i;
2268 bool ret = true;
2270 for (i = 0; i < iNumServices; i++) {
2271 if (!VALID(i)) {
2272 continue;
2275 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2276 continue;
2279 ret = process_registry_service(ServicePtrs[i]->szService);
2280 if (!ret) {
2281 goto done;
2285 done:
2286 return ret;
2290 #define MAX_INCLUDE_DEPTH 100
2292 static uint8_t include_depth;
2295 * Free the file lists
2297 static void free_file_list(void)
2299 struct file_lists *f;
2300 struct file_lists *next;
2302 f = file_lists;
2303 while( f ) {
2304 next = f->next;
2305 TALLOC_FREE( f );
2306 f = next;
2308 file_lists = NULL;
2313 * Utility function for outsiders to check if we're running on registry.
2315 bool lp_config_backend_is_registry(void)
2317 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2321 * Utility function to check if the config backend is FILE.
2323 bool lp_config_backend_is_file(void)
2325 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2328 /*******************************************************************
2329 Check if a config file has changed date.
2330 ********************************************************************/
2332 bool lp_file_list_changed(void)
2334 struct file_lists *f = file_lists;
2336 DEBUG(6, ("lp_file_list_changed()\n"));
2338 while (f) {
2339 time_t mod_time;
2341 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2342 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2344 if (conf_ctx == NULL) {
2345 return false;
2347 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2348 NULL))
2350 DEBUGADD(6, ("registry config changed\n"));
2351 return true;
2353 } else {
2354 char *n2 = NULL;
2355 n2 = talloc_sub_basic(talloc_tos(),
2356 get_current_username(),
2357 current_user_info.domain,
2358 f->name);
2359 if (!n2) {
2360 return false;
2362 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2363 f->name, n2, ctime(&f->modtime)));
2365 mod_time = file_modtime(n2);
2367 if (mod_time &&
2368 ((f->modtime != mod_time) ||
2369 (f->subfname == NULL) ||
2370 (strcmp(n2, f->subfname) != 0)))
2372 DEBUGADD(6,
2373 ("file %s modified: %s\n", n2,
2374 ctime(&mod_time)));
2375 f->modtime = mod_time;
2376 TALLOC_FREE(f->subfname);
2377 f->subfname = talloc_strdup(f, n2);
2378 if (f->subfname == NULL) {
2379 smb_panic("talloc_strdup failed");
2381 TALLOC_FREE(n2);
2382 return true;
2384 TALLOC_FREE(n2);
2386 f = f->next;
2388 return false;
2393 * Initialize iconv conversion descriptors.
2395 * This is called the first time it is needed, and also called again
2396 * every time the configuration is reloaded, because the charset or
2397 * codepage might have changed.
2399 static void init_iconv(void)
2401 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2402 lp_unix_charset(),
2403 true, global_iconv_handle);
2406 /***************************************************************************
2407 Handle the include operation.
2408 ***************************************************************************/
2409 static bool bAllowIncludeRegistry = true;
2411 bool lp_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2413 char *fname;
2415 if (include_depth >= MAX_INCLUDE_DEPTH) {
2416 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2417 include_depth));
2418 return false;
2421 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2422 if (!bAllowIncludeRegistry) {
2423 return true;
2425 if (bInGlobalSection) {
2426 bool ret;
2427 include_depth++;
2428 ret = process_registry_globals();
2429 include_depth--;
2430 return ret;
2431 } else {
2432 DEBUG(1, ("\"include = registry\" only effective "
2433 "in %s section\n", GLOBAL_NAME));
2434 return false;
2438 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2439 current_user_info.domain,
2440 pszParmValue);
2442 add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2444 if (snum < 0) {
2445 string_set(Globals.ctx, ptr, fname);
2446 } else {
2447 string_set(ServicePtrs[snum], ptr, fname);
2450 if (file_exist(fname)) {
2451 bool ret;
2452 include_depth++;
2453 ret = pm_process(fname, do_section, do_parameter, NULL);
2454 include_depth--;
2455 TALLOC_FREE(fname);
2456 return ret;
2459 DEBUG(2, ("Can't find include file %s\n", fname));
2460 TALLOC_FREE(fname);
2461 return true;
2464 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2466 char *config_option = NULL;
2467 const char *range = NULL;
2468 bool ret = false;
2470 SMB_ASSERT(low != NULL);
2471 SMB_ASSERT(high != NULL);
2473 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2474 domain_name = "*";
2477 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2478 domain_name);
2479 if (config_option == NULL) {
2480 DEBUG(0, ("out of memory\n"));
2481 return false;
2484 range = lp_parm_const_string(-1, config_option, "range", NULL);
2485 if (range == NULL) {
2486 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2487 goto done;
2490 if (sscanf(range, "%u - %u", low, high) != 2) {
2491 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2492 range, domain_name));
2493 goto done;
2496 ret = true;
2498 done:
2499 talloc_free(config_option);
2500 return ret;
2504 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2506 return lp_idmap_range("*", low, high);
2509 const char *lp_idmap_backend(const char *domain_name)
2511 char *config_option = NULL;
2512 const char *backend = NULL;
2514 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2515 domain_name = "*";
2518 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2519 domain_name);
2520 if (config_option == NULL) {
2521 DEBUG(0, ("out of memory\n"));
2522 return false;
2525 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2526 if (backend == NULL) {
2527 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2528 goto done;
2531 done:
2532 talloc_free(config_option);
2533 return backend;
2536 const char *lp_idmap_default_backend(void)
2538 return lp_idmap_backend("*");
2541 /***************************************************************************
2542 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2543 ***************************************************************************/
2545 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2547 const char *suffix_string;
2549 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2550 Globals.ldap_suffix );
2551 if ( !suffix_string ) {
2552 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2553 return "";
2556 return suffix_string;
2559 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2561 if (Globals.szLdapMachineSuffix[0])
2562 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
2564 return lp_string(ctx, Globals.ldap_suffix);
2567 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2569 if (Globals.szLdapUserSuffix[0])
2570 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
2572 return lp_string(ctx, Globals.ldap_suffix);
2575 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2577 if (Globals.szLdapGroupSuffix[0])
2578 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
2580 return lp_string(ctx, Globals.ldap_suffix);
2583 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2585 if (Globals.szLdapIdmapSuffix[0])
2586 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
2588 return lp_string(ctx, Globals.ldap_suffix);
2592 return the parameter pointer for a parameter
2594 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2596 if (service == NULL) {
2597 if (parm->p_class == P_LOCAL)
2598 return (void *)(((char *)&sDefault)+parm->offset);
2599 else if (parm->p_class == P_GLOBAL)
2600 return (void *)(((char *)&Globals)+parm->offset);
2601 else return NULL;
2602 } else {
2603 return (void *)(((char *)service) + parm->offset);
2607 /***************************************************************************
2608 Return the local pointer to a parameter given the service number and parameter
2609 ***************************************************************************/
2611 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
2613 return lp_parm_ptr(ServicePtrs[snum], parm);
2616 /***************************************************************************
2617 Process a parameter for a particular service number. If snum < 0
2618 then assume we are in the globals.
2619 ***************************************************************************/
2621 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2623 int parmnum, i;
2624 void *parm_ptr = NULL; /* where we are going to store the result */
2625 struct parmlist_entry **opt_list;
2626 TALLOC_CTX *mem_ctx;
2628 parmnum = lpcfg_map_parameter(pszParmName);
2630 if (parmnum < 0) {
2631 if (strchr(pszParmName, ':') == NULL) {
2632 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
2633 pszParmName));
2634 return true;
2638 * We've got a parametric option
2641 if (snum < 0) {
2642 opt_list = &Globals.param_opt;
2643 set_param_opt(NULL, opt_list, pszParmName, pszParmValue, 0);
2644 } else {
2645 opt_list = &ServicePtrs[snum]->param_opt;
2646 set_param_opt(ServicePtrs[snum], opt_list, pszParmName, pszParmValue, 0);
2649 return true;
2652 /* if it's already been set by the command line, then we don't
2653 override here */
2654 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2655 return true;
2658 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2659 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2660 pszParmName));
2663 /* we might point at a service, the default service or a global */
2664 if (snum < 0) {
2665 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
2666 } else {
2667 if (parm_table[parmnum].p_class == P_GLOBAL) {
2668 DEBUG(0,
2669 ("Global parameter %s found in service section!\n",
2670 pszParmName));
2671 return true;
2673 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
2676 if (snum >= 0) {
2677 if (!ServicePtrs[snum]->copymap)
2678 init_copymap(ServicePtrs[snum]);
2680 /* this handles the aliases - set the copymap for other entries with
2681 the same data pointer */
2682 for (i = 0; parm_table[i].label; i++) {
2683 if ((parm_table[i].offset == parm_table[parmnum].offset)
2684 && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
2685 bitmap_clear(ServicePtrs[snum]->copymap, i);
2688 mem_ctx = ServicePtrs[snum];
2689 } else {
2690 mem_ctx = Globals.ctx;
2693 /* if it is a special case then go ahead */
2694 if (parm_table[parmnum].special) {
2695 bool ok;
2696 struct loadparm_context *lp_ctx = loadparm_init_s3(talloc_tos(),
2697 loadparm_s3_helpers());
2698 lp_ctx->sDefault = &sDefault;
2699 lp_ctx->services = ServicePtrs;
2700 ok = parm_table[parmnum].special(lp_ctx, snum, pszParmValue,
2701 (char **)parm_ptr);
2702 TALLOC_FREE(lp_ctx);
2704 return ok;
2707 /* now switch on the type of variable it is */
2708 switch (parm_table[parmnum].type)
2710 case P_BOOL:
2711 *(bool *)parm_ptr = lp_bool(pszParmValue);
2712 break;
2714 case P_BOOLREV:
2715 *(bool *)parm_ptr = !lp_bool(pszParmValue);
2716 break;
2718 case P_INTEGER:
2719 *(int *)parm_ptr = lp_int(pszParmValue);
2720 break;
2722 case P_CHAR:
2723 *(char *)parm_ptr = *pszParmValue;
2724 break;
2726 case P_OCTAL:
2727 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
2728 if ( i != 1 ) {
2729 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
2731 break;
2733 case P_BYTES:
2735 uint64_t val;
2736 if (conv_str_size_error(pszParmValue, &val)) {
2737 if (val <= INT_MAX) {
2738 *(int *)parm_ptr = (int)val;
2739 break;
2743 DEBUG(0,("lp_do_parameter(%s): value is not "
2744 "a valid size specifier!\n", pszParmValue));
2745 return false;
2748 case P_LIST:
2749 case P_CMDLIST:
2750 TALLOC_FREE(*((char ***)parm_ptr));
2751 *(char ***)parm_ptr = str_list_make_v3(
2752 NULL, pszParmValue, NULL);
2753 break;
2755 case P_STRING:
2756 string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
2757 break;
2759 case P_USTRING:
2761 char *upper_string = strupper_talloc(talloc_tos(),
2762 pszParmValue);
2763 string_set(mem_ctx, (char **)parm_ptr, upper_string);
2764 TALLOC_FREE(upper_string);
2765 break;
2767 case P_ENUM:
2768 if (!lp_set_enum_parm(&parm_table[parmnum], pszParmValue, (int*)parm_ptr)) {
2769 return false;
2771 break;
2772 case P_SEP:
2773 break;
2776 return true;
2779 /***************************************************************************
2780 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2781 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2782 ***************************************************************************/
2784 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
2786 int parmnum, i;
2787 parmnum = lpcfg_map_parameter(pszParmName);
2788 if (parmnum >= 0) {
2789 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2790 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2791 return false;
2793 parm_table[parmnum].flags |= FLAG_CMDLINE;
2795 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2796 * be grouped in the table, so we don't have to search the
2797 * whole table */
2798 for (i=parmnum-1;
2799 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2800 && parm_table[i].p_class == parm_table[parmnum].p_class;
2801 i--) {
2802 parm_table[i].flags |= FLAG_CMDLINE;
2804 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
2805 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2806 parm_table[i].flags |= FLAG_CMDLINE;
2809 if (store_values) {
2810 store_lp_set_cmdline(pszParmName, pszParmValue);
2812 return true;
2815 /* it might be parametric */
2816 if (strchr(pszParmName, ':') != NULL) {
2817 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2818 if (store_values) {
2819 store_lp_set_cmdline(pszParmName, pszParmValue);
2821 return true;
2824 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2825 return true;
2828 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2830 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
2833 /***************************************************************************
2834 Process a parameter.
2835 ***************************************************************************/
2837 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2838 void *userdata)
2840 if (!bInGlobalSection && bGlobalOnly)
2841 return true;
2843 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2845 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2846 pszParmName, pszParmValue));
2849 /***************************************************************************
2850 Initialize any local variables in the sDefault table, after parsing a
2851 [globals] section.
2852 ***************************************************************************/
2854 static void init_locals(void)
2857 * We run this check once the [globals] is parsed, to force
2858 * the VFS objects and other per-share settings we need for
2859 * the standard way a AD DC is operated. We may change these
2860 * as our code evolves, which is why we force these settings.
2862 * We can't do this at the end of lp_load_ex(), as by that
2863 * point the services have been loaded and they will already
2864 * have "" as their vfs objects.
2866 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2867 const char **vfs_objects = lp_vfs_objects(-1);
2868 if (!vfs_objects || !vfs_objects[0]) {
2869 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2870 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2871 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2872 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2873 } else {
2874 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2878 lp_do_parameter(-1, "map hidden", "no");
2879 lp_do_parameter(-1, "map system", "no");
2880 lp_do_parameter(-1, "map readonly", "no");
2881 lp_do_parameter(-1, "map archive", "no");
2882 lp_do_parameter(-1, "store dos attributes", "yes");
2886 /***************************************************************************
2887 Process a new section (service). At this stage all sections are services.
2888 Later we'll have special sections that permit server parameters to be set.
2889 Returns true on success, false on failure.
2890 ***************************************************************************/
2892 static bool do_section(const char *pszSectionName, void *userdata)
2894 bool bRetval;
2895 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2896 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2897 bRetval = false;
2899 /* if we were in a global section then do the local inits */
2900 if (bInGlobalSection && !isglobal)
2901 init_locals();
2903 /* if we've just struck a global section, note the fact. */
2904 bInGlobalSection = isglobal;
2906 /* check for multiple global sections */
2907 if (bInGlobalSection) {
2908 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2909 return true;
2912 if (!bInGlobalSection && bGlobalOnly)
2913 return true;
2915 /* if we have a current service, tidy it up before moving on */
2916 bRetval = true;
2918 if (iServiceIndex >= 0)
2919 bRetval = service_ok(iServiceIndex);
2921 /* if all is still well, move to the next record in the services array */
2922 if (bRetval) {
2923 /* We put this here to avoid an odd message order if messages are */
2924 /* issued by the post-processing of a previous section. */
2925 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2927 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2928 if (iServiceIndex < 0) {
2929 DEBUG(0, ("Failed to add a new service\n"));
2930 return false;
2932 /* Clean all parametric options for service */
2933 /* They will be added during parsing again */
2934 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2937 return bRetval;
2941 /***************************************************************************
2942 Determine if a partcular base parameter is currentl set to the default value.
2943 ***************************************************************************/
2945 static bool is_default(int i)
2947 switch (parm_table[i].type) {
2948 case P_LIST:
2949 case P_CMDLIST:
2950 return str_list_equal((const char * const *)parm_table[i].def.lvalue,
2951 *(const char ***)lp_parm_ptr(NULL,
2952 &parm_table[i]));
2953 case P_STRING:
2954 case P_USTRING:
2955 return strequal(parm_table[i].def.svalue,
2956 *(char **)lp_parm_ptr(NULL,
2957 &parm_table[i]));
2958 case P_BOOL:
2959 case P_BOOLREV:
2960 return parm_table[i].def.bvalue ==
2961 *(bool *)lp_parm_ptr(NULL,
2962 &parm_table[i]);
2963 case P_CHAR:
2964 return parm_table[i].def.cvalue ==
2965 *(char *)lp_parm_ptr(NULL,
2966 &parm_table[i]);
2967 case P_INTEGER:
2968 case P_OCTAL:
2969 case P_ENUM:
2970 case P_BYTES:
2971 return parm_table[i].def.ivalue ==
2972 *(int *)lp_parm_ptr(NULL,
2973 &parm_table[i]);
2974 case P_SEP:
2975 break;
2977 return false;
2980 /***************************************************************************
2981 Display the contents of the global structure.
2982 ***************************************************************************/
2984 static void dump_globals(FILE *f)
2986 int i;
2987 struct parmlist_entry *data;
2989 fprintf(f, "[global]\n");
2991 for (i = 0; parm_table[i].label; i++)
2992 if (parm_table[i].p_class == P_GLOBAL &&
2993 !(parm_table[i].flags & FLAG_META) &&
2994 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
2995 if (defaults_saved && is_default(i))
2996 continue;
2997 fprintf(f, "\t%s = ", parm_table[i].label);
2998 lpcfg_print_parameter(&parm_table[i], lp_parm_ptr(NULL,
2999 &parm_table[i]),
3001 fprintf(f, "\n");
3003 if (Globals.param_opt != NULL) {
3004 data = Globals.param_opt;
3005 while(data) {
3006 fprintf(f, "\t%s = %s\n", data->key, data->value);
3007 data = data->next;
3013 /***************************************************************************
3014 Display the contents of a single services record.
3015 ***************************************************************************/
3017 static void dump_a_service(struct loadparm_service *pService, FILE * f)
3019 int i;
3020 struct parmlist_entry *data;
3022 if (pService != &sDefault)
3023 fprintf(f, "[%s]\n", pService->szService);
3025 for (i = 0; parm_table[i].label; i++) {
3027 if (parm_table[i].p_class == P_LOCAL &&
3028 !(parm_table[i].flags & FLAG_META) &&
3029 (*parm_table[i].label != '-') &&
3030 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
3032 if (pService == &sDefault) {
3033 if (defaults_saved && is_default(i))
3034 continue;
3035 } else {
3036 if (lpcfg_equal_parameter(parm_table[i].type,
3037 lp_parm_ptr(pService, &parm_table[i]),
3038 lp_parm_ptr(NULL, &parm_table[i])))
3039 continue;
3042 fprintf(f, "\t%s = ", parm_table[i].label);
3043 lpcfg_print_parameter(&parm_table[i],
3044 lp_parm_ptr(pService, &parm_table[i]),
3046 fprintf(f, "\n");
3050 if (pService->param_opt != NULL) {
3051 data = pService->param_opt;
3052 while(data) {
3053 fprintf(f, "\t%s = %s\n", data->key, data->value);
3054 data = data->next;
3059 /***************************************************************************
3060 Display the contents of a parameter of a single services record.
3061 ***************************************************************************/
3063 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
3065 bool result = false;
3066 fstring local_parm_name;
3067 char *parm_opt;
3068 const char *parm_opt_value;
3070 struct loadparm_context *lp_ctx;
3072 /* check for parametrical option */
3073 fstrcpy( local_parm_name, parm_name);
3074 parm_opt = strchr( local_parm_name, ':');
3076 if (parm_opt) {
3077 *parm_opt = '\0';
3078 parm_opt++;
3079 if (strlen(parm_opt)) {
3080 parm_opt_value = lp_parm_const_string( snum,
3081 local_parm_name, parm_opt, NULL);
3082 if (parm_opt_value) {
3083 printf( "%s\n", parm_opt_value);
3084 result = true;
3087 return result;
3090 lp_ctx = loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
3091 if (lp_ctx == NULL) {
3092 return false;
3095 if (isGlobal) {
3096 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
3097 } else {
3098 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
3100 TALLOC_FREE(lp_ctx);
3101 return result;
3104 /***************************************************************************
3105 Return info about the requested parameter (given as a string).
3106 Return NULL when the string is not a valid parameter name.
3107 ***************************************************************************/
3109 struct parm_struct *lp_get_parameter(const char *param_name)
3111 int num = lpcfg_map_parameter(param_name);
3113 if (num < 0) {
3114 return NULL;
3117 return &parm_table[num];
3120 #if 0
3121 /***************************************************************************
3122 Display the contents of a single copy structure.
3123 ***************************************************************************/
3124 static void dump_copy_map(bool *pcopymap)
3126 int i;
3127 if (!pcopymap)
3128 return;
3130 printf("\n\tNon-Copied parameters:\n");
3132 for (i = 0; parm_table[i].label; i++)
3133 if (parm_table[i].p_class == P_LOCAL &&
3134 parm_table[i].ptr && !pcopymap[i] &&
3135 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3137 printf("\t\t%s\n", parm_table[i].label);
3140 #endif
3142 /***************************************************************************
3143 Return TRUE if the passed service number is within range.
3144 ***************************************************************************/
3146 bool lp_snum_ok(int iService)
3148 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3151 /***************************************************************************
3152 Auto-load some home services.
3153 ***************************************************************************/
3155 static void lp_add_auto_services(char *str)
3157 char *s;
3158 char *p;
3159 int homes;
3160 char *saveptr;
3162 if (!str)
3163 return;
3165 s = talloc_strdup(talloc_tos(), str);
3166 if (!s) {
3167 smb_panic("talloc_strdup failed");
3168 return;
3171 homes = lp_servicenumber(HOMES_NAME);
3173 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
3174 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
3175 char *home;
3177 if (lp_servicenumber(p) >= 0)
3178 continue;
3180 home = get_user_home_dir(talloc_tos(), p);
3182 if (home && home[0] && homes >= 0)
3183 lp_add_home(p, homes, p, home);
3185 TALLOC_FREE(home);
3187 TALLOC_FREE(s);
3190 /***************************************************************************
3191 Auto-load one printer.
3192 ***************************************************************************/
3194 void lp_add_one_printer(const char *name, const char *comment,
3195 const char *location, void *pdata)
3197 int printers = lp_servicenumber(PRINTERS_NAME);
3198 int i;
3200 if (lp_servicenumber(name) < 0) {
3201 lp_add_printer(name, printers);
3202 if ((i = lp_servicenumber(name)) >= 0) {
3203 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
3204 ServicePtrs[i]->autoloaded = true;
3209 /***************************************************************************
3210 Have we loaded a services file yet?
3211 ***************************************************************************/
3213 bool lp_loaded(void)
3215 return (bLoaded);
3218 /***************************************************************************
3219 Unload unused services.
3220 ***************************************************************************/
3222 void lp_killunused(struct smbd_server_connection *sconn,
3223 bool (*snumused) (struct smbd_server_connection *, int))
3225 int i;
3226 for (i = 0; i < iNumServices; i++) {
3227 if (!VALID(i))
3228 continue;
3230 /* don't kill autoloaded or usershare services */
3231 if ( ServicePtrs[i]->autoloaded ||
3232 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3233 continue;
3236 if (!snumused || !snumused(sconn, i)) {
3237 free_service_byindex(i);
3243 * Kill all except autoloaded and usershare services - convenience wrapper
3245 void lp_kill_all_services(void)
3247 lp_killunused(NULL, NULL);
3250 /***************************************************************************
3251 Unload a service.
3252 ***************************************************************************/
3254 void lp_killservice(int iServiceIn)
3256 if (VALID(iServiceIn)) {
3257 free_service_byindex(iServiceIn);
3261 /***************************************************************************
3262 Save the curent values of all global and sDefault parameters into the
3263 defaults union. This allows testparm to show only the
3264 changed (ie. non-default) parameters.
3265 ***************************************************************************/
3267 static void lp_save_defaults(void)
3269 int i;
3270 for (i = 0; parm_table[i].label; i++) {
3271 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3272 && parm_table[i].p_class == parm_table[i - 1].p_class)
3273 continue;
3274 switch (parm_table[i].type) {
3275 case P_LIST:
3276 case P_CMDLIST:
3277 parm_table[i].def.lvalue = str_list_copy(
3278 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3279 break;
3280 case P_STRING:
3281 case P_USTRING:
3282 parm_table[i].def.svalue = talloc_strdup(Globals.ctx, *(char **)lp_parm_ptr(NULL, &parm_table[i]));
3283 if (parm_table[i].def.svalue == NULL) {
3284 smb_panic("talloc_strdup failed");
3286 break;
3287 case P_BOOL:
3288 case P_BOOLREV:
3289 parm_table[i].def.bvalue =
3290 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3291 break;
3292 case P_CHAR:
3293 parm_table[i].def.cvalue =
3294 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3295 break;
3296 case P_INTEGER:
3297 case P_OCTAL:
3298 case P_ENUM:
3299 case P_BYTES:
3300 parm_table[i].def.ivalue =
3301 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3302 break;
3303 case P_SEP:
3304 break;
3307 defaults_saved = true;
3310 /***********************************************************
3311 If we should send plaintext/LANMAN passwords in the clinet
3312 ************************************************************/
3314 static void set_allowed_client_auth(void)
3316 if (Globals.client_ntlmv2_auth) {
3317 Globals.client_lanman_auth = false;
3319 if (!Globals.client_lanman_auth) {
3320 Globals.client_plaintext_auth = false;
3324 /***************************************************************************
3325 JRA.
3326 The following code allows smbd to read a user defined share file.
3327 Yes, this is my intent. Yes, I'm comfortable with that...
3329 THE FOLLOWING IS SECURITY CRITICAL CODE.
3331 It washes your clothes, it cleans your house, it guards you while you sleep...
3332 Do not f%^k with it....
3333 ***************************************************************************/
3335 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3337 /***************************************************************************
3338 Check allowed stat state of a usershare file.
3339 Ensure we print out who is dicking with us so the admin can
3340 get their sorry ass fired.
3341 ***************************************************************************/
3343 static bool check_usershare_stat(const char *fname,
3344 const SMB_STRUCT_STAT *psbuf)
3346 if (!S_ISREG(psbuf->st_ex_mode)) {
3347 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3348 "not a regular file\n",
3349 fname, (unsigned int)psbuf->st_ex_uid ));
3350 return false;
3353 /* Ensure this doesn't have the other write bit set. */
3354 if (psbuf->st_ex_mode & S_IWOTH) {
3355 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3356 "public write. Refusing to allow as a usershare file.\n",
3357 fname, (unsigned int)psbuf->st_ex_uid ));
3358 return false;
3361 /* Should be 10k or less. */
3362 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
3363 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3364 "too large (%u) to be a user share file.\n",
3365 fname, (unsigned int)psbuf->st_ex_uid,
3366 (unsigned int)psbuf->st_ex_size ));
3367 return false;
3370 return true;
3373 /***************************************************************************
3374 Parse the contents of a usershare file.
3375 ***************************************************************************/
3377 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
3378 SMB_STRUCT_STAT *psbuf,
3379 const char *servicename,
3380 int snum,
3381 char **lines,
3382 int numlines,
3383 char **pp_sharepath,
3384 char **pp_comment,
3385 char **pp_cp_servicename,
3386 struct security_descriptor **ppsd,
3387 bool *pallow_guest)
3389 const char **prefixallowlist = lp_usershare_prefix_allow_list();
3390 const char **prefixdenylist = lp_usershare_prefix_deny_list();
3391 int us_vers;
3392 DIR *dp;
3393 SMB_STRUCT_STAT sbuf;
3394 char *sharepath = NULL;
3395 char *comment = NULL;
3397 *pp_sharepath = NULL;
3398 *pp_comment = NULL;
3400 *pallow_guest = false;
3402 if (numlines < 4) {
3403 return USERSHARE_MALFORMED_FILE;
3406 if (strcmp(lines[0], "#VERSION 1") == 0) {
3407 us_vers = 1;
3408 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3409 us_vers = 2;
3410 if (numlines < 5) {
3411 return USERSHARE_MALFORMED_FILE;
3413 } else {
3414 return USERSHARE_BAD_VERSION;
3417 if (strncmp(lines[1], "path=", 5) != 0) {
3418 return USERSHARE_MALFORMED_PATH;
3421 sharepath = talloc_strdup(ctx, &lines[1][5]);
3422 if (!sharepath) {
3423 return USERSHARE_POSIX_ERR;
3425 trim_string(sharepath, " ", " ");
3427 if (strncmp(lines[2], "comment=", 8) != 0) {
3428 return USERSHARE_MALFORMED_COMMENT_DEF;
3431 comment = talloc_strdup(ctx, &lines[2][8]);
3432 if (!comment) {
3433 return USERSHARE_POSIX_ERR;
3435 trim_string(comment, " ", " ");
3436 trim_char(comment, '"', '"');
3438 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3439 return USERSHARE_MALFORMED_ACL_DEF;
3442 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3443 return USERSHARE_ACL_ERR;
3446 if (us_vers == 2) {
3447 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3448 return USERSHARE_MALFORMED_ACL_DEF;
3450 if (lines[4][9] == 'y') {
3451 *pallow_guest = true;
3454 /* Backwards compatible extension to file version #2. */
3455 if (numlines > 5) {
3456 if (strncmp(lines[5], "sharename=", 10) != 0) {
3457 return USERSHARE_MALFORMED_SHARENAME_DEF;
3459 if (!strequal(&lines[5][10], servicename)) {
3460 return USERSHARE_BAD_SHARENAME;
3462 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3463 if (!*pp_cp_servicename) {
3464 return USERSHARE_POSIX_ERR;
3469 if (*pp_cp_servicename == NULL) {
3470 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3471 if (!*pp_cp_servicename) {
3472 return USERSHARE_POSIX_ERR;
3476 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3477 /* Path didn't change, no checks needed. */
3478 *pp_sharepath = sharepath;
3479 *pp_comment = comment;
3480 return USERSHARE_OK;
3483 /* The path *must* be absolute. */
3484 if (sharepath[0] != '/') {
3485 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3486 servicename, sharepath));
3487 return USERSHARE_PATH_NOT_ABSOLUTE;
3490 /* If there is a usershare prefix deny list ensure one of these paths
3491 doesn't match the start of the user given path. */
3492 if (prefixdenylist) {
3493 int i;
3494 for ( i=0; prefixdenylist[i]; i++ ) {
3495 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3496 servicename, i, prefixdenylist[i], sharepath ));
3497 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3498 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3499 "usershare prefix deny list entries.\n",
3500 servicename, sharepath));
3501 return USERSHARE_PATH_IS_DENIED;
3506 /* If there is a usershare prefix allow list ensure one of these paths
3507 does match the start of the user given path. */
3509 if (prefixallowlist) {
3510 int i;
3511 for ( i=0; prefixallowlist[i]; i++ ) {
3512 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3513 servicename, i, prefixallowlist[i], sharepath ));
3514 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3515 break;
3518 if (prefixallowlist[i] == NULL) {
3519 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3520 "usershare prefix allow list entries.\n",
3521 servicename, sharepath));
3522 return USERSHARE_PATH_NOT_ALLOWED;
3526 /* Ensure this is pointing to a directory. */
3527 dp = opendir(sharepath);
3529 if (!dp) {
3530 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3531 servicename, sharepath));
3532 return USERSHARE_PATH_NOT_DIRECTORY;
3535 /* Ensure the owner of the usershare file has permission to share
3536 this directory. */
3538 if (sys_stat(sharepath, &sbuf, false) == -1) {
3539 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3540 servicename, sharepath, strerror(errno) ));
3541 closedir(dp);
3542 return USERSHARE_POSIX_ERR;
3545 closedir(dp);
3547 if (!S_ISDIR(sbuf.st_ex_mode)) {
3548 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3549 servicename, sharepath ));
3550 return USERSHARE_PATH_NOT_DIRECTORY;
3553 /* Check if sharing is restricted to owner-only. */
3554 /* psbuf is the stat of the usershare definition file,
3555 sbuf is the stat of the target directory to be shared. */
3557 if (lp_usershare_owner_only()) {
3558 /* root can share anything. */
3559 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3560 return USERSHARE_PATH_NOT_ALLOWED;
3564 *pp_sharepath = sharepath;
3565 *pp_comment = comment;
3566 return USERSHARE_OK;
3569 /***************************************************************************
3570 Deal with a usershare file.
3571 Returns:
3572 >= 0 - snum
3573 -1 - Bad name, invalid contents.
3574 - service name already existed and not a usershare, problem
3575 with permissions to share directory etc.
3576 ***************************************************************************/
3578 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3580 SMB_STRUCT_STAT sbuf;
3581 SMB_STRUCT_STAT lsbuf;
3582 char *fname = NULL;
3583 char *sharepath = NULL;
3584 char *comment = NULL;
3585 char *cp_service_name = NULL;
3586 char **lines = NULL;
3587 int numlines = 0;
3588 int fd = -1;
3589 int iService = -1;
3590 TALLOC_CTX *ctx = talloc_stackframe();
3591 struct security_descriptor *psd = NULL;
3592 bool guest_ok = false;
3593 char *canon_name = NULL;
3594 bool added_service = false;
3595 int ret = -1;
3597 /* Ensure share name doesn't contain invalid characters. */
3598 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3599 DEBUG(0,("process_usershare_file: share name %s contains "
3600 "invalid characters (any of %s)\n",
3601 file_name, INVALID_SHARENAME_CHARS ));
3602 goto out;
3605 canon_name = canonicalize_servicename(ctx, file_name);
3606 if (!canon_name) {
3607 goto out;
3610 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3611 if (!fname) {
3612 goto out;
3615 /* Minimize the race condition by doing an lstat before we
3616 open and fstat. Ensure this isn't a symlink link. */
3618 if (sys_lstat(fname, &lsbuf, false) != 0) {
3619 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3620 fname, strerror(errno) ));
3621 goto out;
3624 /* This must be a regular file, not a symlink, directory or
3625 other strange filetype. */
3626 if (!check_usershare_stat(fname, &lsbuf)) {
3627 goto out;
3631 TDB_DATA data;
3632 NTSTATUS status;
3634 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3635 canon_name, &data);
3637 iService = -1;
3639 if (NT_STATUS_IS_OK(status) &&
3640 (data.dptr != NULL) &&
3641 (data.dsize == sizeof(iService))) {
3642 memcpy(&iService, data.dptr, sizeof(iService));
3646 if (iService != -1 &&
3647 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3648 &lsbuf.st_ex_mtime) == 0) {
3649 /* Nothing changed - Mark valid and return. */
3650 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3651 canon_name ));
3652 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3653 ret = iService;
3654 goto out;
3657 /* Try and open the file read only - no symlinks allowed. */
3658 #ifdef O_NOFOLLOW
3659 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3660 #else
3661 fd = open(fname, O_RDONLY, 0);
3662 #endif
3664 if (fd == -1) {
3665 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3666 fname, strerror(errno) ));
3667 goto out;
3670 /* Now fstat to be *SURE* it's a regular file. */
3671 if (sys_fstat(fd, &sbuf, false) != 0) {
3672 close(fd);
3673 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3674 fname, strerror(errno) ));
3675 goto out;
3678 /* Is it the same dev/inode as was lstated ? */
3679 if (!check_same_stat(&lsbuf, &sbuf)) {
3680 close(fd);
3681 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3682 "Symlink spoofing going on ?\n", fname ));
3683 goto out;
3686 /* This must be a regular file, not a symlink, directory or
3687 other strange filetype. */
3688 if (!check_usershare_stat(fname, &sbuf)) {
3689 close(fd);
3690 goto out;
3693 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3695 close(fd);
3696 if (lines == NULL) {
3697 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3698 fname, (unsigned int)sbuf.st_ex_uid ));
3699 goto out;
3702 if (parse_usershare_file(ctx, &sbuf, file_name,
3703 iService, lines, numlines, &sharepath,
3704 &comment, &cp_service_name,
3705 &psd, &guest_ok) != USERSHARE_OK) {
3706 goto out;
3709 /* Everything ok - add the service possibly using a template. */
3710 if (iService < 0) {
3711 const struct loadparm_service *sp = &sDefault;
3712 if (snum_template != -1) {
3713 sp = ServicePtrs[snum_template];
3716 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3717 DEBUG(0, ("process_usershare_file: Failed to add "
3718 "new service %s\n", cp_service_name));
3719 goto out;
3722 added_service = true;
3724 /* Read only is controlled by usershare ACL below. */
3725 ServicePtrs[iService]->read_only = false;
3728 /* Write the ACL of the new/modified share. */
3729 if (!set_share_security(canon_name, psd)) {
3730 DEBUG(0, ("process_usershare_file: Failed to set share "
3731 "security for user share %s\n",
3732 canon_name ));
3733 goto out;
3736 /* If from a template it may be marked invalid. */
3737 ServicePtrs[iService]->valid = true;
3739 /* Set the service as a valid usershare. */
3740 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3742 /* Set guest access. */
3743 if (lp_usershare_allow_guests()) {
3744 ServicePtrs[iService]->guest_ok = guest_ok;
3747 /* And note when it was loaded. */
3748 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3749 string_set(ServicePtrs[iService], &ServicePtrs[iService]->path, sharepath);
3750 string_set(ServicePtrs[iService], &ServicePtrs[iService]->comment, comment);
3752 ret = iService;
3754 out:
3756 if (ret == -1 && iService != -1 && added_service) {
3757 lp_remove_service(iService);
3760 TALLOC_FREE(lines);
3761 TALLOC_FREE(ctx);
3762 return ret;
3765 /***************************************************************************
3766 Checks if a usershare entry has been modified since last load.
3767 ***************************************************************************/
3769 static bool usershare_exists(int iService, struct timespec *last_mod)
3771 SMB_STRUCT_STAT lsbuf;
3772 const char *usersharepath = Globals.usershare_path;
3773 char *fname;
3775 fname = talloc_asprintf(talloc_tos(),
3776 "%s/%s",
3777 usersharepath,
3778 ServicePtrs[iService]->szService);
3779 if (fname == NULL) {
3780 return false;
3783 if (sys_lstat(fname, &lsbuf, false) != 0) {
3784 TALLOC_FREE(fname);
3785 return false;
3788 if (!S_ISREG(lsbuf.st_ex_mode)) {
3789 TALLOC_FREE(fname);
3790 return false;
3793 TALLOC_FREE(fname);
3794 *last_mod = lsbuf.st_ex_mtime;
3795 return true;
3798 /***************************************************************************
3799 Load a usershare service by name. Returns a valid servicenumber or -1.
3800 ***************************************************************************/
3802 int load_usershare_service(const char *servicename)
3804 SMB_STRUCT_STAT sbuf;
3805 const char *usersharepath = Globals.usershare_path;
3806 int max_user_shares = Globals.usershare_max_shares;
3807 int snum_template = -1;
3809 if (*usersharepath == 0 || max_user_shares == 0) {
3810 return -1;
3813 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3814 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3815 usersharepath, strerror(errno) ));
3816 return -1;
3819 if (!S_ISDIR(sbuf.st_ex_mode)) {
3820 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3821 usersharepath ));
3822 return -1;
3826 * This directory must be owned by root, and have the 't' bit set.
3827 * It also must not be writable by "other".
3830 #ifdef S_ISVTX
3831 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3832 #else
3833 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3834 #endif
3835 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3836 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3837 usersharepath ));
3838 return -1;
3841 /* Ensure the template share exists if it's set. */
3842 if (Globals.usershare_template_share[0]) {
3843 /* We can't use lp_servicenumber here as we are recommending that
3844 template shares have -valid=false set. */
3845 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3846 if (ServicePtrs[snum_template]->szService &&
3847 strequal(ServicePtrs[snum_template]->szService,
3848 Globals.usershare_template_share)) {
3849 break;
3853 if (snum_template == -1) {
3854 DEBUG(0,("load_usershare_service: usershare template share %s "
3855 "does not exist.\n",
3856 Globals.usershare_template_share ));
3857 return -1;
3861 return process_usershare_file(usersharepath, servicename, snum_template);
3864 /***************************************************************************
3865 Load all user defined shares from the user share directory.
3866 We only do this if we're enumerating the share list.
3867 This is the function that can delete usershares that have
3868 been removed.
3869 ***************************************************************************/
3871 int load_usershare_shares(struct smbd_server_connection *sconn,
3872 bool (*snumused) (struct smbd_server_connection *, int))
3874 DIR *dp;
3875 SMB_STRUCT_STAT sbuf;
3876 struct dirent *de;
3877 int num_usershares = 0;
3878 int max_user_shares = Globals.usershare_max_shares;
3879 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3880 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3881 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3882 int iService;
3883 int snum_template = -1;
3884 const char *usersharepath = Globals.usershare_path;
3885 int ret = lp_numservices();
3886 TALLOC_CTX *tmp_ctx;
3888 if (max_user_shares == 0 || *usersharepath == '\0') {
3889 return lp_numservices();
3892 if (sys_stat(usersharepath, &sbuf, false) != 0) {
3893 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3894 usersharepath, strerror(errno) ));
3895 return ret;
3899 * This directory must be owned by root, and have the 't' bit set.
3900 * It also must not be writable by "other".
3903 #ifdef S_ISVTX
3904 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3905 #else
3906 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3907 #endif
3908 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3909 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3910 usersharepath ));
3911 return ret;
3914 /* Ensure the template share exists if it's set. */
3915 if (Globals.usershare_template_share[0]) {
3916 /* We can't use lp_servicenumber here as we are recommending that
3917 template shares have -valid=false set. */
3918 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3919 if (ServicePtrs[snum_template]->szService &&
3920 strequal(ServicePtrs[snum_template]->szService,
3921 Globals.usershare_template_share)) {
3922 break;
3926 if (snum_template == -1) {
3927 DEBUG(0,("load_usershare_shares: usershare template share %s "
3928 "does not exist.\n",
3929 Globals.usershare_template_share ));
3930 return ret;
3934 /* Mark all existing usershares as pending delete. */
3935 for (iService = iNumServices - 1; iService >= 0; iService--) {
3936 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3937 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3941 dp = opendir(usersharepath);
3942 if (!dp) {
3943 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3944 usersharepath, strerror(errno) ));
3945 return ret;
3948 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3949 (de = readdir(dp));
3950 num_dir_entries++ ) {
3951 int r;
3952 const char *n = de->d_name;
3954 /* Ignore . and .. */
3955 if (*n == '.') {
3956 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3957 continue;
3961 if (n[0] == ':') {
3962 /* Temporary file used when creating a share. */
3963 num_tmp_dir_entries++;
3966 /* Allow 20% tmp entries. */
3967 if (num_tmp_dir_entries > allowed_tmp_entries) {
3968 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3969 "in directory %s\n",
3970 num_tmp_dir_entries, usersharepath));
3971 break;
3974 r = process_usershare_file(usersharepath, n, snum_template);
3975 if (r == 0) {
3976 /* Update the services count. */
3977 num_usershares++;
3978 if (num_usershares >= max_user_shares) {
3979 DEBUG(0,("load_usershare_shares: max user shares reached "
3980 "on file %s in directory %s\n",
3981 n, usersharepath ));
3982 break;
3984 } else if (r == -1) {
3985 num_bad_dir_entries++;
3988 /* Allow 20% bad entries. */
3989 if (num_bad_dir_entries > allowed_bad_entries) {
3990 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3991 "in directory %s\n",
3992 num_bad_dir_entries, usersharepath));
3993 break;
3996 /* Allow 20% bad entries. */
3997 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3998 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3999 "in directory %s\n",
4000 num_dir_entries, usersharepath));
4001 break;
4005 closedir(dp);
4007 /* Sweep through and delete any non-refreshed usershares that are
4008 not currently in use. */
4009 tmp_ctx = talloc_stackframe();
4010 for (iService = iNumServices - 1; iService >= 0; iService--) {
4011 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4012 char *servname;
4014 if (snumused && snumused(sconn, iService)) {
4015 continue;
4018 servname = lp_servicename(tmp_ctx, iService);
4020 /* Remove from the share ACL db. */
4021 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4022 servname ));
4023 delete_share_security(servname);
4024 free_service_byindex(iService);
4027 talloc_free(tmp_ctx);
4029 return lp_numservices();
4032 /********************************************************
4033 Destroy global resources allocated in this file
4034 ********************************************************/
4036 void gfree_loadparm(void)
4038 int i;
4040 free_file_list();
4042 /* Free resources allocated to services */
4044 for ( i = 0; i < iNumServices; i++ ) {
4045 if ( VALID(i) ) {
4046 free_service_byindex(i);
4050 TALLOC_FREE( ServicePtrs );
4051 iNumServices = 0;
4053 /* Now release all resources allocated to global
4054 parameters and the default service */
4056 free_global_parameters();
4060 /***************************************************************************
4061 Allow client apps to specify that they are a client
4062 ***************************************************************************/
4063 static void lp_set_in_client(bool b)
4065 in_client = b;
4069 /***************************************************************************
4070 Determine if we're running in a client app
4071 ***************************************************************************/
4072 static bool lp_is_in_client(void)
4074 return in_client;
4077 /***************************************************************************
4078 Load the services array from the services file. Return true on success,
4079 false on failure.
4080 ***************************************************************************/
4082 static bool lp_load_ex(const char *pszFname,
4083 bool global_only,
4084 bool save_defaults,
4085 bool add_ipc,
4086 bool initialize_globals,
4087 bool allow_include_registry,
4088 bool load_all_shares)
4090 char *n2 = NULL;
4091 bool bRetval;
4093 bRetval = false;
4095 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4097 bInGlobalSection = true;
4098 bGlobalOnly = global_only;
4099 bAllowIncludeRegistry = allow_include_registry;
4101 init_globals(initialize_globals);
4103 free_file_list();
4105 if (save_defaults) {
4106 init_locals();
4107 lp_save_defaults();
4110 if (!initialize_globals) {
4111 free_param_opts(&Globals.param_opt);
4112 apply_lp_set_cmdline();
4115 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
4117 /* We get sections first, so have to start 'behind' to make up */
4118 iServiceIndex = -1;
4120 if (lp_config_backend_is_file()) {
4121 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4122 current_user_info.domain,
4123 pszFname);
4124 if (!n2) {
4125 smb_panic("lp_load_ex: out of memory");
4128 add_to_file_list(NULL, &file_lists, pszFname, n2);
4130 bRetval = pm_process(n2, do_section, do_parameter, NULL);
4131 TALLOC_FREE(n2);
4133 /* finish up the last section */
4134 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4135 if (bRetval) {
4136 if (iServiceIndex >= 0) {
4137 bRetval = service_ok(iServiceIndex);
4141 if (lp_config_backend_is_registry()) {
4142 /* config backend changed to registry in config file */
4144 * We need to use this extra global variable here to
4145 * survive restart: init_globals uses this as a default
4146 * for config_backend. Otherwise, init_globals would
4147 * send us into an endless loop here.
4149 config_backend = CONFIG_BACKEND_REGISTRY;
4150 /* start over */
4151 DEBUG(1, ("lp_load_ex: changing to config backend "
4152 "registry\n"));
4153 init_globals(true);
4154 lp_kill_all_services();
4155 return lp_load_ex(pszFname, global_only, save_defaults,
4156 add_ipc, initialize_globals,
4157 allow_include_registry,
4158 load_all_shares);
4160 } else if (lp_config_backend_is_registry()) {
4161 bRetval = process_registry_globals();
4162 } else {
4163 DEBUG(0, ("Illegal config backend given: %d\n",
4164 lp_config_backend()));
4165 bRetval = false;
4168 if (bRetval && lp_registry_shares()) {
4169 if (load_all_shares) {
4170 bRetval = process_registry_shares();
4171 } else {
4172 bRetval = reload_registry_shares();
4177 char *serv = lp_auto_services(talloc_tos());
4178 lp_add_auto_services(serv);
4179 TALLOC_FREE(serv);
4182 if (add_ipc) {
4183 /* When 'restrict anonymous = 2' guest connections to ipc$
4184 are denied */
4185 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4186 if ( lp_enable_asu_support() ) {
4187 lp_add_ipc("ADMIN$", false);
4191 set_allowed_client_auth();
4193 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
4194 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4195 lp_password_server()));
4198 bLoaded = true;
4200 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4201 /* if we_are_a_wins_server is true and we are in the client */
4202 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
4203 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4206 init_iconv();
4208 fault_configure(smb_panic_s3);
4211 * We run this check once the whole smb.conf is parsed, to
4212 * force some settings for the standard way a AD DC is
4213 * operated. We may changed these as our code evolves, which
4214 * is why we force these settings.
4216 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4217 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4219 lp_do_parameter(-1, "rpc_server:default", "external");
4220 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4221 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4222 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4223 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4224 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4225 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4226 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4227 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4230 bAllowIncludeRegistry = true;
4232 return (bRetval);
4235 bool lp_load(const char *pszFname,
4236 bool global_only,
4237 bool save_defaults,
4238 bool add_ipc,
4239 bool initialize_globals)
4241 return lp_load_ex(pszFname,
4242 global_only,
4243 save_defaults,
4244 add_ipc,
4245 initialize_globals,
4246 true, /* allow_include_registry */
4247 false); /* load_all_shares*/
4250 bool lp_load_initial_only(const char *pszFname)
4252 return lp_load_ex(pszFname,
4253 true, /* global only */
4254 false, /* save_defaults */
4255 false, /* add_ipc */
4256 true, /* initialize_globals */
4257 false, /* allow_include_registry */
4258 false); /* load_all_shares*/
4262 * most common lp_load wrapper, loading only the globals
4264 bool lp_load_global(const char *file_name)
4266 return lp_load_ex(file_name,
4267 true, /* global_only */
4268 false, /* save_defaults */
4269 false, /* add_ipc */
4270 true, /* initialize_globals */
4271 true, /* allow_include_registry */
4272 false); /* load_all_shares*/
4276 * lp_load wrapper, especially for clients
4278 bool lp_load_client(const char *file_name)
4280 lp_set_in_client(true);
4282 return lp_load_global(file_name);
4286 * lp_load wrapper, loading only globals, but intended
4287 * for subsequent calls, not reinitializing the globals
4288 * to default values
4290 bool lp_load_global_no_reinit(const char *file_name)
4292 return lp_load_ex(file_name,
4293 true, /* global_only */
4294 false, /* save_defaults */
4295 false, /* add_ipc */
4296 false, /* initialize_globals */
4297 true, /* allow_include_registry */
4298 false); /* load_all_shares*/
4302 * lp_load wrapper, especially for clients, no reinitialization
4304 bool lp_load_client_no_reinit(const char *file_name)
4306 lp_set_in_client(true);
4308 return lp_load_global_no_reinit(file_name);
4311 bool lp_load_with_registry_shares(const char *pszFname,
4312 bool global_only,
4313 bool save_defaults,
4314 bool add_ipc,
4315 bool initialize_globals)
4317 return lp_load_ex(pszFname,
4318 global_only,
4319 save_defaults,
4320 add_ipc,
4321 initialize_globals,
4322 true, /* allow_include_registry */
4323 true); /* load_all_shares*/
4326 /***************************************************************************
4327 Return the max number of services.
4328 ***************************************************************************/
4330 int lp_numservices(void)
4332 return (iNumServices);
4335 /***************************************************************************
4336 Display the contents of the services array in human-readable form.
4337 ***************************************************************************/
4339 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4341 int iService;
4343 if (show_defaults)
4344 defaults_saved = false;
4346 dump_globals(f);
4348 dump_a_service(&sDefault, f);
4350 for (iService = 0; iService < maxtoprint; iService++) {
4351 fprintf(f,"\n");
4352 lp_dump_one(f, show_defaults, iService);
4356 /***************************************************************************
4357 Display the contents of one service in human-readable form.
4358 ***************************************************************************/
4360 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4362 if (VALID(snum)) {
4363 if (ServicePtrs[snum]->szService[0] == '\0')
4364 return;
4365 dump_a_service(ServicePtrs[snum], f);
4369 /***************************************************************************
4370 Return the number of the service with the given name, or -1 if it doesn't
4371 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4372 getservicebyname()! This works ONLY if all services have been loaded, and
4373 does not copy the found service.
4374 ***************************************************************************/
4376 int lp_servicenumber(const char *pszServiceName)
4378 int iService;
4379 fstring serviceName;
4381 if (!pszServiceName) {
4382 return GLOBAL_SECTION_SNUM;
4385 for (iService = iNumServices - 1; iService >= 0; iService--) {
4386 if (VALID(iService) && ServicePtrs[iService]->szService) {
4388 * The substitution here is used to support %U is
4389 * service names
4391 fstrcpy(serviceName, ServicePtrs[iService]->szService);
4392 standard_sub_basic(get_current_username(),
4393 current_user_info.domain,
4394 serviceName,sizeof(serviceName));
4395 if (strequal(serviceName, pszServiceName)) {
4396 break;
4401 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4402 struct timespec last_mod;
4404 if (!usershare_exists(iService, &last_mod)) {
4405 /* Remove the share security tdb entry for it. */
4406 delete_share_security(lp_servicename(talloc_tos(), iService));
4407 /* Remove it from the array. */
4408 free_service_byindex(iService);
4409 /* Doesn't exist anymore. */
4410 return GLOBAL_SECTION_SNUM;
4413 /* Has it been modified ? If so delete and reload. */
4414 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4415 &last_mod) < 0) {
4416 /* Remove it from the array. */
4417 free_service_byindex(iService);
4418 /* and now reload it. */
4419 iService = load_usershare_service(pszServiceName);
4423 if (iService < 0) {
4424 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4425 return GLOBAL_SECTION_SNUM;
4428 return (iService);
4431 /*******************************************************************
4432 A useful volume label function.
4433 ********************************************************************/
4435 const char *volume_label(TALLOC_CTX *ctx, int snum)
4437 char *ret;
4438 const char *label = lp_volume(ctx, snum);
4439 if (!*label) {
4440 label = lp_servicename(ctx, snum);
4443 /* This returns a 33 byte guarenteed null terminated string. */
4444 ret = talloc_strndup(ctx, label, 32);
4445 if (!ret) {
4446 return "";
4448 return ret;
4451 /*******************************************************************
4452 Get the default server type we will announce as via nmbd.
4453 ********************************************************************/
4455 int lp_default_server_announce(void)
4457 int default_server_announce = 0;
4458 default_server_announce |= SV_TYPE_WORKSTATION;
4459 default_server_announce |= SV_TYPE_SERVER;
4460 default_server_announce |= SV_TYPE_SERVER_UNIX;
4462 /* note that the flag should be set only if we have a
4463 printer service but nmbd doesn't actually load the
4464 services so we can't tell --jerry */
4466 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4468 default_server_announce |= SV_TYPE_SERVER_NT;
4469 default_server_announce |= SV_TYPE_NT;
4471 switch (lp_server_role()) {
4472 case ROLE_DOMAIN_MEMBER:
4473 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4474 break;
4475 case ROLE_DOMAIN_PDC:
4476 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4477 break;
4478 case ROLE_DOMAIN_BDC:
4479 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4480 break;
4481 case ROLE_STANDALONE:
4482 default:
4483 break;
4485 if (lp_time_server())
4486 default_server_announce |= SV_TYPE_TIME_SOURCE;
4488 if (lp_host_msdfs())
4489 default_server_announce |= SV_TYPE_DFS_SERVER;
4491 return default_server_announce;
4494 /***********************************************************
4495 If we are PDC then prefer us as DMB
4496 ************************************************************/
4498 bool lp_domain_master(void)
4500 if (Globals._domain_master == Auto)
4501 return (lp_server_role() == ROLE_DOMAIN_PDC);
4503 return (bool)Globals._domain_master;
4506 /***********************************************************
4507 If we are PDC then prefer us as DMB
4508 ************************************************************/
4510 static bool lp_domain_master_true_or_auto(void)
4512 if (Globals._domain_master) /* auto or yes */
4513 return true;
4515 return false;
4518 /***********************************************************
4519 If we are DMB then prefer us as LMB
4520 ************************************************************/
4522 bool lp_preferred_master(void)
4524 if (Globals.iPreferredMaster == Auto)
4525 return (lp_local_master() && lp_domain_master());
4527 return (bool)Globals.iPreferredMaster;
4530 /*******************************************************************
4531 Remove a service.
4532 ********************************************************************/
4534 void lp_remove_service(int snum)
4536 ServicePtrs[snum]->valid = false;
4539 const char *lp_printername(TALLOC_CTX *ctx, int snum)
4541 const char *ret = lp__printername(ctx, snum);
4542 if (ret == NULL || *ret == '\0') {
4543 ret = lp_const_servicename(snum);
4546 return ret;
4550 /***********************************************************
4551 Allow daemons such as winbindd to fix their logfile name.
4552 ************************************************************/
4554 void lp_set_logfile(const char *name)
4556 string_set(Globals.ctx, &Globals.logfile, name);
4557 debug_set_logfile(name);
4560 /*******************************************************************
4561 Return the max print jobs per queue.
4562 ********************************************************************/
4564 int lp_maxprintjobs(int snum)
4566 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4567 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4568 maxjobs = PRINT_MAX_JOBID - 1;
4570 return maxjobs;
4573 const char *lp_printcapname(void)
4575 if ((Globals.szPrintcapname != NULL) &&
4576 (Globals.szPrintcapname[0] != '\0'))
4577 return Globals.szPrintcapname;
4579 if (sDefault.printing == PRINT_CUPS) {
4580 return "cups";
4583 if (sDefault.printing == PRINT_BSD)
4584 return "/etc/printcap";
4586 return PRINTCAP_NAME;
4589 static uint32 spoolss_state;
4591 bool lp_disable_spoolss( void )
4593 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4594 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4596 return spoolss_state == SVCCTL_STOPPED ? true : false;
4599 void lp_set_spoolss_state( uint32 state )
4601 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4603 spoolss_state = state;
4606 uint32 lp_get_spoolss_state( void )
4608 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4611 /*******************************************************************
4612 Ensure we don't use sendfile if server smb signing is active.
4613 ********************************************************************/
4615 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
4617 bool sign_active = false;
4619 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4620 if (get_Protocol() < PROTOCOL_NT1) {
4621 return false;
4623 if (signing_state) {
4624 sign_active = smb_signing_is_active(signing_state);
4626 return (lp__use_sendfile(snum) &&
4627 (get_remote_arch() != RA_WIN95) &&
4628 !sign_active);
4631 /*******************************************************************
4632 Turn off sendfile if we find the underlying OS doesn't support it.
4633 ********************************************************************/
4635 void set_use_sendfile(int snum, bool val)
4637 if (LP_SNUM_OK(snum))
4638 ServicePtrs[snum]->_use_sendfile = val;
4639 else
4640 sDefault._use_sendfile = val;
4643 /*******************************************************************
4644 Turn off storing DOS attributes if this share doesn't support it.
4645 ********************************************************************/
4647 void set_store_dos_attributes(int snum, bool val)
4649 if (!LP_SNUM_OK(snum))
4650 return;
4651 ServicePtrs[(snum)]->store_dos_attributes = val;
4654 void lp_set_mangling_method(const char *new_method)
4656 string_set(Globals.ctx, &Globals.mangling_method, new_method);
4659 /*******************************************************************
4660 Global state for POSIX pathname processing.
4661 ********************************************************************/
4663 static bool posix_pathnames;
4665 bool lp_posix_pathnames(void)
4667 return posix_pathnames;
4670 /*******************************************************************
4671 Change everything needed to ensure POSIX pathname processing (currently
4672 not much).
4673 ********************************************************************/
4675 void lp_set_posix_pathnames(void)
4677 posix_pathnames = true;
4680 /*******************************************************************
4681 Global state for POSIX lock processing - CIFS unix extensions.
4682 ********************************************************************/
4684 bool posix_default_lock_was_set;
4685 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4687 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4689 if (posix_default_lock_was_set) {
4690 return posix_cifsx_locktype;
4691 } else {
4692 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
4696 /*******************************************************************
4697 ********************************************************************/
4699 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4701 posix_default_lock_was_set = true;
4702 posix_cifsx_locktype = val;
4705 int lp_min_receive_file_size(void)
4707 if (Globals.iminreceivefile < 0) {
4708 return 0;
4710 return Globals.iminreceivefile;
4713 /*******************************************************************
4714 Safe wide links checks.
4715 This helper function always verify the validity of wide links,
4716 even after a configuration file reload.
4717 ********************************************************************/
4719 static bool lp_widelinks_internal(int snum)
4721 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
4722 sDefault.bWidelinks);
4725 void widelinks_warning(int snum)
4727 if (lp_allow_insecure_wide_links()) {
4728 return;
4731 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
4732 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4733 "These parameters are incompatible. "
4734 "Wide links will be disabled for this share.\n",
4735 lp_servicename(talloc_tos(), snum) ));
4739 bool lp_widelinks(int snum)
4741 /* wide links is always incompatible with unix extensions */
4742 if (lp_unix_extensions()) {
4744 * Unless we have "allow insecure widelinks"
4745 * turned on.
4747 if (!lp_allow_insecure_wide_links()) {
4748 return false;
4752 return lp_widelinks_internal(snum);
4755 int lp_server_role(void)
4757 return lp_find_server_role(lp__server_role(),
4758 lp__security(),
4759 lp__domain_logons(),
4760 lp_domain_master_true_or_auto());
4763 int lp_security(void)
4765 return lp_find_security(lp__server_role(),
4766 lp__security());
4769 struct loadparm_global * get_globals(void)
4771 return &Globals;