s3:param: move lp_ctdbd_socket() to ctdbd_conn.c
[Samba.git] / source3 / param / loadparm.c
blobad879725b480a896e5f45ebe87ba7eaeb8c62627
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;
260 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
262 /* prototypes for the special type handlers */
263 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
264 static bool handle_copy(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_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
269 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
270 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
271 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
272 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
273 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
274 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
276 /* these are parameter handlers which are not needed in the
277 * source3 code
280 #define handle_logfile NULL
282 static void set_allowed_client_auth(void);
284 static void add_to_file_list(const char *fname, const char *subfname);
285 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
286 static void free_param_opts(struct parmlist_entry **popts);
288 #include "lib/param/param_table.c"
290 /* this is used to prevent lots of mallocs of size 1 */
291 static const char null_string[] = "";
294 Set a string value, allocing the space for the string
297 static bool string_init(char **dest,const char *src)
299 size_t l;
301 if (!src)
302 src = "";
304 l = strlen(src);
306 if (l == 0) {
307 *dest = discard_const_p(char, null_string);
308 } else {
309 (*dest) = SMB_STRDUP(src);
310 if ((*dest) == NULL) {
311 DEBUG(0,("Out of memory in string_init\n"));
312 return false;
315 return(true);
319 Free a string value.
322 static void string_free(char **s)
324 if (!s || !(*s))
325 return;
326 if (*s == null_string)
327 *s = NULL;
328 SAFE_FREE(*s);
332 Set a string value, deallocating any existing space, and allocing the space
333 for the string
336 static bool string_set(char **dest,const char *src)
338 string_free(dest);
339 return(string_init(dest,src));
342 /***************************************************************************
343 Initialise the sDefault parameter structure for the printer values.
344 ***************************************************************************/
346 static void init_printer_values(struct loadparm_service *pService)
348 /* choose defaults depending on the type of printing */
349 switch (pService->printing) {
350 case PRINT_BSD:
351 case PRINT_AIX:
352 case PRINT_LPRNT:
353 case PRINT_LPROS2:
354 string_set(&pService->lpq_command, "lpq -P'%p'");
355 string_set(&pService->lprm_command, "lprm -P'%p' %j");
356 string_set(&pService->print_command, "lpr -r -P'%p' %s");
357 break;
359 case PRINT_LPRNG:
360 case PRINT_PLP:
361 string_set(&pService->lpq_command, "lpq -P'%p'");
362 string_set(&pService->lprm_command, "lprm -P'%p' %j");
363 string_set(&pService->print_command, "lpr -r -P'%p' %s");
364 string_set(&pService->queuepause_command, "lpc stop '%p'");
365 string_set(&pService->queueresume_command, "lpc start '%p'");
366 string_set(&pService->lppause_command, "lpc hold '%p' %j");
367 string_set(&pService->lpresume_command, "lpc release '%p' %j");
368 break;
370 case PRINT_CUPS:
371 case PRINT_IPRINT:
372 /* set the lpq command to contain the destination printer
373 name only. This is used by cups_queue_get() */
374 string_set(&pService->lpq_command, "%p");
375 string_set(&pService->lprm_command, "");
376 string_set(&pService->print_command, "");
377 string_set(&pService->lppause_command, "");
378 string_set(&pService->lpresume_command, "");
379 string_set(&pService->queuepause_command, "");
380 string_set(&pService->queueresume_command, "");
381 break;
383 case PRINT_SYSV:
384 case PRINT_HPUX:
385 string_set(&pService->lpq_command, "lpstat -o%p");
386 string_set(&pService->lprm_command, "cancel %p-%j");
387 string_set(&pService->print_command, "lp -c -d%p %s; rm %s");
388 string_set(&pService->queuepause_command, "disable %p");
389 string_set(&pService->queueresume_command, "enable %p");
390 #ifndef HPUX
391 string_set(&pService->lppause_command, "lp -i %p-%j -H hold");
392 string_set(&pService->lpresume_command, "lp -i %p-%j -H resume");
393 #endif /* HPUX */
394 break;
396 case PRINT_QNX:
397 string_set(&pService->lpq_command, "lpq -P%p");
398 string_set(&pService->lprm_command, "lprm -P%p %j");
399 string_set(&pService->print_command, "lp -r -P%p %s");
400 break;
402 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
404 case PRINT_TEST:
405 case PRINT_VLP: {
406 const char *tdbfile;
407 TALLOC_CTX *tmp_ctx = talloc_stackframe();
408 char *tmp;
410 tdbfile = talloc_asprintf(
411 tmp_ctx, "tdbfile=%s",
412 lp_parm_const_string(-1, "vlp", "tdbfile",
413 "/tmp/vlp.tdb"));
414 if (tdbfile == NULL) {
415 tdbfile="tdbfile=/tmp/vlp.tdb";
418 tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
419 tdbfile);
420 string_set(&pService->print_command,
421 tmp ? tmp : "vlp print %p %s");
423 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
424 tdbfile);
425 string_set(&pService->lpq_command,
426 tmp ? tmp : "vlp lpq %p");
428 tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
429 tdbfile);
430 string_set(&pService->lprm_command,
431 tmp ? tmp : "vlp lprm %p %j");
433 tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
434 tdbfile);
435 string_set(&pService->lppause_command,
436 tmp ? tmp : "vlp lppause %p %j");
438 tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
439 tdbfile);
440 string_set(&pService->lpresume_command,
441 tmp ? tmp : "vlp lpresume %p %j");
443 tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
444 tdbfile);
445 string_set(&pService->queuepause_command,
446 tmp ? tmp : "vlp queuepause %p");
448 tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
449 tdbfile);
450 string_set(&pService->queueresume_command,
451 tmp ? tmp : "vlp queueresume %p");
452 TALLOC_FREE(tmp_ctx);
454 break;
456 #endif /* DEVELOPER */
461 * Function to return the default value for the maximum number of open
462 * file descriptors permitted. This function tries to consult the
463 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
464 * the smaller of those.
466 static int max_open_files(void)
468 int sysctl_max = MAX_OPEN_FILES;
469 int rlimit_max = MAX_OPEN_FILES;
471 #ifdef HAVE_SYSCTLBYNAME
473 size_t size = sizeof(sysctl_max);
474 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
477 #endif
479 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
481 struct rlimit rl;
483 ZERO_STRUCT(rl);
485 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
486 rlimit_max = rl.rlim_cur;
488 #if defined(RLIM_INFINITY)
489 if(rl.rlim_cur == RLIM_INFINITY)
490 rlimit_max = MAX_OPEN_FILES;
491 #endif
493 #endif
495 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
496 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
497 "minimum Windows limit (%d)\n",
498 sysctl_max,
499 MIN_OPEN_FILES_WINDOWS));
500 sysctl_max = MIN_OPEN_FILES_WINDOWS;
503 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
504 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
505 "minimum Windows limit (%d)\n",
506 rlimit_max,
507 MIN_OPEN_FILES_WINDOWS));
508 rlimit_max = MIN_OPEN_FILES_WINDOWS;
511 return MIN(sysctl_max, rlimit_max);
515 * Common part of freeing allocated data for one parameter.
517 static void free_one_parameter_common(void *parm_ptr,
518 struct parm_struct parm)
520 if ((parm.type == P_STRING) ||
521 (parm.type == P_USTRING))
523 string_free((char**)parm_ptr);
524 } else if (parm.type == P_LIST) {
525 TALLOC_FREE(*((char***)parm_ptr));
530 * Free the allocated data for one parameter for a share
531 * given as a service struct.
533 static void free_one_parameter(struct loadparm_service *service,
534 struct parm_struct parm)
536 void *parm_ptr;
538 if (parm.p_class != P_LOCAL) {
539 return;
542 parm_ptr = lp_parm_ptr(service, &parm);
544 free_one_parameter_common(parm_ptr, parm);
548 * Free the allocated parameter data of a share given
549 * as a service struct.
551 static void free_parameters(struct loadparm_service *service)
553 uint32_t i;
555 for (i=0; parm_table[i].label; i++) {
556 free_one_parameter(service, parm_table[i]);
561 * Free the allocated data for one parameter for a given share
562 * specified by an snum.
564 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
566 void *parm_ptr;
568 if (snum < 0) {
569 parm_ptr = lp_parm_ptr(NULL, &parm);
570 } else if (parm.p_class != P_LOCAL) {
571 return;
572 } else {
573 parm_ptr = lp_local_ptr_by_snum(snum, &parm);
576 free_one_parameter_common(parm_ptr, parm);
580 * Free the allocated parameter data for a share specified
581 * by an snum.
583 static void free_parameters_by_snum(int snum)
585 uint32_t i;
587 for (i=0; parm_table[i].label; i++) {
588 free_one_parameter_by_snum(snum, parm_table[i]);
593 * Free the allocated global parameters.
595 static void free_global_parameters(void)
597 free_param_opts(&Globals.param_opt);
598 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
599 TALLOC_FREE(Globals.ctx);
602 struct lp_stored_option {
603 struct lp_stored_option *prev, *next;
604 const char *label;
605 const char *value;
608 static struct lp_stored_option *stored_options;
611 save options set by lp_set_cmdline() into a list. This list is
612 re-applied when we do a globals reset, so that cmdline set options
613 are sticky across reloads of smb.conf
615 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
617 struct lp_stored_option *entry, *entry_next;
618 for (entry = stored_options; entry != NULL; entry = entry_next) {
619 entry_next = entry->next;
620 if (strcmp(pszParmName, entry->label) == 0) {
621 DLIST_REMOVE(stored_options, entry);
622 talloc_free(entry);
623 break;
627 entry = talloc(NULL, struct lp_stored_option);
628 if (!entry) {
629 return false;
632 entry->label = talloc_strdup(entry, pszParmName);
633 if (!entry->label) {
634 talloc_free(entry);
635 return false;
638 entry->value = talloc_strdup(entry, pszParmValue);
639 if (!entry->value) {
640 talloc_free(entry);
641 return false;
644 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
646 return true;
649 static bool apply_lp_set_cmdline(void)
651 struct lp_stored_option *entry = NULL;
652 for (entry = stored_options; entry != NULL; entry = entry->next) {
653 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
654 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
655 entry->label, entry->value));
656 return false;
659 return true;
662 /***************************************************************************
663 Initialise the global parameter structure.
664 ***************************************************************************/
666 static void init_globals(bool reinit_globals)
668 static bool done_init = false;
669 char *s = NULL;
670 int i;
672 /* If requested to initialize only once and we've already done it... */
673 if (!reinit_globals && done_init) {
674 /* ... then we have nothing more to do */
675 return;
678 if (!done_init) {
679 /* The logfile can be set before this is invoked. Free it if so. */
680 if (Globals.logfile != NULL) {
681 string_free(&Globals.logfile);
682 Globals.logfile = NULL;
684 done_init = true;
685 } else {
686 free_global_parameters();
689 /* This memset and the free_global_parameters() above will
690 * wipe out smb.conf options set with lp_set_cmdline(). The
691 * apply_lp_set_cmdline() call puts these values back in the
692 * table once the defaults are set */
693 ZERO_STRUCT(Globals);
695 Globals.ctx = talloc_new(NULL);
697 for (i = 0; parm_table[i].label; i++) {
698 if ((parm_table[i].type == P_STRING ||
699 parm_table[i].type == P_USTRING))
701 string_set((char **)lp_parm_ptr(NULL, &parm_table[i]), "");
706 string_set(&sDefault.fstype, FSTYPE_STRING);
707 string_set(&sDefault.printjob_username, "%U");
709 init_printer_values(&sDefault);
711 sDefault.ntvfs_handler = (const char **)str_list_make_v3(NULL, "unixuid default", NULL);
713 DEBUG(3, ("Initialising global parameters\n"));
715 /* Must manually force to upper case here, as this does not go via the handler */
716 string_set(&Globals.netbios_name, myhostname_upper());
718 string_set(&Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE());
719 string_set(&Globals.private_dir, get_dyn_PRIVATE_DIR());
721 /* use the new 'hash2' method by default, with a prefix of 1 */
722 string_set(&Globals.mangling_method, "hash2");
723 Globals.mangle_prefix = 1;
725 string_set(&Globals.guest_account, GUEST_ACCOUNT);
727 /* using UTF8 by default allows us to support all chars */
728 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
730 /* Use codepage 850 as a default for the dos character set */
731 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
734 * Allow the default PASSWD_CHAT to be overridden in local.h.
736 string_set(&Globals.passwd_chat, DEFAULT_PASSWD_CHAT);
738 string_set(&Globals.workgroup, DEFAULT_WORKGROUP);
740 string_set(&Globals.passwd_program, "");
741 string_set(&Globals.lock_directory, get_dyn_LOCKDIR());
742 string_set(&Globals.state_directory, get_dyn_STATEDIR());
743 string_set(&Globals.cache_directory, get_dyn_CACHEDIR());
744 string_set(&Globals.pid_directory, get_dyn_PIDDIR());
745 string_set(&Globals.nbt_client_socket_address, "0.0.0.0");
747 * By default support explicit binding to broadcast
748 * addresses.
750 Globals.nmbd_bind_explicit_broadcast = true;
752 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
753 smb_panic("init_globals: ENOMEM");
755 string_set(&Globals.server_string, s);
756 SAFE_FREE(s);
757 #ifdef DEVELOPER
758 string_set(&Globals.panic_action, "/bin/sleep 999999999");
759 #endif
761 string_set(&Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
763 string_set(&Globals.logon_drive, "");
764 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
765 string_set(&Globals.logon_home, "\\\\%N\\%U");
766 string_set(&Globals.logon_path, "\\\\%N\\%U\\profile");
768 Globals.name_resolve_order = (const char **)str_list_make_v3(NULL, "lmhosts wins host bcast", NULL);
769 string_set(&Globals.password_server, "*");
771 Globals.algorithmic_rid_base = BASE_RID;
773 Globals.load_printers = true;
774 Globals.printcap_cache_time = 750; /* 12.5 minutes */
776 Globals.config_backend = config_backend;
777 Globals._server_role = ROLE_AUTO;
779 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
780 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
781 Globals.max_xmit = 0x4104;
782 Globals.max_mux = 50; /* This is *needed* for profile support. */
783 Globals.lpq_cache_time = 30; /* changed to handle large print servers better -- jerry */
784 Globals._disable_spoolss = false;
785 Globals.max_smbd_processes = 0;/* no limit specified */
786 Globals.username_level = 0;
787 Globals.deadtime = 0;
788 Globals.getwd_cache = true;
789 Globals.large_readwrite = true;
790 Globals.max_log_size = 5000;
791 Globals.max_open_files = max_open_files();
792 Globals.server_max_protocol = PROTOCOL_SMB3_00;
793 Globals.server_min_protocol = PROTOCOL_LANMAN1;
794 Globals.client_max_protocol = PROTOCOL_NT1;
795 Globals.client_min_protocol = PROTOCOL_CORE;
796 Globals._security = SEC_AUTO;
797 Globals.encrypt_passwords = true;
798 Globals.client_schannel = Auto;
799 Globals.winbind_sealed_pipes = true;
800 Globals.require_strong_key = true;
801 Globals.server_schannel = Auto;
802 Globals.read_raw = true;
803 Globals.write_raw = true;
804 Globals.null_passwords = false;
805 Globals.obey_pam_restrictions = false;
806 Globals.syslog = 1;
807 Globals.syslog_only = false;
808 Globals.timestamp_logs = true;
809 string_set(&Globals.log_level, "0");
810 Globals.debug_prefix_timestamp = false;
811 Globals.debug_hires_timestamp = true;
812 Globals.debug_pid = false;
813 Globals.debug_uid = false;
814 Globals.debug_class = false;
815 Globals.enable_core_files = true;
816 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
817 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
818 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
819 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
820 Globals.lm_announce = Auto; /* = Auto: send only if LM clients found */
821 Globals.lm_interval = 60;
822 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
823 Globals.nis_homedir = false;
824 #ifdef WITH_NISPLUS_HOME
825 string_set(&Globals.homedir_map, "auto_home.org_dir");
826 #else
827 string_set(&Globals.homedir_map, "auto.home");
828 #endif
829 #endif
830 Globals.time_server = false;
831 Globals.bind_interfaces_only = false;
832 Globals.unix_password_sync = false;
833 Globals.pam_password_change = false;
834 Globals.passwd_chat_debug = false;
835 Globals.passwd_chat_timeout = 2; /* 2 second default. */
836 Globals.nt_pipe_support = true; /* Do NT pipes by default. */
837 Globals.nt_status_support = true; /* Use NT status by default. */
838 Globals.stat_cache = true; /* use stat cache by default */
839 Globals.max_stat_cache_size = 256; /* 256k by default */
840 Globals.restrict_anonymous = 0;
841 Globals.client_lanman_auth = false; /* Do NOT use the LanMan hash if it is available */
842 Globals.client_plaintext_auth = false; /* Do NOT use a plaintext password even if is requested by the server */
843 Globals.lanman_auth = false; /* Do NOT use the LanMan hash, even if it is supplied */
844 Globals.ntlm_auth = true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
845 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 */
846 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
848 Globals.map_to_guest = 0; /* By Default, "Never" */
849 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
850 Globals.enhanced_browsing = true;
851 Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
852 #ifdef MMAP_BLACKLIST
853 Globals.use_mmap = false;
854 #else
855 Globals.use_mmap = true;
856 #endif
857 Globals.unicode = true;
858 Globals.unix_extensions = true;
859 Globals.reset_on_zero_vc = false;
860 Globals.log_writeable_files_on_exit = false;
861 Globals.create_krb5_conf = true;
862 Globals.winbindMaxDomainConnections = 1;
864 /* hostname lookups can be very expensive and are broken on
865 a large number of sites (tridge) */
866 Globals.hostname_lookups = false;
868 string_set(&Globals.passdb_backend, "tdbsam");
869 string_set(&Globals.ldap_suffix, "");
870 string_set(&Globals.szLdapMachineSuffix, "");
871 string_set(&Globals.szLdapUserSuffix, "");
872 string_set(&Globals.szLdapGroupSuffix, "");
873 string_set(&Globals.szLdapIdmapSuffix, "");
875 string_set(&Globals.ldap_admin_dn, "");
876 Globals.ldap_ssl = LDAP_SSL_START_TLS;
877 Globals.ldap_ssl_ads = false;
878 Globals.ldap_deref = -1;
879 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
880 Globals.ldap_delete_dn = false;
881 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
882 Globals.ldap_follow_referral = Auto;
883 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
884 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
885 Globals.ldap_page_size = LDAP_PAGE_SIZE;
887 Globals.ldap_debug_level = 0;
888 Globals.ldap_debug_threshold = 10;
890 /* This is what we tell the afs client. in reality we set the token
891 * to never expire, though, when this runs out the afs client will
892 * forget the token. Set to 0 to get NEVERDATE.*/
893 Globals.afs_token_lifetime = 604800;
894 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
896 /* these parameters are set to defaults that are more appropriate
897 for the increasing samba install base:
899 as a member of the workgroup, that will possibly become a
900 _local_ master browser (lm = true). this is opposed to a forced
901 local master browser startup (pm = true).
903 doesn't provide WINS server service by default (wsupp = false),
904 and doesn't provide domain master browser services by default, either.
908 Globals.show_add_printer_wizard = true;
909 Globals.os_level = 20;
910 Globals.local_master = true;
911 Globals._domain_master = Auto; /* depending on _domain_logons */
912 Globals._domain_logons = false;
913 Globals.browse_list = true;
914 Globals.we_are_a_wins_server = false;
915 Globals.wins_proxy = false;
917 TALLOC_FREE(Globals.init_logon_delayed_hosts);
918 Globals.init_logon_delay = 100; /* 100 ms default delay */
920 Globals.wins_dns_proxy = true;
922 Globals.allow_trusted_domains = true;
923 string_set(&Globals.szIdmapBackend, "tdb");
925 string_set(&Globals.template_shell, "/bin/false");
926 string_set(&Globals.template_homedir, "/home/%D/%U");
927 string_set(&Globals.winbind_separator, "\\");
928 string_set(&Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
930 string_set(&Globals.cups_server, "");
931 string_set(&Globals.iprint_server, "");
933 string_set(&Globals._ctdbd_socket, "");
935 Globals.cluster_addresses = NULL;
936 Globals.clustering = false;
937 Globals.ctdb_timeout = 0;
938 Globals.ctdb_locktime_warn_threshold = 0;
940 Globals.winbind_cache_time = 300; /* 5 minutes */
941 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
942 Globals.winbind_max_clients = 200;
943 Globals.winbind_enum_users = false;
944 Globals.winbind_enum_groups = false;
945 Globals.winbind_use_default_domain = false;
946 Globals.winbind_trusted_domains_only = false;
947 Globals.winbind_nested_groups = true;
948 Globals.winbind_expand_groups = 1;
949 Globals.winbind_nss_info = (const char **)str_list_make_v3(NULL, "template", NULL);
950 Globals.winbind_refresh_tickets = false;
951 Globals.winbind_offline_logon = false;
953 Globals.idmap_cache_time = 86400 * 7; /* a week by default */
954 Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
956 Globals.passdb_expand_explicit = false;
958 Globals.name_cache_timeout = 660; /* In seconds */
960 Globals.use_spnego = true;
961 Globals.client_use_spnego = true;
963 Globals.client_signing = SMB_SIGNING_DEFAULT;
964 Globals.server_signing = SMB_SIGNING_DEFAULT;
966 Globals.defer_sharing_violations = true;
967 Globals.smb_ports = (const char **)str_list_make_v3(NULL, SMB_PORTS, NULL);
969 Globals.enable_privileges = true;
970 Globals.host_msdfs = true;
971 Globals.enable_asu_support = false;
973 /* User defined shares. */
974 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
975 smb_panic("init_globals: ENOMEM");
977 string_set(&Globals.usershare_path, s);
978 SAFE_FREE(s);
979 string_set(&Globals.usershare_template_share, "");
980 Globals.usershare_max_shares = 0;
981 /* By default disallow sharing of directories not owned by the sharer. */
982 Globals.usershare_owner_only = true;
983 /* By default disallow guest access to usershares. */
984 Globals.usershare_allow_guests = false;
986 Globals.keepalive = DEFAULT_KEEPALIVE;
988 /* By default no shares out of the registry */
989 Globals.registry_shares = false;
991 Globals.iminreceivefile = 0;
993 Globals.map_untrusted_to_domain = false;
994 Globals.multicast_dns_register = true;
996 Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
997 Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
998 Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
999 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1001 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
1003 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);
1005 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);
1007 Globals.tls_enabled = true;
1009 string_set(&Globals._tls_keyfile, "tls/key.pem");
1010 string_set(&Globals._tls_certfile, "tls/cert.pem");
1011 string_set(&Globals._tls_cafile, "tls/ca.pem");
1013 string_set(&Globals.share_backend, "classic");
1015 Globals.iPreferredMaster = Auto;
1017 Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
1019 string_set(&Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR());
1021 string_set(&Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
1023 if (asprintf(&s, "%s/samba_kcc", get_dyn_SCRIPTSBINDIR()) < 0) {
1024 smb_panic("init_globals: ENOMEM");
1026 Globals.samba_kcc_command = (const char **)str_list_make_v3(NULL, s, NULL);
1027 SAFE_FREE(s);
1029 if (asprintf(&s, "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
1030 smb_panic("init_globals: ENOMEM");
1032 Globals.dns_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
1033 SAFE_FREE(s);
1035 if (asprintf(&s, "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
1036 smb_panic("init_globals: ENOMEM");
1038 Globals.spn_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
1039 SAFE_FREE(s);
1041 Globals.nsupdate_command = (const char **)str_list_make_v3(NULL, "/usr/bin/nsupdate -g", NULL);
1043 Globals.rndc_command = (const char **)str_list_make_v3(NULL, "/usr/sbin/rndc", NULL);
1045 Globals.cldap_port = 389;
1047 Globals.dgram_port = 138;
1049 Globals.nbt_port = 137;
1051 Globals.krb5_port = 88;
1053 Globals.kpasswd_port = 464;
1055 Globals.web_port = 901;
1057 /* Now put back the settings that were set with lp_set_cmdline() */
1058 apply_lp_set_cmdline();
1061 /*******************************************************************
1062 Convenience routine to grab string parameters into talloced memory
1063 and run standard_sub_basic on them. The buffers can be written to by
1064 callers without affecting the source string.
1065 ********************************************************************/
1067 char *lp_string(TALLOC_CTX *ctx, const char *s)
1069 char *ret;
1071 /* The follow debug is useful for tracking down memory problems
1072 especially if you have an inner loop that is calling a lp_*()
1073 function that returns a string. Perhaps this debug should be
1074 present all the time? */
1076 #if 0
1077 DEBUG(10, ("lp_string(%s)\n", s));
1078 #endif
1079 if (!s) {
1080 return NULL;
1083 ret = talloc_sub_basic(ctx,
1084 get_current_username(),
1085 current_user_info.domain,
1087 if (trim_char(ret, '\"', '\"')) {
1088 if (strchr(ret,'\"') != NULL) {
1089 TALLOC_FREE(ret);
1090 ret = talloc_sub_basic(ctx,
1091 get_current_username(),
1092 current_user_info.domain,
1096 return ret;
1100 In this section all the functions that are used to access the
1101 parameters from the rest of the program are defined
1104 #define FN_GLOBAL_STRING(fn_name,ptr) \
1105 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1106 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1107 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1108 #define FN_GLOBAL_LIST(fn_name,ptr) \
1109 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1110 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1111 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1112 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1113 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1114 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1115 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1117 #define FN_LOCAL_STRING(fn_name,val) \
1118 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));}
1119 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1120 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1121 #define FN_LOCAL_LIST(fn_name,val) \
1122 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1123 #define FN_LOCAL_BOOL(fn_name,val) \
1124 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1125 #define FN_LOCAL_INTEGER(fn_name,val) \
1126 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1128 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1129 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1130 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1131 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1132 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1133 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1135 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
1136 winbindMaxDomainConnections)
1138 int lp_winbind_max_domain_connections(void)
1140 if (lp_winbind_offline_logon() &&
1141 lp_winbind_max_domain_connections_int() > 1) {
1142 DEBUG(1, ("offline logons active, restricting max domain "
1143 "connections to 1\n"));
1144 return 1;
1146 return MAX(1, lp_winbind_max_domain_connections_int());
1149 int lp_smb2_max_credits(void)
1151 if (Globals.ismb2_max_credits == 0) {
1152 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1154 return Globals.ismb2_max_credits;
1156 int lp_cups_encrypt(void)
1158 int result = 0;
1159 #ifdef HAVE_HTTPCONNECTENCRYPT
1160 switch (Globals.CupsEncrypt) {
1161 case Auto:
1162 result = HTTP_ENCRYPT_REQUIRED;
1163 break;
1164 case true:
1165 result = HTTP_ENCRYPT_ALWAYS;
1166 break;
1167 case false:
1168 result = HTTP_ENCRYPT_NEVER;
1169 break;
1171 #endif
1172 return result;
1175 /* These functions remain in source3/param for now */
1177 #include "lib/param/param_functions.c"
1179 FN_LOCAL_STRING(servicename, szService)
1180 FN_LOCAL_CONST_STRING(const_servicename, szService)
1182 /* These functions cannot be auto-generated */
1183 FN_LOCAL_BOOL(autoloaded, autoloaded)
1185 /* local prototypes */
1187 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1188 static const char *get_boolean(bool bool_value);
1189 static int getservicebyname(const char *pszServiceName,
1190 struct loadparm_service *pserviceDest);
1191 static void copy_service(struct loadparm_service *pserviceDest,
1192 struct loadparm_service *pserviceSource,
1193 struct bitmap *pcopymapDest);
1194 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1195 void *userdata);
1196 static bool do_section(const char *pszSectionName, void *userdata);
1197 static void init_copymap(struct loadparm_service *pservice);
1198 static bool hash_a_service(const char *name, int number);
1199 static void free_service_byindex(int iService);
1200 static void show_parameter(int parmIndex);
1201 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1204 * This is a helper function for parametrical options support. It returns a
1205 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1206 * parametrical functions are quite simple
1208 static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service *service, const char *type,
1209 const char *option)
1211 bool global_section = false;
1212 char* param_key;
1213 struct parmlist_entry *data;
1215 if (service == NULL) {
1216 data = Globals.param_opt;
1217 global_section = true;
1218 } else {
1219 data = service->param_opt;
1222 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
1223 DEBUG(0,("asprintf failed!\n"));
1224 return NULL;
1227 while (data) {
1228 if (strwicmp(data->key, param_key) == 0) {
1229 string_free(&param_key);
1230 return data;
1232 data = data->next;
1235 if (!global_section) {
1236 /* Try to fetch the same option but from globals */
1237 /* but only if we are not already working with Globals */
1238 data = Globals.param_opt;
1239 while (data) {
1240 if (strwicmp(data->key, param_key) == 0) {
1241 string_free(&param_key);
1242 return data;
1244 data = data->next;
1248 string_free(&param_key);
1250 return NULL;
1254 * This is a helper function for parametrical options support. It returns a
1255 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1256 * parametrical functions are quite simple
1258 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1259 const char *option)
1261 if (snum >= iNumServices) return NULL;
1263 if (snum < 0) {
1264 return get_parametrics_by_service(NULL, type, option);
1265 } else {
1266 return get_parametrics_by_service(ServicePtrs[snum], type, option);
1271 #define MISSING_PARAMETER(name) \
1272 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1274 /*******************************************************************
1275 convenience routine to return int parameters.
1276 ********************************************************************/
1277 static int lp_int(const char *s)
1280 if (!s || !*s) {
1281 MISSING_PARAMETER(lp_int);
1282 return (-1);
1285 return (int)strtol(s, NULL, 0);
1288 /*******************************************************************
1289 convenience routine to return unsigned long parameters.
1290 ********************************************************************/
1291 static unsigned long lp_ulong(const char *s)
1294 if (!s || !*s) {
1295 MISSING_PARAMETER(lp_ulong);
1296 return (0);
1299 return strtoul(s, NULL, 0);
1302 /*******************************************************************
1303 convenience routine to return boolean parameters.
1304 ********************************************************************/
1305 static bool lp_bool(const char *s)
1307 bool ret = false;
1309 if (!s || !*s) {
1310 MISSING_PARAMETER(lp_bool);
1311 return false;
1314 if (!set_boolean(s, &ret)) {
1315 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1316 return false;
1319 return ret;
1322 /*******************************************************************
1323 convenience routine to return enum parameters.
1324 ********************************************************************/
1325 static int lp_enum(const char *s,const struct enum_list *_enum)
1327 int i;
1329 if (!s || !*s || !_enum) {
1330 MISSING_PARAMETER(lp_enum);
1331 return (-1);
1334 for (i=0; _enum[i].name; i++) {
1335 if (strequal(_enum[i].name,s))
1336 return _enum[i].value;
1339 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1340 return (-1);
1343 #undef MISSING_PARAMETER
1345 /* Return parametric option from a given service. Type is a part of option before ':' */
1346 /* Parametric option has following syntax: 'Type: option = value' */
1347 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1349 struct parmlist_entry *data = get_parametrics(snum, type, option);
1351 if (data == NULL||data->value==NULL) {
1352 if (def) {
1353 return lp_string(ctx, def);
1354 } else {
1355 return NULL;
1359 return lp_string(ctx, data->value);
1362 /* Return parametric option from a given service. Type is a part of option before ':' */
1363 /* Parametric option has following syntax: 'Type: option = value' */
1364 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1366 struct parmlist_entry *data = get_parametrics(snum, type, option);
1368 if (data == NULL||data->value==NULL)
1369 return def;
1371 return data->value;
1374 const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
1376 struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
1378 if (data == NULL||data->value==NULL)
1379 return NULL;
1381 return data->value;
1385 /* Return parametric option from a given service. Type is a part of option before ':' */
1386 /* Parametric option has following syntax: 'Type: option = value' */
1388 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1390 struct parmlist_entry *data = get_parametrics(snum, type, option);
1392 if (data == NULL||data->value==NULL)
1393 return (const char **)def;
1395 if (data->list==NULL) {
1396 data->list = str_list_make_v3(NULL, data->value, NULL);
1399 return (const char **)data->list;
1402 /* Return parametric option from a given service. Type is a part of option before ':' */
1403 /* Parametric option has following syntax: 'Type: option = value' */
1405 int lp_parm_int(int snum, const char *type, const char *option, int def)
1407 struct parmlist_entry *data = get_parametrics(snum, type, option);
1409 if (data && data->value && *data->value)
1410 return lp_int(data->value);
1412 return def;
1415 /* Return parametric option from a given service. Type is a part of option before ':' */
1416 /* Parametric option has following syntax: 'Type: option = value' */
1418 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1420 struct parmlist_entry *data = get_parametrics(snum, type, option);
1422 if (data && data->value && *data->value)
1423 return lp_ulong(data->value);
1425 return def;
1428 /* Return parametric option from a given service. Type is a part of option before ':' */
1429 /* Parametric option has following syntax: 'Type: option = value' */
1431 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1433 struct parmlist_entry *data = get_parametrics(snum, type, option);
1435 if (data && data->value && *data->value)
1436 return lp_bool(data->value);
1438 return def;
1441 /* Return parametric option from a given service. Type is a part of option before ':' */
1442 /* Parametric option has following syntax: 'Type: option = value' */
1444 int lp_parm_enum(int snum, const char *type, const char *option,
1445 const struct enum_list *_enum, int def)
1447 struct parmlist_entry *data = get_parametrics(snum, type, option);
1449 if (data && data->value && *data->value && _enum)
1450 return lp_enum(data->value, _enum);
1452 return def;
1456 /***************************************************************************
1457 Initialise a service to the defaults.
1458 ***************************************************************************/
1460 static void init_service(struct loadparm_service *pservice)
1462 memset((char *)pservice, '\0', sizeof(struct loadparm_service));
1463 copy_service(pservice, &sDefault, NULL);
1468 * free a param_opts structure.
1469 * param_opts handling should be moved to talloc;
1470 * then this whole functions reduces to a TALLOC_FREE().
1473 static void free_param_opts(struct parmlist_entry **popts)
1475 struct parmlist_entry *opt, *next_opt;
1477 if (*popts != NULL) {
1478 DEBUG(5, ("Freeing parametrics:\n"));
1480 opt = *popts;
1481 while (opt != NULL) {
1482 string_free(&opt->key);
1483 string_free(&opt->value);
1484 TALLOC_FREE(opt->list);
1485 next_opt = opt->next;
1486 SAFE_FREE(opt);
1487 opt = next_opt;
1489 *popts = NULL;
1492 /***************************************************************************
1493 Free the dynamically allocated parts of a service struct.
1494 ***************************************************************************/
1496 static void free_service(struct loadparm_service *pservice)
1498 if (!pservice)
1499 return;
1501 if (pservice->szService)
1502 DEBUG(5, ("free_service: Freeing service %s\n",
1503 pservice->szService));
1505 free_parameters(pservice);
1507 string_free(&pservice->szService);
1508 TALLOC_FREE(pservice->copymap);
1510 free_param_opts(&pservice->param_opt);
1512 ZERO_STRUCTP(pservice);
1516 /***************************************************************************
1517 remove a service indexed in the ServicePtrs array from the ServiceHash
1518 and free the dynamically allocated parts
1519 ***************************************************************************/
1521 static void free_service_byindex(int idx)
1523 if ( !LP_SNUM_OK(idx) )
1524 return;
1526 ServicePtrs[idx]->valid = false;
1528 /* we have to cleanup the hash record */
1530 if (ServicePtrs[idx]->szService) {
1531 char *canon_name = canonicalize_servicename(
1532 talloc_tos(),
1533 ServicePtrs[idx]->szService );
1535 dbwrap_delete_bystring(ServiceHash, canon_name );
1536 TALLOC_FREE(canon_name);
1539 free_service(ServicePtrs[idx]);
1540 talloc_free_children(ServicePtrs[idx]);
1543 /***************************************************************************
1544 Add a new service to the services array initialising it with the given
1545 service.
1546 ***************************************************************************/
1548 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1550 int i;
1551 struct loadparm_service tservice;
1552 int num_to_alloc = iNumServices + 1;
1553 struct loadparm_service **tsp = NULL;
1555 tservice = *pservice;
1557 /* it might already exist */
1558 if (name) {
1559 i = getservicebyname(name, NULL);
1560 if (i >= 0) {
1561 return (i);
1565 /* if not, then create one */
1566 i = iNumServices;
1567 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
1568 if (tsp == NULL) {
1569 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1570 return (-1);
1572 ServicePtrs = tsp;
1573 ServicePtrs[iNumServices] = talloc(NULL, struct loadparm_service);
1574 if (!ServicePtrs[iNumServices]) {
1575 DEBUG(0,("add_a_service: out of memory!\n"));
1576 return (-1);
1578 iNumServices++;
1580 ServicePtrs[i]->valid = true;
1582 init_service(ServicePtrs[i]);
1583 copy_service(ServicePtrs[i], &tservice, NULL);
1584 if (name)
1585 string_set(&ServicePtrs[i]->szService, name);
1587 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1588 i, ServicePtrs[i]->szService));
1590 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1591 return (-1);
1594 return (i);
1597 /***************************************************************************
1598 Convert a string to uppercase and remove whitespaces.
1599 ***************************************************************************/
1601 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1603 char *result;
1605 if ( !src ) {
1606 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1607 return NULL;
1610 result = talloc_strdup(ctx, src);
1611 SMB_ASSERT(result != NULL);
1613 if (!strlower_m(result)) {
1614 TALLOC_FREE(result);
1615 return NULL;
1617 return result;
1620 /***************************************************************************
1621 Add a name/index pair for the services array to the hash table.
1622 ***************************************************************************/
1624 static bool hash_a_service(const char *name, int idx)
1626 char *canon_name;
1628 if ( !ServiceHash ) {
1629 DEBUG(10,("hash_a_service: creating servicehash\n"));
1630 ServiceHash = db_open_rbt(NULL);
1631 if ( !ServiceHash ) {
1632 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1633 return false;
1637 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1638 idx, name));
1640 canon_name = canonicalize_servicename(talloc_tos(), name );
1642 dbwrap_store_bystring(ServiceHash, canon_name,
1643 make_tdb_data((uint8 *)&idx, sizeof(idx)),
1644 TDB_REPLACE);
1646 TALLOC_FREE(canon_name);
1648 return true;
1651 /***************************************************************************
1652 Add a new home service, with the specified home directory, defaults coming
1653 from service ifrom.
1654 ***************************************************************************/
1656 bool lp_add_home(const char *pszHomename, int iDefaultService,
1657 const char *user, const char *pszHomedir)
1659 int i;
1661 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1662 pszHomedir[0] == '\0') {
1663 return false;
1666 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1668 if (i < 0)
1669 return false;
1671 if (!(*(ServicePtrs[iDefaultService]->path))
1672 || strequal(ServicePtrs[iDefaultService]->path,
1673 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1674 string_set(&ServicePtrs[i]->path, pszHomedir);
1677 if (!(*(ServicePtrs[i]->comment))) {
1678 char *comment = NULL;
1679 if (asprintf(&comment, "Home directory of %s", user) < 0) {
1680 return false;
1682 string_set(&ServicePtrs[i]->comment, comment);
1683 SAFE_FREE(comment);
1686 /* set the browseable flag from the global default */
1688 ServicePtrs[i]->browseable = sDefault.browseable;
1689 ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1691 ServicePtrs[i]->autoloaded = true;
1693 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1694 user, ServicePtrs[i]->path ));
1696 return true;
1699 /***************************************************************************
1700 Add a new service, based on an old one.
1701 ***************************************************************************/
1703 int lp_add_service(const char *pszService, int iDefaultService)
1705 if (iDefaultService < 0) {
1706 return add_a_service(&sDefault, pszService);
1709 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1712 /***************************************************************************
1713 Add the IPC service.
1714 ***************************************************************************/
1716 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1718 char *comment = NULL;
1719 int i = add_a_service(&sDefault, ipc_name);
1721 if (i < 0)
1722 return false;
1724 if (asprintf(&comment, "IPC Service (%s)",
1725 Globals.server_string) < 0) {
1726 return false;
1729 string_set(&ServicePtrs[i]->path, tmpdir());
1730 string_set(&ServicePtrs[i]->username, "");
1731 string_set(&ServicePtrs[i]->comment, comment);
1732 string_set(&ServicePtrs[i]->fstype, "IPC");
1733 ServicePtrs[i]->max_connections = 0;
1734 ServicePtrs[i]->bAvailable = true;
1735 ServicePtrs[i]->read_only = true;
1736 ServicePtrs[i]->guest_only = false;
1737 ServicePtrs[i]->administrative_share = true;
1738 ServicePtrs[i]->guest_ok = guest_ok;
1739 ServicePtrs[i]->printable = false;
1740 ServicePtrs[i]->browseable = sDefault.browseable;
1742 DEBUG(3, ("adding IPC service\n"));
1744 SAFE_FREE(comment);
1745 return true;
1748 /***************************************************************************
1749 Add a new printer service, with defaults coming from service iFrom.
1750 ***************************************************************************/
1752 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1754 const char *comment = "From Printcap";
1755 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1757 if (i < 0)
1758 return false;
1760 /* note that we do NOT default the availability flag to true - */
1761 /* we take it from the default service passed. This allows all */
1762 /* dynamic printers to be disabled by disabling the [printers] */
1763 /* entry (if/when the 'available' keyword is implemented!). */
1765 /* the printer name is set to the service name. */
1766 string_set(&ServicePtrs[i]->_printername, pszPrintername);
1767 string_set(&ServicePtrs[i]->comment, comment);
1769 /* set the browseable flag from the gloabl default */
1770 ServicePtrs[i]->browseable = sDefault.browseable;
1772 /* Printers cannot be read_only. */
1773 ServicePtrs[i]->read_only = false;
1774 /* No oplocks on printer services. */
1775 ServicePtrs[i]->oplocks = false;
1776 /* Printer services must be printable. */
1777 ServicePtrs[i]->printable = true;
1779 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1781 return true;
1785 /***************************************************************************
1786 Check whether the given parameter name is valid.
1787 Parametric options (names containing a colon) are considered valid.
1788 ***************************************************************************/
1790 bool lp_parameter_is_valid(const char *pszParmName)
1792 return ((lpcfg_map_parameter(pszParmName) != -1) ||
1793 (strchr(pszParmName, ':') != NULL));
1796 /***************************************************************************
1797 Check whether the given name is the name of a global parameter.
1798 Returns true for strings belonging to parameters of class
1799 P_GLOBAL, false for all other strings, also for parametric options
1800 and strings not belonging to any option.
1801 ***************************************************************************/
1803 bool lp_parameter_is_global(const char *pszParmName)
1805 int num = lpcfg_map_parameter(pszParmName);
1807 if (num >= 0) {
1808 return (parm_table[num].p_class == P_GLOBAL);
1811 return false;
1814 /**************************************************************************
1815 Check whether the given name is the canonical name of a parameter.
1816 Returns false if it is not a valid parameter Name.
1817 For parametric options, true is returned.
1818 **************************************************************************/
1820 bool lp_parameter_is_canonical(const char *parm_name)
1822 if (!lp_parameter_is_valid(parm_name)) {
1823 return false;
1826 return (lpcfg_map_parameter(parm_name) ==
1827 map_parameter_canonical(parm_name, NULL));
1830 /**************************************************************************
1831 Determine the canonical name for a parameter.
1832 Indicate when it is an inverse (boolean) synonym instead of a
1833 "usual" synonym.
1834 **************************************************************************/
1836 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1837 bool *inverse)
1839 int num;
1841 if (!lp_parameter_is_valid(parm_name)) {
1842 *canon_parm = NULL;
1843 return false;
1846 num = map_parameter_canonical(parm_name, inverse);
1847 if (num < 0) {
1848 /* parametric option */
1849 *canon_parm = parm_name;
1850 } else {
1851 *canon_parm = parm_table[num].label;
1854 return true;
1858 /**************************************************************************
1859 Determine the canonical name for a parameter.
1860 Turn the value given into the inverse boolean expression when
1861 the synonym is an invers boolean synonym.
1863 Return true if parm_name is a valid parameter name and
1864 in case it is an invers boolean synonym, if the val string could
1865 successfully be converted to the reverse bool.
1866 Return false in all other cases.
1867 **************************************************************************/
1869 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1870 const char *val,
1871 const char **canon_parm,
1872 const char **canon_val)
1874 int num;
1875 bool inverse;
1877 if (!lp_parameter_is_valid(parm_name)) {
1878 *canon_parm = NULL;
1879 *canon_val = NULL;
1880 return false;
1883 num = map_parameter_canonical(parm_name, &inverse);
1884 if (num < 0) {
1885 /* parametric option */
1886 *canon_parm = parm_name;
1887 *canon_val = val;
1888 } else {
1889 *canon_parm = parm_table[num].label;
1890 if (inverse) {
1891 if (!lp_invert_boolean(val, canon_val)) {
1892 *canon_val = NULL;
1893 return false;
1895 } else {
1896 *canon_val = val;
1900 return true;
1903 /***************************************************************************
1904 Map a parameter's string representation to the index of the canonical
1905 form of the parameter (it might be a synonym).
1906 Returns -1 if the parameter string is not recognised.
1907 ***************************************************************************/
1909 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1911 int parm_num, canon_num;
1912 bool loc_inverse = false;
1914 parm_num = lpcfg_map_parameter(pszParmName);
1915 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
1916 /* invalid, parametric or no canidate for synonyms ... */
1917 goto done;
1920 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1921 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1922 parm_num = canon_num;
1923 goto done;
1927 done:
1928 if (inverse != NULL) {
1929 *inverse = loc_inverse;
1931 return parm_num;
1934 /***************************************************************************
1935 return true if parameter number parm1 is a synonym of parameter
1936 number parm2 (parm2 being the principal name).
1937 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1938 false otherwise.
1939 ***************************************************************************/
1941 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1943 if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1944 (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1945 (parm_table[parm1].flags & FLAG_HIDE) &&
1946 !(parm_table[parm2].flags & FLAG_HIDE))
1948 if (inverse != NULL) {
1949 if ((parm_table[parm1].type == P_BOOLREV) &&
1950 (parm_table[parm2].type == P_BOOL))
1952 *inverse = true;
1953 } else {
1954 *inverse = false;
1957 return true;
1959 return false;
1962 /***************************************************************************
1963 Show one parameter's name, type, [values,] and flags.
1964 (helper functions for show_parameter_list)
1965 ***************************************************************************/
1967 static void show_parameter(int parmIndex)
1969 int enumIndex, flagIndex;
1970 int parmIndex2;
1971 bool hadFlag;
1972 bool hadSyn;
1973 bool inverse;
1974 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1975 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1976 "P_ENUM", "P_SEP"};
1977 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
1978 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
1979 FLAG_HIDE};
1980 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
1981 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
1982 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
1984 printf("%s=%s", parm_table[parmIndex].label,
1985 type[parm_table[parmIndex].type]);
1986 if (parm_table[parmIndex].type == P_ENUM) {
1987 printf(",");
1988 for (enumIndex=0;
1989 parm_table[parmIndex].enum_list[enumIndex].name;
1990 enumIndex++)
1992 printf("%s%s",
1993 enumIndex ? "|" : "",
1994 parm_table[parmIndex].enum_list[enumIndex].name);
1997 printf(",");
1998 hadFlag = false;
1999 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
2000 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2001 printf("%s%s",
2002 hadFlag ? "|" : "",
2003 flag_names[flagIndex]);
2004 hadFlag = true;
2008 /* output synonyms */
2009 hadSyn = false;
2010 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
2011 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
2012 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
2013 parm_table[parmIndex2].label);
2014 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
2015 if (!hadSyn) {
2016 printf(" (synonyms: ");
2017 hadSyn = true;
2018 } else {
2019 printf(", ");
2021 printf("%s%s", parm_table[parmIndex2].label,
2022 inverse ? "[i]" : "");
2025 if (hadSyn) {
2026 printf(")");
2029 printf("\n");
2032 /***************************************************************************
2033 Show all parameter's name, type, [values,] and flags.
2034 ***************************************************************************/
2036 void show_parameter_list(void)
2038 int classIndex, parmIndex;
2039 const char *section_names[] = { "local", "global", NULL};
2041 for (classIndex=0; section_names[classIndex]; classIndex++) {
2042 printf("[%s]\n", section_names[classIndex]);
2043 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2044 if (parm_table[parmIndex].p_class == classIndex) {
2045 show_parameter(parmIndex);
2051 /***************************************************************************
2052 Check if a given string correctly represents a boolean value.
2053 ***************************************************************************/
2055 bool lp_string_is_valid_boolean(const char *parm_value)
2057 return set_boolean(parm_value, NULL);
2060 /***************************************************************************
2061 Get the standard string representation of a boolean value ("yes" or "no")
2062 ***************************************************************************/
2064 static const char *get_boolean(bool bool_value)
2066 static const char *yes_str = "yes";
2067 static const char *no_str = "no";
2069 return (bool_value ? yes_str : no_str);
2072 /***************************************************************************
2073 Provide the string of the negated boolean value associated to the boolean
2074 given as a string. Returns false if the passed string does not correctly
2075 represent a boolean.
2076 ***************************************************************************/
2078 bool lp_invert_boolean(const char *str, const char **inverse_str)
2080 bool val;
2082 if (!set_boolean(str, &val)) {
2083 return false;
2086 *inverse_str = get_boolean(!val);
2087 return true;
2090 /***************************************************************************
2091 Provide the canonical string representation of a boolean value given
2092 as a string. Return true on success, false if the string given does
2093 not correctly represent a boolean.
2094 ***************************************************************************/
2096 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2098 bool val;
2100 if (!set_boolean(str, &val)) {
2101 return false;
2104 *canon_str = get_boolean(val);
2105 return true;
2108 /***************************************************************************
2109 Find a service by name. Otherwise works like get_service.
2110 ***************************************************************************/
2112 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2114 int iService = -1;
2115 char *canon_name;
2116 TDB_DATA data;
2117 NTSTATUS status;
2119 if (ServiceHash == NULL) {
2120 return -1;
2123 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2125 status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2126 &data);
2128 if (NT_STATUS_IS_OK(status) &&
2129 (data.dptr != NULL) &&
2130 (data.dsize == sizeof(iService)))
2132 iService = *(int *)data.dptr;
2135 TALLOC_FREE(canon_name);
2137 if ((iService != -1) && (LP_SNUM_OK(iService))
2138 && (pserviceDest != NULL)) {
2139 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2142 return (iService);
2145 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2146 struct loadparm_service *lp_service(const char *pszServiceName)
2148 int iService = getservicebyname(pszServiceName, NULL);
2149 if (iService == -1 || !LP_SNUM_OK(iService)) {
2150 return NULL;
2152 return ServicePtrs[iService];
2155 struct loadparm_service *lp_servicebynum(int snum)
2157 if ((snum == -1) || !LP_SNUM_OK(snum)) {
2158 return NULL;
2160 return ServicePtrs[snum];
2163 struct loadparm_service *lp_default_loadparm_service()
2165 return &sDefault;
2169 /***************************************************************************
2170 Copy a service structure to another.
2171 If pcopymapDest is NULL then copy all fields
2172 ***************************************************************************/
2175 * Add a parametric option to a parmlist_entry,
2176 * replacing old value, if already present.
2178 static void set_param_opt(struct parmlist_entry **opt_list,
2179 const char *opt_name,
2180 const char *opt_value,
2181 unsigned priority)
2183 struct parmlist_entry *new_opt, *opt;
2184 bool not_added;
2186 opt = *opt_list;
2187 not_added = true;
2189 /* Traverse destination */
2190 while (opt) {
2191 /* If we already have same option, override it */
2192 if (strwicmp(opt->key, opt_name) == 0) {
2193 if ((opt->priority & FLAG_CMDLINE) &&
2194 !(priority & FLAG_CMDLINE)) {
2195 /* it's been marked as not to be
2196 overridden */
2197 return;
2199 string_free(&opt->value);
2200 TALLOC_FREE(opt->list);
2201 opt->value = SMB_STRDUP(opt_value);
2202 opt->priority = priority;
2203 not_added = false;
2204 break;
2206 opt = opt->next;
2208 if (not_added) {
2209 new_opt = SMB_XMALLOC_P(struct parmlist_entry);
2210 new_opt->key = SMB_STRDUP(opt_name);
2211 new_opt->value = SMB_STRDUP(opt_value);
2212 new_opt->list = NULL;
2213 new_opt->priority = priority;
2214 DLIST_ADD(*opt_list, new_opt);
2218 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
2219 struct bitmap *pcopymapDest)
2221 int i;
2222 bool bcopyall = (pcopymapDest == NULL);
2223 struct parmlist_entry *data;
2225 for (i = 0; parm_table[i].label; i++)
2226 if (parm_table[i].p_class == P_LOCAL &&
2227 (bcopyall || bitmap_query(pcopymapDest,i))) {
2228 void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
2229 void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
2231 switch (parm_table[i].type) {
2232 case P_BOOL:
2233 case P_BOOLREV:
2234 *(bool *)dest_ptr = *(bool *)src_ptr;
2235 break;
2237 case P_INTEGER:
2238 case P_ENUM:
2239 case P_OCTAL:
2240 case P_BYTES:
2241 *(int *)dest_ptr = *(int *)src_ptr;
2242 break;
2244 case P_CHAR:
2245 *(char *)dest_ptr = *(char *)src_ptr;
2246 break;
2248 case P_STRING:
2249 string_set((char **)dest_ptr,
2250 *(char **)src_ptr);
2251 break;
2253 case P_USTRING:
2255 char *upper_string = strupper_talloc(talloc_tos(),
2256 *(char **)src_ptr);
2257 string_set((char **)dest_ptr,
2258 upper_string);
2259 TALLOC_FREE(upper_string);
2260 break;
2262 case P_LIST:
2263 TALLOC_FREE(*((char ***)dest_ptr));
2264 *((char ***)dest_ptr) = str_list_copy(NULL,
2265 *(const char ***)src_ptr);
2266 break;
2267 default:
2268 break;
2272 if (bcopyall) {
2273 init_copymap(pserviceDest);
2274 if (pserviceSource->copymap)
2275 bitmap_copy(pserviceDest->copymap,
2276 pserviceSource->copymap);
2279 data = pserviceSource->param_opt;
2280 while (data) {
2281 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
2282 data = data->next;
2286 /***************************************************************************
2287 Check a service for consistency. Return false if the service is in any way
2288 incomplete or faulty, else true.
2289 ***************************************************************************/
2291 bool service_ok(int iService)
2293 bool bRetval;
2295 bRetval = true;
2296 if (ServicePtrs[iService]->szService[0] == '\0') {
2297 DEBUG(0, ("The following message indicates an internal error:\n"));
2298 DEBUG(0, ("No service name in service entry.\n"));
2299 bRetval = false;
2302 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2303 /* I can't see why you'd want a non-printable printer service... */
2304 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2305 if (!ServicePtrs[iService]->printable) {
2306 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2307 ServicePtrs[iService]->szService));
2308 ServicePtrs[iService]->printable = true;
2310 /* [printers] service must also be non-browsable. */
2311 if (ServicePtrs[iService]->browseable)
2312 ServicePtrs[iService]->browseable = false;
2315 if (ServicePtrs[iService]->path[0] == '\0' &&
2316 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
2317 ServicePtrs[iService]->msdfs_proxy[0] == '\0'
2319 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2320 ServicePtrs[iService]->szService));
2321 ServicePtrs[iService]->bAvailable = false;
2324 /* If a service is flagged unavailable, log the fact at level 1. */
2325 if (!ServicePtrs[iService]->bAvailable)
2326 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2327 ServicePtrs[iService]->szService));
2329 return (bRetval);
2332 static struct smbconf_ctx *lp_smbconf_ctx(void)
2334 sbcErr err;
2335 static struct smbconf_ctx *conf_ctx = NULL;
2337 if (conf_ctx == NULL) {
2338 err = smbconf_init(NULL, &conf_ctx, "registry:");
2339 if (!SBC_ERROR_IS_OK(err)) {
2340 DEBUG(1, ("error initializing registry configuration: "
2341 "%s\n", sbcErrorString(err)));
2342 conf_ctx = NULL;
2346 return conf_ctx;
2349 static bool process_smbconf_service(struct smbconf_service *service)
2351 uint32_t count;
2352 bool ret;
2354 if (service == NULL) {
2355 return false;
2358 ret = do_section(service->name, NULL);
2359 if (ret != true) {
2360 return false;
2362 for (count = 0; count < service->num_params; count++) {
2363 ret = do_parameter(service->param_names[count],
2364 service->param_values[count],
2365 NULL);
2366 if (ret != true) {
2367 return false;
2370 if (iServiceIndex >= 0) {
2371 return service_ok(iServiceIndex);
2373 return true;
2377 * load a service from registry and activate it
2379 bool process_registry_service(const char *service_name)
2381 sbcErr err;
2382 struct smbconf_service *service = NULL;
2383 TALLOC_CTX *mem_ctx = talloc_stackframe();
2384 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2385 bool ret = false;
2387 if (conf_ctx == NULL) {
2388 goto done;
2391 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2393 if (!smbconf_share_exists(conf_ctx, service_name)) {
2395 * Registry does not contain data for this service (yet),
2396 * but make sure lp_load doesn't return false.
2398 ret = true;
2399 goto done;
2402 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2403 if (!SBC_ERROR_IS_OK(err)) {
2404 goto done;
2407 ret = process_smbconf_service(service);
2408 if (!ret) {
2409 goto done;
2412 /* store the csn */
2413 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2415 done:
2416 TALLOC_FREE(mem_ctx);
2417 return ret;
2421 * process_registry_globals
2423 static bool process_registry_globals(void)
2425 bool ret;
2427 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2429 ret = do_parameter("registry shares", "yes", NULL);
2430 if (!ret) {
2431 return ret;
2434 return process_registry_service(GLOBAL_NAME);
2437 bool process_registry_shares(void)
2439 sbcErr err;
2440 uint32_t count;
2441 struct smbconf_service **service = NULL;
2442 uint32_t num_shares = 0;
2443 TALLOC_CTX *mem_ctx = talloc_stackframe();
2444 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2445 bool ret = false;
2447 if (conf_ctx == NULL) {
2448 goto done;
2451 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2452 if (!SBC_ERROR_IS_OK(err)) {
2453 goto done;
2456 ret = true;
2458 for (count = 0; count < num_shares; count++) {
2459 if (strequal(service[count]->name, GLOBAL_NAME)) {
2460 continue;
2462 ret = process_smbconf_service(service[count]);
2463 if (!ret) {
2464 goto done;
2468 /* store the csn */
2469 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2471 done:
2472 TALLOC_FREE(mem_ctx);
2473 return ret;
2477 * reload those shares from registry that are already
2478 * activated in the services array.
2480 static bool reload_registry_shares(void)
2482 int i;
2483 bool ret = true;
2485 for (i = 0; i < iNumServices; i++) {
2486 if (!VALID(i)) {
2487 continue;
2490 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2491 continue;
2494 ret = process_registry_service(ServicePtrs[i]->szService);
2495 if (!ret) {
2496 goto done;
2500 done:
2501 return ret;
2505 #define MAX_INCLUDE_DEPTH 100
2507 static uint8_t include_depth;
2509 static struct file_lists {
2510 struct file_lists *next;
2511 char *name;
2512 char *subfname;
2513 time_t modtime;
2514 } *file_lists = NULL;
2516 /*******************************************************************
2517 Keep a linked list of all config files so we know when one has changed
2518 it's date and needs to be reloaded.
2519 ********************************************************************/
2521 static void add_to_file_list(const char *fname, const char *subfname)
2523 struct file_lists *f = file_lists;
2525 while (f) {
2526 if (f->name && !strcmp(f->name, fname))
2527 break;
2528 f = f->next;
2531 if (!f) {
2532 f = SMB_MALLOC_P(struct file_lists);
2533 if (!f)
2534 return;
2535 f->next = file_lists;
2536 f->name = SMB_STRDUP(fname);
2537 if (!f->name) {
2538 SAFE_FREE(f);
2539 return;
2541 f->subfname = SMB_STRDUP(subfname);
2542 if (!f->subfname) {
2543 SAFE_FREE(f->name);
2544 SAFE_FREE(f);
2545 return;
2547 file_lists = f;
2548 f->modtime = file_modtime(subfname);
2549 } else {
2550 time_t t = file_modtime(subfname);
2551 if (t)
2552 f->modtime = t;
2554 return;
2558 * Free the file lists
2560 static void free_file_list(void)
2562 struct file_lists *f;
2563 struct file_lists *next;
2565 f = file_lists;
2566 while( f ) {
2567 next = f->next;
2568 SAFE_FREE( f->name );
2569 SAFE_FREE( f->subfname );
2570 SAFE_FREE( f );
2571 f = next;
2573 file_lists = NULL;
2578 * Utility function for outsiders to check if we're running on registry.
2580 bool lp_config_backend_is_registry(void)
2582 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2586 * Utility function to check if the config backend is FILE.
2588 bool lp_config_backend_is_file(void)
2590 return (lp_config_backend() == CONFIG_BACKEND_FILE);
2593 /*******************************************************************
2594 Check if a config file has changed date.
2595 ********************************************************************/
2597 bool lp_file_list_changed(void)
2599 struct file_lists *f = file_lists;
2601 DEBUG(6, ("lp_file_list_changed()\n"));
2603 while (f) {
2604 time_t mod_time;
2606 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2607 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2609 if (conf_ctx == NULL) {
2610 return false;
2612 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2613 NULL))
2615 DEBUGADD(6, ("registry config changed\n"));
2616 return true;
2618 } else {
2619 char *n2 = NULL;
2620 n2 = talloc_sub_basic(talloc_tos(),
2621 get_current_username(),
2622 current_user_info.domain,
2623 f->name);
2624 if (!n2) {
2625 return false;
2627 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2628 f->name, n2, ctime(&f->modtime)));
2630 mod_time = file_modtime(n2);
2632 if (mod_time &&
2633 ((f->modtime != mod_time) ||
2634 (f->subfname == NULL) ||
2635 (strcmp(n2, f->subfname) != 0)))
2637 DEBUGADD(6,
2638 ("file %s modified: %s\n", n2,
2639 ctime(&mod_time)));
2640 f->modtime = mod_time;
2641 SAFE_FREE(f->subfname);
2642 f->subfname = SMB_STRDUP(n2);
2643 TALLOC_FREE(n2);
2644 return true;
2646 TALLOC_FREE(n2);
2648 f = f->next;
2650 return false;
2655 * Initialize iconv conversion descriptors.
2657 * This is called the first time it is needed, and also called again
2658 * every time the configuration is reloaded, because the charset or
2659 * codepage might have changed.
2661 static void init_iconv(void)
2663 global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2664 lp_unix_charset(),
2665 true, global_iconv_handle);
2668 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2670 if (strcmp(*ptr, pszParmValue) != 0) {
2671 string_set(ptr, pszParmValue);
2672 init_iconv();
2674 return true;
2677 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2679 bool is_utf8 = false;
2680 size_t len = strlen(pszParmValue);
2682 if (len == 4 || len == 5) {
2683 /* Don't use StrCaseCmp here as we don't want to
2684 initialize iconv. */
2685 if ((toupper_m(pszParmValue[0]) == 'U') &&
2686 (toupper_m(pszParmValue[1]) == 'T') &&
2687 (toupper_m(pszParmValue[2]) == 'F')) {
2688 if (len == 4) {
2689 if (pszParmValue[3] == '8') {
2690 is_utf8 = true;
2692 } else {
2693 if (pszParmValue[3] == '-' &&
2694 pszParmValue[4] == '8') {
2695 is_utf8 = true;
2701 if (strcmp(*ptr, pszParmValue) != 0) {
2702 if (is_utf8) {
2703 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
2704 "be UTF8, using (default value) %s instead.\n",
2705 DEFAULT_DOS_CHARSET));
2706 pszParmValue = DEFAULT_DOS_CHARSET;
2708 string_set(ptr, pszParmValue);
2709 init_iconv();
2711 return true;
2714 static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2716 bool ret = true;
2717 TALLOC_CTX *frame = talloc_stackframe();
2718 char *realm = strupper_talloc(frame, pszParmValue);
2719 char *dnsdomain = strlower_talloc(realm, pszParmValue);
2721 ret &= string_set(&Globals.realm_original, pszParmValue);
2722 ret &= string_set(&Globals.realm, realm);
2723 ret &= string_set(&Globals.dnsdomain, dnsdomain);
2724 TALLOC_FREE(frame);
2726 return ret;
2729 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2731 TALLOC_FREE(Globals.netbios_aliases);
2732 Globals.netbios_aliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
2733 return set_netbios_aliases(Globals.netbios_aliases);
2736 /***************************************************************************
2737 Handle the include operation.
2738 ***************************************************************************/
2739 static bool bAllowIncludeRegistry = true;
2741 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2743 char *fname;
2745 if (include_depth >= MAX_INCLUDE_DEPTH) {
2746 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2747 include_depth));
2748 return false;
2751 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2752 if (!bAllowIncludeRegistry) {
2753 return true;
2755 if (bInGlobalSection) {
2756 bool ret;
2757 include_depth++;
2758 ret = process_registry_globals();
2759 include_depth--;
2760 return ret;
2761 } else {
2762 DEBUG(1, ("\"include = registry\" only effective "
2763 "in %s section\n", GLOBAL_NAME));
2764 return false;
2768 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2769 current_user_info.domain,
2770 pszParmValue);
2772 add_to_file_list(pszParmValue, fname);
2774 string_set(ptr, fname);
2776 if (file_exist(fname)) {
2777 bool ret;
2778 include_depth++;
2779 ret = pm_process(fname, do_section, do_parameter, NULL);
2780 include_depth--;
2781 TALLOC_FREE(fname);
2782 return ret;
2785 DEBUG(2, ("Can't find include file %s\n", fname));
2786 TALLOC_FREE(fname);
2787 return true;
2790 /***************************************************************************
2791 Handle the interpretation of the copy parameter.
2792 ***************************************************************************/
2794 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2796 bool bRetval;
2797 int iTemp;
2798 struct loadparm_service serviceTemp;
2800 string_set(ptr, pszParmValue);
2802 init_service(&serviceTemp);
2804 bRetval = false;
2806 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2808 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2809 if (iTemp == iServiceIndex) {
2810 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2811 } else {
2812 copy_service(ServicePtrs[iServiceIndex],
2813 &serviceTemp,
2814 ServicePtrs[iServiceIndex]->copymap);
2815 bRetval = true;
2817 } else {
2818 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2819 bRetval = false;
2822 free_service(&serviceTemp);
2823 return (bRetval);
2826 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2828 Globals.ldap_debug_level = lp_int(pszParmValue);
2829 init_ldap_debugging();
2830 return true;
2834 * idmap related parameters
2837 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2839 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
2841 return true;
2844 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2846 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2848 return true;
2851 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2853 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2855 return true;
2858 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2860 char *config_option = NULL;
2861 const char *range = NULL;
2862 bool ret = false;
2864 SMB_ASSERT(low != NULL);
2865 SMB_ASSERT(high != NULL);
2867 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2868 domain_name = "*";
2871 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2872 domain_name);
2873 if (config_option == NULL) {
2874 DEBUG(0, ("out of memory\n"));
2875 return false;
2878 range = lp_parm_const_string(-1, config_option, "range", NULL);
2879 if (range == NULL) {
2880 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2881 goto done;
2884 if (sscanf(range, "%u - %u", low, high) != 2) {
2885 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2886 range, domain_name));
2887 goto done;
2890 ret = true;
2892 done:
2893 talloc_free(config_option);
2894 return ret;
2898 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2900 return lp_idmap_range("*", low, high);
2903 const char *lp_idmap_backend(const char *domain_name)
2905 char *config_option = NULL;
2906 const char *backend = NULL;
2908 if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2909 domain_name = "*";
2912 config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2913 domain_name);
2914 if (config_option == NULL) {
2915 DEBUG(0, ("out of memory\n"));
2916 return false;
2919 backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2920 if (backend == NULL) {
2921 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2922 goto done;
2925 done:
2926 talloc_free(config_option);
2927 return backend;
2930 const char *lp_idmap_default_backend(void)
2932 return lp_idmap_backend("*");
2935 /***************************************************************************
2936 Handle the DEBUG level list.
2937 ***************************************************************************/
2939 static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
2941 string_set(ptr, pszParmValueIn);
2942 return debug_parse_levels(pszParmValueIn);
2945 /***************************************************************************
2946 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2947 ***************************************************************************/
2949 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2951 const char *suffix_string;
2953 suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2954 Globals.ldap_suffix );
2955 if ( !suffix_string ) {
2956 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2957 return "";
2960 return suffix_string;
2963 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2965 if (Globals.szLdapMachineSuffix[0])
2966 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
2968 return lp_string(ctx, Globals.ldap_suffix);
2971 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2973 if (Globals.szLdapUserSuffix[0])
2974 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
2976 return lp_string(ctx, Globals.ldap_suffix);
2979 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2981 if (Globals.szLdapGroupSuffix[0])
2982 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
2984 return lp_string(ctx, Globals.ldap_suffix);
2987 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2989 if (Globals.szLdapIdmapSuffix[0])
2990 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
2992 return lp_string(ctx, Globals.ldap_suffix);
2995 /****************************************************************************
2996 set the value for a P_ENUM
2997 ***************************************************************************/
2999 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3000 int *ptr )
3002 int i;
3004 for (i = 0; parm->enum_list[i].name; i++) {
3005 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3006 *ptr = parm->enum_list[i].value;
3007 return;
3010 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
3011 pszParmValue, parm->label));
3014 /***************************************************************************
3015 ***************************************************************************/
3017 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
3019 static int parm_num = -1;
3020 struct loadparm_service *s;
3022 if ( parm_num == -1 )
3023 parm_num = lpcfg_map_parameter( "printing" );
3025 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3027 if ( snum < 0 )
3028 s = &sDefault;
3029 else
3030 s = ServicePtrs[snum];
3032 init_printer_values( s );
3034 return true;
3038 /***************************************************************************
3039 Initialise a copymap.
3040 ***************************************************************************/
3042 static void init_copymap(struct loadparm_service *pservice)
3044 int i;
3046 TALLOC_FREE(pservice->copymap);
3048 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
3049 if (!pservice->copymap)
3050 DEBUG(0,
3051 ("Couldn't allocate copymap!! (size %d)\n",
3052 (int)NUMPARAMETERS));
3053 else
3054 for (i = 0; i < NUMPARAMETERS; i++)
3055 bitmap_set(pservice->copymap, i);
3059 return the parameter pointer for a parameter
3061 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
3063 if (service == NULL) {
3064 if (parm->p_class == P_LOCAL)
3065 return (void *)(((char *)&sDefault)+parm->offset);
3066 else if (parm->p_class == P_GLOBAL)
3067 return (void *)(((char *)&Globals)+parm->offset);
3068 else return NULL;
3069 } else {
3070 return (void *)(((char *)service) + parm->offset);
3074 /***************************************************************************
3075 Return the local pointer to a parameter given the service number and parameter
3076 ***************************************************************************/
3078 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
3080 return lp_parm_ptr(ServicePtrs[snum], parm);
3083 /***************************************************************************
3084 Process a parameter for a particular service number. If snum < 0
3085 then assume we are in the globals.
3086 ***************************************************************************/
3088 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3090 int parmnum, i;
3091 void *parm_ptr = NULL; /* where we are going to store the result */
3092 struct parmlist_entry **opt_list;
3094 parmnum = lpcfg_map_parameter(pszParmName);
3096 if (parmnum < 0) {
3097 if (strchr(pszParmName, ':') == NULL) {
3098 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
3099 pszParmName));
3100 return true;
3104 * We've got a parametric option
3107 opt_list = (snum < 0)
3108 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
3109 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
3111 return true;
3114 /* if it's already been set by the command line, then we don't
3115 override here */
3116 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
3117 return true;
3120 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3121 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3122 pszParmName));
3125 /* we might point at a service, the default service or a global */
3126 if (snum < 0) {
3127 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
3128 } else {
3129 if (parm_table[parmnum].p_class == P_GLOBAL) {
3130 DEBUG(0,
3131 ("Global parameter %s found in service section!\n",
3132 pszParmName));
3133 return true;
3135 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
3138 if (snum >= 0) {
3139 if (!ServicePtrs[snum]->copymap)
3140 init_copymap(ServicePtrs[snum]);
3142 /* this handles the aliases - set the copymap for other entries with
3143 the same data pointer */
3144 for (i = 0; parm_table[i].label; i++) {
3145 if ((parm_table[i].offset == parm_table[parmnum].offset)
3146 && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
3147 bitmap_clear(ServicePtrs[snum]->copymap, i);
3152 /* if it is a special case then go ahead */
3153 if (parm_table[parmnum].special) {
3154 return parm_table[parmnum].special(NULL, snum, pszParmValue,
3155 (char **)parm_ptr);
3158 /* now switch on the type of variable it is */
3159 switch (parm_table[parmnum].type)
3161 case P_BOOL:
3162 *(bool *)parm_ptr = lp_bool(pszParmValue);
3163 break;
3165 case P_BOOLREV:
3166 *(bool *)parm_ptr = !lp_bool(pszParmValue);
3167 break;
3169 case P_INTEGER:
3170 *(int *)parm_ptr = lp_int(pszParmValue);
3171 break;
3173 case P_CHAR:
3174 *(char *)parm_ptr = *pszParmValue;
3175 break;
3177 case P_OCTAL:
3178 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3179 if ( i != 1 ) {
3180 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3182 break;
3184 case P_BYTES:
3186 uint64_t val;
3187 if (conv_str_size_error(pszParmValue, &val)) {
3188 if (val <= INT_MAX) {
3189 *(int *)parm_ptr = (int)val;
3190 break;
3194 DEBUG(0,("lp_do_parameter(%s): value is not "
3195 "a valid size specifier!\n", pszParmValue));
3196 return false;
3199 case P_LIST:
3200 case P_CMDLIST:
3201 TALLOC_FREE(*((char ***)parm_ptr));
3202 *(char ***)parm_ptr = str_list_make_v3(
3203 NULL, pszParmValue, NULL);
3204 break;
3206 case P_STRING:
3207 string_set((char **)parm_ptr, pszParmValue);
3208 break;
3210 case P_USTRING:
3212 char *upper_string = strupper_talloc(talloc_tos(),
3213 pszParmValue);
3214 string_set((char **)parm_ptr, upper_string);
3215 TALLOC_FREE(upper_string);
3216 break;
3218 case P_ENUM:
3219 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3220 break;
3221 case P_SEP:
3222 break;
3225 return true;
3228 /***************************************************************************
3229 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
3230 FLAG_CMDLINE won't be overridden by loads from smb.conf.
3231 ***************************************************************************/
3233 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
3235 int parmnum, i;
3236 parmnum = lpcfg_map_parameter(pszParmName);
3237 if (parmnum >= 0) {
3238 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
3239 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
3240 return false;
3242 parm_table[parmnum].flags |= FLAG_CMDLINE;
3244 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
3245 * be grouped in the table, so we don't have to search the
3246 * whole table */
3247 for (i=parmnum-1;
3248 i>=0 && parm_table[i].offset == parm_table[parmnum].offset
3249 && parm_table[i].p_class == parm_table[parmnum].p_class;
3250 i--) {
3251 parm_table[i].flags |= FLAG_CMDLINE;
3253 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
3254 && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
3255 parm_table[i].flags |= FLAG_CMDLINE;
3258 if (store_values) {
3259 store_lp_set_cmdline(pszParmName, pszParmValue);
3261 return true;
3264 /* it might be parametric */
3265 if (strchr(pszParmName, ':') != NULL) {
3266 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
3267 if (store_values) {
3268 store_lp_set_cmdline(pszParmName, pszParmValue);
3270 return true;
3273 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3274 return true;
3277 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
3279 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
3282 /***************************************************************************
3283 Process a parameter.
3284 ***************************************************************************/
3286 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
3287 void *userdata)
3289 if (!bInGlobalSection && bGlobalOnly)
3290 return true;
3292 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3294 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3295 pszParmName, pszParmValue));
3299 set a option from the commandline in 'a=b' format. Use to support --option
3301 bool lp_set_option(const char *option)
3303 char *p, *s;
3304 bool ret;
3306 s = talloc_strdup(NULL, option);
3307 if (!s) {
3308 return false;
3311 p = strchr(s, '=');
3312 if (!p) {
3313 talloc_free(s);
3314 return false;
3317 *p = 0;
3319 /* skip white spaces after the = sign */
3320 do {
3321 p++;
3322 } while (*p == ' ');
3324 ret = lp_set_cmdline(s, p);
3325 talloc_free(s);
3326 return ret;
3329 /***************************************************************************
3330 Initialize any local variables in the sDefault table, after parsing a
3331 [globals] section.
3332 ***************************************************************************/
3334 static void init_locals(void)
3337 * We run this check once the [globals] is parsed, to force
3338 * the VFS objects and other per-share settings we need for
3339 * the standard way a AD DC is operated. We may change these
3340 * as our code evolves, which is why we force these settings.
3342 * We can't do this at the end of lp_load_ex(), as by that
3343 * point the services have been loaded and they will already
3344 * have "" as their vfs objects.
3346 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3347 const char **vfs_objects = lp_vfs_objects(-1);
3348 if (!vfs_objects || !vfs_objects[0]) {
3349 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
3350 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
3351 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
3352 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
3353 } else {
3354 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
3358 lp_do_parameter(-1, "map hidden", "no");
3359 lp_do_parameter(-1, "map system", "no");
3360 lp_do_parameter(-1, "map readonly", "no");
3361 lp_do_parameter(-1, "map archive", "no");
3362 lp_do_parameter(-1, "store dos attributes", "yes");
3366 /***************************************************************************
3367 Process a new section (service). At this stage all sections are services.
3368 Later we'll have special sections that permit server parameters to be set.
3369 Returns true on success, false on failure.
3370 ***************************************************************************/
3372 static bool do_section(const char *pszSectionName, void *userdata)
3374 bool bRetval;
3375 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3376 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3377 bRetval = false;
3379 /* if we were in a global section then do the local inits */
3380 if (bInGlobalSection && !isglobal)
3381 init_locals();
3383 /* if we've just struck a global section, note the fact. */
3384 bInGlobalSection = isglobal;
3386 /* check for multiple global sections */
3387 if (bInGlobalSection) {
3388 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3389 return true;
3392 if (!bInGlobalSection && bGlobalOnly)
3393 return true;
3395 /* if we have a current service, tidy it up before moving on */
3396 bRetval = true;
3398 if (iServiceIndex >= 0)
3399 bRetval = service_ok(iServiceIndex);
3401 /* if all is still well, move to the next record in the services array */
3402 if (bRetval) {
3403 /* We put this here to avoid an odd message order if messages are */
3404 /* issued by the post-processing of a previous section. */
3405 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3407 iServiceIndex = add_a_service(&sDefault, pszSectionName);
3408 if (iServiceIndex < 0) {
3409 DEBUG(0, ("Failed to add a new service\n"));
3410 return false;
3412 /* Clean all parametric options for service */
3413 /* They will be added during parsing again */
3414 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
3417 return bRetval;
3421 /***************************************************************************
3422 Determine if a partcular base parameter is currentl set to the default value.
3423 ***************************************************************************/
3425 static bool is_default(int i)
3427 switch (parm_table[i].type) {
3428 case P_LIST:
3429 case P_CMDLIST:
3430 return str_list_equal((const char **)parm_table[i].def.lvalue,
3431 *(const char ***)lp_parm_ptr(NULL,
3432 &parm_table[i]));
3433 case P_STRING:
3434 case P_USTRING:
3435 return strequal(parm_table[i].def.svalue,
3436 *(char **)lp_parm_ptr(NULL,
3437 &parm_table[i]));
3438 case P_BOOL:
3439 case P_BOOLREV:
3440 return parm_table[i].def.bvalue ==
3441 *(bool *)lp_parm_ptr(NULL,
3442 &parm_table[i]);
3443 case P_CHAR:
3444 return parm_table[i].def.cvalue ==
3445 *(char *)lp_parm_ptr(NULL,
3446 &parm_table[i]);
3447 case P_INTEGER:
3448 case P_OCTAL:
3449 case P_ENUM:
3450 case P_BYTES:
3451 return parm_table[i].def.ivalue ==
3452 *(int *)lp_parm_ptr(NULL,
3453 &parm_table[i]);
3454 case P_SEP:
3455 break;
3457 return false;
3460 /***************************************************************************
3461 Display the contents of the global structure.
3462 ***************************************************************************/
3464 static void dump_globals(FILE *f)
3466 int i;
3467 struct parmlist_entry *data;
3469 fprintf(f, "[global]\n");
3471 for (i = 0; parm_table[i].label; i++)
3472 if (parm_table[i].p_class == P_GLOBAL &&
3473 !(parm_table[i].flags & FLAG_META) &&
3474 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
3475 if (defaults_saved && is_default(i))
3476 continue;
3477 fprintf(f, "\t%s = ", parm_table[i].label);
3478 lpcfg_print_parameter(&parm_table[i], lp_parm_ptr(NULL,
3479 &parm_table[i]),
3481 fprintf(f, "\n");
3483 if (Globals.param_opt != NULL) {
3484 data = Globals.param_opt;
3485 while(data) {
3486 fprintf(f, "\t%s = %s\n", data->key, data->value);
3487 data = data->next;
3493 /***************************************************************************
3494 Display the contents of a single services record.
3495 ***************************************************************************/
3497 static void dump_a_service(struct loadparm_service *pService, FILE * f)
3499 int i;
3500 struct parmlist_entry *data;
3502 if (pService != &sDefault)
3503 fprintf(f, "[%s]\n", pService->szService);
3505 for (i = 0; parm_table[i].label; i++) {
3507 if (parm_table[i].p_class == P_LOCAL &&
3508 !(parm_table[i].flags & FLAG_META) &&
3509 (*parm_table[i].label != '-') &&
3510 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
3512 if (pService == &sDefault) {
3513 if (defaults_saved && is_default(i))
3514 continue;
3515 } else {
3516 if (lpcfg_equal_parameter(parm_table[i].type,
3517 lp_parm_ptr(pService, &parm_table[i]),
3518 lp_parm_ptr(NULL, &parm_table[i])))
3519 continue;
3522 fprintf(f, "\t%s = ", parm_table[i].label);
3523 lpcfg_print_parameter(&parm_table[i],
3524 lp_parm_ptr(pService, &parm_table[i]),
3526 fprintf(f, "\n");
3530 if (pService->param_opt != NULL) {
3531 data = pService->param_opt;
3532 while(data) {
3533 fprintf(f, "\t%s = %s\n", data->key, data->value);
3534 data = data->next;
3539 /***************************************************************************
3540 Display the contents of a parameter of a single services record.
3541 ***************************************************************************/
3543 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
3545 bool result = false;
3546 fstring local_parm_name;
3547 char *parm_opt;
3548 const char *parm_opt_value;
3550 struct loadparm_context *lp_ctx;
3552 /* check for parametrical option */
3553 fstrcpy( local_parm_name, parm_name);
3554 parm_opt = strchr( local_parm_name, ':');
3556 if (parm_opt) {
3557 *parm_opt = '\0';
3558 parm_opt++;
3559 if (strlen(parm_opt)) {
3560 parm_opt_value = lp_parm_const_string( snum,
3561 local_parm_name, parm_opt, NULL);
3562 if (parm_opt_value) {
3563 printf( "%s\n", parm_opt_value);
3564 result = true;
3567 return result;
3570 lp_ctx = loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
3571 if (lp_ctx == NULL) {
3572 return false;
3575 if (isGlobal) {
3576 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
3577 } else {
3578 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
3580 TALLOC_FREE(lp_ctx);
3581 return result;
3584 /***************************************************************************
3585 Return info about the requested parameter (given as a string).
3586 Return NULL when the string is not a valid parameter name.
3587 ***************************************************************************/
3589 struct parm_struct *lp_get_parameter(const char *param_name)
3591 int num = lpcfg_map_parameter(param_name);
3593 if (num < 0) {
3594 return NULL;
3597 return &parm_table[num];
3600 #if 0
3601 /***************************************************************************
3602 Display the contents of a single copy structure.
3603 ***************************************************************************/
3604 static void dump_copy_map(bool *pcopymap)
3606 int i;
3607 if (!pcopymap)
3608 return;
3610 printf("\n\tNon-Copied parameters:\n");
3612 for (i = 0; parm_table[i].label; i++)
3613 if (parm_table[i].p_class == P_LOCAL &&
3614 parm_table[i].ptr && !pcopymap[i] &&
3615 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3617 printf("\t\t%s\n", parm_table[i].label);
3620 #endif
3622 /***************************************************************************
3623 Return TRUE if the passed service number is within range.
3624 ***************************************************************************/
3626 bool lp_snum_ok(int iService)
3628 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3631 /***************************************************************************
3632 Auto-load some home services.
3633 ***************************************************************************/
3635 static void lp_add_auto_services(char *str)
3637 char *s;
3638 char *p;
3639 int homes;
3640 char *saveptr;
3642 if (!str)
3643 return;
3645 s = SMB_STRDUP(str);
3646 if (!s)
3647 return;
3649 homes = lp_servicenumber(HOMES_NAME);
3651 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
3652 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
3653 char *home;
3655 if (lp_servicenumber(p) >= 0)
3656 continue;
3658 home = get_user_home_dir(talloc_tos(), p);
3660 if (home && home[0] && homes >= 0)
3661 lp_add_home(p, homes, p, home);
3663 TALLOC_FREE(home);
3665 SAFE_FREE(s);
3668 /***************************************************************************
3669 Auto-load one printer.
3670 ***************************************************************************/
3672 void lp_add_one_printer(const char *name, const char *comment,
3673 const char *location, void *pdata)
3675 int printers = lp_servicenumber(PRINTERS_NAME);
3676 int i;
3678 if (lp_servicenumber(name) < 0) {
3679 lp_add_printer(name, printers);
3680 if ((i = lp_servicenumber(name)) >= 0) {
3681 string_set(&ServicePtrs[i]->comment, comment);
3682 ServicePtrs[i]->autoloaded = true;
3687 /***************************************************************************
3688 Have we loaded a services file yet?
3689 ***************************************************************************/
3691 bool lp_loaded(void)
3693 return (bLoaded);
3696 /***************************************************************************
3697 Unload unused services.
3698 ***************************************************************************/
3700 void lp_killunused(struct smbd_server_connection *sconn,
3701 bool (*snumused) (struct smbd_server_connection *, int))
3703 int i;
3704 for (i = 0; i < iNumServices; i++) {
3705 if (!VALID(i))
3706 continue;
3708 /* don't kill autoloaded or usershare services */
3709 if ( ServicePtrs[i]->autoloaded ||
3710 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3711 continue;
3714 if (!snumused || !snumused(sconn, i)) {
3715 free_service_byindex(i);
3721 * Kill all except autoloaded and usershare services - convenience wrapper
3723 void lp_kill_all_services(void)
3725 lp_killunused(NULL, NULL);
3728 /***************************************************************************
3729 Unload a service.
3730 ***************************************************************************/
3732 void lp_killservice(int iServiceIn)
3734 if (VALID(iServiceIn)) {
3735 free_service_byindex(iServiceIn);
3739 /***************************************************************************
3740 Save the curent values of all global and sDefault parameters into the
3741 defaults union. This allows testparm to show only the
3742 changed (ie. non-default) parameters.
3743 ***************************************************************************/
3745 static void lp_save_defaults(void)
3747 int i;
3748 for (i = 0; parm_table[i].label; i++) {
3749 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3750 && parm_table[i].p_class == parm_table[i - 1].p_class)
3751 continue;
3752 switch (parm_table[i].type) {
3753 case P_LIST:
3754 case P_CMDLIST:
3755 parm_table[i].def.lvalue = str_list_copy(
3756 NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3757 break;
3758 case P_STRING:
3759 case P_USTRING:
3760 parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
3761 break;
3762 case P_BOOL:
3763 case P_BOOLREV:
3764 parm_table[i].def.bvalue =
3765 *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3766 break;
3767 case P_CHAR:
3768 parm_table[i].def.cvalue =
3769 *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3770 break;
3771 case P_INTEGER:
3772 case P_OCTAL:
3773 case P_ENUM:
3774 case P_BYTES:
3775 parm_table[i].def.ivalue =
3776 *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3777 break;
3778 case P_SEP:
3779 break;
3782 defaults_saved = true;
3785 /***********************************************************
3786 If we should send plaintext/LANMAN passwords in the clinet
3787 ************************************************************/
3789 static void set_allowed_client_auth(void)
3791 if (Globals.client_ntlmv2_auth) {
3792 Globals.client_lanman_auth = false;
3794 if (!Globals.client_lanman_auth) {
3795 Globals.client_plaintext_auth = false;
3799 /***************************************************************************
3800 JRA.
3801 The following code allows smbd to read a user defined share file.
3802 Yes, this is my intent. Yes, I'm comfortable with that...
3804 THE FOLLOWING IS SECURITY CRITICAL CODE.
3806 It washes your clothes, it cleans your house, it guards you while you sleep...
3807 Do not f%^k with it....
3808 ***************************************************************************/
3810 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3812 /***************************************************************************
3813 Check allowed stat state of a usershare file.
3814 Ensure we print out who is dicking with us so the admin can
3815 get their sorry ass fired.
3816 ***************************************************************************/
3818 static bool check_usershare_stat(const char *fname,
3819 const SMB_STRUCT_STAT *psbuf)
3821 if (!S_ISREG(psbuf->st_ex_mode)) {
3822 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3823 "not a regular file\n",
3824 fname, (unsigned int)psbuf->st_ex_uid ));
3825 return false;
3828 /* Ensure this doesn't have the other write bit set. */
3829 if (psbuf->st_ex_mode & S_IWOTH) {
3830 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3831 "public write. Refusing to allow as a usershare file.\n",
3832 fname, (unsigned int)psbuf->st_ex_uid ));
3833 return false;
3836 /* Should be 10k or less. */
3837 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
3838 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3839 "too large (%u) to be a user share file.\n",
3840 fname, (unsigned int)psbuf->st_ex_uid,
3841 (unsigned int)psbuf->st_ex_size ));
3842 return false;
3845 return true;
3848 /***************************************************************************
3849 Parse the contents of a usershare file.
3850 ***************************************************************************/
3852 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
3853 SMB_STRUCT_STAT *psbuf,
3854 const char *servicename,
3855 int snum,
3856 char **lines,
3857 int numlines,
3858 char **pp_sharepath,
3859 char **pp_comment,
3860 char **pp_cp_servicename,
3861 struct security_descriptor **ppsd,
3862 bool *pallow_guest)
3864 const char **prefixallowlist = lp_usershare_prefix_allow_list();
3865 const char **prefixdenylist = lp_usershare_prefix_deny_list();
3866 int us_vers;
3867 DIR *dp;
3868 SMB_STRUCT_STAT sbuf;
3869 char *sharepath = NULL;
3870 char *comment = NULL;
3872 *pp_sharepath = NULL;
3873 *pp_comment = NULL;
3875 *pallow_guest = false;
3877 if (numlines < 4) {
3878 return USERSHARE_MALFORMED_FILE;
3881 if (strcmp(lines[0], "#VERSION 1") == 0) {
3882 us_vers = 1;
3883 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3884 us_vers = 2;
3885 if (numlines < 5) {
3886 return USERSHARE_MALFORMED_FILE;
3888 } else {
3889 return USERSHARE_BAD_VERSION;
3892 if (strncmp(lines[1], "path=", 5) != 0) {
3893 return USERSHARE_MALFORMED_PATH;
3896 sharepath = talloc_strdup(ctx, &lines[1][5]);
3897 if (!sharepath) {
3898 return USERSHARE_POSIX_ERR;
3900 trim_string(sharepath, " ", " ");
3902 if (strncmp(lines[2], "comment=", 8) != 0) {
3903 return USERSHARE_MALFORMED_COMMENT_DEF;
3906 comment = talloc_strdup(ctx, &lines[2][8]);
3907 if (!comment) {
3908 return USERSHARE_POSIX_ERR;
3910 trim_string(comment, " ", " ");
3911 trim_char(comment, '"', '"');
3913 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3914 return USERSHARE_MALFORMED_ACL_DEF;
3917 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3918 return USERSHARE_ACL_ERR;
3921 if (us_vers == 2) {
3922 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3923 return USERSHARE_MALFORMED_ACL_DEF;
3925 if (lines[4][9] == 'y') {
3926 *pallow_guest = true;
3929 /* Backwards compatible extension to file version #2. */
3930 if (numlines > 5) {
3931 if (strncmp(lines[5], "sharename=", 10) != 0) {
3932 return USERSHARE_MALFORMED_SHARENAME_DEF;
3934 if (!strequal(&lines[5][10], servicename)) {
3935 return USERSHARE_BAD_SHARENAME;
3937 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3938 if (!*pp_cp_servicename) {
3939 return USERSHARE_POSIX_ERR;
3944 if (*pp_cp_servicename == NULL) {
3945 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3946 if (!*pp_cp_servicename) {
3947 return USERSHARE_POSIX_ERR;
3951 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3952 /* Path didn't change, no checks needed. */
3953 *pp_sharepath = sharepath;
3954 *pp_comment = comment;
3955 return USERSHARE_OK;
3958 /* The path *must* be absolute. */
3959 if (sharepath[0] != '/') {
3960 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3961 servicename, sharepath));
3962 return USERSHARE_PATH_NOT_ABSOLUTE;
3965 /* If there is a usershare prefix deny list ensure one of these paths
3966 doesn't match the start of the user given path. */
3967 if (prefixdenylist) {
3968 int i;
3969 for ( i=0; prefixdenylist[i]; i++ ) {
3970 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3971 servicename, i, prefixdenylist[i], sharepath ));
3972 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3973 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3974 "usershare prefix deny list entries.\n",
3975 servicename, sharepath));
3976 return USERSHARE_PATH_IS_DENIED;
3981 /* If there is a usershare prefix allow list ensure one of these paths
3982 does match the start of the user given path. */
3984 if (prefixallowlist) {
3985 int i;
3986 for ( i=0; prefixallowlist[i]; i++ ) {
3987 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3988 servicename, i, prefixallowlist[i], sharepath ));
3989 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3990 break;
3993 if (prefixallowlist[i] == NULL) {
3994 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3995 "usershare prefix allow list entries.\n",
3996 servicename, sharepath));
3997 return USERSHARE_PATH_NOT_ALLOWED;
4001 /* Ensure this is pointing to a directory. */
4002 dp = opendir(sharepath);
4004 if (!dp) {
4005 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4006 servicename, sharepath));
4007 return USERSHARE_PATH_NOT_DIRECTORY;
4010 /* Ensure the owner of the usershare file has permission to share
4011 this directory. */
4013 if (sys_stat(sharepath, &sbuf, false) == -1) {
4014 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4015 servicename, sharepath, strerror(errno) ));
4016 closedir(dp);
4017 return USERSHARE_POSIX_ERR;
4020 closedir(dp);
4022 if (!S_ISDIR(sbuf.st_ex_mode)) {
4023 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4024 servicename, sharepath ));
4025 return USERSHARE_PATH_NOT_DIRECTORY;
4028 /* Check if sharing is restricted to owner-only. */
4029 /* psbuf is the stat of the usershare definition file,
4030 sbuf is the stat of the target directory to be shared. */
4032 if (lp_usershare_owner_only()) {
4033 /* root can share anything. */
4034 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
4035 return USERSHARE_PATH_NOT_ALLOWED;
4039 *pp_sharepath = sharepath;
4040 *pp_comment = comment;
4041 return USERSHARE_OK;
4044 /***************************************************************************
4045 Deal with a usershare file.
4046 Returns:
4047 >= 0 - snum
4048 -1 - Bad name, invalid contents.
4049 - service name already existed and not a usershare, problem
4050 with permissions to share directory etc.
4051 ***************************************************************************/
4053 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4055 SMB_STRUCT_STAT sbuf;
4056 SMB_STRUCT_STAT lsbuf;
4057 char *fname = NULL;
4058 char *sharepath = NULL;
4059 char *comment = NULL;
4060 char *cp_service_name = NULL;
4061 char **lines = NULL;
4062 int numlines = 0;
4063 int fd = -1;
4064 int iService = -1;
4065 TALLOC_CTX *ctx = talloc_stackframe();
4066 struct security_descriptor *psd = NULL;
4067 bool guest_ok = false;
4068 char *canon_name = NULL;
4069 bool added_service = false;
4070 int ret = -1;
4072 /* Ensure share name doesn't contain invalid characters. */
4073 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4074 DEBUG(0,("process_usershare_file: share name %s contains "
4075 "invalid characters (any of %s)\n",
4076 file_name, INVALID_SHARENAME_CHARS ));
4077 goto out;
4080 canon_name = canonicalize_servicename(ctx, file_name);
4081 if (!canon_name) {
4082 goto out;
4085 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
4086 if (!fname) {
4087 goto out;
4090 /* Minimize the race condition by doing an lstat before we
4091 open and fstat. Ensure this isn't a symlink link. */
4093 if (sys_lstat(fname, &lsbuf, false) != 0) {
4094 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4095 fname, strerror(errno) ));
4096 goto out;
4099 /* This must be a regular file, not a symlink, directory or
4100 other strange filetype. */
4101 if (!check_usershare_stat(fname, &lsbuf)) {
4102 goto out;
4106 TDB_DATA data;
4107 NTSTATUS status;
4109 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
4110 canon_name, &data);
4112 iService = -1;
4114 if (NT_STATUS_IS_OK(status) &&
4115 (data.dptr != NULL) &&
4116 (data.dsize == sizeof(iService))) {
4117 memcpy(&iService, data.dptr, sizeof(iService));
4121 if (iService != -1 &&
4122 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4123 &lsbuf.st_ex_mtime) == 0) {
4124 /* Nothing changed - Mark valid and return. */
4125 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4126 canon_name ));
4127 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4128 ret = iService;
4129 goto out;
4132 /* Try and open the file read only - no symlinks allowed. */
4133 #ifdef O_NOFOLLOW
4134 fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
4135 #else
4136 fd = open(fname, O_RDONLY, 0);
4137 #endif
4139 if (fd == -1) {
4140 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4141 fname, strerror(errno) ));
4142 goto out;
4145 /* Now fstat to be *SURE* it's a regular file. */
4146 if (sys_fstat(fd, &sbuf, false) != 0) {
4147 close(fd);
4148 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4149 fname, strerror(errno) ));
4150 goto out;
4153 /* Is it the same dev/inode as was lstated ? */
4154 if (!check_same_stat(&lsbuf, &sbuf)) {
4155 close(fd);
4156 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4157 "Symlink spoofing going on ?\n", fname ));
4158 goto out;
4161 /* This must be a regular file, not a symlink, directory or
4162 other strange filetype. */
4163 if (!check_usershare_stat(fname, &sbuf)) {
4164 close(fd);
4165 goto out;
4168 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
4170 close(fd);
4171 if (lines == NULL) {
4172 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4173 fname, (unsigned int)sbuf.st_ex_uid ));
4174 goto out;
4177 if (parse_usershare_file(ctx, &sbuf, file_name,
4178 iService, lines, numlines, &sharepath,
4179 &comment, &cp_service_name,
4180 &psd, &guest_ok) != USERSHARE_OK) {
4181 goto out;
4184 /* Everything ok - add the service possibly using a template. */
4185 if (iService < 0) {
4186 const struct loadparm_service *sp = &sDefault;
4187 if (snum_template != -1) {
4188 sp = ServicePtrs[snum_template];
4191 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
4192 DEBUG(0, ("process_usershare_file: Failed to add "
4193 "new service %s\n", cp_service_name));
4194 goto out;
4197 added_service = true;
4199 /* Read only is controlled by usershare ACL below. */
4200 ServicePtrs[iService]->read_only = false;
4203 /* Write the ACL of the new/modified share. */
4204 if (!set_share_security(canon_name, psd)) {
4205 DEBUG(0, ("process_usershare_file: Failed to set share "
4206 "security for user share %s\n",
4207 canon_name ));
4208 goto out;
4211 /* If from a template it may be marked invalid. */
4212 ServicePtrs[iService]->valid = true;
4214 /* Set the service as a valid usershare. */
4215 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4217 /* Set guest access. */
4218 if (lp_usershare_allow_guests()) {
4219 ServicePtrs[iService]->guest_ok = guest_ok;
4222 /* And note when it was loaded. */
4223 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
4224 string_set(&ServicePtrs[iService]->path, sharepath);
4225 string_set(&ServicePtrs[iService]->comment, comment);
4227 ret = iService;
4229 out:
4231 if (ret == -1 && iService != -1 && added_service) {
4232 lp_remove_service(iService);
4235 TALLOC_FREE(lines);
4236 TALLOC_FREE(ctx);
4237 return ret;
4240 /***************************************************************************
4241 Checks if a usershare entry has been modified since last load.
4242 ***************************************************************************/
4244 static bool usershare_exists(int iService, struct timespec *last_mod)
4246 SMB_STRUCT_STAT lsbuf;
4247 const char *usersharepath = Globals.usershare_path;
4248 char *fname;
4250 if (asprintf(&fname, "%s/%s",
4251 usersharepath,
4252 ServicePtrs[iService]->szService) < 0) {
4253 return false;
4256 if (sys_lstat(fname, &lsbuf, false) != 0) {
4257 SAFE_FREE(fname);
4258 return false;
4261 if (!S_ISREG(lsbuf.st_ex_mode)) {
4262 SAFE_FREE(fname);
4263 return false;
4266 SAFE_FREE(fname);
4267 *last_mod = lsbuf.st_ex_mtime;
4268 return true;
4271 /***************************************************************************
4272 Load a usershare service by name. Returns a valid servicenumber or -1.
4273 ***************************************************************************/
4275 int load_usershare_service(const char *servicename)
4277 SMB_STRUCT_STAT sbuf;
4278 const char *usersharepath = Globals.usershare_path;
4279 int max_user_shares = Globals.usershare_max_shares;
4280 int snum_template = -1;
4282 if (*usersharepath == 0 || max_user_shares == 0) {
4283 return -1;
4286 if (sys_stat(usersharepath, &sbuf, false) != 0) {
4287 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4288 usersharepath, strerror(errno) ));
4289 return -1;
4292 if (!S_ISDIR(sbuf.st_ex_mode)) {
4293 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4294 usersharepath ));
4295 return -1;
4299 * This directory must be owned by root, and have the 't' bit set.
4300 * It also must not be writable by "other".
4303 #ifdef S_ISVTX
4304 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4305 #else
4306 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4307 #endif
4308 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4309 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4310 usersharepath ));
4311 return -1;
4314 /* Ensure the template share exists if it's set. */
4315 if (Globals.usershare_template_share[0]) {
4316 /* We can't use lp_servicenumber here as we are recommending that
4317 template shares have -valid=false set. */
4318 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4319 if (ServicePtrs[snum_template]->szService &&
4320 strequal(ServicePtrs[snum_template]->szService,
4321 Globals.usershare_template_share)) {
4322 break;
4326 if (snum_template == -1) {
4327 DEBUG(0,("load_usershare_service: usershare template share %s "
4328 "does not exist.\n",
4329 Globals.usershare_template_share ));
4330 return -1;
4334 return process_usershare_file(usersharepath, servicename, snum_template);
4337 /***************************************************************************
4338 Load all user defined shares from the user share directory.
4339 We only do this if we're enumerating the share list.
4340 This is the function that can delete usershares that have
4341 been removed.
4342 ***************************************************************************/
4344 int load_usershare_shares(struct smbd_server_connection *sconn,
4345 bool (*snumused) (struct smbd_server_connection *, int))
4347 DIR *dp;
4348 SMB_STRUCT_STAT sbuf;
4349 struct dirent *de;
4350 int num_usershares = 0;
4351 int max_user_shares = Globals.usershare_max_shares;
4352 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4353 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4354 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4355 int iService;
4356 int snum_template = -1;
4357 const char *usersharepath = Globals.usershare_path;
4358 int ret = lp_numservices();
4359 TALLOC_CTX *tmp_ctx;
4361 if (max_user_shares == 0 || *usersharepath == '\0') {
4362 return lp_numservices();
4365 if (sys_stat(usersharepath, &sbuf, false) != 0) {
4366 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4367 usersharepath, strerror(errno) ));
4368 return ret;
4372 * This directory must be owned by root, and have the 't' bit set.
4373 * It also must not be writable by "other".
4376 #ifdef S_ISVTX
4377 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4378 #else
4379 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4380 #endif
4381 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4382 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4383 usersharepath ));
4384 return ret;
4387 /* Ensure the template share exists if it's set. */
4388 if (Globals.usershare_template_share[0]) {
4389 /* We can't use lp_servicenumber here as we are recommending that
4390 template shares have -valid=false set. */
4391 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4392 if (ServicePtrs[snum_template]->szService &&
4393 strequal(ServicePtrs[snum_template]->szService,
4394 Globals.usershare_template_share)) {
4395 break;
4399 if (snum_template == -1) {
4400 DEBUG(0,("load_usershare_shares: usershare template share %s "
4401 "does not exist.\n",
4402 Globals.usershare_template_share ));
4403 return ret;
4407 /* Mark all existing usershares as pending delete. */
4408 for (iService = iNumServices - 1; iService >= 0; iService--) {
4409 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4410 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4414 dp = opendir(usersharepath);
4415 if (!dp) {
4416 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4417 usersharepath, strerror(errno) ));
4418 return ret;
4421 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4422 (de = readdir(dp));
4423 num_dir_entries++ ) {
4424 int r;
4425 const char *n = de->d_name;
4427 /* Ignore . and .. */
4428 if (*n == '.') {
4429 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4430 continue;
4434 if (n[0] == ':') {
4435 /* Temporary file used when creating a share. */
4436 num_tmp_dir_entries++;
4439 /* Allow 20% tmp entries. */
4440 if (num_tmp_dir_entries > allowed_tmp_entries) {
4441 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4442 "in directory %s\n",
4443 num_tmp_dir_entries, usersharepath));
4444 break;
4447 r = process_usershare_file(usersharepath, n, snum_template);
4448 if (r == 0) {
4449 /* Update the services count. */
4450 num_usershares++;
4451 if (num_usershares >= max_user_shares) {
4452 DEBUG(0,("load_usershare_shares: max user shares reached "
4453 "on file %s in directory %s\n",
4454 n, usersharepath ));
4455 break;
4457 } else if (r == -1) {
4458 num_bad_dir_entries++;
4461 /* Allow 20% bad entries. */
4462 if (num_bad_dir_entries > allowed_bad_entries) {
4463 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4464 "in directory %s\n",
4465 num_bad_dir_entries, usersharepath));
4466 break;
4469 /* Allow 20% bad entries. */
4470 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4471 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4472 "in directory %s\n",
4473 num_dir_entries, usersharepath));
4474 break;
4478 closedir(dp);
4480 /* Sweep through and delete any non-refreshed usershares that are
4481 not currently in use. */
4482 tmp_ctx = talloc_stackframe();
4483 for (iService = iNumServices - 1; iService >= 0; iService--) {
4484 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4485 char *servname;
4487 if (snumused && snumused(sconn, iService)) {
4488 continue;
4491 servname = lp_servicename(tmp_ctx, iService);
4493 /* Remove from the share ACL db. */
4494 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4495 servname ));
4496 delete_share_security(servname);
4497 free_service_byindex(iService);
4500 talloc_free(tmp_ctx);
4502 return lp_numservices();
4505 /********************************************************
4506 Destroy global resources allocated in this file
4507 ********************************************************/
4509 void gfree_loadparm(void)
4511 int i;
4513 free_file_list();
4515 /* Free resources allocated to services */
4517 for ( i = 0; i < iNumServices; i++ ) {
4518 if ( VALID(i) ) {
4519 free_service_byindex(i);
4523 SAFE_FREE( ServicePtrs );
4524 iNumServices = 0;
4526 /* Now release all resources allocated to global
4527 parameters and the default service */
4529 free_global_parameters();
4533 /***************************************************************************
4534 Allow client apps to specify that they are a client
4535 ***************************************************************************/
4536 static void lp_set_in_client(bool b)
4538 in_client = b;
4542 /***************************************************************************
4543 Determine if we're running in a client app
4544 ***************************************************************************/
4545 static bool lp_is_in_client(void)
4547 return in_client;
4550 /***************************************************************************
4551 Load the services array from the services file. Return true on success,
4552 false on failure.
4553 ***************************************************************************/
4555 static bool lp_load_ex(const char *pszFname,
4556 bool global_only,
4557 bool save_defaults,
4558 bool add_ipc,
4559 bool initialize_globals,
4560 bool allow_include_registry,
4561 bool load_all_shares)
4563 char *n2 = NULL;
4564 bool bRetval;
4566 bRetval = false;
4568 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4570 bInGlobalSection = true;
4571 bGlobalOnly = global_only;
4572 bAllowIncludeRegistry = allow_include_registry;
4574 init_globals(initialize_globals);
4576 free_file_list();
4578 if (save_defaults) {
4579 init_locals();
4580 lp_save_defaults();
4583 if (!initialize_globals) {
4584 free_param_opts(&Globals.param_opt);
4585 apply_lp_set_cmdline();
4588 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
4590 /* We get sections first, so have to start 'behind' to make up */
4591 iServiceIndex = -1;
4593 if (lp_config_backend_is_file()) {
4594 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4595 current_user_info.domain,
4596 pszFname);
4597 if (!n2) {
4598 smb_panic("lp_load_ex: out of memory");
4601 add_to_file_list(pszFname, n2);
4603 bRetval = pm_process(n2, do_section, do_parameter, NULL);
4604 TALLOC_FREE(n2);
4606 /* finish up the last section */
4607 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4608 if (bRetval) {
4609 if (iServiceIndex >= 0) {
4610 bRetval = service_ok(iServiceIndex);
4614 if (lp_config_backend_is_registry()) {
4615 /* config backend changed to registry in config file */
4617 * We need to use this extra global variable here to
4618 * survive restart: init_globals uses this as a default
4619 * for config_backend. Otherwise, init_globals would
4620 * send us into an endless loop here.
4622 config_backend = CONFIG_BACKEND_REGISTRY;
4623 /* start over */
4624 DEBUG(1, ("lp_load_ex: changing to config backend "
4625 "registry\n"));
4626 init_globals(true);
4627 lp_kill_all_services();
4628 return lp_load_ex(pszFname, global_only, save_defaults,
4629 add_ipc, initialize_globals,
4630 allow_include_registry,
4631 load_all_shares);
4633 } else if (lp_config_backend_is_registry()) {
4634 bRetval = process_registry_globals();
4635 } else {
4636 DEBUG(0, ("Illegal config backend given: %d\n",
4637 lp_config_backend()));
4638 bRetval = false;
4641 if (bRetval && lp_registry_shares()) {
4642 if (load_all_shares) {
4643 bRetval = process_registry_shares();
4644 } else {
4645 bRetval = reload_registry_shares();
4650 char *serv = lp_auto_services(talloc_tos());
4651 lp_add_auto_services(serv);
4652 TALLOC_FREE(serv);
4655 if (add_ipc) {
4656 /* When 'restrict anonymous = 2' guest connections to ipc$
4657 are denied */
4658 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4659 if ( lp_enable_asu_support() ) {
4660 lp_add_ipc("ADMIN$", false);
4664 set_allowed_client_auth();
4666 if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
4667 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4668 lp_password_server()));
4671 bLoaded = true;
4673 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4674 /* if we_are_a_wins_server is true and we are in the client */
4675 if (lp_is_in_client() && Globals.we_are_a_wins_server) {
4676 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4679 init_iconv();
4681 fault_configure(smb_panic_s3);
4684 * We run this check once the whole smb.conf is parsed, to
4685 * force some settings for the standard way a AD DC is
4686 * operated. We may changed these as our code evolves, which
4687 * is why we force these settings.
4689 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4690 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4692 lp_do_parameter(-1, "rpc_server:default", "external");
4693 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4694 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4695 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4696 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4697 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4698 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4699 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4700 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4703 bAllowIncludeRegistry = true;
4705 return (bRetval);
4708 bool lp_load(const char *pszFname,
4709 bool global_only,
4710 bool save_defaults,
4711 bool add_ipc,
4712 bool initialize_globals)
4714 return lp_load_ex(pszFname,
4715 global_only,
4716 save_defaults,
4717 add_ipc,
4718 initialize_globals,
4719 true, /* allow_include_registry */
4720 false); /* load_all_shares*/
4723 bool lp_load_initial_only(const char *pszFname)
4725 return lp_load_ex(pszFname,
4726 true, /* global only */
4727 false, /* save_defaults */
4728 false, /* add_ipc */
4729 true, /* initialize_globals */
4730 false, /* allow_include_registry */
4731 false); /* load_all_shares*/
4735 * most common lp_load wrapper, loading only the globals
4737 bool lp_load_global(const char *file_name)
4739 return lp_load_ex(file_name,
4740 true, /* global_only */
4741 false, /* save_defaults */
4742 false, /* add_ipc */
4743 true, /* initialize_globals */
4744 true, /* allow_include_registry */
4745 false); /* load_all_shares*/
4749 * lp_load wrapper, especially for clients
4751 bool lp_load_client(const char *file_name)
4753 lp_set_in_client(true);
4755 return lp_load_global(file_name);
4759 * lp_load wrapper, loading only globals, but intended
4760 * for subsequent calls, not reinitializing the globals
4761 * to default values
4763 bool lp_load_global_no_reinit(const char *file_name)
4765 return lp_load_ex(file_name,
4766 true, /* global_only */
4767 false, /* save_defaults */
4768 false, /* add_ipc */
4769 false, /* initialize_globals */
4770 true, /* allow_include_registry */
4771 false); /* load_all_shares*/
4775 * lp_load wrapper, especially for clients, no reinitialization
4777 bool lp_load_client_no_reinit(const char *file_name)
4779 lp_set_in_client(true);
4781 return lp_load_global_no_reinit(file_name);
4784 bool lp_load_with_registry_shares(const char *pszFname,
4785 bool global_only,
4786 bool save_defaults,
4787 bool add_ipc,
4788 bool initialize_globals)
4790 return lp_load_ex(pszFname,
4791 global_only,
4792 save_defaults,
4793 add_ipc,
4794 initialize_globals,
4795 true, /* allow_include_registry */
4796 true); /* load_all_shares*/
4799 /***************************************************************************
4800 Return the max number of services.
4801 ***************************************************************************/
4803 int lp_numservices(void)
4805 return (iNumServices);
4808 /***************************************************************************
4809 Display the contents of the services array in human-readable form.
4810 ***************************************************************************/
4812 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4814 int iService;
4816 if (show_defaults)
4817 defaults_saved = false;
4819 dump_globals(f);
4821 dump_a_service(&sDefault, f);
4823 for (iService = 0; iService < maxtoprint; iService++) {
4824 fprintf(f,"\n");
4825 lp_dump_one(f, show_defaults, iService);
4829 /***************************************************************************
4830 Display the contents of one service in human-readable form.
4831 ***************************************************************************/
4833 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4835 if (VALID(snum)) {
4836 if (ServicePtrs[snum]->szService[0] == '\0')
4837 return;
4838 dump_a_service(ServicePtrs[snum], f);
4842 /***************************************************************************
4843 Return the number of the service with the given name, or -1 if it doesn't
4844 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4845 getservicebyname()! This works ONLY if all services have been loaded, and
4846 does not copy the found service.
4847 ***************************************************************************/
4849 int lp_servicenumber(const char *pszServiceName)
4851 int iService;
4852 fstring serviceName;
4854 if (!pszServiceName) {
4855 return GLOBAL_SECTION_SNUM;
4858 for (iService = iNumServices - 1; iService >= 0; iService--) {
4859 if (VALID(iService) && ServicePtrs[iService]->szService) {
4861 * The substitution here is used to support %U is
4862 * service names
4864 fstrcpy(serviceName, ServicePtrs[iService]->szService);
4865 standard_sub_basic(get_current_username(),
4866 current_user_info.domain,
4867 serviceName,sizeof(serviceName));
4868 if (strequal(serviceName, pszServiceName)) {
4869 break;
4874 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4875 struct timespec last_mod;
4877 if (!usershare_exists(iService, &last_mod)) {
4878 /* Remove the share security tdb entry for it. */
4879 delete_share_security(lp_servicename(talloc_tos(), iService));
4880 /* Remove it from the array. */
4881 free_service_byindex(iService);
4882 /* Doesn't exist anymore. */
4883 return GLOBAL_SECTION_SNUM;
4886 /* Has it been modified ? If so delete and reload. */
4887 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4888 &last_mod) < 0) {
4889 /* Remove it from the array. */
4890 free_service_byindex(iService);
4891 /* and now reload it. */
4892 iService = load_usershare_service(pszServiceName);
4896 if (iService < 0) {
4897 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4898 return GLOBAL_SECTION_SNUM;
4901 return (iService);
4904 /*******************************************************************
4905 A useful volume label function.
4906 ********************************************************************/
4908 const char *volume_label(TALLOC_CTX *ctx, int snum)
4910 char *ret;
4911 const char *label = lp_volume(ctx, snum);
4912 if (!*label) {
4913 label = lp_servicename(ctx, snum);
4916 /* This returns a 33 byte guarenteed null terminated string. */
4917 ret = talloc_strndup(ctx, label, 32);
4918 if (!ret) {
4919 return "";
4921 return ret;
4924 /*******************************************************************
4925 Get the default server type we will announce as via nmbd.
4926 ********************************************************************/
4928 int lp_default_server_announce(void)
4930 int default_server_announce = 0;
4931 default_server_announce |= SV_TYPE_WORKSTATION;
4932 default_server_announce |= SV_TYPE_SERVER;
4933 default_server_announce |= SV_TYPE_SERVER_UNIX;
4935 /* note that the flag should be set only if we have a
4936 printer service but nmbd doesn't actually load the
4937 services so we can't tell --jerry */
4939 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4941 default_server_announce |= SV_TYPE_SERVER_NT;
4942 default_server_announce |= SV_TYPE_NT;
4944 switch (lp_server_role()) {
4945 case ROLE_DOMAIN_MEMBER:
4946 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4947 break;
4948 case ROLE_DOMAIN_PDC:
4949 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4950 break;
4951 case ROLE_DOMAIN_BDC:
4952 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4953 break;
4954 case ROLE_STANDALONE:
4955 default:
4956 break;
4958 if (lp_time_server())
4959 default_server_announce |= SV_TYPE_TIME_SOURCE;
4961 if (lp_host_msdfs())
4962 default_server_announce |= SV_TYPE_DFS_SERVER;
4964 return default_server_announce;
4967 /***********************************************************
4968 If we are PDC then prefer us as DMB
4969 ************************************************************/
4971 bool lp_domain_master(void)
4973 if (Globals._domain_master == Auto)
4974 return (lp_server_role() == ROLE_DOMAIN_PDC);
4976 return (bool)Globals._domain_master;
4979 /***********************************************************
4980 If we are PDC then prefer us as DMB
4981 ************************************************************/
4983 static bool lp_domain_master_true_or_auto(void)
4985 if (Globals._domain_master) /* auto or yes */
4986 return true;
4988 return false;
4991 /***********************************************************
4992 If we are DMB then prefer us as LMB
4993 ************************************************************/
4995 bool lp_preferred_master(void)
4997 if (Globals.iPreferredMaster == Auto)
4998 return (lp_local_master() && lp_domain_master());
5000 return (bool)Globals.iPreferredMaster;
5003 /*******************************************************************
5004 Remove a service.
5005 ********************************************************************/
5007 void lp_remove_service(int snum)
5009 ServicePtrs[snum]->valid = false;
5012 /*******************************************************************
5013 Copy a service.
5014 ********************************************************************/
5016 void lp_copy_service(int snum, const char *new_name)
5018 do_section(new_name, NULL);
5019 if (snum >= 0) {
5020 snum = lp_servicenumber(new_name);
5021 if (snum >= 0) {
5022 char *name = lp_servicename(talloc_tos(), snum);
5023 lp_do_parameter(snum, "copy", name);
5028 const char *lp_printername(TALLOC_CTX *ctx, int snum)
5030 const char *ret = lp__printername(ctx, snum);
5031 if (ret == NULL || *ret == '\0') {
5032 ret = lp_const_servicename(snum);
5035 return ret;
5039 /***********************************************************
5040 Allow daemons such as winbindd to fix their logfile name.
5041 ************************************************************/
5043 void lp_set_logfile(const char *name)
5045 string_set(&Globals.logfile, name);
5046 debug_set_logfile(name);
5049 /*******************************************************************
5050 Return the max print jobs per queue.
5051 ********************************************************************/
5053 int lp_maxprintjobs(int snum)
5055 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5056 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5057 maxjobs = PRINT_MAX_JOBID - 1;
5059 return maxjobs;
5062 const char *lp_printcapname(void)
5064 if ((Globals.szPrintcapname != NULL) &&
5065 (Globals.szPrintcapname[0] != '\0'))
5066 return Globals.szPrintcapname;
5068 if (sDefault.printing == PRINT_CUPS) {
5069 return "cups";
5072 if (sDefault.printing == PRINT_BSD)
5073 return "/etc/printcap";
5075 return PRINTCAP_NAME;
5078 static uint32 spoolss_state;
5080 bool lp_disable_spoolss( void )
5082 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5083 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5085 return spoolss_state == SVCCTL_STOPPED ? true : false;
5088 void lp_set_spoolss_state( uint32 state )
5090 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5092 spoolss_state = state;
5095 uint32 lp_get_spoolss_state( void )
5097 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5100 /*******************************************************************
5101 Ensure we don't use sendfile if server smb signing is active.
5102 ********************************************************************/
5104 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
5106 bool sign_active = false;
5108 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5109 if (get_Protocol() < PROTOCOL_NT1) {
5110 return false;
5112 if (signing_state) {
5113 sign_active = smb_signing_is_active(signing_state);
5115 return (lp__use_sendfile(snum) &&
5116 (get_remote_arch() != RA_WIN95) &&
5117 !sign_active);
5120 /*******************************************************************
5121 Turn off sendfile if we find the underlying OS doesn't support it.
5122 ********************************************************************/
5124 void set_use_sendfile(int snum, bool val)
5126 if (LP_SNUM_OK(snum))
5127 ServicePtrs[snum]->_use_sendfile = val;
5128 else
5129 sDefault._use_sendfile = val;
5132 /*******************************************************************
5133 Turn off storing DOS attributes if this share doesn't support it.
5134 ********************************************************************/
5136 void set_store_dos_attributes(int snum, bool val)
5138 if (!LP_SNUM_OK(snum))
5139 return;
5140 ServicePtrs[(snum)]->store_dos_attributes = val;
5143 void lp_set_mangling_method(const char *new_method)
5145 string_set(&Globals.mangling_method, new_method);
5148 /*******************************************************************
5149 Global state for POSIX pathname processing.
5150 ********************************************************************/
5152 static bool posix_pathnames;
5154 bool lp_posix_pathnames(void)
5156 return posix_pathnames;
5159 /*******************************************************************
5160 Change everything needed to ensure POSIX pathname processing (currently
5161 not much).
5162 ********************************************************************/
5164 void lp_set_posix_pathnames(void)
5166 posix_pathnames = true;
5169 /*******************************************************************
5170 Global state for POSIX lock processing - CIFS unix extensions.
5171 ********************************************************************/
5173 bool posix_default_lock_was_set;
5174 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5176 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5178 if (posix_default_lock_was_set) {
5179 return posix_cifsx_locktype;
5180 } else {
5181 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5185 /*******************************************************************
5186 ********************************************************************/
5188 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5190 posix_default_lock_was_set = true;
5191 posix_cifsx_locktype = val;
5194 int lp_min_receive_file_size(void)
5196 if (Globals.iminreceivefile < 0) {
5197 return 0;
5199 return Globals.iminreceivefile;
5202 /*******************************************************************
5203 Safe wide links checks.
5204 This helper function always verify the validity of wide links,
5205 even after a configuration file reload.
5206 ********************************************************************/
5208 static bool lp_widelinks_internal(int snum)
5210 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
5211 sDefault.bWidelinks);
5214 void widelinks_warning(int snum)
5216 if (lp_allow_insecure_wide_links()) {
5217 return;
5220 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
5221 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
5222 "These parameters are incompatible. "
5223 "Wide links will be disabled for this share.\n",
5224 lp_servicename(talloc_tos(), snum) ));
5228 bool lp_widelinks(int snum)
5230 /* wide links is always incompatible with unix extensions */
5231 if (lp_unix_extensions()) {
5233 * Unless we have "allow insecure widelinks"
5234 * turned on.
5236 if (!lp_allow_insecure_wide_links()) {
5237 return false;
5241 return lp_widelinks_internal(snum);
5244 int lp_server_role(void)
5246 return lp_find_server_role(lp__server_role(),
5247 lp__security(),
5248 lp__domain_logons(),
5249 lp_domain_master_true_or_auto());
5252 int lp_security(void)
5254 return lp_find_security(lp__server_role(),
5255 lp__security());
5258 struct loadparm_global * get_globals(void)
5260 return &Globals;