param: inline init_iconv into handle [dos] charset
[Samba.git] / source3 / param / loadparm.c
blob5f1470a321d39bbb4e404620f5e1d3893c656474
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 /* prototypes for the special type handlers */
264 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
265 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
266 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
267 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
268 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
269 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
270 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
271 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
272 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
274 static void set_allowed_client_auth(void);
276 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
277 static void free_param_opts(struct parmlist_entry **popts);
279 #include "lib/param/param_table.c"
281 /* this is used to prevent lots of mallocs of size 1 */
282 static const char null_string[] = "";
285 Free a string value.
288 static void string_free(char **s)
290 if (!s || !(*s))
291 return;
292 if (*s == null_string)
293 *s = NULL;
294 TALLOC_FREE(*s);
298 Set a string value, deallocating any existing space, and allocing the space
299 for the string
302 static bool string_set(TALLOC_CTX *mem_ctx, char **dest,const char *src)
304 string_free(dest);
306 if (!src) {
307 src = "";
310 (*dest) = talloc_strdup(mem_ctx, src);
311 if ((*dest) == NULL) {
312 DEBUG(0,("Out of memory in string_init\n"));
313 return false;
316 return true;
319 bool lp_string_set(char **dest, const char *src) {
320 return string_set(Globals.ctx, dest, src);
323 /***************************************************************************
324 Initialise the sDefault parameter structure for the printer values.
325 ***************************************************************************/
327 static void init_printer_values(TALLOC_CTX *ctx, struct loadparm_service *pService)
329 /* choose defaults depending on the type of printing */
330 switch (pService->printing) {
331 case PRINT_BSD:
332 case PRINT_AIX:
333 case PRINT_LPRNT:
334 case PRINT_LPROS2:
335 string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
336 string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
337 string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
338 break;
340 case PRINT_LPRNG:
341 case PRINT_PLP:
342 string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
343 string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
344 string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
345 string_set(ctx, &pService->queuepause_command, "lpc stop '%p'");
346 string_set(ctx, &pService->queueresume_command, "lpc start '%p'");
347 string_set(ctx, &pService->lppause_command, "lpc hold '%p' %j");
348 string_set(ctx, &pService->lpresume_command, "lpc release '%p' %j");
349 break;
351 case PRINT_CUPS:
352 case PRINT_IPRINT:
353 /* set the lpq command to contain the destination printer
354 name only. This is used by cups_queue_get() */
355 string_set(ctx, &pService->lpq_command, "%p");
356 string_set(ctx, &pService->lprm_command, "");
357 string_set(ctx, &pService->print_command, "");
358 string_set(ctx, &pService->lppause_command, "");
359 string_set(ctx, &pService->lpresume_command, "");
360 string_set(ctx, &pService->queuepause_command, "");
361 string_set(ctx, &pService->queueresume_command, "");
362 break;
364 case PRINT_SYSV:
365 case PRINT_HPUX:
366 string_set(ctx, &pService->lpq_command, "lpstat -o%p");
367 string_set(ctx, &pService->lprm_command, "cancel %p-%j");
368 string_set(ctx, &pService->print_command, "lp -c -d%p %s; rm %s");
369 string_set(ctx, &pService->queuepause_command, "disable %p");
370 string_set(ctx, &pService->queueresume_command, "enable %p");
371 #ifndef HPUX
372 string_set(ctx, &pService->lppause_command, "lp -i %p-%j -H hold");
373 string_set(ctx, &pService->lpresume_command, "lp -i %p-%j -H resume");
374 #endif /* HPUX */
375 break;
377 case PRINT_QNX:
378 string_set(ctx, &pService->lpq_command, "lpq -P%p");
379 string_set(ctx, &pService->lprm_command, "lprm -P%p %j");
380 string_set(ctx, &pService->print_command, "lp -r -P%p %s");
381 break;
383 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
385 case PRINT_TEST:
386 case PRINT_VLP: {
387 const char *tdbfile;
388 TALLOC_CTX *tmp_ctx = talloc_stackframe();
389 char *tmp;
391 tdbfile = talloc_asprintf(
392 tmp_ctx, "tdbfile=%s",
393 lp_parm_const_string(-1, "vlp", "tdbfile",
394 "/tmp/vlp.tdb"));
395 if (tdbfile == NULL) {
396 tdbfile="tdbfile=/tmp/vlp.tdb";
399 tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
400 tdbfile);
401 string_set(ctx, &pService->print_command,
402 tmp ? tmp : "vlp print %p %s");
404 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
405 tdbfile);
406 string_set(ctx, &pService->lpq_command,
407 tmp ? tmp : "vlp lpq %p");
409 tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
410 tdbfile);
411 string_set(ctx, &pService->lprm_command,
412 tmp ? tmp : "vlp lprm %p %j");
414 tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
415 tdbfile);
416 string_set(ctx, &pService->lppause_command,
417 tmp ? tmp : "vlp lppause %p %j");
419 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
420 tdbfile);
421 string_set(ctx, &pService->lpresume_command,
422 tmp ? tmp : "vlp lpresume %p %j");
424 tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
425 tdbfile);
426 string_set(ctx, &pService->queuepause_command,
427 tmp ? tmp : "vlp queuepause %p");
429 tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
430 tdbfile);
431 string_set(ctx, &pService->queueresume_command,
432 tmp ? tmp : "vlp queueresume %p");
433 TALLOC_FREE(tmp_ctx);
435 break;
437 #endif /* DEVELOPER */
442 * Function to return the default value for the maximum number of open
443 * file descriptors permitted. This function tries to consult the
444 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
445 * the smaller of those.
447 static int max_open_files(void)
449 int sysctl_max = MAX_OPEN_FILES;
450 int rlimit_max = MAX_OPEN_FILES;
452 #ifdef HAVE_SYSCTLBYNAME
454 size_t size = sizeof(sysctl_max);
455 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
458 #endif
460 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
462 struct rlimit rl;
464 ZERO_STRUCT(rl);
466 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
467 rlimit_max = rl.rlim_cur;
469 #if defined(RLIM_INFINITY)
470 if(rl.rlim_cur == RLIM_INFINITY)
471 rlimit_max = MAX_OPEN_FILES;
472 #endif
474 #endif
476 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
477 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
478 "minimum Windows limit (%d)\n",
479 sysctl_max,
480 MIN_OPEN_FILES_WINDOWS));
481 sysctl_max = MIN_OPEN_FILES_WINDOWS;
484 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
485 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
486 "minimum Windows limit (%d)\n",
487 rlimit_max,
488 MIN_OPEN_FILES_WINDOWS));
489 rlimit_max = MIN_OPEN_FILES_WINDOWS;
492 return MIN(sysctl_max, rlimit_max);
496 * Common part of freeing allocated data for one parameter.
498 static void free_one_parameter_common(void *parm_ptr,
499 struct parm_struct parm)
501 if ((parm.type == P_STRING) ||
502 (parm.type == P_USTRING))
504 string_free((char**)parm_ptr);
505 } else if (parm.type == P_LIST) {
506 TALLOC_FREE(*((char***)parm_ptr));
511 * Free the allocated data for one parameter for a share
512 * given as a service struct.
514 static void free_one_parameter(struct loadparm_service *service,
515 struct parm_struct parm)
517 void *parm_ptr;
519 if (parm.p_class != P_LOCAL) {
520 return;
523 parm_ptr = lp_parm_ptr(service, &parm);
525 free_one_parameter_common(parm_ptr, parm);
529 * Free the allocated parameter data of a share given
530 * as a service struct.
532 static void free_parameters(struct loadparm_service *service)
534 uint32_t i;
536 for (i=0; parm_table[i].label; i++) {
537 free_one_parameter(service, parm_table[i]);
542 * Free the allocated data for one parameter for a given share
543 * specified by an snum.
545 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
547 void *parm_ptr;
549 if (snum < 0) {
550 parm_ptr = lp_parm_ptr(NULL, &parm);
551 } else if (parm.p_class != P_LOCAL) {
552 return;
553 } else {
554 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
557 free_one_parameter_common(parm_ptr, parm);
561 * Free the allocated parameter data for a share specified
562 * by an snum.
564 static void free_parameters_by_snum(int snum)
566 uint32_t i;
568 for (i=0; parm_table[i].label; i++) {
569 free_one_parameter_by_snum(snum, parm_table[i]);
574 * Free the allocated global parameters.
576 static void free_global_parameters(void)
578 free_param_opts(&Globals.param_opt);
579 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
580 TALLOC_FREE(Globals.ctx);
583 struct lp_stored_option {
584 struct lp_stored_option *prev, *next;
585 const char *label;
586 const char *value;
589 static struct lp_stored_option *stored_options;
592 save options set by lp_set_cmdline() into a list. This list is
593 re-applied when we do a globals reset, so that cmdline set options
594 are sticky across reloads of smb.conf
596 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
598 struct lp_stored_option *entry, *entry_next;
599 for (entry = stored_options; entry != NULL; entry = entry_next) {
600 entry_next = entry->next;
601 if (strcmp(pszParmName, entry->label) == 0) {
602 DLIST_REMOVE(stored_options, entry);
603 talloc_free(entry);
604 break;
608 entry = talloc(NULL, struct lp_stored_option);
609 if (!entry) {
610 return false;
613 entry->label = talloc_strdup(entry, pszParmName);
614 if (!entry->label) {
615 talloc_free(entry);
616 return false;
619 entry->value = talloc_strdup(entry, pszParmValue);
620 if (!entry->value) {
621 talloc_free(entry);
622 return false;
625 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
627 return true;
630 static bool apply_lp_set_cmdline(void)
632 struct lp_stored_option *entry = NULL;
633 for (entry = stored_options; entry != NULL; entry = entry->next) {
634 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
635 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
636 entry->label, entry->value));
637 return false;
640 return true;
643 /***************************************************************************
644 Initialise the global parameter structure.
645 ***************************************************************************/
647 static void init_globals(bool reinit_globals)
649 static bool done_init = false;
650 char *s = NULL;
651 int i;
653 /* If requested to initialize only once and we've already done it... */
654 if (!reinit_globals && done_init) {
655 /* ... then we have nothing more to do */
656 return;
659 if (!done_init) {
660 /* The logfile can be set before this is invoked. Free it if so. */
661 if (Globals.logfile != NULL) {
662 string_free(&Globals.logfile);
663 Globals.logfile = NULL;
665 done_init = true;
666 } else {
667 free_global_parameters();
670 /* This memset and the free_global_parameters() above will
671 * wipe out smb.conf options set with lp_set_cmdline(). The
672 * apply_lp_set_cmdline() call puts these values back in the
673 * table once the defaults are set */
674 ZERO_STRUCT(Globals);
676 Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
678 for (i = 0; parm_table[i].label; i++) {
679 if ((parm_table[i].type == P_STRING ||
680 parm_table[i].type == P_USTRING))
682 string_set(Globals.ctx, (char **)lp_parm_ptr(NULL, &parm_table[i]), "");
687 string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
688 string_set(Globals.ctx, &sDefault.printjob_username, "%U");
690 init_printer_values(Globals.ctx, &sDefault);
692 sDefault.ntvfs_handler = (const char **)str_list_make_v3(NULL, "unixuid default", NULL);
694 DEBUG(3, ("Initialising global parameters\n"));
696 /* Must manually force to upper case here, as this does not go via the handler */
697 string_set(Globals.ctx, &Globals.netbios_name, myhostname_upper());
699 string_set(Globals.ctx, &Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE());
700 string_set(Globals.ctx, &Globals.private_dir, get_dyn_PRIVATE_DIR());
702 /* use the new 'hash2' method by default, with a prefix of 1 */
703 string_set(Globals.ctx, &Globals.mangling_method, "hash2");
704 Globals.mangle_prefix = 1;
706 string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
708 /* using UTF8 by default allows us to support all chars */
709 string_set(Globals.ctx, &Globals.unix_charset, DEFAULT_UNIX_CHARSET);
711 /* Use codepage 850 as a default for the dos character set */
712 string_set(Globals.ctx, &Globals.dos_charset, DEFAULT_DOS_CHARSET);
715 * Allow the default PASSWD_CHAT to be overridden in local.h.
717 string_set(Globals.ctx, &Globals.passwd_chat, DEFAULT_PASSWD_CHAT);
719 string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
721 string_set(Globals.ctx, &Globals.passwd_program, "");
722 string_set(Globals.ctx, &Globals.lock_directory, get_dyn_LOCKDIR());
723 string_set(Globals.ctx, &Globals.state_directory, get_dyn_STATEDIR());
724 string_set(Globals.ctx, &Globals.cache_directory, get_dyn_CACHEDIR());
725 string_set(Globals.ctx, &Globals.pid_directory, get_dyn_PIDDIR());
726 string_set(Globals.ctx, &Globals.nbt_client_socket_address, "0.0.0.0");
728 * By default support explicit binding to broadcast
729 * addresses.
731 Globals.nmbd_bind_explicit_broadcast = true;
733 s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
734 if (s == NULL) {
735 smb_panic("init_globals: ENOMEM");
737 string_set(Globals.ctx, &Globals.server_string, s);
738 TALLOC_FREE(s);
739 #ifdef DEVELOPER
740 string_set(Globals.ctx, &Globals.panic_action, "/bin/sleep 999999999");
741 #endif
743 string_set(Globals.ctx, &Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
745 string_set(Globals.ctx, &Globals.logon_drive, "");
746 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
747 string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
748 string_set(Globals.ctx, &Globals.logon_path, "\\\\%N\\%U\\profile");
750 Globals.name_resolve_order = (const char **)str_list_make_v3(NULL, "lmhosts wins host bcast", NULL);
751 string_set(Globals.ctx, &Globals.password_server, "*");
753 Globals.algorithmic_rid_base = BASE_RID;
755 Globals.load_printers = true;
756 Globals.printcap_cache_time = 750; /* 12.5 minutes */
758 Globals.config_backend = config_backend;
759 Globals._server_role = ROLE_AUTO;
761 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
762 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
763 Globals.max_xmit = 0x4104;
764 Globals.max_mux = 50; /* This is *needed* for profile support. */
765 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
766 Globals._disable_spoolss = false;
767 Globals.max_smbd_processes = 0;/* no limit specified */
768 Globals.username_level = 0;
769 Globals.deadtime = 0;
770 Globals.getwd_cache = true;
771 Globals.large_readwrite = true;
772 Globals.max_log_size = 5000;
773 Globals.max_open_files = max_open_files();
774 Globals.server_max_protocol = PROTOCOL_SMB3_00;
775 Globals.server_min_protocol = PROTOCOL_LANMAN1;
776 Globals.client_max_protocol = PROTOCOL_NT1;
777 Globals.client_min_protocol = PROTOCOL_CORE;
778 Globals._security = SEC_AUTO;
779 Globals.encrypt_passwords = true;
780 Globals.client_schannel = Auto;
781 Globals.winbind_sealed_pipes = true;
782 Globals.require_strong_key = true;
783 Globals.server_schannel = Auto;
784 Globals.read_raw = true;
785 Globals.write_raw = true;
786 Globals.null_passwords = false;
787 Globals.old_password_allowed_period = 60;
788 Globals.obey_pam_restrictions = false;
789 Globals.syslog = 1;
790 Globals.syslog_only = false;
791 Globals.timestamp_logs = true;
792 string_set(Globals.ctx, &Globals.log_level, "0");
793 Globals.debug_prefix_timestamp = false;
794 Globals.debug_hires_timestamp = true;
795 Globals.debug_pid = false;
796 Globals.debug_uid = false;
797 Globals.debug_class = false;
798 Globals.enable_core_files = true;
799 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
800 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
801 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
802 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
803 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
804 Globals.lm_interval = 60;
805 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
806 Globals.nis_homedir = false;
807 #ifdef WITH_NISPLUS_HOME
808 string_set(Globals.ctx, &Globals.homedir_map, "auto_home.org_dir");
809 #else
810 string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
811 #endif
812 #endif
813 Globals.time_server = false;
814 Globals.bind_interfaces_only = false;
815 Globals.unix_password_sync = false;
816 Globals.pam_password_change = false;
817 Globals.passwd_chat_debug = false;
818 Globals.passwd_chat_timeout = 2; /* 2 second default. */
819 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
820 Globals.nt_status_support = true; /* Use NT status by default. */
821 Globals.stat_cache = true; /* use stat cache by default */
822 Globals.max_stat_cache_size = 256; /* 256k by default */
823 Globals.restrict_anonymous = 0;
824 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
825 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
826 Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
827 Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
828 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 */
829 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
831 Globals.map_to_guest = 0; /* By Default, "Never" */
832 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
833 Globals.enhanced_browsing = true;
834 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
835 #ifdef MMAP_BLACKLIST
836 Globals.use_mmap = false;
837 #else
838 Globals.use_mmap = true;
839 #endif
840 Globals.unicode = true;
841 Globals.unix_extensions = true;
842 Globals.reset_on_zero_vc = false;
843 Globals.log_writeable_files_on_exit = false;
844 Globals.create_krb5_conf = true;
845 Globals.winbindMaxDomainConnections = 1;
847 /* hostname lookups can be very expensive and are broken on
848 a large number of sites (tridge) */
849 Globals.hostname_lookups = false;
851 string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
852 string_set(Globals.ctx, &Globals.ldap_suffix, "");
853 string_set(Globals.ctx, &Globals.szLdapMachineSuffix, "");
854 string_set(Globals.ctx, &Globals.szLdapUserSuffix, "");
855 string_set(Globals.ctx, &Globals.szLdapGroupSuffix, "");
856 string_set(Globals.ctx, &Globals.szLdapIdmapSuffix, "");
858 string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
859 Globals.ldap_ssl = LDAP_SSL_START_TLS;
860 Globals.ldap_ssl_ads = false;
861 Globals.ldap_deref = -1;
862 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
863 Globals.ldap_delete_dn = false;
864 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
865 Globals.ldap_follow_referral = Auto;
866 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
867 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
868 Globals.ldap_page_size = LDAP_PAGE_SIZE;
870 Globals.ldap_debug_level = 0;
871 Globals.ldap_debug_threshold = 10;
873 /* This is what we tell the afs client. in reality we set the token
874 * to never expire, though, when this runs out the afs client will
875 * forget the token. Set to 0 to get NEVERDATE.*/
876 Globals.afs_token_lifetime = 604800;
877 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
879 /* these parameters are set to defaults that are more appropriate
880 for the increasing samba install base:
882 as a member of the workgroup, that will possibly become a
883 _local_ master browser (lm = true). this is opposed to a forced
884 local master browser startup (pm = true).
886 doesn't provide WINS server service by default (wsupp = false),
887 and doesn't provide domain master browser services by default, either.
891 Globals.show_add_printer_wizard = true;
892 Globals.os_level = 20;
893 Globals.local_master = true;
894 Globals._domain_master = Auto; /* depending on _domain_logons */
895 Globals._domain_logons = false;
896 Globals.browse_list = true;
897 Globals.we_are_a_wins_server = false;
898 Globals.wins_proxy = false;
900 TALLOC_FREE(Globals.init_logon_delayed_hosts);
901 Globals.init_logon_delay = 100; /* 100 ms default delay */
903 Globals.wins_dns_proxy = true;
905 Globals.allow_trusted_domains = true;
906 string_set(Globals.ctx, &Globals.szIdmapBackend, "tdb");
908 string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
909 string_set(Globals.ctx, &Globals.template_homedir, "/home/%D/%U");
910 string_set(Globals.ctx, &Globals.winbind_separator, "\\");
911 string_set(Globals.ctx, &Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
913 string_set(Globals.ctx, &Globals.cups_server, "");
914 string_set(Globals.ctx, &Globals.iprint_server, "");
916 string_set(Globals.ctx, &Globals._ctdbd_socket, "");
918 Globals.cluster_addresses = NULL;
919 Globals.clustering = false;
920 Globals.ctdb_timeout = 0;
921 Globals.ctdb_locktime_warn_threshold = 0;
923 Globals.winbind_cache_time = 300; /* 5 minutes */
924 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
925 Globals.winbind_max_clients = 200;
926 Globals.winbind_enum_users = false;
927 Globals.winbind_enum_groups = false;
928 Globals.winbind_use_default_domain = false;
929 Globals.winbind_trusted_domains_only = false;
930 Globals.winbind_nested_groups = true;
931 Globals.winbind_expand_groups = 1;
932 Globals.winbind_nss_info = (const char **)str_list_make_v3(NULL, "template", NULL);
933 Globals.winbind_refresh_tickets = false;
934 Globals.winbind_offline_logon = false;
936 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
937 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
939 Globals.passdb_expand_explicit = false;
941 Globals.name_cache_timeout = 660; /* In seconds */
943 Globals.use_spnego = true;
944 Globals.client_use_spnego = true;
946 Globals.client_signing = SMB_SIGNING_DEFAULT;
947 Globals.server_signing = SMB_SIGNING_DEFAULT;
949 Globals.defer_sharing_violations = true;
950 Globals.smb_ports = (const char **)str_list_make_v3(NULL, SMB_PORTS, NULL);
952 Globals.enable_privileges = true;
953 Globals.host_msdfs = true;
954 Globals.enable_asu_support = false;
956 /* User defined shares. */
957 s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
958 if (s == NULL) {
959 smb_panic("init_globals: ENOMEM");
961 string_set(Globals.ctx, &Globals.usershare_path, s);
962 TALLOC_FREE(s);
963 string_set(Globals.ctx, &Globals.usershare_template_share, "");
964 Globals.usershare_max_shares = 0;
965 /* By default disallow sharing of directories not owned by the sharer. */
966 Globals.usershare_owner_only = true;
967 /* By default disallow guest access to usershares. */
968 Globals.usershare_allow_guests = false;
970 Globals.keepalive = DEFAULT_KEEPALIVE;
972 /* By default no shares out of the registry */
973 Globals.registry_shares = false;
975 Globals.iminreceivefile = 0;
977 Globals.map_untrusted_to_domain = false;
978 Globals.multicast_dns_register = true;
980 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
981 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
982 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
983 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
985 string_set(Globals.ctx, &Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
987 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);
989 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);
991 Globals.tls_enabled = true;
993 string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
994 string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
995 string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
997 string_set(Globals.ctx, &Globals.share_backend, "classic");
999 Globals.iPreferredMaster = Auto;
1001 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
1003 string_set(Globals.ctx, &Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR());
1005 string_set(Globals.ctx, &Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
1007 s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
1008 if (s == NULL) {
1009 smb_panic("init_globals: ENOMEM");
1011 Globals.samba_kcc_command = (const char **)str_list_make_v3(NULL, s, NULL);
1012 TALLOC_FREE(s);
1014 s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
1015 if (s == NULL) {
1016 smb_panic("init_globals: ENOMEM");
1018 Globals.dns_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
1019 TALLOC_FREE(s);
1021 s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
1022 if (s == NULL) {
1023 smb_panic("init_globals: ENOMEM");
1025 Globals.spn_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
1026 TALLOC_FREE(s);
1028 Globals.nsupdate_command = (const char **)str_list_make_v3(NULL, "/usr/bin/nsupdate -g", NULL);
1030 Globals.rndc_command = (const char **)str_list_make_v3(NULL, "/usr/sbin/rndc", NULL);
1032 Globals.cldap_port = 389;
1034 Globals.dgram_port = 138;
1036 Globals.nbt_port = 137;
1038 Globals.krb5_port = 88;
1040 Globals.kpasswd_port = 464;
1042 Globals.web_port = 901;
1044 /* Now put back the settings that were set with lp_set_cmdline() */
1045 apply_lp_set_cmdline();
1048 /*******************************************************************
1049 Convenience routine to grab string parameters into talloced memory
1050 and run standard_sub_basic on them. The buffers can be written to by
1051 callers without affecting the source string.
1052 ********************************************************************/
1054 char *lp_string(TALLOC_CTX *ctx, const char *s)
1056 char *ret;
1058 /* The follow debug is useful for tracking down memory problems
1059 especially if you have an inner loop that is calling a lp_*()
1060 function that returns a string. Perhaps this debug should be
1061 present all the time? */
1063 #if 0
1064 DEBUG(10, ("lp_string(%s)\n", s));
1065 #endif
1066 if (!s) {
1067 return NULL;
1070 ret = talloc_sub_basic(ctx,
1071 get_current_username(),
1072 current_user_info.domain,
1074 if (trim_char(ret, '\"', '\"')) {
1075 if (strchr(ret,'\"') != NULL) {
1076 TALLOC_FREE(ret);
1077 ret = talloc_sub_basic(ctx,
1078 get_current_username(),
1079 current_user_info.domain,
1083 return ret;
1087 In this section all the functions that are used to access the
1088 parameters from the rest of the program are defined
1091 #define FN_GLOBAL_STRING(fn_name,ptr) \
1092 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1093 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1094 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1095 #define FN_GLOBAL_LIST(fn_name,ptr) \
1096 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1097 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1098 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1099 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1100 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1101 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1102 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1104 #define FN_LOCAL_STRING(fn_name,val) \
1105 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));}
1106 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1107 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1108 #define FN_LOCAL_LIST(fn_name,val) \
1109 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1110 #define FN_LOCAL_BOOL(fn_name,val) \
1111 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1112 #define FN_LOCAL_INTEGER(fn_name,val) \
1113 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1115 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1116 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1117 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1118 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1119 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1120 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1122 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
1123 winbindMaxDomainConnections)
1125 int lp_winbind_max_domain_connections(void)
1127 if (lp_winbind_offline_logon() &&
1128 lp_winbind_max_domain_connections_int() > 1) {
1129 DEBUG(1, ("offline logons active, restricting max domain "
1130 "connections to 1\n"));
1131 return 1;
1133 return MAX(1, lp_winbind_max_domain_connections_int());
1136 int lp_smb2_max_credits(void)
1138 if (Globals.ismb2_max_credits == 0) {
1139 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1141 return Globals.ismb2_max_credits;
1143 int lp_cups_encrypt(void)
1145 int result = 0;
1146 #ifdef HAVE_HTTPCONNECTENCRYPT
1147 switch (Globals.CupsEncrypt) {
1148 case Auto:
1149 result = HTTP_ENCRYPT_REQUIRED;
1150 break;
1151 case true:
1152 result = HTTP_ENCRYPT_ALWAYS;
1153 break;
1154 case false:
1155 result = HTTP_ENCRYPT_NEVER;
1156 break;
1158 #endif
1159 return result;
1162 /* These functions remain in source3/param for now */
1164 #include "lib/param/param_functions.c"
1166 FN_LOCAL_STRING(servicename, szService)
1167 FN_LOCAL_CONST_STRING(const_servicename, szService)
1169 /* These functions cannot be auto-generated */
1170 FN_LOCAL_BOOL(autoloaded, autoloaded)
1172 /* local prototypes */
1174 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1175 static const char *get_boolean(bool bool_value);
1176 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1177 void *userdata);
1178 static bool do_section(const char *pszSectionName, void *userdata);
1179 static bool hash_a_service(const char *name, int number);
1180 static void free_service_byindex(int iService);
1181 static void show_parameter(int parmIndex);
1182 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1185 * This is a helper function for parametrical options support. It returns a
1186 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1187 * parametrical functions are quite simple
1189 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
1190 const char *option)
1192 bool global_section = false;
1193 char* param_key;
1194 struct parmlist_entry *data;
1195 TALLOC_CTX *mem_ctx = talloc_stackframe();
1197 if (service == NULL) {
1198 data = Globals.param_opt;
1199 global_section = true;
1200 } else {
1201 data = service->param_opt;
1204 param_key = talloc_asprintf(mem_ctx, "%s:%s", type, option);
1205 if (param_key == NULL) {
1206 DEBUG(0,("asprintf failed!\n"));
1207 TALLOC_FREE(mem_ctx);
1208 return NULL;
1211 while (data) {
1212 if (strwicmp(data->key, param_key) == 0) {
1213 TALLOC_FREE(mem_ctx);
1214 return data;
1216 data = data->next;
1219 if (!global_section) {
1220 /* Try to fetch the same option but from globals */
1221 /* but only if we are not already working with Globals */
1222 data = Globals.param_opt;
1223 while (data) {
1224 if (strwicmp(data->key, param_key) == 0) {
1225 TALLOC_FREE(mem_ctx);
1226 return data;
1228 data = data->next;
1232 TALLOC_FREE(mem_ctx);
1234 return NULL;
1238 * This is a helper function for parametrical options support. It returns a
1239 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1240 * parametrical functions are quite simple
1242 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1243 const char *option)
1245 if (snum >= iNumServices) return NULL;
1247 if (snum < 0) {
1248 return get_parametrics_by_service(NULL, type, option);
1249 } else {
1250 return get_parametrics_by_service(ServicePtrs[snum], type, option);
1255 #define MISSING_PARAMETER(name) \
1256 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1258 /*******************************************************************
1259 convenience routine to return int parameters.
1260 ********************************************************************/
1261 static int lp_int(const char *s)
1264 if (!s || !*s) {
1265 MISSING_PARAMETER(lp_int);
1266 return (-1);
1269 return (int)strtol(s, NULL, 0);
1272 /*******************************************************************
1273 convenience routine to return unsigned long parameters.
1274 ********************************************************************/
1275 static unsigned long lp_ulong(const char *s)
1278 if (!s || !*s) {
1279 MISSING_PARAMETER(lp_ulong);
1280 return (0);
1283 return strtoul(s, NULL, 0);
1286 /*******************************************************************
1287 convenience routine to return boolean parameters.
1288 ********************************************************************/
1289 static bool lp_bool(const char *s)
1291 bool ret = false;
1293 if (!s || !*s) {
1294 MISSING_PARAMETER(lp_bool);
1295 return false;
1298 if (!set_boolean(s, &ret)) {
1299 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1300 return false;
1303 return ret;
1306 /*******************************************************************
1307 convenience routine to return enum parameters.
1308 ********************************************************************/
1309 static int lp_enum(const char *s,const struct enum_list *_enum)
1311 int i;
1313 if (!s || !*s || !_enum) {
1314 MISSING_PARAMETER(lp_enum);
1315 return (-1);
1318 for (i=0; _enum[i].name; i++) {
1319 if (strequal(_enum[i].name,s))
1320 return _enum[i].value;
1323 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1324 return (-1);
1327 #undef MISSING_PARAMETER
1329 /* Return parametric option from a given service. Type is a part of option before ':' */
1330 /* Parametric option has following syntax: 'Type: option = value' */
1331 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1333 struct parmlist_entry *data = get_parametrics(snum, type, option);
1335 if (data == NULL||data->value==NULL) {
1336 if (def) {
1337 return lp_string(ctx, def);
1338 } else {
1339 return NULL;
1343 return lp_string(ctx, data->value);
1346 /* Return parametric option from a given service. Type is a part of option before ':' */
1347 /* Parametric option has following syntax: 'Type: option = value' */
1348 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1350 struct parmlist_entry *data = get_parametrics(snum, type, option);
1352 if (data == NULL||data->value==NULL)
1353 return def;
1355 return data->value;
1358 const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
1360 struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
1362 if (data == NULL||data->value==NULL)
1363 return NULL;
1365 return data->value;
1369 /* Return parametric option from a given service. Type is a part of option before ':' */
1370 /* Parametric option has following syntax: 'Type: option = value' */
1372 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1374 struct parmlist_entry *data = get_parametrics(snum, type, option);
1376 if (data == NULL||data->value==NULL)
1377 return (const char **)def;
1379 if (data->list==NULL) {
1380 data->list = str_list_make_v3(NULL, data->value, NULL);
1383 return (const char **)data->list;
1386 /* Return parametric option from a given service. Type is a part of option before ':' */
1387 /* Parametric option has following syntax: 'Type: option = value' */
1389 int lp_parm_int(int snum, const char *type, const char *option, int def)
1391 struct parmlist_entry *data = get_parametrics(snum, type, option);
1393 if (data && data->value && *data->value)
1394 return lp_int(data->value);
1396 return def;
1399 /* Return parametric option from a given service. Type is a part of option before ':' */
1400 /* Parametric option has following syntax: 'Type: option = value' */
1402 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1404 struct parmlist_entry *data = get_parametrics(snum, type, option);
1406 if (data && data->value && *data->value)
1407 return lp_ulong(data->value);
1409 return def;
1412 /* Return parametric option from a given service. Type is a part of option before ':' */
1413 /* Parametric option has following syntax: 'Type: option = value' */
1415 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1417 struct parmlist_entry *data = get_parametrics(snum, type, option);
1419 if (data && data->value && *data->value)
1420 return lp_bool(data->value);
1422 return def;
1425 /* Return parametric option from a given service. Type is a part of option before ':' */
1426 /* Parametric option has following syntax: 'Type: option = value' */
1428 int lp_parm_enum(int snum, const char *type, const char *option,
1429 const struct enum_list *_enum, int def)
1431 struct parmlist_entry *data = get_parametrics(snum, type, option);
1433 if (data && data->value && *data->value && _enum)
1434 return lp_enum(data->value, _enum);
1436 return def;
1440 * free a param_opts structure.
1441 * param_opts handling should be moved to talloc;
1442 * then this whole functions reduces to a TALLOC_FREE().
1445 static void free_param_opts(struct parmlist_entry **popts)
1447 struct parmlist_entry *opt, *next_opt;
1449 if (*popts != NULL) {
1450 DEBUG(5, ("Freeing parametrics:\n"));
1452 opt = *popts;
1453 while (opt != NULL) {
1454 string_free(&opt->key);
1455 string_free(&opt->value);
1456 TALLOC_FREE(opt->list);
1457 next_opt = opt->next;
1458 TALLOC_FREE(opt);
1459 opt = next_opt;
1461 *popts = NULL;
1464 /***************************************************************************
1465 Free the dynamically allocated parts of a service struct.
1466 ***************************************************************************/
1468 static void free_service(struct loadparm_service *pservice)
1470 if (!pservice)
1471 return;
1473 if (pservice->szService)
1474 DEBUG(5, ("free_service: Freeing service %s\n",
1475 pservice->szService));
1477 free_parameters(pservice);
1479 string_free(&pservice->szService);
1480 TALLOC_FREE(pservice->copymap);
1482 free_param_opts(&pservice->param_opt);
1484 ZERO_STRUCTP(pservice);
1488 /***************************************************************************
1489 remove a service indexed in the ServicePtrs array from the ServiceHash
1490 and free the dynamically allocated parts
1491 ***************************************************************************/
1493 static void free_service_byindex(int idx)
1495 if ( !LP_SNUM_OK(idx) )
1496 return;
1498 ServicePtrs[idx]->valid = false;
1500 /* we have to cleanup the hash record */
1502 if (ServicePtrs[idx]->szService) {
1503 char *canon_name = canonicalize_servicename(
1504 talloc_tos(),
1505 ServicePtrs[idx]->szService );
1507 dbwrap_delete_bystring(ServiceHash, canon_name );
1508 TALLOC_FREE(canon_name);
1511 free_service(ServicePtrs[idx]);
1512 talloc_free_children(ServicePtrs[idx]);
1515 /***************************************************************************
1516 Add a new service to the services array initialising it with the given
1517 service.
1518 ***************************************************************************/
1520 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1522 int i;
1523 int num_to_alloc = iNumServices + 1;
1524 struct loadparm_service **tsp = NULL;
1526 /* it might already exist */
1527 if (name) {
1528 i = getservicebyname(name, NULL);
1529 if (i >= 0) {
1530 return (i);
1534 /* if not, then create one */
1535 i = iNumServices;
1536 tsp = talloc_realloc(NULL, ServicePtrs, struct loadparm_service *, num_to_alloc);
1537 if (tsp == NULL) {
1538 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1539 return (-1);
1541 ServicePtrs = tsp;
1542 ServicePtrs[iNumServices] = talloc_zero(NULL, struct loadparm_service);
1543 if (!ServicePtrs[iNumServices]) {
1544 DEBUG(0,("add_a_service: out of memory!\n"));
1545 return (-1);
1547 iNumServices++;
1549 ServicePtrs[i]->valid = true;
1551 copy_service(ServicePtrs[i], pservice, NULL);
1552 if (name)
1553 string_set(ServicePtrs[i], &ServicePtrs[i]->szService, name);
1555 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1556 i, ServicePtrs[i]->szService));
1558 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1559 return (-1);
1562 return (i);
1565 /***************************************************************************
1566 Convert a string to uppercase and remove whitespaces.
1567 ***************************************************************************/
1569 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1571 char *result;
1573 if ( !src ) {
1574 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1575 return NULL;
1578 result = talloc_strdup(ctx, src);
1579 SMB_ASSERT(result != NULL);
1581 if (!strlower_m(result)) {
1582 TALLOC_FREE(result);
1583 return NULL;
1585 return result;
1588 /***************************************************************************
1589 Add a name/index pair for the services array to the hash table.
1590 ***************************************************************************/
1592 static bool hash_a_service(const char *name, int idx)
1594 char *canon_name;
1596 if ( !ServiceHash ) {
1597 DEBUG(10,("hash_a_service: creating servicehash\n"));
1598 ServiceHash = db_open_rbt(NULL);
1599 if ( !ServiceHash ) {
1600 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1601 return false;
1605 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1606 idx, name));
1608 canon_name = canonicalize_servicename(talloc_tos(), name );
1610 dbwrap_store_bystring(ServiceHash, canon_name,
1611 make_tdb_data((uint8 *)&idx, sizeof(idx)),
1612 TDB_REPLACE);
1614 TALLOC_FREE(canon_name);
1616 return true;
1619 /***************************************************************************
1620 Add a new home service, with the specified home directory, defaults coming
1621 from service ifrom.
1622 ***************************************************************************/
1624 bool lp_add_home(const char *pszHomename, int iDefaultService,
1625 const char *user, const char *pszHomedir)
1627 int i;
1629 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1630 pszHomedir[0] == '\0') {
1631 return false;
1634 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1636 if (i < 0)
1637 return false;
1639 if (!(*(ServicePtrs[iDefaultService]->path))
1640 || strequal(ServicePtrs[iDefaultService]->path,
1641 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1642 string_set(ServicePtrs[i], &ServicePtrs[i]->path, pszHomedir);
1645 if (!(*(ServicePtrs[i]->comment))) {
1646 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1647 if (comment == NULL) {
1648 return false;
1650 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1651 TALLOC_FREE(comment);
1654 /* set the browseable flag from the global default */
1656 ServicePtrs[i]->browseable = sDefault.browseable;
1657 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1659 ServicePtrs[i]->autoloaded = true;
1661 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1662 user, ServicePtrs[i]->path ));
1664 return true;
1667 /***************************************************************************
1668 Add a new service, based on an old one.
1669 ***************************************************************************/
1671 int lp_add_service(const char *pszService, int iDefaultService)
1673 if (iDefaultService < 0) {
1674 return add_a_service(&sDefault, pszService);
1677 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1680 /***************************************************************************
1681 Add the IPC service.
1682 ***************************************************************************/
1684 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1686 char *comment = NULL;
1687 int i = add_a_service(&sDefault, ipc_name);
1689 if (i < 0)
1690 return false;
1692 comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1693 Globals.server_string);
1694 if (comment == NULL) {
1695 return false;
1698 string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1699 string_set(ServicePtrs[i], &ServicePtrs[i]->username, "");
1700 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1701 string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1702 ServicePtrs[i]->max_connections = 0;
1703 ServicePtrs[i]->bAvailable = true;
1704 ServicePtrs[i]->read_only = true;
1705 ServicePtrs[i]->guest_only = false;
1706 ServicePtrs[i]->administrative_share = true;
1707 ServicePtrs[i]->guest_ok = guest_ok;
1708 ServicePtrs[i]->printable = false;
1709 ServicePtrs[i]->browseable = sDefault.browseable;
1711 DEBUG(3, ("adding IPC service\n"));
1713 TALLOC_FREE(comment);
1714 return true;
1717 /***************************************************************************
1718 Add a new printer service, with defaults coming from service iFrom.
1719 ***************************************************************************/
1721 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1723 const char *comment = "From Printcap";
1724 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1726 if (i < 0)
1727 return false;
1729 /* note that we do NOT default the availability flag to true - */
1730 /* we take it from the default service passed. This allows all */
1731 /* dynamic printers to be disabled by disabling the [printers] */
1732 /* entry (if/when the 'available' keyword is implemented!). */
1734 /* the printer name is set to the service name. */
1735 string_set(ServicePtrs[i], &ServicePtrs[i]->_printername, pszPrintername);
1736 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1738 /* set the browseable flag from the gloabl default */
1739 ServicePtrs[i]->browseable = sDefault.browseable;
1741 /* Printers cannot be read_only. */
1742 ServicePtrs[i]->read_only = false;
1743 /* No oplocks on printer services. */
1744 ServicePtrs[i]->oplocks = false;
1745 /* Printer services must be printable. */
1746 ServicePtrs[i]->printable = true;
1748 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1750 return true;
1754 /***************************************************************************
1755 Check whether the given parameter name is valid.
1756 Parametric options (names containing a colon) are considered valid.
1757 ***************************************************************************/
1759 bool lp_parameter_is_valid(const char *pszParmName)
1761 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1762 (strchr(pszParmName, ':') != NULL));
1765 /***************************************************************************
1766 Check whether the given name is the name of a global parameter.
1767 Returns true for strings belonging to parameters of class
1768 P_GLOBAL, false for all other strings, also for parametric options
1769 and strings not belonging to any option.
1770 ***************************************************************************/
1772 bool lp_parameter_is_global(const char *pszParmName)
1774 int num = lpcfg_map_parameter(pszParmName);
1776 if (num >= 0) {
1777 return (parm_table[num].p_class == P_GLOBAL);
1780 return false;
1783 /**************************************************************************
1784 Check whether the given name is the canonical name of a parameter.
1785 Returns false if it is not a valid parameter Name.
1786 For parametric options, true is returned.
1787 **************************************************************************/
1789 bool lp_parameter_is_canonical(const char *parm_name)
1791 if (!lp_parameter_is_valid(parm_name)) {
1792 return false;
1795 return (lpcfg_map_parameter(parm_name) ==
1796 map_parameter_canonical(parm_name, NULL));
1799 /**************************************************************************
1800 Determine the canonical name for a parameter.
1801 Indicate when it is an inverse (boolean) synonym instead of a
1802 "usual" synonym.
1803 **************************************************************************/
1805 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1806 bool *inverse)
1808 int num;
1810 if (!lp_parameter_is_valid(parm_name)) {
1811 *canon_parm = NULL;
1812 return false;
1815 num = map_parameter_canonical(parm_name, inverse);
1816 if (num < 0) {
1817 /* parametric option */
1818 *canon_parm = parm_name;
1819 } else {
1820 *canon_parm = parm_table[num].label;
1823 return true;
1827 /**************************************************************************
1828 Determine the canonical name for a parameter.
1829 Turn the value given into the inverse boolean expression when
1830 the synonym is an invers boolean synonym.
1832 Return true if parm_name is a valid parameter name and
1833 in case it is an invers boolean synonym, if the val string could
1834 successfully be converted to the reverse bool.
1835 Return false in all other cases.
1836 **************************************************************************/
1838 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1839 const char *val,
1840 const char **canon_parm,
1841 const char **canon_val)
1843 int num;
1844 bool inverse;
1846 if (!lp_parameter_is_valid(parm_name)) {
1847 *canon_parm = NULL;
1848 *canon_val = NULL;
1849 return false;
1852 num = map_parameter_canonical(parm_name, &inverse);
1853 if (num < 0) {
1854 /* parametric option */
1855 *canon_parm = parm_name;
1856 *canon_val = val;
1857 } else {
1858 *canon_parm = parm_table[num].label;
1859 if (inverse) {
1860 if (!lp_invert_boolean(val, canon_val)) {
1861 *canon_val = NULL;
1862 return false;
1864 } else {
1865 *canon_val = val;
1869 return true;
1872 /***************************************************************************
1873 Map a parameter's string representation to the index of the canonical
1874 form of the parameter (it might be a synonym).
1875 Returns -1 if the parameter string is not recognised.
1876 ***************************************************************************/
1878 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1880 int parm_num, canon_num;
1881 bool loc_inverse = false;
1883 parm_num = lpcfg_map_parameter(pszParmName);
1884 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
1885 /* invalid, parametric or no canidate for synonyms ... */
1886 goto done;
1889 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1890 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1891 parm_num = canon_num;
1892 goto done;
1896 done:
1897 if (inverse != NULL) {
1898 *inverse = loc_inverse;
1900 return parm_num;
1903 /***************************************************************************
1904 return true if parameter number parm1 is a synonym of parameter
1905 number parm2 (parm2 being the principal name).
1906 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1907 false otherwise.
1908 ***************************************************************************/
1910 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1912 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1913 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1914 (parm_table[parm1].flags & FLAG_HIDE) &&
1915 !(parm_table[parm2].flags & FLAG_HIDE))
1917 if (inverse != NULL) {
1918 if ((parm_table[parm1].type == P_BOOLREV) &&
1919 (parm_table[parm2].type == P_BOOL))
1921 *inverse = true;
1922 } else {
1923 *inverse = false;
1926 return true;
1928 return false;
1931 /***************************************************************************
1932 Show one parameter's name, type, [values,] and flags.
1933 (helper functions for show_parameter_list)
1934 ***************************************************************************/
1936 static void show_parameter(int parmIndex)
1938 int enumIndex, flagIndex;
1939 int parmIndex2;
1940 bool hadFlag;
1941 bool hadSyn;
1942 bool inverse;
1943 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1944 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1945 "P_ENUM", "P_SEP"};
1946 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
1947 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
1948 FLAG_HIDE};
1949 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
1950 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
1951 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
1953 printf("%s=%s", parm_table[parmIndex].label,
1954 type[parm_table[parmIndex].type]);
1955 if (parm_table[parmIndex].type == P_ENUM) {
1956 printf(",");
1957 for (enumIndex=0;
1958 parm_table[parmIndex].enum_list[enumIndex].name;
1959 enumIndex++)
1961 printf("%s%s",
1962 enumIndex ? "|" : "",
1963 parm_table[parmIndex].enum_list[enumIndex].name);
1966 printf(",");
1967 hadFlag = false;
1968 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1969 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1970 printf("%s%s",
1971 hadFlag ? "|" : "",
1972 flag_names[flagIndex]);
1973 hadFlag = true;
1977 /* output synonyms */
1978 hadSyn = false;
1979 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1980 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1981 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1982 parm_table[parmIndex2].label);
1983 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1984 if (!hadSyn) {
1985 printf(" (synonyms: ");
1986 hadSyn = true;
1987 } else {
1988 printf(", ");
1990 printf("%s%s", parm_table[parmIndex2].label,
1991 inverse ? "[i]" : "");
1994 if (hadSyn) {
1995 printf(")");
1998 printf("\n");
2001 /***************************************************************************
2002 Show all parameter's name, type, [values,] and flags.
2003 ***************************************************************************/
2005 void show_parameter_list(void)
2007 int classIndex, parmIndex;
2008 const char *section_names[] = { "local", "global", NULL};
2010 for (classIndex=0; section_names[classIndex]; classIndex++) {
2011 printf("[%s]\n", section_names[classIndex]);
2012 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2013 if (parm_table[parmIndex].p_class == classIndex) {
2014 show_parameter(parmIndex);
2020 /***************************************************************************
2021 Get the standard string representation of a boolean value ("yes" or "no")
2022 ***************************************************************************/
2024 static const char *get_boolean(bool bool_value)
2026 static const char *yes_str = "yes";
2027 static const char *no_str = "no";
2029 return (bool_value ? yes_str : no_str);
2032 /***************************************************************************
2033 Provide the string of the negated boolean value associated to the boolean
2034 given as a string. Returns false if the passed string does not correctly
2035 represent a boolean.
2036 ***************************************************************************/
2038 bool lp_invert_boolean(const char *str, const char **inverse_str)
2040 bool val;
2042 if (!set_boolean(str, &val)) {
2043 return false;
2046 *inverse_str = get_boolean(!val);
2047 return true;
2050 /***************************************************************************
2051 Provide the canonical string representation of a boolean value given
2052 as a string. Return true on success, false if the string given does
2053 not correctly represent a boolean.
2054 ***************************************************************************/
2056 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2058 bool val;
2060 if (!set_boolean(str, &val)) {
2061 return false;
2064 *canon_str = get_boolean(val);
2065 return true;
2068 /***************************************************************************
2069 Find a service by name. Otherwise works like get_service.
2070 ***************************************************************************/
2072 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2074 int iService = -1;
2075 char *canon_name;
2076 TDB_DATA data;
2077 NTSTATUS status;
2079 if (ServiceHash == NULL) {
2080 return -1;
2083 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2085 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2086 &data);
2088 if (NT_STATUS_IS_OK(status) &&
2089 (data.dptr != NULL) &&
2090 (data.dsize == sizeof(iService)))
2092 iService = *(int *)data.dptr;
2095 TALLOC_FREE(canon_name);
2097 if ((iService != -1) && (LP_SNUM_OK(iService))
2098 && (pserviceDest != NULL)) {
2099 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2102 return (iService);
2105 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2106 struct loadparm_service *lp_service(const char *pszServiceName)
2108 int iService = getservicebyname(pszServiceName, NULL);
2109 if (iService == -1 || !LP_SNUM_OK(iService)) {
2110 return NULL;
2112 return ServicePtrs[iService];
2115 struct loadparm_service *lp_servicebynum(int snum)
2117 if ((snum == -1) || !LP_SNUM_OK(snum)) {
2118 return NULL;
2120 return ServicePtrs[snum];
2123 struct loadparm_service *lp_default_loadparm_service()
2125 return &sDefault;
2128 /***************************************************************************
2129 Check a service for consistency. Return false if the service is in any way
2130 incomplete or faulty, else true.
2131 ***************************************************************************/
2133 bool service_ok(int iService)
2135 bool bRetval;
2137 bRetval = true;
2138 if (ServicePtrs[iService]->szService[0] == '\0') {
2139 DEBUG(0, ("The following message indicates an internal error:\n"));
2140 DEBUG(0, ("No service name in service entry.\n"));
2141 bRetval = false;
2144 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2145 /* I can't see why you'd want a non-printable printer service... */
2146 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2147 if (!ServicePtrs[iService]->printable) {
2148 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2149 ServicePtrs[iService]->szService));
2150 ServicePtrs[iService]->printable = true;
2152 /* [printers] service must also be non-browsable. */
2153 if (ServicePtrs[iService]->browseable)
2154 ServicePtrs[iService]->browseable = false;
2157 if (ServicePtrs[iService]->path[0] == '\0' &&
2158 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
2159 ServicePtrs[iService]->msdfs_proxy[0] == '\0'
2161 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2162 ServicePtrs[iService]->szService));
2163 ServicePtrs[iService]->bAvailable = false;
2166 /* If a service is flagged unavailable, log the fact at level 1. */
2167 if (!ServicePtrs[iService]->bAvailable)
2168 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2169 ServicePtrs[iService]->szService));
2171 return (bRetval);
2174 static struct smbconf_ctx *lp_smbconf_ctx(void)
2176 sbcErr err;
2177 static struct smbconf_ctx *conf_ctx = NULL;
2179 if (conf_ctx == NULL) {
2180 err = smbconf_init(NULL, &conf_ctx, "registry:");
2181 if (!SBC_ERROR_IS_OK(err)) {
2182 DEBUG(1, ("error initializing registry configuration: "
2183 "%s\n", sbcErrorString(err)));
2184 conf_ctx = NULL;
2188 return conf_ctx;
2191 static bool process_smbconf_service(struct smbconf_service *service)
2193 uint32_t count;
2194 bool ret;
2196 if (service == NULL) {
2197 return false;
2200 ret = do_section(service->name, NULL);
2201 if (ret != true) {
2202 return false;
2204 for (count = 0; count < service->num_params; count++) {
2205 ret = do_parameter(service->param_names[count],
2206 service->param_values[count],
2207 NULL);
2208 if (ret != true) {
2209 return false;
2212 if (iServiceIndex >= 0) {
2213 return service_ok(iServiceIndex);
2215 return true;
2219 * load a service from registry and activate it
2221 bool process_registry_service(const char *service_name)
2223 sbcErr err;
2224 struct smbconf_service *service = NULL;
2225 TALLOC_CTX *mem_ctx = talloc_stackframe();
2226 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2227 bool ret = false;
2229 if (conf_ctx == NULL) {
2230 goto done;
2233 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2235 if (!smbconf_share_exists(conf_ctx, service_name)) {
2237 * Registry does not contain data for this service (yet),
2238 * but make sure lp_load doesn't return false.
2240 ret = true;
2241 goto done;
2244 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2245 if (!SBC_ERROR_IS_OK(err)) {
2246 goto done;
2249 ret = process_smbconf_service(service);
2250 if (!ret) {
2251 goto done;
2254 /* store the csn */
2255 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2257 done:
2258 TALLOC_FREE(mem_ctx);
2259 return ret;
2263 * process_registry_globals
2265 static bool process_registry_globals(void)
2267 bool ret;
2269 add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2271 ret = do_parameter("registry shares", "yes", NULL);
2272 if (!ret) {
2273 return ret;
2276 return process_registry_service(GLOBAL_NAME);
2279 bool process_registry_shares(void)
2281 sbcErr err;
2282 uint32_t count;
2283 struct smbconf_service **service = NULL;
2284 uint32_t num_shares = 0;
2285 TALLOC_CTX *mem_ctx = talloc_stackframe();
2286 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2287 bool ret = false;
2289 if (conf_ctx == NULL) {
2290 goto done;
2293 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2294 if (!SBC_ERROR_IS_OK(err)) {
2295 goto done;
2298 ret = true;
2300 for (count = 0; count < num_shares; count++) {
2301 if (strequal(service[count]->name, GLOBAL_NAME)) {
2302 continue;
2304 ret = process_smbconf_service(service[count]);
2305 if (!ret) {
2306 goto done;
2310 /* store the csn */
2311 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2313 done:
2314 TALLOC_FREE(mem_ctx);
2315 return ret;
2319 * reload those shares from registry that are already
2320 * activated in the services array.
2322 static bool reload_registry_shares(void)
2324 int i;
2325 bool ret = true;
2327 for (i = 0; i < iNumServices; i++) {
2328 if (!VALID(i)) {
2329 continue;
2332 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2333 continue;
2336 ret = process_registry_service(ServicePtrs[i]->szService);
2337 if (!ret) {
2338 goto done;
2342 done:
2343 return ret;
2347 #define MAX_INCLUDE_DEPTH 100
2349 static uint8_t include_depth;
2352 * Free the file lists
2354 static void free_file_list(void)
2356 struct file_lists *f;
2357 struct file_lists *next;
2359 f = file_lists;
2360 while( f ) {
2361 next = f->next;
2362 TALLOC_FREE( f );
2363 f = next;
2365 file_lists = NULL;
2370 * Utility function for outsiders to check if we're running on registry.
2372 bool lp_config_backend_is_registry(void)
2374 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2378 * Utility function to check if the config backend is FILE.
2380 bool lp_config_backend_is_file(void)
2382 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2385 /*******************************************************************
2386 Check if a config file has changed date.
2387 ********************************************************************/
2389 bool lp_file_list_changed(void)
2391 struct file_lists *f = file_lists;
2393 DEBUG(6, ("lp_file_list_changed()\n"));
2395 while (f) {
2396 time_t mod_time;
2398 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2399 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2401 if (conf_ctx == NULL) {
2402 return false;
2404 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2405 NULL))
2407 DEBUGADD(6, ("registry config changed\n"));
2408 return true;
2410 } else {
2411 char *n2 = NULL;
2412 n2 = talloc_sub_basic(talloc_tos(),
2413 get_current_username(),
2414 current_user_info.domain,
2415 f->name);
2416 if (!n2) {
2417 return false;
2419 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2420 f->name, n2, ctime(&f->modtime)));
2422 mod_time = file_modtime(n2);
2424 if (mod_time &&
2425 ((f->modtime != mod_time) ||
2426 (f->subfname == NULL) ||
2427 (strcmp(n2, f->subfname) != 0)))
2429 DEBUGADD(6,
2430 ("file %s modified: %s\n", n2,
2431 ctime(&mod_time)));
2432 f->modtime = mod_time;
2433 TALLOC_FREE(f->subfname);
2434 f->subfname = talloc_strdup(f, n2);
2435 if (f->subfname == NULL) {
2436 smb_panic("talloc_strdup failed");
2438 TALLOC_FREE(n2);
2439 return true;
2441 TALLOC_FREE(n2);
2443 f = f->next;
2445 return false;
2450 * Initialize iconv conversion descriptors.
2452 * This is called the first time it is needed, and also called again
2453 * every time the configuration is reloaded, because the charset or
2454 * codepage might have changed.
2456 static void init_iconv(void)
2458 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2459 lp_unix_charset(),
2460 true, global_iconv_handle);
2463 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2465 if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
2466 string_set(Globals.ctx, ptr, pszParmValue);
2467 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2468 lp_unix_charset(),
2469 true, global_iconv_handle);
2471 return true;
2474 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2476 bool is_utf8 = false;
2477 size_t len = strlen(pszParmValue);
2479 if (len == 4 || len == 5) {
2480 /* Don't use StrCaseCmp here as we don't want to
2481 initialize iconv. */
2482 if ((toupper_m(pszParmValue[0]) == 'U') &&
2483 (toupper_m(pszParmValue[1]) == 'T') &&
2484 (toupper_m(pszParmValue[2]) == 'F')) {
2485 if (len == 4) {
2486 if (pszParmValue[3] == '8') {
2487 is_utf8 = true;
2489 } else {
2490 if (pszParmValue[3] == '-' &&
2491 pszParmValue[4] == '8') {
2492 is_utf8 = true;
2498 if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
2499 if (is_utf8) {
2500 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
2501 "be UTF8, using (default value) %s instead.\n",
2502 DEFAULT_DOS_CHARSET));
2503 pszParmValue = DEFAULT_DOS_CHARSET;
2505 string_set(Globals.ctx, ptr, pszParmValue);
2506 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2507 lp_unix_charset(),
2508 true, global_iconv_handle);
2510 return true;
2513 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2515 TALLOC_FREE(Globals.netbios_aliases);
2516 Globals.netbios_aliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
2517 return set_netbios_aliases(Globals.netbios_aliases);
2520 /***************************************************************************
2521 Handle the include operation.
2522 ***************************************************************************/
2523 static bool bAllowIncludeRegistry = true;
2525 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2527 char *fname;
2529 if (include_depth >= MAX_INCLUDE_DEPTH) {
2530 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2531 include_depth));
2532 return false;
2535 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2536 if (!bAllowIncludeRegistry) {
2537 return true;
2539 if (bInGlobalSection) {
2540 bool ret;
2541 include_depth++;
2542 ret = process_registry_globals();
2543 include_depth--;
2544 return ret;
2545 } else {
2546 DEBUG(1, ("\"include = registry\" only effective "
2547 "in %s section\n", GLOBAL_NAME));
2548 return false;
2552 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2553 current_user_info.domain,
2554 pszParmValue);
2556 add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2558 if (snum < 0) {
2559 string_set(Globals.ctx, ptr, fname);
2560 } else {
2561 string_set(ServicePtrs[snum], ptr, fname);
2564 if (file_exist(fname)) {
2565 bool ret;
2566 include_depth++;
2567 ret = pm_process(fname, do_section, do_parameter, NULL);
2568 include_depth--;
2569 TALLOC_FREE(fname);
2570 return ret;
2573 DEBUG(2, ("Can't find include file %s\n", fname));
2574 TALLOC_FREE(fname);
2575 return true;
2578 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2580 Globals.ldap_debug_level = lp_int(pszParmValue);
2581 init_ldap_debugging();
2582 return true;
2586 * idmap related parameters
2589 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2591 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
2593 return true;
2596 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2598 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2600 return true;
2603 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2605 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2607 return true;
2610 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2612 char *config_option = NULL;
2613 const char *range = NULL;
2614 bool ret = false;
2616 SMB_ASSERT(low != NULL);
2617 SMB_ASSERT(high != NULL);
2619 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2620 domain_name = "*";
2623 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2624 domain_name);
2625 if (config_option == NULL) {
2626 DEBUG(0, ("out of memory\n"));
2627 return false;
2630 range = lp_parm_const_string(-1, config_option, "range", NULL);
2631 if (range == NULL) {
2632 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2633 goto done;
2636 if (sscanf(range, "%u - %u", low, high) != 2) {
2637 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2638 range, domain_name));
2639 goto done;
2642 ret = true;
2644 done:
2645 talloc_free(config_option);
2646 return ret;
2650 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2652 return lp_idmap_range("*", low, high);
2655 const char *lp_idmap_backend(const char *domain_name)
2657 char *config_option = NULL;
2658 const char *backend = NULL;
2660 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2661 domain_name = "*";
2664 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2665 domain_name);
2666 if (config_option == NULL) {
2667 DEBUG(0, ("out of memory\n"));
2668 return false;
2671 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2672 if (backend == NULL) {
2673 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2674 goto done;
2677 done:
2678 talloc_free(config_option);
2679 return backend;
2682 const char *lp_idmap_default_backend(void)
2684 return lp_idmap_backend("*");
2687 /***************************************************************************
2688 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2689 ***************************************************************************/
2691 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2693 const char *suffix_string;
2695 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2696 Globals.ldap_suffix );
2697 if ( !suffix_string ) {
2698 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2699 return "";
2702 return suffix_string;
2705 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2707 if (Globals.szLdapMachineSuffix[0])
2708 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
2710 return lp_string(ctx, Globals.ldap_suffix);
2713 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2715 if (Globals.szLdapUserSuffix[0])
2716 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
2718 return lp_string(ctx, Globals.ldap_suffix);
2721 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2723 if (Globals.szLdapGroupSuffix[0])
2724 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
2726 return lp_string(ctx, Globals.ldap_suffix);
2729 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2731 if (Globals.szLdapIdmapSuffix[0])
2732 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
2734 return lp_string(ctx, Globals.ldap_suffix);
2737 /****************************************************************************
2738 set the value for a P_ENUM
2739 ***************************************************************************/
2741 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
2742 int *ptr )
2744 int i;
2746 for (i = 0; parm->enum_list[i].name; i++) {
2747 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
2748 *ptr = parm->enum_list[i].value;
2749 return;
2752 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
2753 pszParmValue, parm->label));
2756 /***************************************************************************
2757 ***************************************************************************/
2759 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2761 static int parm_num = -1;
2762 struct loadparm_service *s;
2764 if ( parm_num == -1 )
2765 parm_num = lpcfg_map_parameter( "printing" );
2767 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
2769 if ( snum < 0 ) {
2770 s = &sDefault;
2771 init_printer_values(Globals.ctx, s);
2772 } else {
2773 s = ServicePtrs[snum];
2774 init_printer_values(s, s);
2777 return true;
2781 return the parameter pointer for a parameter
2783 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2785 if (service == NULL) {
2786 if (parm->p_class == P_LOCAL)
2787 return (void *)(((char *)&sDefault)+parm->offset);
2788 else if (parm->p_class == P_GLOBAL)
2789 return (void *)(((char *)&Globals)+parm->offset);
2790 else return NULL;
2791 } else {
2792 return (void *)(((char *)service) + parm->offset);
2796 /***************************************************************************
2797 Return the local pointer to a parameter given the service number and parameter
2798 ***************************************************************************/
2800 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
2802 return lp_parm_ptr(ServicePtrs[snum], parm);
2805 /***************************************************************************
2806 Process a parameter for a particular service number. If snum < 0
2807 then assume we are in the globals.
2808 ***************************************************************************/
2810 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2812 int parmnum, i;
2813 void *parm_ptr = NULL; /* where we are going to store the result */
2814 struct parmlist_entry **opt_list;
2815 TALLOC_CTX *mem_ctx;
2817 parmnum = lpcfg_map_parameter(pszParmName);
2819 if (parmnum < 0) {
2820 if (strchr(pszParmName, ':') == NULL) {
2821 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
2822 pszParmName));
2823 return true;
2827 * We've got a parametric option
2830 if (snum < 0) {
2831 opt_list = &Globals.param_opt;
2832 set_param_opt(NULL, opt_list, pszParmName, pszParmValue, 0);
2833 } else {
2834 opt_list = &ServicePtrs[snum]->param_opt;
2835 set_param_opt(ServicePtrs[snum], opt_list, pszParmName, pszParmValue, 0);
2838 return true;
2841 /* if it's already been set by the command line, then we don't
2842 override here */
2843 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2844 return true;
2847 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2848 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2849 pszParmName));
2852 /* we might point at a service, the default service or a global */
2853 if (snum < 0) {
2854 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
2855 } else {
2856 if (parm_table[parmnum].p_class == P_GLOBAL) {
2857 DEBUG(0,
2858 ("Global parameter %s found in service section!\n",
2859 pszParmName));
2860 return true;
2862 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
2865 if (snum >= 0) {
2866 if (!ServicePtrs[snum]->copymap)
2867 init_copymap(ServicePtrs[snum]);
2869 /* this handles the aliases - set the copymap for other entries with
2870 the same data pointer */
2871 for (i = 0; parm_table[i].label; i++) {
2872 if ((parm_table[i].offset == parm_table[parmnum].offset)
2873 && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
2874 bitmap_clear(ServicePtrs[snum]->copymap, i);
2877 mem_ctx = ServicePtrs[snum];
2878 } else {
2879 mem_ctx = Globals.ctx;
2882 /* if it is a special case then go ahead */
2883 if (parm_table[parmnum].special) {
2884 bool ok;
2885 struct loadparm_context *lp_ctx = loadparm_init_s3(talloc_tos(),
2886 loadparm_s3_helpers());
2887 ok = parm_table[parmnum].special(lp_ctx, snum, pszParmValue,
2888 (char **)parm_ptr);
2889 TALLOC_FREE(lp_ctx);
2891 return ok;
2894 /* now switch on the type of variable it is */
2895 switch (parm_table[parmnum].type)
2897 case P_BOOL:
2898 *(bool *)parm_ptr = lp_bool(pszParmValue);
2899 break;
2901 case P_BOOLREV:
2902 *(bool *)parm_ptr = !lp_bool(pszParmValue);
2903 break;
2905 case P_INTEGER:
2906 *(int *)parm_ptr = lp_int(pszParmValue);
2907 break;
2909 case P_CHAR:
2910 *(char *)parm_ptr = *pszParmValue;
2911 break;
2913 case P_OCTAL:
2914 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
2915 if ( i != 1 ) {
2916 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
2918 break;
2920 case P_BYTES:
2922 uint64_t val;
2923 if (conv_str_size_error(pszParmValue, &val)) {
2924 if (val <= INT_MAX) {
2925 *(int *)parm_ptr = (int)val;
2926 break;
2930 DEBUG(0,("lp_do_parameter(%s): value is not "
2931 "a valid size specifier!\n", pszParmValue));
2932 return false;
2935 case P_LIST:
2936 case P_CMDLIST:
2937 TALLOC_FREE(*((char ***)parm_ptr));
2938 *(char ***)parm_ptr = str_list_make_v3(
2939 NULL, pszParmValue, NULL);
2940 break;
2942 case P_STRING:
2943 string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
2944 break;
2946 case P_USTRING:
2948 char *upper_string = strupper_talloc(talloc_tos(),
2949 pszParmValue);
2950 string_set(mem_ctx, (char **)parm_ptr, upper_string);
2951 TALLOC_FREE(upper_string);
2952 break;
2954 case P_ENUM:
2955 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
2956 break;
2957 case P_SEP:
2958 break;
2961 return true;
2964 /***************************************************************************
2965 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2966 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2967 ***************************************************************************/
2969 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
2971 int parmnum, i;
2972 parmnum = lpcfg_map_parameter(pszParmName);
2973 if (parmnum >= 0) {
2974 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2975 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2976 return false;
2978 parm_table[parmnum].flags |= FLAG_CMDLINE;
2980 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2981 * be grouped in the table, so we don't have to search the
2982 * whole table */
2983 for (i=parmnum-1;
2984 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2985 && parm_table[i].p_class == parm_table[parmnum].p_class;
2986 i--) {
2987 parm_table[i].flags |= FLAG_CMDLINE;
2989 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
2990 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2991 parm_table[i].flags |= FLAG_CMDLINE;
2994 if (store_values) {
2995 store_lp_set_cmdline(pszParmName, pszParmValue);
2997 return true;
3000 /* it might be parametric */
3001 if (strchr(pszParmName, ':') != NULL) {
3002 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
3003 if (store_values) {
3004 store_lp_set_cmdline(pszParmName, pszParmValue);
3006 return true;
3009 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3010 return true;
3013 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
3015 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
3018 /***************************************************************************
3019 Process a parameter.
3020 ***************************************************************************/
3022 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
3023 void *userdata)
3025 if (!bInGlobalSection && bGlobalOnly)
3026 return true;
3028 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3030 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3031 pszParmName, pszParmValue));
3035 set a option from the commandline in 'a=b' format. Use to support --option
3037 bool lp_set_option(const char *option)
3039 char *p, *s;
3040 bool ret;
3042 s = talloc_strdup(NULL, option);
3043 if (!s) {
3044 return false;
3047 p = strchr(s, '=');
3048 if (!p) {
3049 talloc_free(s);
3050 return false;
3053 *p = 0;
3055 /* skip white spaces after the = sign */
3056 do {
3057 p++;
3058 } while (*p == ' ');
3060 ret = lp_set_cmdline(s, p);
3061 talloc_free(s);
3062 return ret;
3065 /***************************************************************************
3066 Initialize any local variables in the sDefault table, after parsing a
3067 [globals] section.
3068 ***************************************************************************/
3070 static void init_locals(void)
3073 * We run this check once the [globals] is parsed, to force
3074 * the VFS objects and other per-share settings we need for
3075 * the standard way a AD DC is operated. We may change these
3076 * as our code evolves, which is why we force these settings.
3078 * We can't do this at the end of lp_load_ex(), as by that
3079 * point the services have been loaded and they will already
3080 * have "" as their vfs objects.
3082 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3083 const char **vfs_objects = lp_vfs_objects(-1);
3084 if (!vfs_objects || !vfs_objects[0]) {
3085 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
3086 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
3087 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
3088 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
3089 } else {
3090 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
3094 lp_do_parameter(-1, "map hidden", "no");
3095 lp_do_parameter(-1, "map system", "no");
3096 lp_do_parameter(-1, "map readonly", "no");
3097 lp_do_parameter(-1, "map archive", "no");
3098 lp_do_parameter(-1, "store dos attributes", "yes");
3102 /***************************************************************************
3103 Process a new section (service). At this stage all sections are services.
3104 Later we'll have special sections that permit server parameters to be set.
3105 Returns true on success, false on failure.
3106 ***************************************************************************/
3108 static bool do_section(const char *pszSectionName, void *userdata)
3110 bool bRetval;
3111 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3112 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3113 bRetval = false;
3115 /* if we were in a global section then do the local inits */
3116 if (bInGlobalSection && !isglobal)
3117 init_locals();
3119 /* if we've just struck a global section, note the fact. */
3120 bInGlobalSection = isglobal;
3122 /* check for multiple global sections */
3123 if (bInGlobalSection) {
3124 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3125 return true;
3128 if (!bInGlobalSection && bGlobalOnly)
3129 return true;
3131 /* if we have a current service, tidy it up before moving on */
3132 bRetval = true;
3134 if (iServiceIndex >= 0)
3135 bRetval = service_ok(iServiceIndex);
3137 /* if all is still well, move to the next record in the services array */
3138 if (bRetval) {
3139 /* We put this here to avoid an odd message order if messages are */
3140 /* issued by the post-processing of a previous section. */
3141 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3143 iServiceIndex = add_a_service(&sDefault, pszSectionName);
3144 if (iServiceIndex < 0) {
3145 DEBUG(0, ("Failed to add a new service\n"));
3146 return false;
3148 /* Clean all parametric options for service */
3149 /* They will be added during parsing again */
3150 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
3153 return bRetval;
3157 /***************************************************************************
3158 Determine if a partcular base parameter is currentl set to the default value.
3159 ***************************************************************************/
3161 static bool is_default(int i)
3163 switch (parm_table[i].type) {
3164 case P_LIST:
3165 case P_CMDLIST:
3166 return str_list_equal((const char * const *)parm_table[i].def.lvalue,
3167 *(const char ***)lp_parm_ptr(NULL,
3168 &parm_table[i]));
3169 case P_STRING:
3170 case P_USTRING:
3171 return strequal(parm_table[i].def.svalue,
3172 *(char **)lp_parm_ptr(NULL,
3173 &parm_table[i]));
3174 case P_BOOL:
3175 case P_BOOLREV:
3176 return parm_table[i].def.bvalue ==
3177 *(bool *)lp_parm_ptr(NULL,
3178 &parm_table[i]);
3179 case P_CHAR:
3180 return parm_table[i].def.cvalue ==
3181 *(char *)lp_parm_ptr(NULL,
3182 &parm_table[i]);
3183 case P_INTEGER:
3184 case P_OCTAL:
3185 case P_ENUM:
3186 case P_BYTES:
3187 return parm_table[i].def.ivalue ==
3188 *(int *)lp_parm_ptr(NULL,
3189 &parm_table[i]);
3190 case P_SEP:
3191 break;
3193 return false;
3196 /***************************************************************************
3197 Display the contents of the global structure.
3198 ***************************************************************************/
3200 static void dump_globals(FILE *f)
3202 int i;
3203 struct parmlist_entry *data;
3205 fprintf(f, "[global]\n");
3207 for (i = 0; parm_table[i].label; i++)
3208 if (parm_table[i].p_class == P_GLOBAL &&
3209 !(parm_table[i].flags & FLAG_META) &&
3210 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
3211 if (defaults_saved && is_default(i))
3212 continue;
3213 fprintf(f, "\t%s = ", parm_table[i].label);
3214 lpcfg_print_parameter(&parm_table[i], lp_parm_ptr(NULL,
3215 &parm_table[i]),
3217 fprintf(f, "\n");
3219 if (Globals.param_opt != NULL) {
3220 data = Globals.param_opt;
3221 while(data) {
3222 fprintf(f, "\t%s = %s\n", data->key, data->value);
3223 data = data->next;
3229 /***************************************************************************
3230 Display the contents of a single services record.
3231 ***************************************************************************/
3233 static void dump_a_service(struct loadparm_service *pService, FILE * f)
3235 int i;
3236 struct parmlist_entry *data;
3238 if (pService != &sDefault)
3239 fprintf(f, "[%s]\n", pService->szService);
3241 for (i = 0; parm_table[i].label; i++) {
3243 if (parm_table[i].p_class == P_LOCAL &&
3244 !(parm_table[i].flags & FLAG_META) &&
3245 (*parm_table[i].label != '-') &&
3246 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
3248 if (pService == &sDefault) {
3249 if (defaults_saved && is_default(i))
3250 continue;
3251 } else {
3252 if (lpcfg_equal_parameter(parm_table[i].type,
3253 lp_parm_ptr(pService, &parm_table[i]),
3254 lp_parm_ptr(NULL, &parm_table[i])))
3255 continue;
3258 fprintf(f, "\t%s = ", parm_table[i].label);
3259 lpcfg_print_parameter(&parm_table[i],
3260 lp_parm_ptr(pService, &parm_table[i]),
3262 fprintf(f, "\n");
3266 if (pService->param_opt != NULL) {
3267 data = pService->param_opt;
3268 while(data) {
3269 fprintf(f, "\t%s = %s\n", data->key, data->value);
3270 data = data->next;
3275 /***************************************************************************
3276 Display the contents of a parameter of a single services record.
3277 ***************************************************************************/
3279 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
3281 bool result = false;
3282 fstring local_parm_name;
3283 char *parm_opt;
3284 const char *parm_opt_value;
3286 struct loadparm_context *lp_ctx;
3288 /* check for parametrical option */
3289 fstrcpy( local_parm_name, parm_name);
3290 parm_opt = strchr( local_parm_name, ':');
3292 if (parm_opt) {
3293 *parm_opt = '\0';
3294 parm_opt++;
3295 if (strlen(parm_opt)) {
3296 parm_opt_value = lp_parm_const_string( snum,
3297 local_parm_name, parm_opt, NULL);
3298 if (parm_opt_value) {
3299 printf( "%s\n", parm_opt_value);
3300 result = true;
3303 return result;
3306 lp_ctx = loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
3307 if (lp_ctx == NULL) {
3308 return false;
3311 if (isGlobal) {
3312 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
3313 } else {
3314 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
3316 TALLOC_FREE(lp_ctx);
3317 return result;
3320 /***************************************************************************
3321 Return info about the requested parameter (given as a string).
3322 Return NULL when the string is not a valid parameter name.
3323 ***************************************************************************/
3325 struct parm_struct *lp_get_parameter(const char *param_name)
3327 int num = lpcfg_map_parameter(param_name);
3329 if (num < 0) {
3330 return NULL;
3333 return &parm_table[num];
3336 #if 0
3337 /***************************************************************************
3338 Display the contents of a single copy structure.
3339 ***************************************************************************/
3340 static void dump_copy_map(bool *pcopymap)
3342 int i;
3343 if (!pcopymap)
3344 return;
3346 printf("\n\tNon-Copied parameters:\n");
3348 for (i = 0; parm_table[i].label; i++)
3349 if (parm_table[i].p_class == P_LOCAL &&
3350 parm_table[i].ptr && !pcopymap[i] &&
3351 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3353 printf("\t\t%s\n", parm_table[i].label);
3356 #endif
3358 /***************************************************************************
3359 Return TRUE if the passed service number is within range.
3360 ***************************************************************************/
3362 bool lp_snum_ok(int iService)
3364 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3367 /***************************************************************************
3368 Auto-load some home services.
3369 ***************************************************************************/
3371 static void lp_add_auto_services(char *str)
3373 char *s;
3374 char *p;
3375 int homes;
3376 char *saveptr;
3378 if (!str)
3379 return;
3381 s = talloc_strdup(talloc_tos(), str);
3382 if (!s) {
3383 smb_panic("talloc_strdup failed");
3384 return;
3387 homes = lp_servicenumber(HOMES_NAME);
3389 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
3390 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
3391 char *home;
3393 if (lp_servicenumber(p) >= 0)
3394 continue;
3396 home = get_user_home_dir(talloc_tos(), p);
3398 if (home && home[0] && homes >= 0)
3399 lp_add_home(p, homes, p, home);
3401 TALLOC_FREE(home);
3403 TALLOC_FREE(s);
3406 /***************************************************************************
3407 Auto-load one printer.
3408 ***************************************************************************/
3410 void lp_add_one_printer(const char *name, const char *comment,
3411 const char *location, void *pdata)
3413 int printers = lp_servicenumber(PRINTERS_NAME);
3414 int i;
3416 if (lp_servicenumber(name) < 0) {
3417 lp_add_printer(name, printers);
3418 if ((i = lp_servicenumber(name)) >= 0) {
3419 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
3420 ServicePtrs[i]->autoloaded = true;
3425 /***************************************************************************
3426 Have we loaded a services file yet?
3427 ***************************************************************************/
3429 bool lp_loaded(void)
3431 return (bLoaded);
3434 /***************************************************************************
3435 Unload unused services.
3436 ***************************************************************************/
3438 void lp_killunused(struct smbd_server_connection *sconn,
3439 bool (*snumused) (struct smbd_server_connection *, int))
3441 int i;
3442 for (i = 0; i < iNumServices; i++) {
3443 if (!VALID(i))
3444 continue;
3446 /* don't kill autoloaded or usershare services */
3447 if ( ServicePtrs[i]->autoloaded ||
3448 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3449 continue;
3452 if (!snumused || !snumused(sconn, i)) {
3453 free_service_byindex(i);
3459 * Kill all except autoloaded and usershare services - convenience wrapper
3461 void lp_kill_all_services(void)
3463 lp_killunused(NULL, NULL);
3466 /***************************************************************************
3467 Unload a service.
3468 ***************************************************************************/
3470 void lp_killservice(int iServiceIn)
3472 if (VALID(iServiceIn)) {
3473 free_service_byindex(iServiceIn);
3477 /***************************************************************************
3478 Save the curent values of all global and sDefault parameters into the
3479 defaults union. This allows testparm to show only the
3480 changed (ie. non-default) parameters.
3481 ***************************************************************************/
3483 static void lp_save_defaults(void)
3485 int i;
3486 for (i = 0; parm_table[i].label; i++) {
3487 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3488 && parm_table[i].p_class == parm_table[i - 1].p_class)
3489 continue;
3490 switch (parm_table[i].type) {
3491 case P_LIST:
3492 case P_CMDLIST:
3493 parm_table[i].def.lvalue = str_list_copy(
3494 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3495 break;
3496 case P_STRING:
3497 case P_USTRING:
3498 parm_table[i].def.svalue = talloc_strdup(Globals.ctx, *(char **)lp_parm_ptr(NULL, &parm_table[i]));
3499 if (parm_table[i].def.svalue == NULL) {
3500 smb_panic("talloc_strdup failed");
3502 break;
3503 case P_BOOL:
3504 case P_BOOLREV:
3505 parm_table[i].def.bvalue =
3506 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3507 break;
3508 case P_CHAR:
3509 parm_table[i].def.cvalue =
3510 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3511 break;
3512 case P_INTEGER:
3513 case P_OCTAL:
3514 case P_ENUM:
3515 case P_BYTES:
3516 parm_table[i].def.ivalue =
3517 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3518 break;
3519 case P_SEP:
3520 break;
3523 defaults_saved = true;
3526 /***********************************************************
3527 If we should send plaintext/LANMAN passwords in the clinet
3528 ************************************************************/
3530 static void set_allowed_client_auth(void)
3532 if (Globals.client_ntlmv2_auth) {
3533 Globals.client_lanman_auth = false;
3535 if (!Globals.client_lanman_auth) {
3536 Globals.client_plaintext_auth = false;
3540 /***************************************************************************
3541 JRA.
3542 The following code allows smbd to read a user defined share file.
3543 Yes, this is my intent. Yes, I'm comfortable with that...
3545 THE FOLLOWING IS SECURITY CRITICAL CODE.
3547 It washes your clothes, it cleans your house, it guards you while you sleep...
3548 Do not f%^k with it....
3549 ***************************************************************************/
3551 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3553 /***************************************************************************
3554 Check allowed stat state of a usershare file.
3555 Ensure we print out who is dicking with us so the admin can
3556 get their sorry ass fired.
3557 ***************************************************************************/
3559 static bool check_usershare_stat(const char *fname,
3560 const SMB_STRUCT_STAT *psbuf)
3562 if (!S_ISREG(psbuf->st_ex_mode)) {
3563 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3564 "not a regular file\n",
3565 fname, (unsigned int)psbuf->st_ex_uid ));
3566 return false;
3569 /* Ensure this doesn't have the other write bit set. */
3570 if (psbuf->st_ex_mode & S_IWOTH) {
3571 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3572 "public write. Refusing to allow as a usershare file.\n",
3573 fname, (unsigned int)psbuf->st_ex_uid ));
3574 return false;
3577 /* Should be 10k or less. */
3578 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
3579 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3580 "too large (%u) to be a user share file.\n",
3581 fname, (unsigned int)psbuf->st_ex_uid,
3582 (unsigned int)psbuf->st_ex_size ));
3583 return false;
3586 return true;
3589 /***************************************************************************
3590 Parse the contents of a usershare file.
3591 ***************************************************************************/
3593 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
3594 SMB_STRUCT_STAT *psbuf,
3595 const char *servicename,
3596 int snum,
3597 char **lines,
3598 int numlines,
3599 char **pp_sharepath,
3600 char **pp_comment,
3601 char **pp_cp_servicename,
3602 struct security_descriptor **ppsd,
3603 bool *pallow_guest)
3605 const char **prefixallowlist = lp_usershare_prefix_allow_list();
3606 const char **prefixdenylist = lp_usershare_prefix_deny_list();
3607 int us_vers;
3608 DIR *dp;
3609 SMB_STRUCT_STAT sbuf;
3610 char *sharepath = NULL;
3611 char *comment = NULL;
3613 *pp_sharepath = NULL;
3614 *pp_comment = NULL;
3616 *pallow_guest = false;
3618 if (numlines < 4) {
3619 return USERSHARE_MALFORMED_FILE;
3622 if (strcmp(lines[0], "#VERSION 1") == 0) {
3623 us_vers = 1;
3624 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3625 us_vers = 2;
3626 if (numlines < 5) {
3627 return USERSHARE_MALFORMED_FILE;
3629 } else {
3630 return USERSHARE_BAD_VERSION;
3633 if (strncmp(lines[1], "path=", 5) != 0) {
3634 return USERSHARE_MALFORMED_PATH;
3637 sharepath = talloc_strdup(ctx, &lines[1][5]);
3638 if (!sharepath) {
3639 return USERSHARE_POSIX_ERR;
3641 trim_string(sharepath, " ", " ");
3643 if (strncmp(lines[2], "comment=", 8) != 0) {
3644 return USERSHARE_MALFORMED_COMMENT_DEF;
3647 comment = talloc_strdup(ctx, &lines[2][8]);
3648 if (!comment) {
3649 return USERSHARE_POSIX_ERR;
3651 trim_string(comment, " ", " ");
3652 trim_char(comment, '"', '"');
3654 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3655 return USERSHARE_MALFORMED_ACL_DEF;
3658 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3659 return USERSHARE_ACL_ERR;
3662 if (us_vers == 2) {
3663 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3664 return USERSHARE_MALFORMED_ACL_DEF;
3666 if (lines[4][9] == 'y') {
3667 *pallow_guest = true;
3670 /* Backwards compatible extension to file version #2. */
3671 if (numlines > 5) {
3672 if (strncmp(lines[5], "sharename=", 10) != 0) {
3673 return USERSHARE_MALFORMED_SHARENAME_DEF;
3675 if (!strequal(&lines[5][10], servicename)) {
3676 return USERSHARE_BAD_SHARENAME;
3678 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3679 if (!*pp_cp_servicename) {
3680 return USERSHARE_POSIX_ERR;
3685 if (*pp_cp_servicename == NULL) {
3686 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3687 if (!*pp_cp_servicename) {
3688 return USERSHARE_POSIX_ERR;
3692 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3693 /* Path didn't change, no checks needed. */
3694 *pp_sharepath = sharepath;
3695 *pp_comment = comment;
3696 return USERSHARE_OK;
3699 /* The path *must* be absolute. */
3700 if (sharepath[0] != '/') {
3701 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3702 servicename, sharepath));
3703 return USERSHARE_PATH_NOT_ABSOLUTE;
3706 /* If there is a usershare prefix deny list ensure one of these paths
3707 doesn't match the start of the user given path. */
3708 if (prefixdenylist) {
3709 int i;
3710 for ( i=0; prefixdenylist[i]; i++ ) {
3711 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3712 servicename, i, prefixdenylist[i], sharepath ));
3713 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3714 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3715 "usershare prefix deny list entries.\n",
3716 servicename, sharepath));
3717 return USERSHARE_PATH_IS_DENIED;
3722 /* If there is a usershare prefix allow list ensure one of these paths
3723 does match the start of the user given path. */
3725 if (prefixallowlist) {
3726 int i;
3727 for ( i=0; prefixallowlist[i]; i++ ) {
3728 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3729 servicename, i, prefixallowlist[i], sharepath ));
3730 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3731 break;
3734 if (prefixallowlist[i] == NULL) {
3735 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3736 "usershare prefix allow list entries.\n",
3737 servicename, sharepath));
3738 return USERSHARE_PATH_NOT_ALLOWED;
3742 /* Ensure this is pointing to a directory. */
3743 dp = opendir(sharepath);
3745 if (!dp) {
3746 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3747 servicename, sharepath));
3748 return USERSHARE_PATH_NOT_DIRECTORY;
3751 /* Ensure the owner of the usershare file has permission to share
3752 this directory. */
3754 if (sys_stat(sharepath, &sbuf, false) == -1) {
3755 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3756 servicename, sharepath, strerror(errno) ));
3757 closedir(dp);
3758 return USERSHARE_POSIX_ERR;
3761 closedir(dp);
3763 if (!S_ISDIR(sbuf.st_ex_mode)) {
3764 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3765 servicename, sharepath ));
3766 return USERSHARE_PATH_NOT_DIRECTORY;
3769 /* Check if sharing is restricted to owner-only. */
3770 /* psbuf is the stat of the usershare definition file,
3771 sbuf is the stat of the target directory to be shared. */
3773 if (lp_usershare_owner_only()) {
3774 /* root can share anything. */
3775 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3776 return USERSHARE_PATH_NOT_ALLOWED;
3780 *pp_sharepath = sharepath;
3781 *pp_comment = comment;
3782 return USERSHARE_OK;
3785 /***************************************************************************
3786 Deal with a usershare file.
3787 Returns:
3788 >= 0 - snum
3789 -1 - Bad name, invalid contents.
3790 - service name already existed and not a usershare, problem
3791 with permissions to share directory etc.
3792 ***************************************************************************/
3794 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3796 SMB_STRUCT_STAT sbuf;
3797 SMB_STRUCT_STAT lsbuf;
3798 char *fname = NULL;
3799 char *sharepath = NULL;
3800 char *comment = NULL;
3801 char *cp_service_name = NULL;
3802 char **lines = NULL;
3803 int numlines = 0;
3804 int fd = -1;
3805 int iService = -1;
3806 TALLOC_CTX *ctx = talloc_stackframe();
3807 struct security_descriptor *psd = NULL;
3808 bool guest_ok = false;
3809 char *canon_name = NULL;
3810 bool added_service = false;
3811 int ret = -1;
3813 /* Ensure share name doesn't contain invalid characters. */
3814 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3815 DEBUG(0,("process_usershare_file: share name %s contains "
3816 "invalid characters (any of %s)\n",
3817 file_name, INVALID_SHARENAME_CHARS ));
3818 goto out;
3821 canon_name = canonicalize_servicename(ctx, file_name);
3822 if (!canon_name) {
3823 goto out;
3826 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3827 if (!fname) {
3828 goto out;
3831 /* Minimize the race condition by doing an lstat before we
3832 open and fstat. Ensure this isn't a symlink link. */
3834 if (sys_lstat(fname, &lsbuf, false) != 0) {
3835 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3836 fname, strerror(errno) ));
3837 goto out;
3840 /* This must be a regular file, not a symlink, directory or
3841 other strange filetype. */
3842 if (!check_usershare_stat(fname, &lsbuf)) {
3843 goto out;
3847 TDB_DATA data;
3848 NTSTATUS status;
3850 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3851 canon_name, &data);
3853 iService = -1;
3855 if (NT_STATUS_IS_OK(status) &&
3856 (data.dptr != NULL) &&
3857 (data.dsize == sizeof(iService))) {
3858 memcpy(&iService, data.dptr, sizeof(iService));
3862 if (iService != -1 &&
3863 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3864 &lsbuf.st_ex_mtime) == 0) {
3865 /* Nothing changed - Mark valid and return. */
3866 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3867 canon_name ));
3868 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3869 ret = iService;
3870 goto out;
3873 /* Try and open the file read only - no symlinks allowed. */
3874 #ifdef O_NOFOLLOW
3875 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3876 #else
3877 fd = open(fname, O_RDONLY, 0);
3878 #endif
3880 if (fd == -1) {
3881 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3882 fname, strerror(errno) ));
3883 goto out;
3886 /* Now fstat to be *SURE* it's a regular file. */
3887 if (sys_fstat(fd, &sbuf, false) != 0) {
3888 close(fd);
3889 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3890 fname, strerror(errno) ));
3891 goto out;
3894 /* Is it the same dev/inode as was lstated ? */
3895 if (!check_same_stat(&lsbuf, &sbuf)) {
3896 close(fd);
3897 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3898 "Symlink spoofing going on ?\n", fname ));
3899 goto out;
3902 /* This must be a regular file, not a symlink, directory or
3903 other strange filetype. */
3904 if (!check_usershare_stat(fname, &sbuf)) {
3905 close(fd);
3906 goto out;
3909 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3911 close(fd);
3912 if (lines == NULL) {
3913 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3914 fname, (unsigned int)sbuf.st_ex_uid ));
3915 goto out;
3918 if (parse_usershare_file(ctx, &sbuf, file_name,
3919 iService, lines, numlines, &sharepath,
3920 &comment, &cp_service_name,
3921 &psd, &guest_ok) != USERSHARE_OK) {
3922 goto out;
3925 /* Everything ok - add the service possibly using a template. */
3926 if (iService < 0) {
3927 const struct loadparm_service *sp = &sDefault;
3928 if (snum_template != -1) {
3929 sp = ServicePtrs[snum_template];
3932 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3933 DEBUG(0, ("process_usershare_file: Failed to add "
3934 "new service %s\n", cp_service_name));
3935 goto out;
3938 added_service = true;
3940 /* Read only is controlled by usershare ACL below. */
3941 ServicePtrs[iService]->read_only = false;
3944 /* Write the ACL of the new/modified share. */
3945 if (!set_share_security(canon_name, psd)) {
3946 DEBUG(0, ("process_usershare_file: Failed to set share "
3947 "security for user share %s\n",
3948 canon_name ));
3949 goto out;
3952 /* If from a template it may be marked invalid. */
3953 ServicePtrs[iService]->valid = true;
3955 /* Set the service as a valid usershare. */
3956 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3958 /* Set guest access. */
3959 if (lp_usershare_allow_guests()) {
3960 ServicePtrs[iService]->guest_ok = guest_ok;
3963 /* And note when it was loaded. */
3964 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3965 string_set(ServicePtrs[iService], &ServicePtrs[iService]->path, sharepath);
3966 string_set(ServicePtrs[iService], &ServicePtrs[iService]->comment, comment);
3968 ret = iService;
3970 out:
3972 if (ret == -1 && iService != -1 && added_service) {
3973 lp_remove_service(iService);
3976 TALLOC_FREE(lines);
3977 TALLOC_FREE(ctx);
3978 return ret;
3981 /***************************************************************************
3982 Checks if a usershare entry has been modified since last load.
3983 ***************************************************************************/
3985 static bool usershare_exists(int iService, struct timespec *last_mod)
3987 SMB_STRUCT_STAT lsbuf;
3988 const char *usersharepath = Globals.usershare_path;
3989 char *fname;
3991 fname = talloc_asprintf(talloc_tos(),
3992 "%s/%s",
3993 usersharepath,
3994 ServicePtrs[iService]->szService);
3995 if (fname == NULL) {
3996 return false;
3999 if (sys_lstat(fname, &lsbuf, false) != 0) {
4000 TALLOC_FREE(fname);
4001 return false;
4004 if (!S_ISREG(lsbuf.st_ex_mode)) {
4005 TALLOC_FREE(fname);
4006 return false;
4009 TALLOC_FREE(fname);
4010 *last_mod = lsbuf.st_ex_mtime;
4011 return true;
4014 /***************************************************************************
4015 Load a usershare service by name. Returns a valid servicenumber or -1.
4016 ***************************************************************************/
4018 int load_usershare_service(const char *servicename)
4020 SMB_STRUCT_STAT sbuf;
4021 const char *usersharepath = Globals.usershare_path;
4022 int max_user_shares = Globals.usershare_max_shares;
4023 int snum_template = -1;
4025 if (*usersharepath == 0 || max_user_shares == 0) {
4026 return -1;
4029 if (sys_stat(usersharepath, &sbuf, false) != 0) {
4030 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4031 usersharepath, strerror(errno) ));
4032 return -1;
4035 if (!S_ISDIR(sbuf.st_ex_mode)) {
4036 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4037 usersharepath ));
4038 return -1;
4042 * This directory must be owned by root, and have the 't' bit set.
4043 * It also must not be writable by "other".
4046 #ifdef S_ISVTX
4047 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4048 #else
4049 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4050 #endif
4051 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4052 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4053 usersharepath ));
4054 return -1;
4057 /* Ensure the template share exists if it's set. */
4058 if (Globals.usershare_template_share[0]) {
4059 /* We can't use lp_servicenumber here as we are recommending that
4060 template shares have -valid=false set. */
4061 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4062 if (ServicePtrs[snum_template]->szService &&
4063 strequal(ServicePtrs[snum_template]->szService,
4064 Globals.usershare_template_share)) {
4065 break;
4069 if (snum_template == -1) {
4070 DEBUG(0,("load_usershare_service: usershare template share %s "
4071 "does not exist.\n",
4072 Globals.usershare_template_share ));
4073 return -1;
4077 return process_usershare_file(usersharepath, servicename, snum_template);
4080 /***************************************************************************
4081 Load all user defined shares from the user share directory.
4082 We only do this if we're enumerating the share list.
4083 This is the function that can delete usershares that have
4084 been removed.
4085 ***************************************************************************/
4087 int load_usershare_shares(struct smbd_server_connection *sconn,
4088 bool (*snumused) (struct smbd_server_connection *, int))
4090 DIR *dp;
4091 SMB_STRUCT_STAT sbuf;
4092 struct dirent *de;
4093 int num_usershares = 0;
4094 int max_user_shares = Globals.usershare_max_shares;
4095 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4096 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4097 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4098 int iService;
4099 int snum_template = -1;
4100 const char *usersharepath = Globals.usershare_path;
4101 int ret = lp_numservices();
4102 TALLOC_CTX *tmp_ctx;
4104 if (max_user_shares == 0 || *usersharepath == '\0') {
4105 return lp_numservices();
4108 if (sys_stat(usersharepath, &sbuf, false) != 0) {
4109 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4110 usersharepath, strerror(errno) ));
4111 return ret;
4115 * This directory must be owned by root, and have the 't' bit set.
4116 * It also must not be writable by "other".
4119 #ifdef S_ISVTX
4120 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4121 #else
4122 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4123 #endif
4124 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4125 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4126 usersharepath ));
4127 return ret;
4130 /* Ensure the template share exists if it's set. */
4131 if (Globals.usershare_template_share[0]) {
4132 /* We can't use lp_servicenumber here as we are recommending that
4133 template shares have -valid=false set. */
4134 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4135 if (ServicePtrs[snum_template]->szService &&
4136 strequal(ServicePtrs[snum_template]->szService,
4137 Globals.usershare_template_share)) {
4138 break;
4142 if (snum_template == -1) {
4143 DEBUG(0,("load_usershare_shares: usershare template share %s "
4144 "does not exist.\n",
4145 Globals.usershare_template_share ));
4146 return ret;
4150 /* Mark all existing usershares as pending delete. */
4151 for (iService = iNumServices - 1; iService >= 0; iService--) {
4152 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4153 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4157 dp = opendir(usersharepath);
4158 if (!dp) {
4159 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4160 usersharepath, strerror(errno) ));
4161 return ret;
4164 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4165 (de = readdir(dp));
4166 num_dir_entries++ ) {
4167 int r;
4168 const char *n = de->d_name;
4170 /* Ignore . and .. */
4171 if (*n == '.') {
4172 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4173 continue;
4177 if (n[0] == ':') {
4178 /* Temporary file used when creating a share. */
4179 num_tmp_dir_entries++;
4182 /* Allow 20% tmp entries. */
4183 if (num_tmp_dir_entries > allowed_tmp_entries) {
4184 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4185 "in directory %s\n",
4186 num_tmp_dir_entries, usersharepath));
4187 break;
4190 r = process_usershare_file(usersharepath, n, snum_template);
4191 if (r == 0) {
4192 /* Update the services count. */
4193 num_usershares++;
4194 if (num_usershares >= max_user_shares) {
4195 DEBUG(0,("load_usershare_shares: max user shares reached "
4196 "on file %s in directory %s\n",
4197 n, usersharepath ));
4198 break;
4200 } else if (r == -1) {
4201 num_bad_dir_entries++;
4204 /* Allow 20% bad entries. */
4205 if (num_bad_dir_entries > allowed_bad_entries) {
4206 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4207 "in directory %s\n",
4208 num_bad_dir_entries, usersharepath));
4209 break;
4212 /* Allow 20% bad entries. */
4213 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4214 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4215 "in directory %s\n",
4216 num_dir_entries, usersharepath));
4217 break;
4221 closedir(dp);
4223 /* Sweep through and delete any non-refreshed usershares that are
4224 not currently in use. */
4225 tmp_ctx = talloc_stackframe();
4226 for (iService = iNumServices - 1; iService >= 0; iService--) {
4227 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4228 char *servname;
4230 if (snumused && snumused(sconn, iService)) {
4231 continue;
4234 servname = lp_servicename(tmp_ctx, iService);
4236 /* Remove from the share ACL db. */
4237 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4238 servname ));
4239 delete_share_security(servname);
4240 free_service_byindex(iService);
4243 talloc_free(tmp_ctx);
4245 return lp_numservices();
4248 /********************************************************
4249 Destroy global resources allocated in this file
4250 ********************************************************/
4252 void gfree_loadparm(void)
4254 int i;
4256 free_file_list();
4258 /* Free resources allocated to services */
4260 for ( i = 0; i < iNumServices; i++ ) {
4261 if ( VALID(i) ) {
4262 free_service_byindex(i);
4266 TALLOC_FREE( ServicePtrs );
4267 iNumServices = 0;
4269 /* Now release all resources allocated to global
4270 parameters and the default service */
4272 free_global_parameters();
4276 /***************************************************************************
4277 Allow client apps to specify that they are a client
4278 ***************************************************************************/
4279 static void lp_set_in_client(bool b)
4281 in_client = b;
4285 /***************************************************************************
4286 Determine if we're running in a client app
4287 ***************************************************************************/
4288 static bool lp_is_in_client(void)
4290 return in_client;
4293 /***************************************************************************
4294 Load the services array from the services file. Return true on success,
4295 false on failure.
4296 ***************************************************************************/
4298 static bool lp_load_ex(const char *pszFname,
4299 bool global_only,
4300 bool save_defaults,
4301 bool add_ipc,
4302 bool initialize_globals,
4303 bool allow_include_registry,
4304 bool load_all_shares)
4306 char *n2 = NULL;
4307 bool bRetval;
4309 bRetval = false;
4311 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4313 bInGlobalSection = true;
4314 bGlobalOnly = global_only;
4315 bAllowIncludeRegistry = allow_include_registry;
4317 init_globals(initialize_globals);
4319 free_file_list();
4321 if (save_defaults) {
4322 init_locals();
4323 lp_save_defaults();
4326 if (!initialize_globals) {
4327 free_param_opts(&Globals.param_opt);
4328 apply_lp_set_cmdline();
4331 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
4333 /* We get sections first, so have to start 'behind' to make up */
4334 iServiceIndex = -1;
4336 if (lp_config_backend_is_file()) {
4337 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4338 current_user_info.domain,
4339 pszFname);
4340 if (!n2) {
4341 smb_panic("lp_load_ex: out of memory");
4344 add_to_file_list(NULL, &file_lists, pszFname, n2);
4346 bRetval = pm_process(n2, do_section, do_parameter, NULL);
4347 TALLOC_FREE(n2);
4349 /* finish up the last section */
4350 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4351 if (bRetval) {
4352 if (iServiceIndex >= 0) {
4353 bRetval = service_ok(iServiceIndex);
4357 if (lp_config_backend_is_registry()) {
4358 /* config backend changed to registry in config file */
4360 * We need to use this extra global variable here to
4361 * survive restart: init_globals uses this as a default
4362 * for config_backend. Otherwise, init_globals would
4363 * send us into an endless loop here.
4365 config_backend = CONFIG_BACKEND_REGISTRY;
4366 /* start over */
4367 DEBUG(1, ("lp_load_ex: changing to config backend "
4368 "registry\n"));
4369 init_globals(true);
4370 lp_kill_all_services();
4371 return lp_load_ex(pszFname, global_only, save_defaults,
4372 add_ipc, initialize_globals,
4373 allow_include_registry,
4374 load_all_shares);
4376 } else if (lp_config_backend_is_registry()) {
4377 bRetval = process_registry_globals();
4378 } else {
4379 DEBUG(0, ("Illegal config backend given: %d\n",
4380 lp_config_backend()));
4381 bRetval = false;
4384 if (bRetval && lp_registry_shares()) {
4385 if (load_all_shares) {
4386 bRetval = process_registry_shares();
4387 } else {
4388 bRetval = reload_registry_shares();
4393 char *serv = lp_auto_services(talloc_tos());
4394 lp_add_auto_services(serv);
4395 TALLOC_FREE(serv);
4398 if (add_ipc) {
4399 /* When 'restrict anonymous = 2' guest connections to ipc$
4400 are denied */
4401 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4402 if ( lp_enable_asu_support() ) {
4403 lp_add_ipc("ADMIN$", false);
4407 set_allowed_client_auth();
4409 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
4410 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4411 lp_password_server()));
4414 bLoaded = true;
4416 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4417 /* if we_are_a_wins_server is true and we are in the client */
4418 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
4419 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4422 init_iconv();
4424 fault_configure(smb_panic_s3);
4427 * We run this check once the whole smb.conf is parsed, to
4428 * force some settings for the standard way a AD DC is
4429 * operated. We may changed these as our code evolves, which
4430 * is why we force these settings.
4432 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4433 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4435 lp_do_parameter(-1, "rpc_server:default", "external");
4436 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4437 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4438 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4439 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4440 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4441 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4442 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4443 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4446 bAllowIncludeRegistry = true;
4448 return (bRetval);
4451 bool lp_load(const char *pszFname,
4452 bool global_only,
4453 bool save_defaults,
4454 bool add_ipc,
4455 bool initialize_globals)
4457 return lp_load_ex(pszFname,
4458 global_only,
4459 save_defaults,
4460 add_ipc,
4461 initialize_globals,
4462 true, /* allow_include_registry */
4463 false); /* load_all_shares*/
4466 bool lp_load_initial_only(const char *pszFname)
4468 return lp_load_ex(pszFname,
4469 true, /* global only */
4470 false, /* save_defaults */
4471 false, /* add_ipc */
4472 true, /* initialize_globals */
4473 false, /* allow_include_registry */
4474 false); /* load_all_shares*/
4478 * most common lp_load wrapper, loading only the globals
4480 bool lp_load_global(const char *file_name)
4482 return lp_load_ex(file_name,
4483 true, /* global_only */
4484 false, /* save_defaults */
4485 false, /* add_ipc */
4486 true, /* initialize_globals */
4487 true, /* allow_include_registry */
4488 false); /* load_all_shares*/
4492 * lp_load wrapper, especially for clients
4494 bool lp_load_client(const char *file_name)
4496 lp_set_in_client(true);
4498 return lp_load_global(file_name);
4502 * lp_load wrapper, loading only globals, but intended
4503 * for subsequent calls, not reinitializing the globals
4504 * to default values
4506 bool lp_load_global_no_reinit(const char *file_name)
4508 return lp_load_ex(file_name,
4509 true, /* global_only */
4510 false, /* save_defaults */
4511 false, /* add_ipc */
4512 false, /* initialize_globals */
4513 true, /* allow_include_registry */
4514 false); /* load_all_shares*/
4518 * lp_load wrapper, especially for clients, no reinitialization
4520 bool lp_load_client_no_reinit(const char *file_name)
4522 lp_set_in_client(true);
4524 return lp_load_global_no_reinit(file_name);
4527 bool lp_load_with_registry_shares(const char *pszFname,
4528 bool global_only,
4529 bool save_defaults,
4530 bool add_ipc,
4531 bool initialize_globals)
4533 return lp_load_ex(pszFname,
4534 global_only,
4535 save_defaults,
4536 add_ipc,
4537 initialize_globals,
4538 true, /* allow_include_registry */
4539 true); /* load_all_shares*/
4542 /***************************************************************************
4543 Return the max number of services.
4544 ***************************************************************************/
4546 int lp_numservices(void)
4548 return (iNumServices);
4551 /***************************************************************************
4552 Display the contents of the services array in human-readable form.
4553 ***************************************************************************/
4555 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4557 int iService;
4559 if (show_defaults)
4560 defaults_saved = false;
4562 dump_globals(f);
4564 dump_a_service(&sDefault, f);
4566 for (iService = 0; iService < maxtoprint; iService++) {
4567 fprintf(f,"\n");
4568 lp_dump_one(f, show_defaults, iService);
4572 /***************************************************************************
4573 Display the contents of one service in human-readable form.
4574 ***************************************************************************/
4576 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4578 if (VALID(snum)) {
4579 if (ServicePtrs[snum]->szService[0] == '\0')
4580 return;
4581 dump_a_service(ServicePtrs[snum], f);
4585 /***************************************************************************
4586 Return the number of the service with the given name, or -1 if it doesn't
4587 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4588 getservicebyname()! This works ONLY if all services have been loaded, and
4589 does not copy the found service.
4590 ***************************************************************************/
4592 int lp_servicenumber(const char *pszServiceName)
4594 int iService;
4595 fstring serviceName;
4597 if (!pszServiceName) {
4598 return GLOBAL_SECTION_SNUM;
4601 for (iService = iNumServices - 1; iService >= 0; iService--) {
4602 if (VALID(iService) && ServicePtrs[iService]->szService) {
4604 * The substitution here is used to support %U is
4605 * service names
4607 fstrcpy(serviceName, ServicePtrs[iService]->szService);
4608 standard_sub_basic(get_current_username(),
4609 current_user_info.domain,
4610 serviceName,sizeof(serviceName));
4611 if (strequal(serviceName, pszServiceName)) {
4612 break;
4617 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4618 struct timespec last_mod;
4620 if (!usershare_exists(iService, &last_mod)) {
4621 /* Remove the share security tdb entry for it. */
4622 delete_share_security(lp_servicename(talloc_tos(), iService));
4623 /* Remove it from the array. */
4624 free_service_byindex(iService);
4625 /* Doesn't exist anymore. */
4626 return GLOBAL_SECTION_SNUM;
4629 /* Has it been modified ? If so delete and reload. */
4630 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4631 &last_mod) < 0) {
4632 /* Remove it from the array. */
4633 free_service_byindex(iService);
4634 /* and now reload it. */
4635 iService = load_usershare_service(pszServiceName);
4639 if (iService < 0) {
4640 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4641 return GLOBAL_SECTION_SNUM;
4644 return (iService);
4647 /*******************************************************************
4648 A useful volume label function.
4649 ********************************************************************/
4651 const char *volume_label(TALLOC_CTX *ctx, int snum)
4653 char *ret;
4654 const char *label = lp_volume(ctx, snum);
4655 if (!*label) {
4656 label = lp_servicename(ctx, snum);
4659 /* This returns a 33 byte guarenteed null terminated string. */
4660 ret = talloc_strndup(ctx, label, 32);
4661 if (!ret) {
4662 return "";
4664 return ret;
4667 /*******************************************************************
4668 Get the default server type we will announce as via nmbd.
4669 ********************************************************************/
4671 int lp_default_server_announce(void)
4673 int default_server_announce = 0;
4674 default_server_announce |= SV_TYPE_WORKSTATION;
4675 default_server_announce |= SV_TYPE_SERVER;
4676 default_server_announce |= SV_TYPE_SERVER_UNIX;
4678 /* note that the flag should be set only if we have a
4679 printer service but nmbd doesn't actually load the
4680 services so we can't tell --jerry */
4682 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4684 default_server_announce |= SV_TYPE_SERVER_NT;
4685 default_server_announce |= SV_TYPE_NT;
4687 switch (lp_server_role()) {
4688 case ROLE_DOMAIN_MEMBER:
4689 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4690 break;
4691 case ROLE_DOMAIN_PDC:
4692 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4693 break;
4694 case ROLE_DOMAIN_BDC:
4695 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4696 break;
4697 case ROLE_STANDALONE:
4698 default:
4699 break;
4701 if (lp_time_server())
4702 default_server_announce |= SV_TYPE_TIME_SOURCE;
4704 if (lp_host_msdfs())
4705 default_server_announce |= SV_TYPE_DFS_SERVER;
4707 return default_server_announce;
4710 /***********************************************************
4711 If we are PDC then prefer us as DMB
4712 ************************************************************/
4714 bool lp_domain_master(void)
4716 if (Globals._domain_master == Auto)
4717 return (lp_server_role() == ROLE_DOMAIN_PDC);
4719 return (bool)Globals._domain_master;
4722 /***********************************************************
4723 If we are PDC then prefer us as DMB
4724 ************************************************************/
4726 static bool lp_domain_master_true_or_auto(void)
4728 if (Globals._domain_master) /* auto or yes */
4729 return true;
4731 return false;
4734 /***********************************************************
4735 If we are DMB then prefer us as LMB
4736 ************************************************************/
4738 bool lp_preferred_master(void)
4740 if (Globals.iPreferredMaster == Auto)
4741 return (lp_local_master() && lp_domain_master());
4743 return (bool)Globals.iPreferredMaster;
4746 /*******************************************************************
4747 Remove a service.
4748 ********************************************************************/
4750 void lp_remove_service(int snum)
4752 ServicePtrs[snum]->valid = false;
4755 const char *lp_printername(TALLOC_CTX *ctx, int snum)
4757 const char *ret = lp__printername(ctx, snum);
4758 if (ret == NULL || *ret == '\0') {
4759 ret = lp_const_servicename(snum);
4762 return ret;
4766 /***********************************************************
4767 Allow daemons such as winbindd to fix their logfile name.
4768 ************************************************************/
4770 void lp_set_logfile(const char *name)
4772 string_set(Globals.ctx, &Globals.logfile, name);
4773 debug_set_logfile(name);
4776 /*******************************************************************
4777 Return the max print jobs per queue.
4778 ********************************************************************/
4780 int lp_maxprintjobs(int snum)
4782 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4783 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4784 maxjobs = PRINT_MAX_JOBID - 1;
4786 return maxjobs;
4789 const char *lp_printcapname(void)
4791 if ((Globals.szPrintcapname != NULL) &&
4792 (Globals.szPrintcapname[0] != '\0'))
4793 return Globals.szPrintcapname;
4795 if (sDefault.printing == PRINT_CUPS) {
4796 return "cups";
4799 if (sDefault.printing == PRINT_BSD)
4800 return "/etc/printcap";
4802 return PRINTCAP_NAME;
4805 static uint32 spoolss_state;
4807 bool lp_disable_spoolss( void )
4809 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4810 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4812 return spoolss_state == SVCCTL_STOPPED ? true : false;
4815 void lp_set_spoolss_state( uint32 state )
4817 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4819 spoolss_state = state;
4822 uint32 lp_get_spoolss_state( void )
4824 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4827 /*******************************************************************
4828 Ensure we don't use sendfile if server smb signing is active.
4829 ********************************************************************/
4831 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
4833 bool sign_active = false;
4835 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4836 if (get_Protocol() < PROTOCOL_NT1) {
4837 return false;
4839 if (signing_state) {
4840 sign_active = smb_signing_is_active(signing_state);
4842 return (lp__use_sendfile(snum) &&
4843 (get_remote_arch() != RA_WIN95) &&
4844 !sign_active);
4847 /*******************************************************************
4848 Turn off sendfile if we find the underlying OS doesn't support it.
4849 ********************************************************************/
4851 void set_use_sendfile(int snum, bool val)
4853 if (LP_SNUM_OK(snum))
4854 ServicePtrs[snum]->_use_sendfile = val;
4855 else
4856 sDefault._use_sendfile = val;
4859 /*******************************************************************
4860 Turn off storing DOS attributes if this share doesn't support it.
4861 ********************************************************************/
4863 void set_store_dos_attributes(int snum, bool val)
4865 if (!LP_SNUM_OK(snum))
4866 return;
4867 ServicePtrs[(snum)]->store_dos_attributes = val;
4870 void lp_set_mangling_method(const char *new_method)
4872 string_set(Globals.ctx, &Globals.mangling_method, new_method);
4875 /*******************************************************************
4876 Global state for POSIX pathname processing.
4877 ********************************************************************/
4879 static bool posix_pathnames;
4881 bool lp_posix_pathnames(void)
4883 return posix_pathnames;
4886 /*******************************************************************
4887 Change everything needed to ensure POSIX pathname processing (currently
4888 not much).
4889 ********************************************************************/
4891 void lp_set_posix_pathnames(void)
4893 posix_pathnames = true;
4896 /*******************************************************************
4897 Global state for POSIX lock processing - CIFS unix extensions.
4898 ********************************************************************/
4900 bool posix_default_lock_was_set;
4901 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4903 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4905 if (posix_default_lock_was_set) {
4906 return posix_cifsx_locktype;
4907 } else {
4908 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
4912 /*******************************************************************
4913 ********************************************************************/
4915 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4917 posix_default_lock_was_set = true;
4918 posix_cifsx_locktype = val;
4921 int lp_min_receive_file_size(void)
4923 if (Globals.iminreceivefile < 0) {
4924 return 0;
4926 return Globals.iminreceivefile;
4929 /*******************************************************************
4930 Safe wide links checks.
4931 This helper function always verify the validity of wide links,
4932 even after a configuration file reload.
4933 ********************************************************************/
4935 static bool lp_widelinks_internal(int snum)
4937 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
4938 sDefault.bWidelinks);
4941 void widelinks_warning(int snum)
4943 if (lp_allow_insecure_wide_links()) {
4944 return;
4947 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
4948 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4949 "These parameters are incompatible. "
4950 "Wide links will be disabled for this share.\n",
4951 lp_servicename(talloc_tos(), snum) ));
4955 bool lp_widelinks(int snum)
4957 /* wide links is always incompatible with unix extensions */
4958 if (lp_unix_extensions()) {
4960 * Unless we have "allow insecure widelinks"
4961 * turned on.
4963 if (!lp_allow_insecure_wide_links()) {
4964 return false;
4968 return lp_widelinks_internal(snum);
4971 int lp_server_role(void)
4973 return lp_find_server_role(lp__server_role(),
4974 lp__security(),
4975 lp__domain_logons(),
4976 lp_domain_master_true_or_auto());
4979 int lp_security(void)
4981 return lp_find_security(lp__server_role(),
4982 lp__security());
4985 struct loadparm_global * get_globals(void)
4987 return &Globals;