4e10aaf4724e2a900ab8a063e26788c6c8f6a225
[samba.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
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
15
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.
20
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.
25
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/>.
28 */
29
30 /*
31  *  Load parameters.
32  *
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.
36  *
37  * To add a parameter:
38  *
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
44  *  
45  *
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!
53  *
54  */
55
56 #define LOADPARM_SUBSTITUTION_INTERNALS 1
57 #include "includes.h"
58 #include "system/filesys.h"
59 #include "util_tdb.h"
60 #include "lib/param/loadparm.h"
61 #include "lib/param/param.h"
62 #include "printing.h"
63 #include "lib/smbconf/smbconf.h"
64 #include "lib/smbconf/smbconf_init.h"
65
66 #include "ads.h"
67 #include "../librpc/gen_ndr/svcctl.h"
68 #include "intl.h"
69 #include "../libcli/smb/smb_signing.h"
70 #include "dbwrap/dbwrap.h"
71 #include "dbwrap/dbwrap_rbt.h"
72 #include "../lib/util/bitmap.h"
73 #include "librpc/gen_ndr/nbt.h"
74 #include "source4/lib/tls/tls.h"
75 #include "libcli/auth/ntlm_check.h"
76 #include "lib/crypto/gnutls_helpers.h"
77 #include "lib/util/string_wrappers.h"
78 #include "auth/credentials/credentials.h"
79 #include "source3/lib/substitute.h"
80
81 #ifdef HAVE_SYS_SYSCTL_H
82 #include <sys/sysctl.h>
83 #endif
84
85 bool bLoaded = false;
86
87 extern userdom_struct current_user_info;
88
89 /* the special value for the include parameter
90  * to be interpreted not as a file name but to
91  * trigger loading of the global smb.conf options
92  * from registry. */
93 #ifndef INCLUDE_REGISTRY_NAME
94 #define INCLUDE_REGISTRY_NAME "registry"
95 #endif
96
97 static bool in_client = false;          /* Not in the client by default */
98 static struct smbconf_csn conf_last_csn;
99
100 static int config_backend = CONFIG_BACKEND_FILE;
101
102 /* some helpful bits */
103 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && \
104                        (ServicePtrs != NULL) && \
105                        (ServicePtrs[(i)] != NULL) && ServicePtrs[(i)]->valid)
106 #define VALID(i) ((ServicePtrs != NULL) && (ServicePtrs[i]!= NULL) && \
107                   ServicePtrs[i]->valid)
108
109 #define USERSHARE_VALID 1
110 #define USERSHARE_PENDING_DELETE 2
111
112 static bool defaults_saved = false;
113
114 #include "lib/param/param_global.h"
115
116 static struct loadparm_global Globals;
117
118 /* This is a default service used to prime a services structure */
119 static const struct loadparm_service _sDefault =
120 {
121         .valid = true,
122         .autoloaded = false,
123         .usershare = 0,
124         .usershare_last_mod = {0, 0},
125         .szService = NULL,
126         .path = NULL,
127         .invalid_users = NULL,
128         .valid_users = NULL,
129         .admin_users = NULL,
130         .copy = NULL,
131         .include = NULL,
132         .preexec = NULL,
133         .postexec = NULL,
134         .root_preexec = NULL,
135         .root_postexec = NULL,
136         .cups_options = NULL,
137         .print_command = NULL,
138         .lpq_command = NULL,
139         .lprm_command = NULL,
140         .lppause_command = NULL,
141         .lpresume_command = NULL,
142         .queuepause_command = NULL,
143         .queueresume_command = NULL,
144         ._printername = NULL,
145         .printjob_username = NULL,
146         .dont_descend = NULL,
147         .hosts_allow = NULL,
148         .hosts_deny = NULL,
149         .magic_script = NULL,
150         .magic_output = NULL,
151         .veto_files = NULL,
152         .hide_files = NULL,
153         .veto_oplock_files = NULL,
154         .comment = NULL,
155         .force_user = NULL,
156         .force_group = NULL,
157         .read_list = NULL,
158         .write_list = NULL,
159         .volume = NULL,
160         .fstype = NULL,
161         .vfs_objects = NULL,
162         .msdfs_proxy = NULL,
163         .aio_write_behind = NULL,
164         .dfree_command = NULL,
165         .min_print_space = 0,
166         .max_print_jobs = 1000,
167         .max_reported_print_jobs = 0,
168         .create_mask = 0744,
169         .force_create_mode = 0,
170         .directory_mask = 0755,
171         .force_directory_mode = 0,
172         .max_connections = 0,
173         .default_case = CASE_LOWER,
174         .printing = DEFAULT_PRINTING,
175         .csc_policy = 0,
176         .block_size = 1024,
177         .dfree_cache_time = 0,
178         .preexec_close = false,
179         .root_preexec_close = false,
180         .case_sensitive = Auto,
181         .preserve_case = true,
182         .short_preserve_case = true,
183         .hide_dot_files = true,
184         .hide_special_files = false,
185         .hide_unreadable = false,
186         .hide_unwriteable_files = false,
187         .browseable = true,
188         .access_based_share_enum = false,
189         .available = true,
190         .read_only = true,
191         .spotlight = false,
192         .guest_only = false,
193         .administrative_share = false,
194         .guest_ok = false,
195         .printable = false,
196         .print_notify_backchannel = false,
197         .map_system = false,
198         .map_hidden = false,
199         .map_archive = true,
200         .store_dos_attributes = true,
201         .smbd_max_xattr_size = 65536,
202         .dmapi_support = false,
203         .locking = true,
204         .strict_locking = Auto,
205         .posix_locking = true,
206         .oplocks = true,
207         .kernel_oplocks = false,
208         .level2_oplocks = true,
209         .mangled_names = MANGLED_NAMES_ILLEGAL,
210         .wide_links = false,
211         .follow_symlinks = true,
212         .sync_always = false,
213         .strict_allocate = false,
214         .strict_rename = false,
215         .strict_sync = true,
216         .mangling_char = '~',
217         .copymap = NULL,
218         .delete_readonly = false,
219         .fake_oplocks = false,
220         .delete_veto_files = false,
221         .dos_filemode = false,
222         .dos_filetimes = true,
223         .dos_filetime_resolution = false,
224         .fake_directory_create_times = false,
225         .blocking_locks = true,
226         .inherit_permissions = false,
227         .inherit_acls = false,
228         .inherit_owner = false,
229         .msdfs_root = false,
230         .msdfs_shuffle_referrals = false,
231         .use_client_driver = false,
232         .default_devmode = true,
233         .force_printername = false,
234         .nt_acl_support = true,
235         .force_unknown_acl_user = false,
236         ._use_sendfile = false,
237         .map_acl_inherit = false,
238         .afs_share = false,
239         .ea_support = true,
240         .acl_check_permissions = true,
241         .acl_map_full_control = true,
242         .acl_group_control = false,
243         .acl_allow_execute_always = false,
244         .acl_flag_inherited_canonicalization = true,
245         .aio_read_size = 1,
246         .aio_write_size = 1,
247         .map_readonly = MAP_READONLY_NO,
248         .directory_name_cache_size = 100,
249         .server_smb_encrypt = SMB_ENCRYPTION_DEFAULT,
250         .kernel_share_modes = true,
251         .durable_handles = true,
252         .check_parent_directory_delete_on_close = false,
253         .param_opt = NULL,
254         .smbd_search_ask_sharemode = true,
255         .smbd_getinfo_ask_sharemode = true,
256         .spotlight_backend = SPOTLIGHT_BACKEND_NOINDEX,
257         .honor_change_notify_privilege = false,
258         .dummy = ""
259 };
260
261 /*
262  * This is a copy of the default service structure. Service options in the
263  * global section would otherwise overwrite the initial default values.
264  */
265 static struct loadparm_service sDefault;
266
267 /* local variables */
268 static struct loadparm_service **ServicePtrs = NULL;
269 static int iNumServices = 0;
270 static int iServiceIndex = 0;
271 static struct db_context *ServiceHash;
272 static bool bInGlobalSection = true;
273 static bool bGlobalOnly = false;
274 static struct file_lists *file_lists = NULL;
275 static unsigned int *flags_list = NULL;
276
277 static void set_allowed_client_auth(void);
278
279 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
280 static void free_param_opts(struct parmlist_entry **popts);
281
282 /**
283  *  Function to return the default value for the maximum number of open
284  *  file descriptors permitted.  This function tries to consult the
285  *  kernel-level (sysctl) and ulimit (getrlimit()) values and goes
286  *  the smaller of those.
287  */
288 static int max_open_files(void)
289 {
290         int sysctl_max = MAX_OPEN_FILES;
291         int rlimit_max = MAX_OPEN_FILES;
292
293 #ifdef HAVE_SYSCTLBYNAME
294         {
295                 size_t size = sizeof(sysctl_max);
296                 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
297                              0);
298         }
299 #endif
300
301 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
302         {
303                 struct rlimit rl;
304
305                 ZERO_STRUCT(rl);
306
307                 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
308                         rlimit_max = rl.rlim_cur;
309
310 #if defined(RLIM_INFINITY)
311                 if(rl.rlim_cur == RLIM_INFINITY)
312                         rlimit_max = MAX_OPEN_FILES;
313 #endif
314         }
315 #endif
316
317         if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
318                 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
319                         "minimum Windows limit (%d)\n",
320                         sysctl_max,
321                         MIN_OPEN_FILES_WINDOWS));
322                 sysctl_max = MIN_OPEN_FILES_WINDOWS;
323         }
324
325         if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
326                 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
327                         "minimum Windows limit (%d)\n",
328                         rlimit_max,
329                         MIN_OPEN_FILES_WINDOWS));
330                 rlimit_max = MIN_OPEN_FILES_WINDOWS;
331         }
332
333         return MIN(sysctl_max, rlimit_max);
334 }
335
336 /**
337  * Common part of freeing allocated data for one parameter.
338  */
339 static void free_one_parameter_common(void *parm_ptr,
340                                       struct parm_struct parm)
341 {
342         if ((parm.type == P_STRING) ||
343             (parm.type == P_USTRING))
344         {
345                 lpcfg_string_free((char**)parm_ptr);
346         } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
347                 TALLOC_FREE(*((char***)parm_ptr));
348         }
349 }
350
351 /**
352  * Free the allocated data for one parameter for a share
353  * given as a service struct.
354  */
355 static void free_one_parameter(struct loadparm_service *service,
356                                struct parm_struct parm)
357 {
358         void *parm_ptr;
359
360         if (parm.p_class != P_LOCAL) {
361                 return;
362         }
363
364         parm_ptr = lp_parm_ptr(service, &parm);
365
366         free_one_parameter_common(parm_ptr, parm);
367 }
368
369 /**
370  * Free the allocated parameter data of a share given
371  * as a service struct.
372  */
373 static void free_parameters(struct loadparm_service *service)
374 {
375         uint32_t i;
376
377         for (i=0; parm_table[i].label; i++) {
378                 free_one_parameter(service, parm_table[i]);
379         }
380 }
381
382 /**
383  * Free the allocated data for one parameter for a given share
384  * specified by an snum.
385  */
386 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
387 {
388         void *parm_ptr;
389
390         if (snum < 0) {
391                 parm_ptr = lp_parm_ptr(NULL, &parm);
392         } else if (parm.p_class != P_LOCAL) {
393                 return;
394         } else {
395                 parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
396         }
397
398         free_one_parameter_common(parm_ptr, parm);
399 }
400
401 /**
402  * Free the allocated parameter data for a share specified
403  * by an snum.
404  */
405 static void free_parameters_by_snum(int snum)
406 {
407         uint32_t i;
408
409         for (i=0; parm_table[i].label; i++) {
410                 free_one_parameter_by_snum(snum, parm_table[i]);
411         }
412 }
413
414 /**
415  * Free the allocated global parameters.
416  */
417 static void free_global_parameters(void)
418 {
419         uint32_t i;
420         struct parm_struct *parm;
421
422         free_param_opts(&Globals.param_opt);
423         free_parameters_by_snum(GLOBAL_SECTION_SNUM);
424
425         /* Reset references in the defaults because the context is going to be freed */
426         for (i=0; parm_table[i].label; i++) {
427                 parm = &parm_table[i];
428                 if ((parm->type == P_STRING) ||
429                     (parm->type == P_USTRING)) {
430                         if ((parm->def.svalue != NULL) &&
431                             (*(parm->def.svalue) != '\0')) {
432                                 if (talloc_parent(parm->def.svalue) == Globals.ctx) {
433                                         parm->def.svalue = NULL;
434                                 }
435                         }
436                 }
437         }
438         TALLOC_FREE(Globals.ctx);
439 }
440
441 struct lp_stored_option {
442         struct lp_stored_option *prev, *next;
443         const char *label;
444         const char *value;
445 };
446
447 static struct lp_stored_option *stored_options;
448
449 /*
450   save options set by lp_set_cmdline() into a list. This list is
451   re-applied when we do a globals reset, so that cmdline set options
452   are sticky across reloads of smb.conf
453  */
454 bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
455 {
456         struct lp_stored_option *entry, *entry_next;
457         for (entry = stored_options; entry != NULL; entry = entry_next) {
458                 entry_next = entry->next;
459                 if (strcmp(pszParmName, entry->label) == 0) {
460                         DLIST_REMOVE(stored_options, entry);
461                         talloc_free(entry);
462                         break;
463                 }
464         }
465
466         entry = talloc(NULL, struct lp_stored_option);
467         if (!entry) {
468                 return false;
469         }
470
471         entry->label = talloc_strdup(entry, pszParmName);
472         if (!entry->label) {
473                 talloc_free(entry);
474                 return false;
475         }
476
477         entry->value = talloc_strdup(entry, pszParmValue);
478         if (!entry->value) {
479                 talloc_free(entry);
480                 return false;
481         }
482
483         DLIST_ADD_END(stored_options, entry);
484
485         return true;
486 }
487
488 static bool apply_lp_set_cmdline(void)
489 {
490         struct lp_stored_option *entry = NULL;
491         for (entry = stored_options; entry != NULL; entry = entry->next) {
492                 if (!lp_set_cmdline_helper(entry->label, entry->value)) {
493                         DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
494                                   entry->label, entry->value));
495                         return false;
496                 }
497         }
498         return true;
499 }
500
501 /***************************************************************************
502  Initialise the global parameter structure.
503 ***************************************************************************/
504
505 static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
506 {
507         static bool done_init = false;
508         char *s = NULL;
509         int i;
510
511         /* If requested to initialize only once and we've already done it... */
512         if (!reinit_globals && done_init) {
513                 /* ... then we have nothing more to do */
514                 return;
515         }
516
517         if (!done_init) {
518                 /* The logfile can be set before this is invoked. Free it if so. */
519                 lpcfg_string_free(&Globals.logfile);
520                 done_init = true;
521         } else {
522                 free_global_parameters();
523         }
524
525         /* This memset and the free_global_parameters() above will
526          * wipe out smb.conf options set with lp_set_cmdline().  The
527          * apply_lp_set_cmdline() call puts these values back in the
528          * table once the defaults are set */
529         ZERO_STRUCT(Globals);
530
531         Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
532
533         /* Initialize the flags list if necessary */
534         if (flags_list == NULL) {
535                 get_flags();
536         }
537
538         for (i = 0; parm_table[i].label; i++) {
539                 if ((parm_table[i].type == P_STRING ||
540                      parm_table[i].type == P_USTRING))
541                 {
542                         lpcfg_string_set(
543                                 Globals.ctx,
544                                 (char **)lp_parm_ptr(NULL, &parm_table[i]),
545                                 "");
546                 }
547         }
548
549
550         lpcfg_string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
551         lpcfg_string_set(Globals.ctx, &sDefault.printjob_username, "%U");
552
553         init_printer_values(lp_ctx, Globals.ctx, &sDefault);
554
555         sDefault.ntvfs_handler = str_list_make_v3_const(Globals.ctx, "unixuid default", NULL);
556
557         DEBUG(3, ("Initialising global parameters\n"));
558
559         /* Must manually force to upper case here, as this does not go via the handler */
560         lpcfg_string_set(Globals.ctx, &Globals.netbios_name,
561                          myhostname_upper());
562
563         lpcfg_string_set(Globals.ctx, &Globals.smb_passwd_file,
564                          get_dyn_SMB_PASSWD_FILE());
565         lpcfg_string_set(Globals.ctx, &Globals.private_dir,
566                          get_dyn_PRIVATE_DIR());
567         lpcfg_string_set(Globals.ctx, &Globals.binddns_dir,
568                          get_dyn_BINDDNS_DIR());
569
570         /* use the new 'hash2' method by default, with a prefix of 1 */
571         lpcfg_string_set(Globals.ctx, &Globals.mangling_method, "hash2");
572         Globals.mangle_prefix = 1;
573
574         lpcfg_string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
575
576         /* using UTF8 by default allows us to support all chars */
577         lpcfg_string_set(Globals.ctx, &Globals.unix_charset,
578                          DEFAULT_UNIX_CHARSET);
579
580         /* Use codepage 850 as a default for the dos character set */
581         lpcfg_string_set(Globals.ctx, &Globals.dos_charset,
582                          DEFAULT_DOS_CHARSET);
583
584         /*
585          * Allow the default PASSWD_CHAT to be overridden in local.h.
586          */
587         lpcfg_string_set(Globals.ctx, &Globals.passwd_chat,
588                          DEFAULT_PASSWD_CHAT);
589
590         lpcfg_string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
591
592         lpcfg_string_set(Globals.ctx, &Globals.passwd_program, "");
593         lpcfg_string_set(Globals.ctx, &Globals.lock_directory,
594                          get_dyn_LOCKDIR());
595         lpcfg_string_set(Globals.ctx, &Globals.state_directory,
596                          get_dyn_STATEDIR());
597         lpcfg_string_set(Globals.ctx, &Globals.cache_directory,
598                          get_dyn_CACHEDIR());
599         lpcfg_string_set(Globals.ctx, &Globals.pid_directory,
600                          get_dyn_PIDDIR());
601         lpcfg_string_set(Globals.ctx, &Globals.nbt_client_socket_address,
602                          "0.0.0.0");
603         /*
604          * By default support explicit binding to broadcast
605          * addresses.
606          */
607         Globals.nmbd_bind_explicit_broadcast = true;
608
609         s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
610         if (s == NULL) {
611                 smb_panic("init_globals: ENOMEM");
612         }
613         lpcfg_string_set(Globals.ctx, &Globals.server_string, s);
614         TALLOC_FREE(s);
615 #ifdef DEVELOPER
616         lpcfg_string_set(Globals.ctx, &Globals.panic_action,
617                          "/bin/sleep 999999999");
618 #endif
619
620         lpcfg_string_set(Globals.ctx, &Globals.socket_options,
621                          DEFAULT_SOCKET_OPTIONS);
622
623         lpcfg_string_set(Globals.ctx, &Globals.logon_drive, "");
624         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
625         lpcfg_string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
626         lpcfg_string_set(Globals.ctx, &Globals.logon_path,
627                          "\\\\%N\\%U\\profile");
628
629         Globals.name_resolve_order =
630                         str_list_make_v3_const(Globals.ctx,
631                                                DEFAULT_NAME_RESOLVE_ORDER,
632                                                NULL);
633         lpcfg_string_set(Globals.ctx, &Globals.password_server, "*");
634
635         Globals.algorithmic_rid_base = BASE_RID;
636
637         Globals.load_printers = true;
638         Globals.printcap_cache_time = 750;      /* 12.5 minutes */
639
640         Globals.config_backend = config_backend;
641         Globals._server_role = ROLE_AUTO;
642
643         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
644         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
645         Globals.max_xmit = 0x4104;
646         Globals.max_mux = 50;   /* This is *needed* for profile support. */
647         Globals.lpq_cache_time = 30;    /* changed to handle large print servers better -- jerry */
648         Globals._disable_spoolss = false;
649         Globals.max_smbd_processes = 0;/* no limit specified */
650         Globals.username_level = 0;
651         Globals.deadtime = 10080;
652         Globals.getwd_cache = true;
653         Globals.large_readwrite = true;
654         Globals.max_log_size = 5000;
655         Globals.max_open_files = max_open_files();
656         Globals.server_max_protocol = PROTOCOL_SMB3_11;
657         Globals.server_min_protocol = PROTOCOL_SMB2_02;
658         Globals._client_max_protocol = PROTOCOL_DEFAULT;
659         Globals.client_min_protocol = PROTOCOL_SMB2_02;
660         Globals._client_ipc_max_protocol = PROTOCOL_DEFAULT;
661         Globals._client_ipc_min_protocol = PROTOCOL_DEFAULT;
662         Globals._security = SEC_AUTO;
663         Globals.encrypt_passwords = true;
664         Globals.client_schannel = true;
665         Globals.winbind_sealed_pipes = true;
666         Globals.require_strong_key = true;
667         Globals.reject_md5_servers = true;
668         Globals.server_schannel = true;
669         Globals.server_schannel_require_seal = true;
670         Globals.reject_md5_clients = true;
671         Globals.read_raw = true;
672         Globals.write_raw = true;
673         Globals.null_passwords = false;
674         Globals.old_password_allowed_period = 60;
675         Globals.obey_pam_restrictions = false;
676         Globals.syslog = 1;
677         Globals.syslog_only = false;
678         Globals.timestamp_logs = true;
679         lpcfg_string_set(Globals.ctx, &Globals.log_level, "0");
680         Globals.debug_prefix_timestamp = false;
681         Globals.debug_hires_timestamp = true;
682         Globals.debug_pid = false;
683         Globals.debug_uid = false;
684         Globals.debug_class = false;
685         Globals.enable_core_files = true;
686         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
687         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
688         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
689         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
690         Globals.lm_announce = Auto;     /* = Auto: send only if LM clients found */
691         Globals.lm_interval = 60;
692         Globals.time_server = false;
693         Globals.bind_interfaces_only = false;
694         Globals.unix_password_sync = false;
695         Globals.pam_password_change = false;
696         Globals.passwd_chat_debug = false;
697         Globals.passwd_chat_timeout = 2; /* 2 second default. */
698         Globals.nt_pipe_support = true; /* Do NT pipes by default. */
699         Globals.nt_status_support = true; /* Use NT status by default. */
700         Globals.smbd_profiling_level = 0;
701         Globals.stat_cache = true;      /* use stat cache by default */
702         Globals.max_stat_cache_size = 512; /* 512k by default */
703         Globals.restrict_anonymous = 0;
704         Globals.client_lanman_auth = false;     /* Do NOT use the LanMan hash if it is available */
705         Globals.client_plaintext_auth = false;  /* Do NOT use a plaintext password even if is requested by the server */
706         Globals._lanman_auth = false;   /* Do NOT use the LanMan hash, even if it is supplied */
707         Globals.ntlm_auth = NTLM_AUTH_NTLMV2_ONLY;      /* Do NOT use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
708         Globals.raw_ntlmv2_auth = false; /* Reject NTLMv2 without NTLMSSP */
709         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 */
710         /* Note, that we will also use NTLM2 session security (which is different), if it is available */
711
712         Globals.allow_dcerpc_auth_level_connect = false; /* we don't allow this by default */
713
714         Globals.map_to_guest = 0;       /* By Default, "Never" */
715         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
716         Globals.enhanced_browsing = true;
717         Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
718         Globals.use_mmap = true;
719         Globals.unicode = true;
720         Globals.unix_extensions = true;
721         Globals.reset_on_zero_vc = false;
722         Globals.log_writeable_files_on_exit = false;
723         Globals.create_krb5_conf = true;
724         Globals.include_system_krb5_conf = true;
725         Globals._winbind_max_domain_connections = 1;
726
727         /* hostname lookups can be very expensive and are broken on
728            a large number of sites (tridge) */
729         Globals.hostname_lookups = false;
730
731         Globals.change_notify = true,
732         Globals.kernel_change_notify = true,
733
734         lpcfg_string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
735         lpcfg_string_set(Globals.ctx, &Globals.ldap_suffix, "");
736         lpcfg_string_set(Globals.ctx, &Globals._ldap_machine_suffix, "");
737         lpcfg_string_set(Globals.ctx, &Globals._ldap_user_suffix, "");
738         lpcfg_string_set(Globals.ctx, &Globals._ldap_group_suffix, "");
739         lpcfg_string_set(Globals.ctx, &Globals._ldap_idmap_suffix, "");
740
741         lpcfg_string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
742         Globals.ldap_ssl = LDAP_SSL_START_TLS;
743         Globals.ldap_deref = -1;
744         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
745         Globals.ldap_delete_dn = false;
746         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
747         Globals.ldap_follow_referral = Auto;
748         Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
749         Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
750         Globals.ldap_page_size = LDAP_PAGE_SIZE;
751
752         Globals.ldap_debug_level = 0;
753         Globals.ldap_debug_threshold = 10;
754
755         Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
756
757         Globals.ldap_server_require_strong_auth =
758                 LDAP_SERVER_REQUIRE_STRONG_AUTH_YES;
759
760         /* This is what we tell the afs client. in reality we set the token 
761          * to never expire, though, when this runs out the afs client will 
762          * forget the token. Set to 0 to get NEVERDATE.*/
763         Globals.afs_token_lifetime = 604800;
764         Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
765
766 /* these parameters are set to defaults that are more appropriate
767    for the increasing samba install base:
768
769    as a member of the workgroup, that will possibly become a
770    _local_ master browser (lm = true).  this is opposed to a forced
771    local master browser startup (pm = true).
772
773    doesn't provide WINS server service by default (wsupp = false),
774    and doesn't provide domain master browser services by default, either.
775
776 */
777
778         Globals.show_add_printer_wizard = true;
779         Globals.os_level = 20;
780         Globals.local_master = true;
781         Globals._domain_master = Auto;  /* depending on _domain_logons */
782         Globals._domain_logons = false;
783         Globals.browse_list = true;
784         Globals.we_are_a_wins_server = false;
785         Globals.wins_proxy = false;
786
787         TALLOC_FREE(Globals.init_logon_delayed_hosts);
788         Globals.init_logon_delay = 100; /* 100 ms default delay */
789
790         Globals.wins_dns_proxy = true;
791
792         Globals.allow_trusted_domains = true;
793         lpcfg_string_set(Globals.ctx, &Globals.idmap_backend, "tdb");
794
795         lpcfg_string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
796         lpcfg_string_set(Globals.ctx, &Globals.template_homedir,
797                          "/home/%D/%U");
798         lpcfg_string_set(Globals.ctx, &Globals.winbind_separator, "\\");
799         lpcfg_string_set(Globals.ctx, &Globals.winbindd_socket_directory,
800                          dyn_WINBINDD_SOCKET_DIR);
801
802         lpcfg_string_set(Globals.ctx, &Globals.cups_server, "");
803         lpcfg_string_set(Globals.ctx, &Globals.iprint_server, "");
804
805         lpcfg_string_set(Globals.ctx, &Globals._ctdbd_socket, "");
806
807         Globals.cluster_addresses = NULL;
808         Globals.clustering = false;
809         Globals.ctdb_timeout = 0;
810         Globals.ctdb_locktime_warn_threshold = 0;
811
812         Globals.winbind_cache_time = 300;       /* 5 minutes */
813         Globals.winbind_reconnect_delay = 30;   /* 30 seconds */
814         Globals.winbind_request_timeout = 60;   /* 60 seconds */
815         Globals.winbind_max_clients = 200;
816         Globals.winbind_enum_users = false;
817         Globals.winbind_enum_groups = false;
818         Globals.winbind_use_default_domain = false;
819         Globals.winbind_nested_groups = true;
820         Globals.winbind_expand_groups = 0;
821         Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
822         Globals.winbind_refresh_tickets = false;
823         Globals.winbind_offline_logon = false;
824         Globals.winbind_scan_trusted_domains = false;
825
826         Globals.idmap_cache_time = 86400 * 7; /* a week by default */
827         Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
828
829         Globals.passdb_expand_explicit = false;
830
831         Globals.name_cache_timeout = 660; /* In seconds */
832
833         Globals.client_use_spnego = true;
834
835         Globals.client_signing = SMB_SIGNING_DEFAULT;
836         Globals._client_ipc_signing = SMB_SIGNING_DEFAULT;
837         Globals.server_signing = SMB_SIGNING_DEFAULT;
838
839         Globals.defer_sharing_violations = true;
840         Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL);
841
842         Globals.enable_privileges = true;
843         Globals.host_msdfs        = true;
844         Globals.enable_asu_support       = false;
845
846         /* User defined shares. */
847         s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
848         if (s == NULL) {
849                 smb_panic("init_globals: ENOMEM");
850         }
851         lpcfg_string_set(Globals.ctx, &Globals.usershare_path, s);
852         TALLOC_FREE(s);
853         lpcfg_string_set(Globals.ctx, &Globals.usershare_template_share, "");
854         Globals.usershare_max_shares = 0;
855         /* By default disallow sharing of directories not owned by the sharer. */
856         Globals.usershare_owner_only = true;
857         /* By default disallow guest access to usershares. */
858         Globals.usershare_allow_guests = false;
859
860         Globals.keepalive = DEFAULT_KEEPALIVE;
861
862         /* By default no shares out of the registry */
863         Globals.registry_shares = false;
864
865         Globals.min_receivefile_size = 0;
866
867         Globals.multicast_dns_register = true;
868
869         Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
870         Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
871         Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
872         Globals.smb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
873         Globals.smb2_leases = true;
874         Globals.server_multi_channel_support = true;
875
876         lpcfg_string_set(Globals.ctx, &Globals.ncalrpc_dir,
877                          get_dyn_NCALRPCDIR());
878
879         Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
880
881         Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
882
883         Globals.tls_enabled = true;
884         Globals.tls_verify_peer = TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE;
885
886         lpcfg_string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
887         lpcfg_string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
888         lpcfg_string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
889         lpcfg_string_set(Globals.ctx,
890                          &Globals.tls_priority,
891                          "NORMAL:-VERS-SSL3.0");
892
893         Globals._preferred_master = Auto;
894
895         Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
896         Globals.dns_zone_scavenging = false;
897
898         lpcfg_string_set(Globals.ctx, &Globals.ntp_signd_socket_directory,
899                          get_dyn_NTP_SIGND_SOCKET_DIR());
900
901         s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
902         if (s == NULL) {
903                 smb_panic("init_globals: ENOMEM");
904         }
905         Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
906         TALLOC_FREE(s);
907
908 #ifdef MIT_KDC_PATH
909         Globals.mit_kdc_command = str_list_make_v3_const(NULL, MIT_KDC_PATH, NULL);
910 #endif
911
912         s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
913         if (s == NULL) {
914                 smb_panic("init_globals: ENOMEM");
915         }
916         Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
917         TALLOC_FREE(s);
918
919         s = talloc_asprintf(talloc_tos(), "%s/samba-gpupdate", get_dyn_SCRIPTSBINDIR());
920         if (s == NULL) {
921                 smb_panic("init_globals: ENOMEM");
922         }
923         Globals.gpo_update_command = str_list_make_v3_const(NULL, s, NULL);
924         TALLOC_FREE(s);
925
926         Globals.apply_group_policies = false;
927
928         s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
929         if (s == NULL) {
930                 smb_panic("init_globals: ENOMEM");
931         }
932         Globals.spn_update_command = str_list_make_v3_const(NULL, s, NULL);
933         TALLOC_FREE(s);
934
935         Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
936
937         Globals.cldap_port = 389;
938
939         Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
940
941         Globals.nbt_port = NBT_NAME_SERVICE_PORT;
942
943         Globals.krb5_port = 88;
944
945         Globals.kpasswd_port = 464;
946
947         Globals.aio_max_threads = 100;
948
949         lpcfg_string_set(Globals.ctx,
950                          &Globals.rpc_server_dynamic_port_range,
951                          "49152-65535");
952         Globals.rpc_low_port = SERVER_TCP_LOW_PORT;
953         Globals.rpc_high_port = SERVER_TCP_HIGH_PORT;
954         Globals.prefork_children = 4;
955         Globals.prefork_backoff_increment = 10;
956         Globals.prefork_maximum_backoff = 120;
957
958         Globals.ldap_max_anonymous_request_size = 256000;
959         Globals.ldap_max_authenticated_request_size = 16777216;
960         Globals.ldap_max_search_request_size = 256000;
961
962         /* Async DNS query timeout (in seconds). */
963         Globals.async_dns_timeout = 10;
964
965         Globals.client_smb_encrypt = SMB_ENCRYPTION_DEFAULT;
966
967         Globals._client_use_kerberos = CRED_USE_KERBEROS_DESIRED;
968
969         Globals.client_protection = CRED_CLIENT_PROTECTION_DEFAULT;
970
971         Globals.winbind_use_krb5_enterprise_principals = true;
972
973         Globals.client_smb3_signing_algorithms =
974                 str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
975         Globals.server_smb3_signing_algorithms =
976                 str_list_make_v3_const(NULL, DEFAULT_SMB3_SIGNING_ALGORITHMS, NULL);
977
978         Globals.client_smb3_encryption_algorithms =
979                 str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
980         Globals.server_smb3_encryption_algorithms =
981                 str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL);
982
983         Globals.min_domain_uid = 1000;
984
985         /* Now put back the settings that were set with lp_set_cmdline() */
986         apply_lp_set_cmdline();
987 }
988
989 /* Convenience routine to setup an lp_context with additional s3 variables */
990 static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
991 {
992         struct loadparm_context *lp_ctx;
993
994         lp_ctx = loadparm_init_s3(mem_ctx,
995                                   loadparm_s3_helpers());
996         if (lp_ctx == NULL) {
997                 DEBUG(0, ("loadparm_init_s3 failed\n"));
998                 return NULL;
999         }
1000
1001         lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
1002         if (lp_ctx->sDefault == NULL) {
1003                 DBG_ERR("talloc_zero failed\n");
1004                 TALLOC_FREE(lp_ctx);
1005                 return NULL;
1006         }
1007
1008         *lp_ctx->sDefault = _sDefault;
1009         lp_ctx->services = NULL; /* We do not want to access this directly */
1010         lp_ctx->bInGlobalSection = bInGlobalSection;
1011         lp_ctx->flags = flags_list;
1012
1013         return lp_ctx;
1014 }
1015
1016 /*******************************************************************
1017  Convenience routine to grab string parameters into talloced memory
1018  and run standard_sub_basic on them. The buffers can be written to by
1019  callers without affecting the source string.
1020 ********************************************************************/
1021
1022 static char *loadparm_s3_global_substitution_fn(
1023                         TALLOC_CTX *mem_ctx,
1024                         const struct loadparm_substitution *lp_sub,
1025                         const char *s,
1026                         void *private_data)
1027 {
1028         char *ret;
1029
1030         /* The follow debug is useful for tracking down memory problems
1031            especially if you have an inner loop that is calling a lp_*()
1032            function that returns a string.  Perhaps this debug should be
1033            present all the time? */
1034
1035 #if 0
1036         DEBUG(10, ("lp_string(%s)\n", s));
1037 #endif
1038         if (!s) {
1039                 return NULL;
1040         }
1041
1042         ret = talloc_sub_basic(mem_ctx,
1043                         get_current_username(),
1044                         current_user_info.domain,
1045                         s);
1046         if (trim_char(ret, '\"', '\"')) {
1047                 if (strchr(ret,'\"') != NULL) {
1048                         TALLOC_FREE(ret);
1049                         ret = talloc_sub_basic(mem_ctx,
1050                                         get_current_username(),
1051                                         current_user_info.domain,
1052                                         s);
1053                 }
1054         }
1055         return ret;
1056 }
1057
1058 static const struct loadparm_substitution s3_global_substitution = {
1059         .substituted_string_fn = loadparm_s3_global_substitution_fn,
1060 };
1061
1062 const struct loadparm_substitution *loadparm_s3_global_substitution(void)
1063 {
1064         return &s3_global_substitution;
1065 }
1066
1067 /*
1068    In this section all the functions that are used to access the
1069    parameters from the rest of the program are defined
1070 */
1071
1072 #define FN_GLOBAL_SUBSTITUTED_STRING(fn_name,ptr) \
1073 char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub) \
1074  {return lpcfg_substituted_string(ctx, lp_sub, *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : "");}
1075 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1076  const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1077 #define FN_GLOBAL_LIST(fn_name,ptr) \
1078  const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1079 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1080  bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1081 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1082  char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1083 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1084  int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1085
1086 #define FN_LOCAL_SUBSTITUTED_STRING(fn_name,val) \
1087 char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub, int i) \
1088  {return lpcfg_substituted_string((ctx), lp_sub, (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1089 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1090  const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1091 #define FN_LOCAL_LIST(fn_name,val) \
1092  const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1093 #define FN_LOCAL_BOOL(fn_name,val) \
1094  bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1095 #define FN_LOCAL_INTEGER(fn_name,val) \
1096  int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1097
1098 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1099  bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1100 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1101  int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1102 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1103  char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1104
1105 int lp_winbind_max_domain_connections(void)
1106 {
1107         if (lp_winbind_offline_logon() &&
1108             lp__winbind_max_domain_connections() > 1) {
1109                 DEBUG(1, ("offline logons active, restricting max domain "
1110                           "connections to 1\n"));
1111                 return 1;
1112         }
1113         return MAX(1, lp__winbind_max_domain_connections());
1114 }
1115
1116 /* These functions remain in source3/param for now */
1117
1118 #include "lib/param/param_functions.c"
1119
1120 FN_LOCAL_SUBSTITUTED_STRING(servicename, szService)
1121 FN_LOCAL_CONST_STRING(const_servicename, szService)
1122
1123 /* These functions cannot be auto-generated */
1124 FN_LOCAL_BOOL(autoloaded, autoloaded)
1125 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1126
1127 /* local prototypes */
1128
1129 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1130 static const char *get_boolean(bool bool_value);
1131 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1132                          void *userdata);
1133 static bool hash_a_service(const char *name, int number);
1134 static void free_service_byindex(int iService);
1135 static void show_parameter(int parmIndex);
1136 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1137 static bool lp_parameter_value_is_valid(const char *parm_name, const char *val);
1138
1139 /*
1140  * This is a helper function for parametrical options support.  It returns a
1141  * pointer to parametrical option value if it exists or NULL otherwise. Actual
1142  * parametrical functions are quite simple
1143  */
1144 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1145                                                 const char *option)
1146 {
1147         if (snum >= iNumServices) return NULL;
1148
1149         if (snum < 0) {
1150                 return get_parametric_helper(NULL, type, option, Globals.param_opt);
1151         } else {
1152                 return get_parametric_helper(ServicePtrs[snum],
1153                                              type, option, Globals.param_opt);
1154         }
1155 }
1156
1157 static void discard_whitespace(char *str)
1158 {
1159         size_t len = strlen(str);
1160         size_t i = 0;
1161
1162         while (i < len) {
1163                 if (isspace(str[i])) {
1164                         memmove(&str[i], &str[i+1], len-i);
1165                         len -= 1;
1166                         continue;
1167                 }
1168                 i += 1;
1169         }
1170 }
1171
1172 /**
1173  * @brief Go through all global parametric parameters
1174  *
1175  * @param regex_str     A regular expression to scan param for
1176  * @param max_matches   Max number of submatches the regexp expects
1177  * @param cb            Function to call on match. Should return true
1178  *                      when it wants wi_scan_global_parametrics to stop
1179  *                      scanning
1180  * @param private_data  Anonymous pointer passed to cb
1181  *
1182  * @return              0: success, regcomp/regexec return value on error.
1183  *                      See "man regexec" for possible errors
1184  */
1185
1186 int lp_wi_scan_global_parametrics(
1187         const char *regex_str, size_t max_matches,
1188         bool (*cb)(const char *string, regmatch_t matches[],
1189                    void *private_data),
1190         void *private_data)
1191 {
1192         struct parmlist_entry *data;
1193         regex_t regex;
1194         int ret;
1195
1196         ret = regcomp(&regex, regex_str, REG_ICASE);
1197         if (ret != 0) {
1198                 return ret;
1199         }
1200
1201         for (data = Globals.param_opt; data != NULL; data = data->next) {
1202                 size_t keylen = strlen(data->key);
1203                 char key[keylen+1];
1204                 regmatch_t matches[max_matches];
1205                 bool stop;
1206
1207                 memcpy(key, data->key, sizeof(key));
1208                 discard_whitespace(key);
1209
1210                 ret = regexec(&regex, key, max_matches, matches, 0);
1211                 if (ret == REG_NOMATCH) {
1212                         continue;
1213                 }
1214                 if (ret != 0) {
1215                         goto fail;
1216                 }
1217
1218                 stop = cb(key, matches, private_data);
1219                 if (stop) {
1220                         break;
1221                 }
1222         }
1223
1224         ret = 0;
1225 fail:
1226         regfree(&regex);
1227         return ret;
1228 }
1229
1230
1231 #define MISSING_PARAMETER(name) \
1232     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1233
1234 /*******************************************************************
1235 convenience routine to return enum parameters.
1236 ********************************************************************/
1237 static int lp_enum(const char *s,const struct enum_list *_enum)
1238 {
1239         int i;
1240
1241         if (!s || !*s || !_enum) {
1242                 MISSING_PARAMETER(lp_enum);
1243                 return (-1);
1244         }
1245
1246         for (i=0; _enum[i].name; i++) {
1247                 if (strequal(_enum[i].name,s))
1248                         return _enum[i].value;
1249         }
1250
1251         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1252         return (-1);
1253 }
1254
1255 #undef MISSING_PARAMETER
1256
1257 /* Return parametric option from a given service. Type is a part of option before ':' */
1258 /* Parametric option has following syntax: 'Type: option = value' */
1259 char *lp_parm_substituted_string(TALLOC_CTX *mem_ctx,
1260                                  const struct loadparm_substitution *lp_sub,
1261                                  int snum,
1262                                  const char *type,
1263                                  const char *option,
1264                                  const char *def)
1265 {
1266         struct parmlist_entry *data = get_parametrics(snum, type, option);
1267
1268         SMB_ASSERT(lp_sub != NULL);
1269
1270         if (data == NULL||data->value==NULL) {
1271                 if (def) {
1272                         return lpcfg_substituted_string(mem_ctx, lp_sub, def);
1273                 } else {
1274                         return NULL;
1275                 }
1276         }
1277
1278         return lpcfg_substituted_string(mem_ctx, lp_sub, data->value);
1279 }
1280
1281 /* Return parametric option from a given service. Type is a part of option before ':' */
1282 /* Parametric option has following syntax: 'Type: option = value' */
1283 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1284 {
1285         struct parmlist_entry *data = get_parametrics(snum, type, option);
1286
1287         if (data == NULL||data->value==NULL)
1288                 return def;
1289
1290         return data->value;
1291 }
1292
1293
1294 /* Return parametric option from a given service. Type is a part of option before ':' */
1295 /* Parametric option has following syntax: 'Type: option = value' */
1296
1297 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1298 {
1299         struct parmlist_entry *data = get_parametrics(snum, type, option);
1300
1301         if (data == NULL||data->value==NULL)
1302                 return (const char **)def;
1303
1304         if (data->list==NULL) {
1305                 data->list = str_list_make_v3(NULL, data->value, NULL);
1306         }
1307
1308         return discard_const_p(const char *, data->list);
1309 }
1310
1311 /* Return parametric option from a given service. Type is a part of option before ':' */
1312 /* Parametric option has following syntax: 'Type: option = value' */
1313
1314 int lp_parm_int(int snum, const char *type, const char *option, int def)
1315 {
1316         struct parmlist_entry *data = get_parametrics(snum, type, option);
1317
1318         if (data && data->value && *data->value)
1319                 return lp_int(data->value);
1320
1321         return def;
1322 }
1323
1324 /* Return parametric option from a given service. Type is a part of option before ':' */
1325 /* Parametric option has following syntax: 'Type: option = value' */
1326
1327 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1328 {
1329         struct parmlist_entry *data = get_parametrics(snum, type, option);
1330
1331         if (data && data->value && *data->value)
1332                 return lp_ulong(data->value);
1333
1334         return def;
1335 }
1336
1337 /* Return parametric option from a given service. Type is a part of option before ':' */
1338 /* Parametric option has following syntax: 'Type: option = value' */
1339
1340 unsigned long long lp_parm_ulonglong(int snum, const char *type,
1341                                      const char *option, unsigned long long def)
1342 {
1343         struct parmlist_entry *data = get_parametrics(snum, type, option);
1344
1345         if (data && data->value && *data->value) {
1346                 return lp_ulonglong(data->value);
1347         }
1348
1349         return def;
1350 }
1351
1352 /* Return parametric option from a given service. Type is a part of option
1353  * before ':' */
1354 /* Parametric option has following syntax: 'Type: option = value' */
1355
1356 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1357 {
1358         struct parmlist_entry *data = get_parametrics(snum, type, option);
1359
1360         if (data && data->value && *data->value)
1361                 return lp_bool(data->value);
1362
1363         return def;
1364 }
1365
1366 /* Return parametric option from a given service. Type is a part of option before ':' */
1367 /* Parametric option has following syntax: 'Type: option = value' */
1368
1369 int lp_parm_enum(int snum, const char *type, const char *option,
1370                  const struct enum_list *_enum, int def)
1371 {
1372         struct parmlist_entry *data = get_parametrics(snum, type, option);
1373
1374         if (data && data->value && *data->value && _enum)
1375                 return lp_enum(data->value, _enum);
1376
1377         return def;
1378 }
1379
1380 /**
1381  * free a param_opts structure.
1382  * param_opts handling should be moved to talloc;
1383  * then this whole functions reduces to a TALLOC_FREE().
1384  */
1385
1386 static void free_param_opts(struct parmlist_entry **popts)
1387 {
1388         struct parmlist_entry *opt, *next_opt;
1389
1390         if (*popts != NULL) {
1391                 DEBUG(5, ("Freeing parametrics:\n"));
1392         }
1393         opt = *popts;
1394         while (opt != NULL) {
1395                 lpcfg_string_free(&opt->key);
1396                 lpcfg_string_free(&opt->value);
1397                 TALLOC_FREE(opt->list);
1398                 next_opt = opt->next;
1399                 TALLOC_FREE(opt);
1400                 opt = next_opt;
1401         }
1402         *popts = NULL;
1403 }
1404
1405 /***************************************************************************
1406  Free the dynamically allocated parts of a service struct.
1407 ***************************************************************************/
1408
1409 static void free_service(struct loadparm_service *pservice)
1410 {
1411         if (!pservice)
1412                 return;
1413
1414         if (pservice->szService)
1415                 DEBUG(5, ("free_service: Freeing service %s\n",
1416                        pservice->szService));
1417
1418         free_parameters(pservice);
1419
1420         lpcfg_string_free(&pservice->szService);
1421         TALLOC_FREE(pservice->copymap);
1422
1423         free_param_opts(&pservice->param_opt);
1424
1425         ZERO_STRUCTP(pservice);
1426 }
1427
1428
1429 /***************************************************************************
1430  remove a service indexed in the ServicePtrs array from the ServiceHash
1431  and free the dynamically allocated parts
1432 ***************************************************************************/
1433
1434 static void free_service_byindex(int idx)
1435 {
1436         if ( !LP_SNUM_OK(idx) ) 
1437                 return;
1438
1439         ServicePtrs[idx]->valid = false;
1440
1441         /* we have to cleanup the hash record */
1442
1443         if (ServicePtrs[idx]->szService) {
1444                 char *canon_name = canonicalize_servicename(
1445                         talloc_tos(),
1446                         ServicePtrs[idx]->szService );
1447
1448                 dbwrap_delete_bystring(ServiceHash, canon_name );
1449                 TALLOC_FREE(canon_name);
1450         }
1451
1452         free_service(ServicePtrs[idx]);
1453         TALLOC_FREE(ServicePtrs[idx]);
1454 }
1455
1456 /***************************************************************************
1457  Add a new service to the services array initialising it with the given 
1458  service. 
1459 ***************************************************************************/
1460
1461 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1462 {
1463         int i;
1464         struct loadparm_service **tsp = NULL;
1465
1466         /* it might already exist */
1467         if (name) {
1468                 i = getservicebyname(name, NULL);
1469                 if (i >= 0) {
1470                         return (i);
1471                 }
1472         }
1473
1474         /* Re use empty slots if any before allocating new one.*/
1475         for (i=0; i < iNumServices; i++) {
1476                 if (ServicePtrs[i] == NULL) {
1477                         break;
1478                 }
1479         }
1480         if (i == iNumServices) {
1481                 /* if not, then create one */
1482                 tsp = talloc_realloc(NULL, ServicePtrs,
1483                                      struct loadparm_service *,
1484                                      iNumServices + 1);
1485                 if (tsp == NULL) {
1486                         DEBUG(0, ("add_a_service: failed to enlarge "
1487                                   "ServicePtrs!\n"));
1488                         return (-1);
1489                 }
1490                 ServicePtrs = tsp;
1491                 iNumServices++;
1492         }
1493         ServicePtrs[i] = talloc_zero(ServicePtrs, struct loadparm_service);
1494         if (!ServicePtrs[i]) {
1495                 DEBUG(0,("add_a_service: out of memory!\n"));
1496                 return (-1);
1497         }
1498
1499         ServicePtrs[i]->valid = true;
1500
1501         copy_service(ServicePtrs[i], pservice, NULL);
1502         if (name)
1503                 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->szService,
1504                                  name);
1505
1506         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
1507                 i, ServicePtrs[i]->szService));
1508
1509         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1510                 return (-1);
1511         }
1512
1513         return (i);
1514 }
1515
1516 /***************************************************************************
1517   Convert a string to uppercase and remove whitespaces.
1518 ***************************************************************************/
1519
1520 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1521 {
1522         char *result;
1523
1524         if ( !src ) {
1525                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1526                 return NULL;
1527         }
1528
1529         result = talloc_strdup(ctx, src);
1530         SMB_ASSERT(result != NULL);
1531
1532         if (!strlower_m(result)) {
1533                 TALLOC_FREE(result);
1534                 return NULL;
1535         }
1536         return result;
1537 }
1538
1539 /***************************************************************************
1540   Add a name/index pair for the services array to the hash table.
1541 ***************************************************************************/
1542
1543 static bool hash_a_service(const char *name, int idx)
1544 {
1545         char *canon_name;
1546
1547         if ( !ServiceHash ) {
1548                 DEBUG(10,("hash_a_service: creating servicehash\n"));
1549                 ServiceHash = db_open_rbt(NULL);
1550                 if ( !ServiceHash ) {
1551                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1552                         return false;
1553                 }
1554         }
1555
1556         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1557                 idx, name));
1558
1559         canon_name = canonicalize_servicename(talloc_tos(), name );
1560
1561         dbwrap_store_bystring(ServiceHash, canon_name,
1562                               make_tdb_data((uint8_t *)&idx, sizeof(idx)),
1563                               TDB_REPLACE);
1564
1565         TALLOC_FREE(canon_name);
1566
1567         return true;
1568 }
1569
1570 /***************************************************************************
1571  Add a new home service, with the specified home directory, defaults coming
1572  from service ifrom.
1573 ***************************************************************************/
1574
1575 bool lp_add_home(const char *pszHomename, int iDefaultService,
1576                  const char *user, const char *pszHomedir)
1577 {
1578         const struct loadparm_substitution *lp_sub =
1579                 loadparm_s3_global_substitution();
1580         int i;
1581         char *global_path;
1582
1583         if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1584                         pszHomedir[0] == '\0') {
1585                 return false;
1586         }
1587
1588         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1589
1590         if (i < 0)
1591                 return false;
1592
1593         global_path = lp_path(talloc_tos(), lp_sub, GLOBAL_SECTION_SNUM);
1594         if (!(*(ServicePtrs[iDefaultService]->path))
1595             || strequal(ServicePtrs[iDefaultService]->path, global_path)) {
1596                 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
1597                                  pszHomedir);
1598         }
1599         TALLOC_FREE(global_path);
1600
1601         if (!(*(ServicePtrs[i]->comment))) {
1602                 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1603                 if (comment == NULL) {
1604                         return false;
1605                 }
1606                 lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment,
1607                                  comment);
1608                 TALLOC_FREE(comment);
1609         }
1610
1611         /* set the browseable flag from the global default */
1612
1613         ServicePtrs[i]->browseable = sDefault.browseable;
1614         ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1615
1616         ServicePtrs[i]->autoloaded = true;
1617
1618         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
1619                user, ServicePtrs[i]->path ));
1620
1621         return true;
1622 }
1623
1624 /***************************************************************************
1625  Add a new service, based on an old one.
1626 ***************************************************************************/
1627
1628 int lp_add_service(const char *pszService, int iDefaultService)
1629 {
1630         if (iDefaultService < 0) {
1631                 return add_a_service(&sDefault, pszService);
1632         }
1633
1634         return (add_a_service(ServicePtrs[iDefaultService], pszService));
1635 }
1636
1637 /***************************************************************************
1638  Add the IPC service.
1639 ***************************************************************************/
1640
1641 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1642 {
1643         char *comment = NULL;
1644         int i = add_a_service(&sDefault, ipc_name);
1645
1646         if (i < 0)
1647                 return false;
1648
1649         comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1650                                   Globals.server_string);
1651         if (comment == NULL) {
1652                 return false;
1653         }
1654
1655         lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1656         lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1657         lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1658         ServicePtrs[i]->max_connections = 0;
1659         ServicePtrs[i]->available = true;
1660         ServicePtrs[i]->read_only = true;
1661         ServicePtrs[i]->guest_only = false;
1662         ServicePtrs[i]->administrative_share = true;
1663         ServicePtrs[i]->guest_ok = guest_ok;
1664         ServicePtrs[i]->printable = false;
1665         ServicePtrs[i]->browseable = sDefault.browseable;
1666         ServicePtrs[i]->autoloaded = false;
1667
1668         DEBUG(3, ("adding IPC service\n"));
1669
1670         TALLOC_FREE(comment);
1671         return true;
1672 }
1673
1674 /***************************************************************************
1675  Add a new printer service, with defaults coming from service iFrom.
1676 ***************************************************************************/
1677
1678 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1679 {
1680         const char *comment = "From Printcap";
1681         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1682
1683         if (i < 0)
1684                 return false;
1685
1686         /* note that we do NOT default the availability flag to true - */
1687         /* we take it from the default service passed. This allows all */
1688         /* dynamic printers to be disabled by disabling the [printers] */
1689         /* entry (if/when the 'available' keyword is implemented!).    */
1690
1691         /* the printer name is set to the service name. */
1692         lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->_printername,
1693                          pszPrintername);
1694         lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1695
1696         /* set the browseable flag from the gloabl default */
1697         ServicePtrs[i]->browseable = sDefault.browseable;
1698
1699         /* Printers cannot be read_only. */
1700         ServicePtrs[i]->read_only = false;
1701         /* No oplocks on printer services. */
1702         ServicePtrs[i]->oplocks = false;
1703         /* Printer services must be printable. */
1704         ServicePtrs[i]->printable = true;
1705
1706         DEBUG(3, ("adding printer service %s\n", pszPrintername));
1707
1708         return true;
1709 }
1710
1711
1712 /***************************************************************************
1713  Check whether the given parameter name is valid.
1714  Parametric options (names containing a colon) are considered valid.
1715 ***************************************************************************/
1716
1717 bool lp_parameter_is_valid(const char *pszParmName)
1718 {
1719         return ((lpcfg_map_parameter(pszParmName) != -1) ||
1720                 (strchr(pszParmName, ':') != NULL));
1721 }
1722
1723 /***************************************************************************
1724  Check whether the given name is the name of a global parameter.
1725  Returns true for strings belonging to parameters of class
1726  P_GLOBAL, false for all other strings, also for parametric options
1727  and strings not belonging to any option.
1728 ***************************************************************************/
1729
1730 bool lp_parameter_is_global(const char *pszParmName)
1731 {
1732         int num = lpcfg_map_parameter(pszParmName);
1733
1734         if (num >= 0) {
1735                 return (parm_table[num].p_class == P_GLOBAL);
1736         }
1737
1738         return false;
1739 }
1740
1741 /**************************************************************************
1742  Determine the canonical name for a parameter.
1743  Indicate when it is an inverse (boolean) synonym instead of a
1744  "usual" synonym.
1745 **************************************************************************/
1746
1747 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1748                                bool *inverse)
1749 {
1750         int num;
1751
1752         if (!lp_parameter_is_valid(parm_name)) {
1753                 *canon_parm = NULL;
1754                 return false;
1755         }
1756
1757         num = map_parameter_canonical(parm_name, inverse);
1758         if (num < 0) {
1759                 /* parametric option */
1760                 *canon_parm = parm_name;
1761         } else {
1762                 *canon_parm = parm_table[num].label;
1763         }
1764
1765         return true;
1766
1767 }
1768
1769 /**************************************************************************
1770  Determine the canonical name for a parameter.
1771  Turn the value given into the inverse boolean expression when
1772  the synonym is an invers boolean synonym.
1773
1774  Return true if
1775  - parm_name is a valid parameter name and
1776  - val is a valid value for this parameter and
1777  - in case the parameter is an inverse boolean synonym, if the val
1778    string could successfully be converted to the reverse bool.
1779  Return false in all other cases.
1780 **************************************************************************/
1781
1782 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1783                                           const char *val,
1784                                           const char **canon_parm,
1785                                           const char **canon_val)
1786 {
1787         int num;
1788         bool inverse;
1789         bool ret;
1790
1791         if (!lp_parameter_is_valid(parm_name)) {
1792                 *canon_parm = NULL;
1793                 *canon_val = NULL;
1794                 return false;
1795         }
1796
1797         num = map_parameter_canonical(parm_name, &inverse);
1798         if (num < 0) {
1799                 /* parametric option */
1800                 *canon_parm = parm_name;
1801                 *canon_val = val;
1802                 return true;
1803         }
1804
1805         *canon_parm = parm_table[num].label;
1806         if (inverse) {
1807                 if (!lp_invert_boolean(val, canon_val)) {
1808                         *canon_val = NULL;
1809                         return false;
1810                 }
1811         } else {
1812                 *canon_val = val;
1813         }
1814
1815         ret = lp_parameter_value_is_valid(*canon_parm, *canon_val);
1816
1817         return ret;
1818 }
1819
1820 /***************************************************************************
1821  Map a parameter's string representation to the index of the canonical
1822  form of the parameter (it might be a synonym).
1823  Returns -1 if the parameter string is not recognised.
1824 ***************************************************************************/
1825
1826 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1827 {
1828         int parm_num, canon_num;
1829         bool loc_inverse = false;
1830
1831         parm_num = lpcfg_map_parameter(pszParmName);
1832         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) {
1833                 /* invalid, parametric or no canidate for synonyms ... */
1834                 goto done;
1835         }
1836
1837         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1838                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1839                         parm_num = canon_num;
1840                         goto done;
1841                 }
1842         }
1843
1844 done:
1845         if (inverse != NULL) {
1846                 *inverse = loc_inverse;
1847         }
1848         return parm_num;
1849 }
1850
1851 /***************************************************************************
1852  return true if parameter number parm1 is a synonym of parameter
1853  number parm2 (parm2 being the principal name).
1854  set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1855  false otherwise.
1856 ***************************************************************************/
1857
1858 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1859 {
1860         if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1861             (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1862             (parm_table[parm1].flags & FLAG_SYNONYM) &&
1863             !(parm_table[parm2].flags & FLAG_SYNONYM))
1864         {
1865                 if (inverse != NULL) {
1866                         if ((parm_table[parm1].type == P_BOOLREV) &&
1867                             (parm_table[parm2].type == P_BOOL))
1868                         {
1869                                 *inverse = true;
1870                         } else {
1871                                 *inverse = false;
1872                         }
1873                 }
1874                 return true;
1875         }
1876         return false;
1877 }
1878
1879 /***************************************************************************
1880  Show one parameter's name, type, [values,] and flags.
1881  (helper functions for show_parameter_list)
1882 ***************************************************************************/
1883
1884 static void show_parameter(int parmIndex)
1885 {
1886         size_t enumIndex, flagIndex;
1887         size_t parmIndex2;
1888         bool hadFlag;
1889         bool hadSyn;
1890         bool inverse;
1891         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1892                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1893                 "P_ENUM", "P_BYTES", "P_CMDLIST" };
1894         unsigned flags[] = { FLAG_DEPRECATED, FLAG_SYNONYM };
1895         const char *flag_names[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL};
1896
1897         printf("%s=%s", parm_table[parmIndex].label,
1898                type[parm_table[parmIndex].type]);
1899         if (parm_table[parmIndex].type == P_ENUM) {
1900                 printf(",");
1901                 for (enumIndex=0;
1902                      parm_table[parmIndex].enum_list[enumIndex].name;
1903                      enumIndex++)
1904                 {
1905                         printf("%s%s",
1906                                enumIndex ? "|" : "",
1907                                parm_table[parmIndex].enum_list[enumIndex].name);
1908                 }
1909         }
1910         printf(",");
1911         hadFlag = false;
1912         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1913                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1914                         printf("%s%s",
1915                                 hadFlag ? "|" : "",
1916                                 flag_names[flagIndex]);
1917                         hadFlag = true;
1918                 }
1919         }
1920
1921         /* output synonyms */
1922         hadSyn = false;
1923         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1924                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1925                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1926                                parm_table[parmIndex2].label);
1927                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1928                         if (!hadSyn) {
1929                                 printf(" (synonyms: ");
1930                                 hadSyn = true;
1931                         } else {
1932                                 printf(", ");
1933                         }
1934                         printf("%s%s", parm_table[parmIndex2].label,
1935                                inverse ? "[i]" : "");
1936                 }
1937         }
1938         if (hadSyn) {
1939                 printf(")");
1940         }
1941
1942         printf("\n");
1943 }
1944
1945 /*
1946  * Check the value for a P_ENUM
1947  */
1948 static bool check_enum_parameter(struct parm_struct *parm, const char *value)
1949 {
1950         int i;
1951
1952         for (i = 0; parm->enum_list[i].name; i++) {
1953                 if (strwicmp(value, parm->enum_list[i].name) == 0) {
1954                         return true;
1955                 }
1956         }
1957         return false;
1958 }
1959
1960 /**************************************************************************
1961  Check whether the given value is valid for the given parameter name.
1962 **************************************************************************/
1963
1964 static bool lp_parameter_value_is_valid(const char *parm_name, const char *val)
1965 {
1966         bool ret = false, tmp_bool;
1967         int num = lpcfg_map_parameter(parm_name), tmp_int;
1968         uint64_t tmp_int64 = 0;
1969         struct parm_struct *parm;
1970
1971         /* parametric options (parameter names containing a colon) cannot
1972            be checked and are therefore considered valid. */
1973         if (strchr(parm_name, ':') != NULL) {
1974                 return true;
1975         }
1976
1977         if (num >= 0) {
1978                 parm = &parm_table[num];
1979                 switch (parm->type) {
1980                         case P_BOOL:
1981                         case P_BOOLREV:
1982                                 ret = set_boolean(val, &tmp_bool);
1983                                 break;
1984
1985                         case P_INTEGER:
1986                                 ret = (sscanf(val, "%d", &tmp_int) == 1);
1987                                 break;
1988
1989                         case P_OCTAL:
1990                                 ret = (sscanf(val, "%o", &tmp_int) == 1);
1991                                 break;
1992
1993                         case P_ENUM:
1994                                 ret = check_enum_parameter(parm, val);
1995                                 break;
1996
1997                         case P_BYTES:
1998                                 if (conv_str_size_error(val, &tmp_int64) &&
1999                                     tmp_int64 <= INT_MAX) {
2000                                         ret = true;
2001                                 }
2002                                 break;
2003
2004                         case P_CHAR:
2005                         case P_LIST:
2006                         case P_STRING:
2007                         case P_USTRING:
2008                         case P_CMDLIST:
2009                                 ret = true;
2010                                 break;
2011                 }
2012         }
2013         return ret;
2014 }
2015
2016 /***************************************************************************
2017  Show all parameter's name, type, [values,] and flags.
2018 ***************************************************************************/
2019
2020 void show_parameter_list(void)
2021 {
2022         int classIndex, parmIndex;
2023         const char *section_names[] = { "local", "global", NULL};
2024
2025         for (classIndex=0; section_names[classIndex]; classIndex++) {
2026                 printf("[%s]\n", section_names[classIndex]);
2027                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2028                         if (parm_table[parmIndex].p_class == classIndex) {
2029                                 show_parameter(parmIndex);
2030                         }
2031                 }
2032         }
2033 }
2034
2035 /***************************************************************************
2036  Get the standard string representation of a boolean value ("yes" or "no")
2037 ***************************************************************************/
2038
2039 static const char *get_boolean(bool bool_value)
2040 {
2041         static const char *yes_str = "yes";
2042         static const char *no_str = "no";
2043
2044         return (bool_value ? yes_str : no_str);
2045 }
2046
2047 /***************************************************************************
2048  Provide the string of the negated boolean value associated to the boolean
2049  given as a string. Returns false if the passed string does not correctly
2050  represent a boolean.
2051 ***************************************************************************/
2052
2053 bool lp_invert_boolean(const char *str, const char **inverse_str)
2054 {
2055         bool val;
2056
2057         if (!set_boolean(str, &val)) {
2058                 return false;
2059         }
2060
2061         *inverse_str = get_boolean(!val);
2062         return true;
2063 }
2064
2065 /***************************************************************************
2066  Provide the canonical string representation of a boolean value given
2067  as a string. Return true on success, false if the string given does
2068  not correctly represent a boolean.
2069 ***************************************************************************/
2070
2071 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2072 {
2073         bool val;
2074
2075         if (!set_boolean(str, &val)) {
2076                 return false;
2077         }
2078
2079         *canon_str = get_boolean(val);
2080         return true;
2081 }
2082
2083 /***************************************************************************
2084 Find a service by name. Otherwise works like get_service.
2085 ***************************************************************************/
2086
2087 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2088 {
2089         int iService = -1;
2090         char *canon_name;
2091         TDB_DATA data;
2092         NTSTATUS status;
2093
2094         if (ServiceHash == NULL) {
2095                 return -1;
2096         }
2097
2098         canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2099
2100         status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2101                                        &data);
2102
2103         if (NT_STATUS_IS_OK(status) &&
2104             (data.dptr != NULL) &&
2105             (data.dsize == sizeof(iService)))
2106         {
2107                 memcpy(&iService, data.dptr, sizeof(iService));
2108         }
2109
2110         TALLOC_FREE(canon_name);
2111
2112         if ((iService != -1) && (LP_SNUM_OK(iService))
2113             && (pserviceDest != NULL)) {
2114                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2115         }
2116
2117         return (iService);
2118 }
2119
2120 /* Return a pointer to a service by name.  Unlike getservicebyname, it does not copy the service */
2121 struct loadparm_service *lp_service(const char *pszServiceName)
2122 {
2123         int iService = getservicebyname(pszServiceName, NULL);
2124         if (iService == -1 || !LP_SNUM_OK(iService)) {
2125                 return NULL;
2126         }
2127         return ServicePtrs[iService];
2128 }
2129
2130 struct loadparm_service *lp_servicebynum(int snum)
2131 {
2132         if ((snum == -1) || !LP_SNUM_OK(snum)) {
2133                 return NULL;
2134         }
2135         return ServicePtrs[snum];
2136 }
2137
2138 struct loadparm_service *lp_default_loadparm_service()
2139 {
2140         return &sDefault;
2141 }
2142
2143 static struct smbconf_ctx *lp_smbconf_ctx(void)
2144 {
2145         sbcErr err;
2146         static struct smbconf_ctx *conf_ctx = NULL;
2147
2148         if (conf_ctx == NULL) {
2149                 err = smbconf_init(NULL, &conf_ctx, "registry:");
2150                 if (!SBC_ERROR_IS_OK(err)) {
2151                         DEBUG(1, ("error initializing registry configuration: "
2152                                   "%s\n", sbcErrorString(err)));
2153                         conf_ctx = NULL;
2154                 }
2155         }
2156
2157         return conf_ctx;
2158 }
2159
2160 static bool process_smbconf_service(struct smbconf_service *service)
2161 {
2162         uint32_t count;
2163         bool ret;
2164
2165         if (service == NULL) {
2166                 return false;
2167         }
2168
2169         ret = lp_do_section(service->name, NULL);
2170         if (ret != true) {
2171                 return false;
2172         }
2173         for (count = 0; count < service->num_params; count++) {
2174
2175                 if (!bInGlobalSection && bGlobalOnly) {
2176                         ret = true;
2177                 } else {
2178                         const char *pszParmName = service->param_names[count];
2179                         const char *pszParmValue = service->param_values[count];
2180
2181                         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2182
2183                         ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2184                                               pszParmName, pszParmValue);
2185                 }
2186
2187                 if (ret != true) {
2188                         return false;
2189                 }
2190         }
2191         if (iServiceIndex >= 0) {
2192                 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2193         }
2194         return true;
2195 }
2196
2197 /**
2198  * load a service from registry and activate it
2199  */
2200 bool process_registry_service(const char *service_name)
2201 {
2202         sbcErr err;
2203         struct smbconf_service *service = NULL;
2204         TALLOC_CTX *mem_ctx = talloc_stackframe();
2205         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2206         bool ret = false;
2207
2208         if (conf_ctx == NULL) {
2209                 goto done;
2210         }
2211
2212         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2213
2214         if (!smbconf_share_exists(conf_ctx, service_name)) {
2215                 /*
2216                  * Registry does not contain data for this service (yet),
2217                  * but make sure lp_load doesn't return false.
2218                  */
2219                 ret = true;
2220                 goto done;
2221         }
2222
2223         err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2224         if (!SBC_ERROR_IS_OK(err)) {
2225                 goto done;
2226         }
2227
2228         ret = process_smbconf_service(service);
2229         if (!ret) {
2230                 goto done;
2231         }
2232
2233         /* store the csn */
2234         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2235
2236 done:
2237         TALLOC_FREE(mem_ctx);
2238         return ret;
2239 }
2240
2241 /*
2242  * process_registry_globals
2243  */
2244 static bool process_registry_globals(void)
2245 {
2246         bool ret;
2247
2248         add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2249
2250         if (!bInGlobalSection && bGlobalOnly) {
2251                 ret = true;
2252         } else {
2253                 const char *pszParmName = "registry shares";
2254                 const char *pszParmValue = "yes";
2255
2256                 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2257
2258                 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2259                                       pszParmName, pszParmValue);
2260         }
2261
2262         if (!ret) {
2263                 return ret;
2264         }
2265
2266         return process_registry_service(GLOBAL_NAME);
2267 }
2268
2269 bool process_registry_shares(void)
2270 {
2271         sbcErr err;
2272         uint32_t count;
2273         struct smbconf_service **service = NULL;
2274         uint32_t num_shares = 0;
2275         TALLOC_CTX *mem_ctx = talloc_stackframe();
2276         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2277         bool ret = false;
2278
2279         if (conf_ctx == NULL) {
2280                 goto done;
2281         }
2282
2283         err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2284         if (!SBC_ERROR_IS_OK(err)) {
2285                 goto done;
2286         }
2287
2288         ret = true;
2289
2290         for (count = 0; count < num_shares; count++) {
2291                 if (strequal(service[count]->name, GLOBAL_NAME)) {
2292                         continue;
2293                 }
2294                 ret = process_smbconf_service(service[count]);
2295                 if (!ret) {
2296                         goto done;
2297                 }
2298         }
2299
2300         /* store the csn */
2301         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2302
2303 done:
2304         TALLOC_FREE(mem_ctx);
2305         return ret;
2306 }
2307
2308 /**
2309  * reload those shares from registry that are already
2310  * activated in the services array.
2311  */
2312 static bool reload_registry_shares(void)
2313 {
2314         int i;
2315         bool ret = true;
2316
2317         for (i = 0; i < iNumServices; i++) {
2318                 if (!VALID(i)) {
2319                         continue;
2320                 }
2321
2322                 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2323                         continue;
2324                 }
2325
2326                 ret = process_registry_service(ServicePtrs[i]->szService);
2327                 if (!ret) {
2328                         goto done;
2329                 }
2330         }
2331
2332 done:
2333         return ret;
2334 }
2335
2336
2337 #define MAX_INCLUDE_DEPTH 100
2338
2339 static uint8_t include_depth;
2340
2341 /**
2342  * Free the file lists
2343  */
2344 static void free_file_list(void)
2345 {
2346         struct file_lists *f;
2347         struct file_lists *next;
2348
2349         f = file_lists;
2350         while( f ) {
2351                 next = f->next;
2352                 TALLOC_FREE( f );
2353                 f = next;
2354         }
2355         file_lists = NULL;
2356 }
2357
2358
2359 /**
2360  * Utility function for outsiders to check if we're running on registry.
2361  */
2362 bool lp_config_backend_is_registry(void)
2363 {
2364         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2365 }
2366
2367 /**
2368  * Utility function to check if the config backend is FILE.
2369  */
2370 bool lp_config_backend_is_file(void)
2371 {
2372         return (lp_config_backend() == CONFIG_BACKEND_FILE);
2373 }
2374
2375 /*******************************************************************
2376  Check if a config file has changed date.
2377 ********************************************************************/
2378
2379 bool lp_file_list_changed(void)
2380 {
2381         struct file_lists *f = file_lists;
2382
2383         DEBUG(6, ("lp_file_list_changed()\n"));
2384
2385         while (f) {
2386                 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2387                         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2388
2389                         if (conf_ctx == NULL) {
2390                                 return false;
2391                         }
2392                         if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2393                                             NULL))
2394                         {
2395                                 DEBUGADD(6, ("registry config changed\n"));
2396                                 return true;
2397                         }
2398                 } else {
2399                         time_t mod_time;
2400                         char *n2 = NULL;
2401
2402                         n2 = talloc_sub_basic(talloc_tos(),
2403                                               get_current_username(),
2404                                               current_user_info.domain,
2405                                               f->name);
2406                         if (!n2) {
2407                                 return false;
2408                         }
2409                         DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
2410                                      f->name, n2, ctime(&f->modtime)));
2411
2412                         mod_time = file_modtime(n2);
2413
2414                         if (mod_time &&
2415                             ((f->modtime != mod_time) ||
2416                              (f->subfname == NULL) ||
2417                              (strcmp(n2, f->subfname) != 0)))
2418                         {
2419                                 DEBUGADD(6,
2420                                          ("file %s modified: %s\n", n2,
2421                                           ctime(&mod_time)));
2422                                 f->modtime = mod_time;
2423                                 TALLOC_FREE(f->subfname);
2424                                 f->subfname = talloc_strdup(f, n2);
2425                                 if (f->subfname == NULL) {
2426                                         smb_panic("talloc_strdup failed");
2427                                 }
2428                                 TALLOC_FREE(n2);
2429                                 return true;
2430                         }
2431                         TALLOC_FREE(n2);
2432                 }
2433                 f = f->next;
2434         }
2435         return false;
2436 }
2437
2438
2439 /**
2440  * Initialize iconv conversion descriptors.
2441  *
2442  * This is called the first time it is needed, and also called again
2443  * every time the configuration is reloaded, because the charset or
2444  * codepage might have changed.
2445  **/
2446 static void init_iconv(void)
2447 {
2448         struct smb_iconv_handle *ret = NULL;
2449
2450         ret = reinit_iconv_handle(NULL,
2451                                   lp_dos_charset(),
2452                                   lp_unix_charset());
2453         if (ret == NULL) {
2454                 smb_panic("reinit_iconv_handle failed");
2455         }
2456 }
2457
2458 /***************************************************************************
2459  Handle the include operation.
2460 ***************************************************************************/
2461 static bool bAllowIncludeRegistry = true;
2462
2463 bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2464                 const char *pszParmValue, char **ptr)
2465 {
2466         char *fname;
2467
2468         if (include_depth >= MAX_INCLUDE_DEPTH) {
2469                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2470                           include_depth));
2471                 return false;
2472         }
2473
2474         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2475                 if (!bAllowIncludeRegistry) {
2476                         return true;
2477                 }
2478                 if (lp_ctx->bInGlobalSection) {
2479                         bool ret;
2480                         include_depth++;
2481                         ret = process_registry_globals();
2482                         include_depth--;
2483                         return ret;
2484                 } else {
2485                         DEBUG(1, ("\"include = registry\" only effective "
2486                                   "in %s section\n", GLOBAL_NAME));
2487                         return false;
2488                 }
2489         }
2490
2491         fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2492                                  current_user_info.domain,
2493                                  pszParmValue);
2494
2495         add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2496
2497         if (service == NULL) {
2498                 lpcfg_string_set(Globals.ctx, ptr, fname);
2499         } else {
2500                 lpcfg_string_set(service, ptr, fname);
2501         }
2502
2503         if (file_exist(fname)) {
2504                 bool ret;
2505                 include_depth++;
2506                 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2507                 include_depth--;
2508                 TALLOC_FREE(fname);
2509                 return ret;
2510         }
2511
2512         DEBUG(2, ("Can't find include file %s\n", fname));
2513         TALLOC_FREE(fname);
2514         return true;
2515 }
2516
2517 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2518 {
2519         char *config_option = NULL;
2520         const char *range = NULL;
2521         bool ret = false;
2522
2523         SMB_ASSERT(low != NULL);
2524         SMB_ASSERT(high != NULL);
2525
2526         if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2527                 domain_name = "*";
2528         }
2529
2530         config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2531                                         domain_name);
2532         if (config_option == NULL) {
2533                 DEBUG(0, ("out of memory\n"));
2534                 return false;
2535         }
2536
2537         range = lp_parm_const_string(-1, config_option, "range", NULL);
2538         if (range == NULL) {
2539                 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2540                 goto done;
2541         }
2542
2543         if (sscanf(range, "%u - %u", low, high) != 2) {
2544                 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2545                           range, domain_name));
2546                 goto done;
2547         }
2548
2549         ret = true;
2550
2551 done:
2552         talloc_free(config_option);
2553         return ret;
2554
2555 }
2556
2557 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2558 {
2559         return lp_idmap_range("*", low, high);
2560 }
2561
2562 const char *lp_idmap_backend(const char *domain_name)
2563 {
2564         char *config_option = NULL;
2565         const char *backend = NULL;
2566
2567         if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2568                 domain_name = "*";
2569         }
2570
2571         config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2572                                         domain_name);
2573         if (config_option == NULL) {
2574                 DEBUG(0, ("out of memory\n"));
2575                 return false;
2576         }
2577
2578         backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2579         if (backend == NULL) {
2580                 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2581                 goto done;
2582         }
2583
2584 done:
2585         talloc_free(config_option);
2586         return backend;
2587 }
2588
2589 const char *lp_idmap_default_backend(void)
2590 {
2591         return lp_idmap_backend("*");
2592 }
2593
2594 /***************************************************************************
2595  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2596 ***************************************************************************/
2597
2598 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2599 {
2600         const char *suffix_string;
2601
2602         suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2603                                         Globals.ldap_suffix );
2604         if ( !suffix_string ) {
2605                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2606                 return "";
2607         }
2608
2609         return suffix_string;
2610 }
2611
2612 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2613 {
2614         if (Globals._ldap_machine_suffix[0])
2615                 return append_ldap_suffix(ctx, Globals._ldap_machine_suffix);
2616
2617         return talloc_strdup(ctx, Globals.ldap_suffix);
2618 }
2619
2620 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2621 {
2622         if (Globals._ldap_user_suffix[0])
2623                 return append_ldap_suffix(ctx, Globals._ldap_user_suffix);
2624
2625         return talloc_strdup(ctx, Globals.ldap_suffix);
2626 }
2627
2628 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2629 {
2630         if (Globals._ldap_group_suffix[0])
2631                 return append_ldap_suffix(ctx, Globals._ldap_group_suffix);
2632
2633         return talloc_strdup(ctx, Globals.ldap_suffix);
2634 }
2635
2636 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2637 {
2638         if (Globals._ldap_idmap_suffix[0])
2639                 return append_ldap_suffix(ctx, Globals._ldap_idmap_suffix);
2640
2641         return talloc_strdup(ctx, Globals.ldap_suffix);
2642 }
2643
2644 /**
2645   return the parameter pointer for a parameter
2646 */
2647 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2648 {
2649         if (service == NULL) {
2650                 if (parm->p_class == P_LOCAL)
2651                         return (void *)(((char *)&sDefault)+parm->offset);
2652                 else if (parm->p_class == P_GLOBAL)
2653                         return (void *)(((char *)&Globals)+parm->offset);
2654                 else return NULL;
2655         } else {
2656                 return (void *)(((char *)service) + parm->offset);
2657         }
2658 }
2659
2660 /***************************************************************************
2661  Process a parameter for a particular service number. If snum < 0
2662  then assume we are in the globals.
2663 ***************************************************************************/
2664
2665 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2666 {
2667         TALLOC_CTX *frame = talloc_stackframe();
2668         struct loadparm_context *lp_ctx;
2669         bool ok;
2670
2671         lp_ctx = setup_lp_context(frame);
2672         if (lp_ctx == NULL) {
2673                 TALLOC_FREE(frame);
2674                 return false;
2675         }
2676
2677         if (snum < 0) {
2678                 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2679         } else {
2680                 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2681                                                 pszParmName, pszParmValue);
2682         }
2683
2684         TALLOC_FREE(frame);
2685
2686         return ok;
2687 }
2688
2689 /***************************************************************************
2690 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2691 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2692 ***************************************************************************/
2693
2694 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2695 {
2696         int parmnum, i;
2697         parmnum = lpcfg_map_parameter(pszParmName);
2698         if (parmnum >= 0) {
2699                 flags_list[parmnum] &= ~FLAG_CMDLINE;
2700                 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2701                         return false;
2702                 }
2703                 flags_list[parmnum] |= FLAG_CMDLINE;
2704
2705                 /* we have to also set FLAG_CMDLINE on aliases.  Aliases must
2706                  * be grouped in the table, so we don't have to search the
2707                  * whole table */
2708                 for (i=parmnum-1;
2709                      i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2710                              && parm_table[i].p_class == parm_table[parmnum].p_class;
2711                      i--) {
2712                         flags_list[i] |= FLAG_CMDLINE;
2713                 }
2714                 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2715                              && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2716                         flags_list[i] |= FLAG_CMDLINE;
2717                 }
2718
2719                 return true;
2720         }
2721
2722         /* it might be parametric */
2723         if (strchr(pszParmName, ':') != NULL) {
2724                 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2725                 return true;
2726         }
2727
2728         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",  pszParmName));
2729         return false;
2730 }
2731
2732 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2733 {
2734         bool ret;
2735         TALLOC_CTX *frame = talloc_stackframe();
2736         struct loadparm_context *lp_ctx;
2737
2738         lp_ctx = setup_lp_context(frame);
2739         if (lp_ctx == NULL) {
2740                 TALLOC_FREE(frame);
2741                 return false;
2742         }
2743
2744         ret = lpcfg_set_cmdline(lp_ctx, pszParmName, pszParmValue);
2745
2746         TALLOC_FREE(frame);
2747         return ret;
2748 }
2749
2750 /***************************************************************************
2751  Process a parameter.
2752 ***************************************************************************/
2753
2754 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2755                          void *userdata)
2756 {
2757         if (!bInGlobalSection && bGlobalOnly)
2758                 return true;
2759
2760         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2761
2762         if (bInGlobalSection) {
2763                 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2764         } else {
2765                 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2766                                                   pszParmName, pszParmValue);
2767         }
2768 }
2769
2770
2771 static const char *ad_dc_req_vfs_mods[] = {"dfs_samba4", "acl_xattr", NULL};
2772
2773 /*
2774  * check that @vfs_objects includes all vfs modules required by an AD DC.
2775  */
2776 static bool check_ad_dc_required_mods(const char **vfs_objects)
2777 {
2778         int i;
2779         int j;
2780         int got_req;
2781
2782         for (i = 0; ad_dc_req_vfs_mods[i] != NULL; i++) {
2783                 got_req = false;
2784                 for (j = 0; vfs_objects[j] != NULL; j++) {
2785                         if (!strwicmp(ad_dc_req_vfs_mods[i], vfs_objects[j])) {
2786                                 got_req = true;
2787                                 break;
2788                         }
2789                 }
2790                 if (!got_req) {
2791                         DEBUG(0, ("vfs objects specified without required AD "
2792                                   "DC module: %s\n", ad_dc_req_vfs_mods[i]));
2793                         return false;
2794                 }
2795         }
2796
2797         DEBUG(6, ("vfs objects specified with all required AD DC modules\n"));
2798         return true;
2799 }
2800
2801
2802 /***************************************************************************
2803  Initialize any local variables in the sDefault table, after parsing a
2804  [globals] section.
2805 ***************************************************************************/
2806
2807 static void init_locals(void)
2808 {
2809         /*
2810          * We run this check once the [globals] is parsed, to force
2811          * the VFS objects and other per-share settings we need for
2812          * the standard way a AD DC is operated.  We may change these
2813          * as our code evolves, which is why we force these settings.
2814          *
2815          * We can't do this at the end of lp_load_ex(), as by that
2816          * point the services have been loaded and they will already
2817          * have "" as their vfs objects.
2818          */
2819         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2820                 const char **vfs_objects = lp_vfs_objects(-1);
2821                 if (vfs_objects != NULL) {
2822                         /* ignore return, only warn if modules are missing */
2823                         check_ad_dc_required_mods(vfs_objects);
2824                 } else {
2825                         if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2826                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2827                         } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2828                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2829                         } else {
2830                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2831                         }
2832                 }
2833
2834                 lp_do_parameter(-1, "map hidden", "no");
2835                 lp_do_parameter(-1, "map system", "no");
2836                 lp_do_parameter(-1, "map readonly", "no");
2837                 lp_do_parameter(-1, "map archive", "no");
2838                 lp_do_parameter(-1, "store dos attributes", "yes");
2839         }
2840 }
2841
2842 /***************************************************************************
2843  Process a new section (service). At this stage all sections are services.
2844  Later we'll have special sections that permit server parameters to be set.
2845  Returns true on success, false on failure.
2846 ***************************************************************************/
2847
2848 bool lp_do_section(const char *pszSectionName, void *userdata)
2849 {
2850         struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2851         bool bRetval;
2852         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2853                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2854
2855         /* if we were in a global section then do the local inits */
2856         if (bInGlobalSection && !isglobal)
2857                 init_locals();
2858
2859         /* if we've just struck a global section, note the fact. */
2860         bInGlobalSection = isglobal;
2861         if (lp_ctx != NULL) {
2862                 lp_ctx->bInGlobalSection = isglobal;
2863         }
2864
2865         /* check for multiple global sections */
2866         if (bInGlobalSection) {
2867                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2868                 return true;
2869         }
2870
2871         if (!bInGlobalSection && bGlobalOnly)
2872                 return true;
2873
2874         /* if we have a current service, tidy it up before moving on */
2875         bRetval = true;
2876
2877         if (iServiceIndex >= 0)
2878                 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2879
2880         /* if all is still well, move to the next record in the services array */
2881         if (bRetval) {
2882                 /* We put this here to avoid an odd message order if messages are */
2883                 /* issued by the post-processing of a previous section. */
2884                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2885
2886                 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2887                 if (iServiceIndex < 0) {
2888                         DEBUG(0, ("Failed to add a new service\n"));
2889                         return false;
2890                 }
2891                 /* Clean all parametric options for service */
2892                 /* They will be added during parsing again */
2893                 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2894         }
2895
2896         return bRetval;
2897 }
2898
2899 /***************************************************************************
2900  Display the contents of a parameter of a single services record.
2901 ***************************************************************************/
2902
2903 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2904 {
2905         bool result = false;
2906         struct loadparm_context *lp_ctx;
2907
2908         lp_ctx = setup_lp_context(talloc_tos());
2909         if (lp_ctx == NULL) {
2910                 return false;
2911         }
2912
2913         if (isGlobal) {
2914                 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2915         } else {
2916                 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2917         }
2918         TALLOC_FREE(lp_ctx);
2919         return result;
2920 }
2921
2922 #if 0
2923 /***************************************************************************
2924  Display the contents of a single copy structure.
2925 ***************************************************************************/
2926 static void dump_copy_map(bool *pcopymap)
2927 {
2928         int i;
2929         if (!pcopymap)
2930                 return;
2931
2932         printf("\n\tNon-Copied parameters:\n");
2933
2934         for (i = 0; parm_table[i].label; i++)
2935                 if (parm_table[i].p_class == P_LOCAL &&
2936                     parm_table[i].ptr && !pcopymap[i] &&
2937                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2938                 {
2939                         printf("\t\t%s\n", parm_table[i].label);
2940                 }
2941 }
2942 #endif
2943
2944 /***************************************************************************
2945  Return TRUE if the passed service number is within range.
2946 ***************************************************************************/
2947
2948 bool lp_snum_ok(int iService)
2949 {
2950         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->available);
2951 }
2952
2953 /***************************************************************************
2954  Auto-load some home services.
2955 ***************************************************************************/
2956
2957 static void lp_add_auto_services(const char *str)
2958 {
2959         char *s;
2960         char *p;
2961         int homes;
2962         char *saveptr;
2963
2964         if (!str)
2965                 return;
2966
2967         s = talloc_strdup(talloc_tos(), str);
2968         if (!s) {
2969                 smb_panic("talloc_strdup failed");
2970                 return;
2971         }
2972
2973         homes = lp_servicenumber(HOMES_NAME);
2974
2975         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
2976              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
2977                 char *home;
2978
2979                 if (lp_servicenumber(p) >= 0)
2980                         continue;
2981
2982                 home = get_user_home_dir(talloc_tos(), p);
2983
2984                 if (home && home[0] && homes >= 0)
2985                         lp_add_home(p, homes, p, home);
2986
2987                 TALLOC_FREE(home);
2988         }
2989         TALLOC_FREE(s);
2990 }
2991
2992 /***************************************************************************
2993  Auto-load one printer.
2994 ***************************************************************************/
2995
2996 void lp_add_one_printer(const char *name, const char *comment,
2997                         const char *location, void *pdata)
2998 {
2999         int printers = lp_servicenumber(PRINTERS_NAME);
3000         int i;
3001
3002         if (lp_servicenumber(name) < 0) {
3003                 lp_add_printer(name, printers);
3004                 if ((i = lp_servicenumber(name)) >= 0) {
3005                         lpcfg_string_set(ServicePtrs[i],
3006                                          &ServicePtrs[i]->comment, comment);
3007                         ServicePtrs[i]->autoloaded = true;
3008                 }
3009         }
3010 }
3011
3012 /***************************************************************************
3013  Have we loaded a services file yet?
3014 ***************************************************************************/
3015
3016 bool lp_loaded(void)
3017 {
3018         return (bLoaded);
3019 }
3020
3021 /***************************************************************************
3022  Unload unused services.
3023 ***************************************************************************/
3024
3025 void lp_killunused(struct smbd_server_connection *sconn,
3026                    bool (*snumused) (struct smbd_server_connection *, int))
3027 {
3028         int i;
3029         for (i = 0; i < iNumServices; i++) {
3030                 if (!VALID(i))
3031                         continue;
3032
3033                 /* don't kill autoloaded or usershare services */
3034                 if ( ServicePtrs[i]->autoloaded ||
3035                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3036                         continue;
3037                 }
3038
3039                 if (!snumused || !snumused(sconn, i)) {
3040                         free_service_byindex(i);
3041                 }
3042         }
3043 }
3044
3045 /**
3046  * Kill all except autoloaded and usershare services - convenience wrapper
3047  */
3048 void lp_kill_all_services(void)
3049 {
3050         lp_killunused(NULL, NULL);
3051 }
3052
3053 /***************************************************************************
3054  Unload a service.
3055 ***************************************************************************/
3056
3057 void lp_killservice(int iServiceIn)
3058 {
3059         if (VALID(iServiceIn)) {
3060                 free_service_byindex(iServiceIn);
3061         }
3062 }
3063
3064 /***************************************************************************
3065  Save the curent values of all global and sDefault parameters into the 
3066  defaults union. This allows testparm to show only the
3067  changed (ie. non-default) parameters.
3068 ***************************************************************************/
3069
3070 static void lp_save_defaults(void)
3071 {
3072         int i;
3073         struct parmlist_entry * parm;
3074         for (i = 0; parm_table[i].label; i++) {
3075                 if (!(flags_list[i] & FLAG_CMDLINE)) {
3076                         flags_list[i] |= FLAG_DEFAULT;
3077                 }
3078
3079                 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3080                     && parm_table[i].p_class == parm_table[i - 1].p_class)
3081                         continue;
3082                 switch (parm_table[i].type) {
3083                         case P_LIST:
3084                         case P_CMDLIST:
3085                                 parm_table[i].def.lvalue = str_list_copy(
3086                                         NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3087                                 break;
3088                         case P_STRING:
3089                         case P_USTRING:
3090                                 lpcfg_string_set(
3091                                         Globals.ctx,
3092                                         &parm_table[i].def.svalue,
3093                                         *(char **)lp_parm_ptr(
3094                                                 NULL, &parm_table[i]));
3095                                 if (parm_table[i].def.svalue == NULL) {
3096                                         smb_panic("lpcfg_string_set() failed");
3097                                 }
3098                                 break;
3099                         case P_BOOL:
3100                         case P_BOOLREV:
3101                                 parm_table[i].def.bvalue =
3102                                         *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3103                                 break;
3104                         case P_CHAR:
3105                                 parm_table[i].def.cvalue =
3106                                         *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3107                                 break;
3108                         case P_INTEGER:
3109                         case P_OCTAL:
3110                         case P_ENUM:
3111                         case P_BYTES:
3112                                 parm_table[i].def.ivalue =
3113                                         *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3114                                 break;
3115                 }
3116         }
3117
3118         for (parm=Globals.param_opt; parm; parm=parm->next) {
3119                 if (!(parm->priority & FLAG_CMDLINE)) {
3120                         parm->priority |= FLAG_DEFAULT;
3121                 }
3122         }
3123
3124         for (parm=sDefault.param_opt; parm; parm=parm->next) {
3125                 if (!(parm->priority & FLAG_CMDLINE)) {
3126                         parm->priority |= FLAG_DEFAULT;
3127                 }
3128         }
3129
3130         defaults_saved = true;
3131 }
3132
3133 /***********************************************************
3134  If we should send plaintext/LANMAN passwords in the clinet
3135 ************************************************************/
3136
3137 static void set_allowed_client_auth(void)
3138 {
3139         if (Globals.client_ntlmv2_auth) {
3140                 Globals.client_lanman_auth = false;
3141         }
3142         if (!Globals.client_lanman_auth) {
3143                 Globals.client_plaintext_auth = false;
3144         }
3145 }
3146
3147 /***************************************************************************
3148  JRA.
3149  The following code allows smbd to read a user defined share file.
3150  Yes, this is my intent. Yes, I'm comfortable with that...
3151
3152  THE FOLLOWING IS SECURITY CRITICAL CODE.
3153
3154  It washes your clothes, it cleans your house, it guards you while you sleep...
3155  Do not f%^k with it....
3156 ***************************************************************************/
3157
3158 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3159
3160 /***************************************************************************
3161  Check allowed stat state of a usershare file.
3162  Ensure we print out who is dicking with us so the admin can
3163  get their sorry ass fired.
3164 ***************************************************************************/
3165
3166 static bool check_usershare_stat(const char *fname,
3167                                  const SMB_STRUCT_STAT *psbuf)
3168 {
3169         if (!S_ISREG(psbuf->st_ex_mode)) {
3170                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3171                         "not a regular file\n",
3172                         fname, (unsigned int)psbuf->st_ex_uid ));
3173                 return false;
3174         }
3175
3176         /* Ensure this doesn't have the other write bit set. */
3177         if (psbuf->st_ex_mode & S_IWOTH) {
3178                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3179                         "public write. Refusing to allow as a usershare file.\n",
3180                         fname, (unsigned int)psbuf->st_ex_uid ));
3181                 return false;
3182         }
3183
3184         /* Should be 10k or less. */
3185         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
3186                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3187                         "too large (%u) to be a user share file.\n",
3188                         fname, (unsigned int)psbuf->st_ex_uid,
3189                         (unsigned int)psbuf->st_ex_size ));
3190                 return false;
3191         }
3192
3193         return true;
3194 }
3195
3196 /***************************************************************************
3197  Parse the contents of a usershare file.
3198 ***************************************************************************/
3199
3200 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
3201                         SMB_STRUCT_STAT *psbuf,
3202                         const char *servicename,
3203                         int snum,
3204                         char **lines,
3205                         int numlines,
3206                         char **pp_sharepath,
3207                         char **pp_comment,
3208                         char **pp_cp_servicename,
3209                         struct security_descriptor **ppsd,
3210                         bool *pallow_guest)
3211 {
3212         const char **prefixallowlist = lp_usershare_prefix_allow_list();
3213         const char **prefixdenylist = lp_usershare_prefix_deny_list();
3214         int us_vers;
3215         DIR *dp;
3216         SMB_STRUCT_STAT sbuf;
3217         char *sharepath = NULL;
3218         char *comment = NULL;
3219
3220         *pp_sharepath = NULL;
3221         *pp_comment = NULL;
3222
3223         *pallow_guest = false;
3224
3225         if (numlines < 4) {
3226                 return USERSHARE_MALFORMED_FILE;
3227         }
3228
3229         if (strcmp(lines[0], "#VERSION 1") == 0) {
3230                 us_vers = 1;
3231         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3232                 us_vers = 2;
3233                 if (numlines < 5) {
3234                         return USERSHARE_MALFORMED_FILE;
3235                 }
3236         } else {
3237                 return USERSHARE_BAD_VERSION;
3238         }
3239
3240         if (strncmp(lines[1], "path=", 5) != 0) {
3241                 return USERSHARE_MALFORMED_PATH;
3242         }
3243
3244         sharepath = talloc_strdup(ctx, &lines[1][5]);
3245         if (!sharepath) {
3246                 return USERSHARE_POSIX_ERR;
3247         }
3248         trim_string(sharepath, " ", " ");
3249
3250         if (strncmp(lines[2], "comment=", 8) != 0) {
3251                 return USERSHARE_MALFORMED_COMMENT_DEF;
3252         }
3253
3254         comment = talloc_strdup(ctx, &lines[2][8]);
3255         if (!comment) {
3256                 return USERSHARE_POSIX_ERR;
3257         }
3258         trim_string(comment, " ", " ");
3259         trim_char(comment, '"', '"');
3260
3261         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3262                 return USERSHARE_MALFORMED_ACL_DEF;
3263         }
3264
3265         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3266                 return USERSHARE_ACL_ERR;
3267         }
3268
3269         if (us_vers == 2) {
3270                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3271                         return USERSHARE_MALFORMED_ACL_DEF;
3272                 }
3273                 if (lines[4][9] == 'y') {
3274                         *pallow_guest = true;
3275                 }
3276
3277                 /* Backwards compatible extension to file version #2. */
3278                 if (numlines > 5) {
3279                         if (strncmp(lines[5], "sharename=", 10) != 0) {
3280                                 return USERSHARE_MALFORMED_SHARENAME_DEF;
3281                         }
3282                         if (!strequal(&lines[5][10], servicename)) {
3283                                 return USERSHARE_BAD_SHARENAME;
3284                         }
3285                         *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3286                         if (!*pp_cp_servicename) {
3287                                 return USERSHARE_POSIX_ERR;
3288                         }
3289                 }
3290         }
3291
3292         if (*pp_cp_servicename == NULL) {
3293                 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3294                 if (!*pp_cp_servicename) {
3295                         return USERSHARE_POSIX_ERR;
3296                 }
3297         }
3298
3299         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3300                 /* Path didn't change, no checks needed. */
3301                 *pp_sharepath = sharepath;
3302                 *pp_comment = comment;
3303                 return USERSHARE_OK;
3304         }
3305
3306         /* The path *must* be absolute. */
3307         if (sharepath[0] != '/') {
3308                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3309                         servicename, sharepath));
3310                 return USERSHARE_PATH_NOT_ABSOLUTE;
3311         }
3312
3313         /* If there is a usershare prefix deny list ensure one of these paths
3314            doesn't match the start of the user given path. */
3315         if (prefixdenylist) {
3316                 int i;
3317                 for ( i=0; prefixdenylist[i]; i++ ) {
3318                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3319                                 servicename, i, prefixdenylist[i], sharepath ));
3320                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3321                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3322                                         "usershare prefix deny list entries.\n",
3323                                         servicename, sharepath));
3324                                 return USERSHARE_PATH_IS_DENIED;
3325                         }
3326                 }
3327         }
3328
3329         /* If there is a usershare prefix allow list ensure one of these paths
3330            does match the start of the user given path. */
3331
3332         if (prefixallowlist) {
3333                 int i;
3334                 for ( i=0; prefixallowlist[i]; i++ ) {
3335                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3336                                 servicename, i, prefixallowlist[i], sharepath ));
3337                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3338                                 break;
3339                         }
3340                 }
3341                 if (prefixallowlist[i] == NULL) {
3342                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3343                                 "usershare prefix allow list entries.\n",
3344                                 servicename, sharepath));
3345                         return USERSHARE_PATH_NOT_ALLOWED;
3346                 }
3347         }
3348
3349         /* Ensure this is pointing to a directory. */
3350         dp = opendir(sharepath);
3351
3352         if (!dp) {
3353                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3354                         servicename, sharepath));
3355                 return USERSHARE_PATH_NOT_DIRECTORY;
3356         }
3357
3358         /* Ensure the owner of the usershare file has permission to share
3359            this directory. */
3360
3361         if (sys_stat(sharepath, &sbuf, false) == -1) {
3362                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3363                         servicename, sharepath, strerror(errno) ));
3364                 closedir(dp);
3365                 return USERSHARE_POSIX_ERR;
3366         }
3367
3368         closedir(dp);
3369
3370         if (!S_ISDIR(sbuf.st_ex_mode)) {
3371                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3372                         servicename, sharepath ));
3373                 return USERSHARE_PATH_NOT_DIRECTORY;
3374         }
3375
3376         /* Check if sharing is restricted to owner-only. */
3377         /* psbuf is the stat of the usershare definition file,
3378            sbuf is the stat of the target directory to be shared. */
3379
3380         if (lp_usershare_owner_only()) {
3381                 /* root can share anything. */
3382                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3383                         return USERSHARE_PATH_NOT_ALLOWED;
3384                 }
3385         }
3386
3387         *pp_sharepath = sharepath;
3388         *pp_comment = comment;
3389         return USERSHARE_OK;
3390 }
3391
3392 /***************************************************************************
3393  Deal with a usershare file.
3394  Returns:
3395         >= 0 - snum
3396         -1 - Bad name, invalid contents.
3397            - service name already existed and not a usershare, problem
3398             with permissions to share directory etc.
3399 ***************************************************************************/
3400
3401 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3402 {
3403         SMB_STRUCT_STAT sbuf;
3404         SMB_STRUCT_STAT lsbuf;
3405         char *fname = NULL;
3406         char *sharepath = NULL;
3407         char *comment = NULL;
3408         char *cp_service_name = NULL;
3409         char **lines = NULL;
3410         int numlines = 0;
3411         int fd = -1;
3412         int iService = -1;
3413         TALLOC_CTX *ctx = talloc_stackframe();
3414         struct security_descriptor *psd = NULL;
3415         bool guest_ok = false;
3416         char *canon_name = NULL;
3417         bool added_service = false;
3418         int ret = -1;
3419         NTSTATUS status;
3420
3421         /* Ensure share name doesn't contain invalid characters. */
3422         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3423                 DEBUG(0,("process_usershare_file: share name %s contains "
3424                         "invalid characters (any of %s)\n",
3425                         file_name, INVALID_SHARENAME_CHARS ));
3426                 goto out;
3427         }
3428
3429         canon_name = canonicalize_servicename(ctx, file_name);
3430         if (!canon_name) {
3431                 goto out;
3432         }
3433
3434         fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3435         if (!fname) {
3436                 goto out;
3437         }
3438
3439         /* Minimize the race condition by doing an lstat before we
3440            open and fstat. Ensure this isn't a symlink link. */
3441
3442         if (sys_lstat(fname, &lsbuf, false) != 0) {
3443                 if (errno == ENOENT) {
3444                         /* Unknown share requested. Just ignore. */
3445                         goto out;
3446                 }
3447                 /* Only log messages for meaningful problems. */
3448                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3449                         fname, strerror(errno) ));
3450                 goto out;
3451         }
3452
3453         /* This must be a regular file, not a symlink, directory or
3454            other strange filetype. */
3455         if (!check_usershare_stat(fname, &lsbuf)) {
3456                 goto out;
3457         }
3458
3459         {
3460                 TDB_DATA data;
3461
3462                 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3463                                                canon_name, &data);
3464
3465                 iService = -1;
3466
3467                 if (NT_STATUS_IS_OK(status) &&
3468                     (data.dptr != NULL) &&
3469                     (data.dsize == sizeof(iService))) {
3470                         memcpy(&iService, data.dptr, sizeof(iService));
3471                 }
3472         }
3473
3474         if (iService != -1 &&
3475             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3476                              &lsbuf.st_ex_mtime) == 0) {
3477                 /* Nothing changed - Mark valid and return. */
3478                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3479                         canon_name ));
3480                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3481                 ret = iService;
3482                 goto out;
3483         }
3484
3485         /* Try and open the file read only - no symlinks allowed. */
3486 #ifdef O_NOFOLLOW
3487         fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3488 #else
3489         fd = open(fname, O_RDONLY, 0);
3490 #endif
3491
3492         if (fd == -1) {
3493                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3494                         fname, strerror(errno) ));
3495                 goto out;
3496         }
3497
3498         /* Now fstat to be *SURE* it's a regular file. */
3499         if (sys_fstat(fd, &sbuf, false) != 0) {
3500                 close(fd);
3501                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3502                         fname, strerror(errno) ));
3503                 goto out;
3504         }
3505
3506         /* Is it the same dev/inode as was lstated ? */
3507         if (!check_same_stat(&lsbuf, &sbuf)) {
3508                 close(fd);
3509                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3510                         "Symlink spoofing going on ?\n", fname ));
3511                 goto out;
3512         }
3513
3514         /* This must be a regular file, not a symlink, directory or
3515            other strange filetype. */
3516         if (!check_usershare_stat(fname, &sbuf)) {
3517                 close(fd);
3518                 goto out;
3519         }
3520
3521         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3522
3523         close(fd);
3524         if (lines == NULL) {
3525                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3526                         fname, (unsigned int)sbuf.st_ex_uid ));
3527                 goto out;
3528         }
3529
3530         if (parse_usershare_file(ctx, &sbuf, file_name,
3531                         iService, lines, numlines, &sharepath,
3532                         &comment, &cp_service_name,
3533                         &psd, &guest_ok) != USERSHARE_OK) {
3534                 goto out;
3535         }
3536
3537         /* Everything ok - add the service possibly using a template. */
3538         if (iService < 0) {
3539                 const struct loadparm_service *sp = &sDefault;
3540                 if (snum_template != -1) {
3541                         sp = ServicePtrs[snum_template];
3542                 }
3543
3544                 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3545                         DEBUG(0, ("process_usershare_file: Failed to add "
3546                                 "new service %s\n", cp_service_name));
3547                         goto out;
3548                 }
3549
3550                 added_service = true;
3551
3552                 /* Read only is controlled by usershare ACL below. */
3553                 ServicePtrs[iService]->read_only = false;
3554         }
3555
3556         /* Write the ACL of the new/modified share. */
3557         status = set_share_security(canon_name, psd);
3558         if (!NT_STATUS_IS_OK(status)) {
3559                  DEBUG(0, ("process_usershare_file: Failed to set share "
3560                         "security for user share %s\n",
3561                         canon_name ));
3562                 goto out;
3563         }
3564
3565         /* If from a template it may be marked invalid. */
3566         ServicePtrs[iService]->valid = true;
3567
3568         /* Set the service as a valid usershare. */
3569         ServicePtrs[iService]->usershare = USERSHARE_VALID;
3570
3571         /* Set guest access. */
3572         if (lp_usershare_allow_guests()) {
3573                 ServicePtrs[iService]->guest_ok = guest_ok;
3574         }
3575
3576         /* And note when it was loaded. */
3577         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3578         lpcfg_string_set(ServicePtrs[iService], &ServicePtrs[iService]->path,
3579                          sharepath);
3580         lpcfg_string_set(ServicePtrs[iService],
3581                          &ServicePtrs[iService]->comment, comment);
3582
3583         ret = iService;
3584
3585   out:
3586
3587         if (ret == -1 && iService != -1 && added_service) {
3588                 lp_remove_service(iService);
3589         }
3590
3591         TALLOC_FREE(lines);
3592         TALLOC_FREE(ctx);
3593         return ret;
3594 }
3595
3596 /***************************************************************************
3597  Checks if a usershare entry has been modified since last load.
3598 ***************************************************************************/
3599
3600 static bool usershare_exists(int iService, struct timespec *last_mod)
3601 {
3602         SMB_STRUCT_STAT lsbuf;
3603         const char *usersharepath = Globals.usershare_path;
3604         char *fname;
3605
3606         fname = talloc_asprintf(talloc_tos(),
3607                                 "%s/%s",
3608                                 usersharepath,
3609                                 ServicePtrs[iService]->szService);
3610         if (fname == NULL) {
3611                 return false;
3612         }
3613
3614         if (sys_lstat(fname, &lsbuf, false) != 0) {
3615                 TALLOC_FREE(fname);
3616                 return false;
3617         }
3618
3619         if (!S_ISREG(lsbuf.st_ex_mode)) {
3620                 TALLOC_FREE(fname);
3621                 return false;
3622         }
3623
3624         TALLOC_FREE(fname);
3625         *last_mod = lsbuf.st_ex_mtime;
3626         return true;
3627 }
3628
3629 static bool usershare_directory_is_root(uid_t uid)
3630 {
3631         if (uid == 0) {
3632                 return true;
3633         }
3634
3635         if (uid_wrapper_enabled()) {
3636                 return true;
3637         }
3638
3639         return false;
3640 }
3641
3642 /***************************************************************************
3643  Load a usershare service by name. Returns a valid servicenumber or -1.
3644 ***************************************************************************/
3645
3646 int load_usershare_service(const char *servicename)
3647 {
3648         SMB_STRUCT_STAT sbuf;
3649         const char *usersharepath = Globals.usershare_path;
3650         int max_user_shares = Globals.usershare_max_shares;
3651         int snum_template = -1;
3652
3653         if (servicename[0] == '\0') {
3654                 /* Invalid service name. */
3655                 return -1;
3656         }
3657
3658         if (*usersharepath == 0 ||  max_user_shares == 0) {
3659                 return -1;
3660         }
3661
3662         if (sys_stat(usersharepath, &sbuf, false) != 0) {
3663                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3664                         usersharepath, strerror(errno) ));
3665                 return -1;
3666         }
3667
3668         if (!S_ISDIR(sbuf.st_ex_mode)) {
3669                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3670                         usersharepath ));
3671                 return -1;
3672         }
3673
3674         /*
3675          * This directory must be owned by root, and have the 't' bit set.
3676          * It also must not be writable by "other".
3677          */
3678
3679 #ifdef S_ISVTX
3680         if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
3681             !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3682 #else
3683         if (!usershare_directory_is_root(sbuf.st_ex_uid) ||
3684             (sbuf.st_ex_mode & S_IWOTH)) {
3685 #endif
3686                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3687                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
3688                         usersharepath ));
3689                 return -1;
3690         }
3691
3692         /* Ensure the template share exists if it's set. */
3693         if (Globals.usershare_template_share[0]) {
3694                 /* We can't use lp_servicenumber here as we are recommending that
3695                    template shares have -valid=false set. */
3696                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3697                         if (ServicePtrs[snum_template]->szService &&
3698                                         strequal(ServicePtrs[snum_template]->szService,
3699                                                 Globals.usershare_template_share)) {
3700                                 break;
3701                         }
3702                 }
3703
3704                 if (snum_template == -1) {
3705                         DEBUG(0,("load_usershare_service: usershare template share %s "
3706                                 "does not exist.\n",
3707                                 Globals.usershare_template_share ));
3708                         return -1;
3709                 }
3710         }
3711
3712         return process_usershare_file(usersharepath, servicename, snum_template);
3713 }
3714
3715 /***************************************************************************
3716  Load all user defined shares from the user share directory.
3717  We only do this if we're enumerating the share list.
3718  This is the function that can delete usershares that have
3719  been removed.
3720 ***************************************************************************/
3721
3722 int load_usershare_shares(struct smbd_server_connection *sconn,
3723                           bool (*snumused) (struct smbd_server_connection *, int))
3724 {
3725         DIR *dp;
3726         SMB_STRUCT_STAT sbuf;
3727         struct dirent *de;
3728         int num_usershares = 0;
3729         int max_user_shares = Globals.usershare_max_shares;
3730         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3731         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3732         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3733         int iService;
3734         int snum_template = -1;
3735         const char *usersharepath = Globals.usershare_path;
3736         int ret = lp_numservices();
3737         TALLOC_CTX *tmp_ctx;
3738
3739         if (max_user_shares == 0 || *usersharepath == '\0') {
3740                 return lp_numservices();
3741         }
3742
3743         if (sys_stat(usersharepath, &sbuf, false) != 0) {
3744                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3745                         usersharepath, strerror(errno) ));
3746                 return ret;
3747         }
3748
3749         /*
3750          * This directory must be owned by root, and have the 't' bit set.
3751          * It also must not be writable by "other".
3752          */
3753
3754 #ifdef S_ISVTX
3755         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3756 #else
3757         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3758 #endif
3759                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3760                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
3761                         usersharepath ));
3762                 return ret;
3763         }
3764
3765         /* Ensure the template share exists if it's set. */
3766         if (Globals.usershare_template_share[0]) {
3767                 /* We can't use lp_servicenumber here as we are recommending that
3768                    template shares have -valid=false set. */
3769                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3770                         if (ServicePtrs[snum_template]->szService &&
3771                                         strequal(ServicePtrs[snum_template]->szService,
3772                                                 Globals.usershare_template_share)) {
3773                                 break;
3774                         }
3775                 }
3776
3777                 if (snum_template == -1) {
3778                         DEBUG(0,("load_usershare_shares: usershare template share %s "
3779                                 "does not exist.\n",
3780                                 Globals.usershare_template_share ));
3781                         return ret;
3782                 }
3783         }
3784
3785         /* Mark all existing usershares as pending delete. */
3786         for (iService = iNumServices - 1; iService >= 0; iService--) {
3787                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3788                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3789                 }
3790         }
3791
3792         dp = opendir(usersharepath);
3793         if (!dp) {
3794                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3795                         usersharepath, strerror(errno) ));
3796                 return ret;
3797         }
3798
3799         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3800                         (de = readdir(dp));
3801                         num_dir_entries++ ) {
3802                 int r;
3803                 const char *n = de->d_name;
3804
3805                 /* Ignore . and .. */
3806                 if (*n == '.') {
3807                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3808                                 continue;
3809                         }
3810                 }
3811
3812                 if (n[0] == ':') {
3813                         /* Temporary file used when creating a share. */
3814                         num_tmp_dir_entries++;
3815                 }
3816
3817                 /* Allow 20% tmp entries. */
3818                 if (num_tmp_dir_entries > allowed_tmp_entries) {
3819                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3820                                 "in directory %s\n",
3821                                 num_tmp_dir_entries, usersharepath));
3822                         break;
3823                 }
3824
3825                 r = process_usershare_file(usersharepath, n, snum_template);
3826                 if (r == 0) {
3827                         /* Update the services count. */
3828                         num_usershares++;
3829                         if (num_usershares >= max_user_shares) {
3830                                 DEBUG(0,("load_usershare_shares: max user shares reached "
3831                                         "on file %s in directory %s\n",
3832                                         n, usersharepath ));
3833                                 break;
3834                         }
3835                 } else if (r == -1) {
3836                         num_bad_dir_entries++;
3837                 }
3838
3839                 /* Allow 20% bad entries. */
3840                 if (num_bad_dir_entries > allowed_bad_entries) {
3841                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3842                                 "in directory %s\n",
3843                                 num_bad_dir_entries, usersharepath));
3844                         break;
3845                 }
3846
3847                 /* Allow 20% bad entries. */
3848                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3849                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3850                         "in directory %s\n",
3851                         num_dir_entries, usersharepath));
3852                         break;
3853                 }
3854         }
3855
3856         closedir(dp);
3857
3858         /* Sweep through and delete any non-refreshed usershares that are
3859            not currently in use. */
3860         tmp_ctx = talloc_stackframe();
3861         for (iService = iNumServices - 1; iService >= 0; iService--) {
3862                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3863                         const struct loadparm_substitution *lp_sub =
3864                                 loadparm_s3_global_substitution();
3865                         char *servname;
3866
3867                         if (snumused && snumused(sconn, iService)) {
3868                                 continue;
3869                         }
3870
3871                         servname = lp_servicename(tmp_ctx, lp_sub, iService);
3872
3873                         /* Remove from the share ACL db. */
3874                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3875                                   servname ));
3876                         delete_share_security(servname);
3877                         free_service_byindex(iService);
3878                 }
3879         }
3880         talloc_free(tmp_ctx);
3881
3882         return lp_numservices();
3883 }
3884
3885 /********************************************************
3886  Destroy global resources allocated in this file
3887 ********************************************************/
3888
3889 void gfree_loadparm(void)
3890 {
3891         int i;
3892
3893         free_file_list();
3894
3895         /* Free resources allocated to services */
3896
3897         for ( i = 0; i < iNumServices; i++ ) {
3898                 if ( VALID(i) ) {
3899                         free_service_byindex(i);
3900                 }
3901         }
3902
3903         TALLOC_FREE( ServicePtrs );
3904         iNumServices = 0;
3905
3906         /* Now release all resources allocated to global
3907            parameters and the default service */
3908
3909         free_global_parameters();
3910 }
3911
3912
3913 /***************************************************************************
3914  Allow client apps to specify that they are a client
3915 ***************************************************************************/
3916 static void lp_set_in_client(bool b)
3917 {
3918     in_client = b;
3919 }
3920
3921
3922 /***************************************************************************
3923  Determine if we're running in a client app
3924 ***************************************************************************/
3925 static bool lp_is_in_client(void)
3926 {
3927     return in_client;
3928 }
3929
3930 static void lp_enforce_ad_dc_settings(void)
3931 {
3932         lp_do_parameter(GLOBAL_SECTION_SNUM, "passdb backend", "samba_dsdb");
3933         lp_do_parameter(GLOBAL_SECTION_SNUM,
3934                         "winbindd:use external pipes", "true");
3935         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:default", "external");
3936         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:svcctl", "embedded");
3937         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:srvsvc", "embedded");
3938         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:eventlog", "embedded");
3939         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:ntsvcs", "embedded");
3940         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:winreg", "embedded");
3941         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:spoolss", "embedded");
3942         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_daemon:spoolssd", "embedded");
3943         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:tcpip", "no");
3944 }
3945
3946 /***************************************************************************
3947  Load the services array from the services file. Return true on success,
3948  false on failure.
3949 ***************************************************************************/
3950
3951 static bool lp_load_ex(const char *pszFname,
3952                        bool global_only,
3953                        bool save_defaults,
3954                        bool add_ipc,
3955                        bool reinit_globals,
3956                        bool allow_include_registry,
3957                        bool load_all_shares)
3958 {
3959         char *n2 = NULL;
3960         bool bRetval;
3961         TALLOC_CTX *frame = talloc_stackframe();
3962         struct loadparm_context *lp_ctx;
3963         int max_protocol, min_protocol;
3964
3965         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3966
3967         bInGlobalSection = true;
3968         bGlobalOnly = global_only;
3969         bAllowIncludeRegistry = allow_include_registry;
3970         sDefault = _sDefault;
3971
3972         lp_ctx = setup_lp_context(talloc_tos());
3973
3974         init_globals(lp_ctx, reinit_globals);
3975
3976         free_file_list();
3977
3978         if (save_defaults) {
3979                 init_locals();
3980                 lp_save_defaults();
3981         }
3982
3983         if (!reinit_globals) {
3984                 free_param_opts(&Globals.param_opt);
3985                 apply_lp_set_cmdline();
3986         }
3987
3988         lp_do_parameter(-1, "idmap config * : backend", Globals.idmap_backend);
3989
3990         /* We get sections first, so have to start 'behind' to make up */
3991         iServiceIndex = -1;
3992
3993         if (lp_config_backend_is_file()) {
3994                 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
3995                                         current_user_info.domain,
3996                                         pszFname);
3997                 if (!n2) {
3998                         smb_panic("lp_load_ex: out of memory");
3999                 }
4000
4001                 add_to_file_list(NULL, &file_lists, pszFname, n2);
4002
4003                 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
4004                 TALLOC_FREE(n2);
4005
4006                 /* finish up the last section */
4007                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4008                 if (bRetval) {
4009                         if (iServiceIndex >= 0) {
4010                                 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
4011                         }
4012                 }
4013
4014                 if (lp_config_backend_is_registry()) {
4015                         bool ok;
4016                         /* config backend changed to registry in config file */
4017                         /*
4018                          * We need to use this extra global variable here to
4019                          * survive restart: init_globals uses this as a default
4020                          * for config_backend. Otherwise, init_globals would
4021                          *  send us into an endless loop here.
4022                          */
4023
4024                         config_backend = CONFIG_BACKEND_REGISTRY;
4025                         /* start over */
4026                         DEBUG(1, ("lp_load_ex: changing to config backend "
4027                                   "registry\n"));
4028                         init_globals(lp_ctx, true);
4029
4030                         TALLOC_FREE(lp_ctx);
4031
4032                         lp_kill_all_services();
4033                         ok = lp_load_ex(pszFname, global_only, save_defaults,
4034                                         add_ipc, reinit_globals,
4035                                         allow_include_registry,
4036                                         load_all_shares);
4037                         TALLOC_FREE(frame);
4038                         return ok;
4039                 }
4040         } else if (lp_config_backend_is_registry()) {
4041                 bRetval = process_registry_globals();
4042         } else {
4043                 DEBUG(0, ("Illegal config  backend given: %d\n",
4044                           lp_config_backend()));
4045                 bRetval = false;
4046         }
4047
4048         if (bRetval && lp_registry_shares()) {
4049                 if (load_all_shares) {
4050                         bRetval = process_registry_shares();
4051                 } else {
4052                         bRetval = reload_registry_shares();
4053                 }
4054         }
4055
4056         {
4057                 const struct loadparm_substitution *lp_sub =
4058                         loadparm_s3_global_substitution();
4059                 char *serv = lp_auto_services(talloc_tos(), lp_sub);
4060                 lp_add_auto_services(serv);
4061                 TALLOC_FREE(serv);
4062         }
4063
4064         if (add_ipc) {
4065                 /* When 'restrict anonymous = 2' guest connections to ipc$
4066                    are denied */
4067                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4068                 if ( lp_enable_asu_support() ) {
4069                         lp_add_ipc("ADMIN$", false);
4070                 }
4071         }
4072
4073         set_allowed_client_auth();
4074
4075         if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
4076                 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4077                           lp_password_server()));
4078         }
4079
4080         bLoaded = true;
4081
4082         /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4083         /* if we_are_a_wins_server is true and we are in the client            */
4084         if (lp_is_in_client() && Globals.we_are_a_wins_server) {
4085                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4086         }
4087
4088         init_iconv();
4089
4090         fault_configure(smb_panic_s3);
4091
4092         /*
4093          * We run this check once the whole smb.conf is parsed, to
4094          * force some settings for the standard way a AD DC is
4095          * operated.  We may change these as our code evolves, which
4096          * is why we force these settings.
4097          */
4098         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4099                 lp_enforce_ad_dc_settings();
4100         }
4101
4102         bAllowIncludeRegistry = true;
4103
4104         /* Check if command line max protocol < min protocol, if so
4105          * report a warning to the user.
4106          */
4107         max_protocol = lp_client_max_protocol();
4108         min_protocol = lp_client_min_protocol();
4109         if (max_protocol < min_protocol) {
4110                 const char *max_protocolp, *min_protocolp;
4111                 max_protocolp = lpcfg_get_smb_protocol(max_protocol);
4112                 min_protocolp = lpcfg_get_smb_protocol(min_protocol);
4113                 DBG_ERR("Max protocol %s is less than min protocol %s.\n",
4114                         max_protocolp, min_protocolp);
4115         }
4116
4117         TALLOC_FREE(frame);
4118         return (bRetval);
4119 }
4120
4121 static bool lp_load(const char *pszFname,
4122                     bool global_only,
4123                     bool save_defaults,
4124                     bool add_ipc,
4125                     bool reinit_globals)
4126 {
4127         return lp_load_ex(pszFname,
4128                           global_only,
4129                           save_defaults,
4130                           add_ipc,
4131                           reinit_globals,
4132                           true,   /* allow_include_registry */
4133                           false); /* load_all_shares*/
4134 }
4135
4136 bool lp_load_initial_only(const char *pszFname)
4137 {
4138         return lp_load_ex(pszFname,
4139                           true,   /* global only */
4140                           true,   /* save_defaults */
4141                           false,  /* add_ipc */
4142                           true,   /* reinit_globals */
4143                           false,  /* allow_include_registry */
4144                           false); /* load_all_shares*/
4145 }
4146
4147 /**
4148  * most common lp_load wrapper, loading only the globals
4149  *
4150  * If this is used in a daemon or client utility it should be called
4151  * after processing popt.
4152  */
4153 bool lp_load_global(const char *file_name)
4154 {
4155         return lp_load(file_name,
4156                        true,   /* global_only */
4157                        false,  /* save_defaults */
4158                        false,  /* add_ipc */
4159                        true);  /* reinit_globals */
4160 }
4161
4162 /**
4163  * The typical lp_load wrapper with shares, loads global and
4164  * shares, including IPC, but does not force immediate
4165  * loading of all shares from registry.
4166  */
4167 bool lp_load_with_shares(const char *file_name)
4168 {
4169         return lp_load(file_name,
4170                        false,  /* global_only */
4171                        false,  /* save_defaults */
4172                        true,   /* add_ipc */
4173                        true);  /* reinit_globals */
4174 }
4175
4176 /**
4177  * lp_load wrapper, especially for clients
4178  */
4179 bool lp_load_client(const char *file_name)
4180 {
4181         lp_set_in_client(true);
4182
4183         return lp_load_global(file_name);
4184 }
4185
4186 /**
4187  * lp_load wrapper, loading only globals, but intended
4188  * for subsequent calls, not reinitializing the globals
4189  * to default values
4190  */
4191 bool lp_load_global_no_reinit(const char *file_name)
4192 {
4193         return lp_load(file_name,
4194                        true,   /* global_only */
4195                        false,  /* save_defaults */
4196                        false,  /* add_ipc */
4197                        false); /* reinit_globals */
4198 }
4199
4200 /**
4201  * lp_load wrapper, loading globals and shares,
4202  * intended for subsequent calls, i.e. not reinitializing
4203  * the globals to default values.
4204  */
4205 bool lp_load_no_reinit(const char *file_name)
4206 {
4207         return lp_load(file_name,
4208                        false,  /* global_only */
4209                        false,  /* save_defaults */
4210                        false,  /* add_ipc */
4211                        false); /* reinit_globals */
4212 }
4213
4214
4215 /**
4216  * lp_load wrapper, especially for clients, no reinitialization
4217  */
4218 bool lp_load_client_no_reinit(const char *file_name)
4219 {
4220         lp_set_in_client(true);
4221
4222         return lp_load_global_no_reinit(file_name);
4223 }
4224
4225 bool lp_load_with_registry_shares(const char *pszFname)
4226 {
4227         return lp_load_ex(pszFname,
4228                           false, /* global_only */
4229                           true,  /* save_defaults */
4230                           false, /* add_ipc */
4231                           true, /* reinit_globals */
4232                           true,  /* allow_include_registry */
4233                           true); /* load_all_shares*/
4234 }
4235
4236 /***************************************************************************
4237  Return the max number of services.
4238 ***************************************************************************/
4239
4240 int lp_numservices(void)
4241 {
4242         return (iNumServices);
4243 }
4244
4245 /***************************************************************************
4246 Display the contents of the services array in human-readable form.
4247 ***************************************************************************/
4248
4249 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4250 {
4251         int iService;
4252         struct loadparm_context *lp_ctx;
4253
4254         if (show_defaults)
4255                 defaults_saved = false;
4256
4257         lp_ctx = setup_lp_context(talloc_tos());
4258         if (lp_ctx == NULL) {
4259                 return;
4260         }
4261
4262         lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
4263
4264         lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
4265
4266         for (iService = 0; iService < maxtoprint; iService++) {
4267                 fprintf(f,"\n");
4268                 lp_dump_one(f, show_defaults, iService);
4269         }
4270         TALLOC_FREE(lp_ctx);
4271 }
4272
4273 /***************************************************************************
4274 Display the contents of one service in human-readable form.
4275 ***************************************************************************/
4276
4277 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4278 {
4279         if (VALID(snum)) {
4280                 if (ServicePtrs[snum]->szService[0] == '\0')
4281                         return;
4282                 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
4283                                      flags_list, show_defaults);
4284         }
4285 }
4286
4287 /***************************************************************************
4288 Return the number of the service with the given name, or -1 if it doesn't
4289 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4290 getservicebyname()! This works ONLY if all services have been loaded, and
4291 does not copy the found service.
4292 ***************************************************************************/
4293
4294 int lp_servicenumber(const char *pszServiceName)
4295 {
4296         int iService;
4297         fstring serviceName;
4298
4299         if (!pszServiceName) {
4300                 return GLOBAL_SECTION_SNUM;
4301         }
4302
4303         for (iService = iNumServices - 1; iService >= 0; iService--) {
4304                 if (VALID(iService) && ServicePtrs[iService]->szService) {
4305                         /*
4306                          * The substitution here is used to support %U in
4307                          * service names
4308                          */
4309                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
4310                         standard_sub_basic(get_current_username(),
4311                                            current_user_info.domain,
4312                                            serviceName,sizeof(serviceName));
4313                         if (strequal(serviceName, pszServiceName)) {
4314                                 break;
4315                         }
4316                 }
4317         }
4318
4319         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4320                 struct timespec last_mod;
4321
4322                 if (!usershare_exists(iService, &last_mod)) {
4323                         /* Remove the share security tdb entry for it. */
4324                         delete_share_security(lp_const_servicename(iService));
4325                         /* Remove it from the array. */
4326                         free_service_byindex(iService);
4327                         /* Doesn't exist anymore. */
4328                         return GLOBAL_SECTION_SNUM;
4329                 }
4330
4331                 /* Has it been modified ? If so delete and reload. */
4332                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4333                                      &last_mod) < 0) {
4334                         /* Remove it from the array. */
4335                         free_service_byindex(iService);
4336                         /* and now reload it. */
4337                         iService = load_usershare_service(pszServiceName);
4338                 }
4339         }
4340
4341         if (iService < 0) {
4342                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4343                 return GLOBAL_SECTION_SNUM;
4344         }
4345
4346         return (iService);
4347 }
4348
4349 /*******************************************************************
4350  A useful volume label function. 
4351 ********************************************************************/
4352
4353 const char *volume_label(TALLOC_CTX *ctx, int snum)
4354 {
4355         const struct loadparm_substitution *lp_sub =
4356                 loadparm_s3_global_substitution();
4357         char *ret;
4358         const char *label = lp_volume(ctx, lp_sub, snum);
4359         size_t end = 32;
4360
4361         if (!*label) {
4362                 label = lp_servicename(ctx, lp_sub, snum);
4363         }
4364
4365         /*
4366          * Volume label can be a max of 32 bytes. Make sure to truncate
4367          * it at a codepoint boundary if it's longer than 32 and contains
4368          * multibyte characters. Windows insists on a volume label being
4369          * a valid mb sequence, and errors out if not.
4370          */
4371         if (strlen(label) > 32) {
4372                 /*
4373                  * A MB char can be a max of 5 bytes, thus
4374                  * we should have a valid mb character at a
4375                  * minimum position of (32-5) = 27.
4376                  */
4377                 while (end >= 27) {
4378                         /*
4379                          * Check if a codepoint starting from next byte
4380                          * is valid. If yes, then the current byte is the
4381                          * end of a MB or ascii sequence and the label can
4382                          * be safely truncated here. If not, keep going
4383                          * backwards till a valid codepoint is found.
4384                          */
4385                         size_t len = 0;
4386                         const char *s = &label[end];
4387                         codepoint_t c = next_codepoint(s, &len);
4388                         if (c != INVALID_CODEPOINT) {
4389                                 break;
4390                         }
4391                         end--;
4392                 }
4393         }
4394
4395         /* This returns a max of 33 byte guarenteed null terminated string. */
4396         ret = talloc_strndup(ctx, label, end);
4397         if (!ret) {
4398                 return "";
4399         }
4400         return ret;
4401 }
4402
4403 /*******************************************************************
4404  Get the default server type we will announce as via nmbd.
4405 ********************************************************************/
4406
4407 int lp_default_server_announce(void)
4408 {
4409         int default_server_announce = 0;
4410         default_server_announce |= SV_TYPE_WORKSTATION;
4411         default_server_announce |= SV_TYPE_SERVER;
4412         default_server_announce |= SV_TYPE_SERVER_UNIX;
4413
4414         /* note that the flag should be set only if we have a 
4415            printer service but nmbd doesn't actually load the 
4416            services so we can't tell   --jerry */
4417
4418         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4419
4420         default_server_announce |= SV_TYPE_SERVER_NT;
4421         default_server_announce |= SV_TYPE_NT;
4422
4423         switch (lp_server_role()) {
4424                 case ROLE_DOMAIN_MEMBER:
4425                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4426                         break;
4427                 case ROLE_DOMAIN_PDC:
4428                 case ROLE_IPA_DC:
4429                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4430                         break;
4431                 case ROLE_DOMAIN_BDC:
4432                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4433                         break;
4434                 case ROLE_STANDALONE:
4435                 default:
4436                         break;
4437         }
4438         if (lp_time_server())
4439                 default_server_announce |= SV_TYPE_TIME_SOURCE;
4440
4441         if (lp_host_msdfs())
4442                 default_server_announce |= SV_TYPE_DFS_SERVER;
4443
4444         return default_server_announce;
4445 }
4446
4447 /***********************************************************
4448  If we are PDC then prefer us as DMB
4449 ************************************************************/
4450
4451 bool lp_domain_master(void)
4452 {
4453         if (Globals._domain_master == Auto)
4454                 return (lp_server_role() == ROLE_DOMAIN_PDC ||
4455                         lp_server_role() == ROLE_IPA_DC);
4456
4457         return (bool)Globals._domain_master;
4458 }
4459
4460 /***********************************************************
4461  If we are PDC then prefer us as DMB
4462 ************************************************************/
4463
4464 static bool lp_domain_master_true_or_auto(void)
4465 {
4466         if (Globals._domain_master) /* auto or yes */
4467                 return true;
4468
4469         return false;
4470 }
4471
4472 /***********************************************************
4473  If we are DMB then prefer us as LMB
4474 ************************************************************/
4475
4476 bool lp_preferred_master(void)
4477 {
4478         int preferred_master = lp__preferred_master();
4479
4480         if (preferred_master == Auto)
4481                 return (lp_local_master() && lp_domain_master());
4482
4483         return (bool)preferred_master;
4484 }
4485
4486 /*******************************************************************
4487  Remove a service.
4488 ********************************************************************/
4489
4490 void lp_remove_service(int snum)
4491 {
4492         ServicePtrs[snum]->valid = false;
4493 }
4494
4495 const char *lp_printername(TALLOC_CTX *ctx,
4496                            const struct loadparm_substitution *lp_sub,
4497                            int snum)
4498 {
4499         const char *ret = lp__printername(ctx, lp_sub, snum);
4500
4501         if (ret == NULL || *ret == '\0') {
4502                 ret = lp_const_servicename(snum);
4503         }
4504
4505         return ret;
4506 }
4507
4508
4509 /***********************************************************
4510  Allow daemons such as winbindd to fix their logfile name.
4511 ************************************************************/
4512
4513 void lp_set_logfile(const char *name)
4514 {
4515         lpcfg_string_set(Globals.ctx, &Globals.logfile, name);
4516         debug_set_logfile(name);
4517 }
4518
4519 /*******************************************************************
4520  Return the max print jobs per queue.
4521 ********************************************************************/
4522
4523 int lp_maxprintjobs(int snum)
4524 {
4525         int maxjobs = lp_max_print_jobs(snum);
4526
4527         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4528                 maxjobs = PRINT_MAX_JOBID - 1;
4529
4530         return maxjobs;
4531 }
4532
4533 const char *lp_printcapname(void)
4534 {
4535         const char *printcap_name = lp_printcap_name();
4536
4537         if ((printcap_name != NULL) &&
4538             (printcap_name[0] != '\0'))
4539                 return printcap_name;
4540
4541         if (sDefault.printing == PRINT_CUPS) {
4542                 return "cups";
4543         }
4544
4545         if (sDefault.printing == PRINT_BSD)
4546                 return "/etc/printcap";
4547
4548         return PRINTCAP_NAME;
4549 }
4550
4551 static uint32_t spoolss_state;
4552
4553 bool lp_disable_spoolss( void )
4554 {
4555         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4556                 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4557
4558         return spoolss_state == SVCCTL_STOPPED ? true : false;
4559 }
4560
4561 void lp_set_spoolss_state( uint32_t state )
4562 {
4563         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4564
4565         spoolss_state = state;
4566 }
4567
4568 uint32_t lp_get_spoolss_state( void )
4569 {
4570         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4571 }
4572
4573 /*******************************************************************
4574  Turn off sendfile if we find the underlying OS doesn't support it.
4575 ********************************************************************/
4576
4577 void set_use_sendfile(int snum, bool val)
4578 {
4579         if (LP_SNUM_OK(snum))
4580                 ServicePtrs[snum]->_use_sendfile = val;
4581         else
4582                 sDefault._use_sendfile = val;
4583 }
4584
4585 void lp_set_mangling_method(const char *new_method)
4586 {
4587         lpcfg_string_set(Globals.ctx, &Globals.mangling_method, new_method);
4588 }
4589
4590 /*******************************************************************
4591  Global state for POSIX pathname processing.
4592 ********************************************************************/
4593
4594 static bool posix_pathnames;
4595
4596 bool lp_posix_pathnames(void)
4597 {
4598         return posix_pathnames;
4599 }
4600
4601 /*******************************************************************
4602  Change everything needed to ensure POSIX pathname processing (currently
4603  not much).
4604 ********************************************************************/
4605
4606 void lp_set_posix_pathnames(void)
4607 {
4608         posix_pathnames = true;
4609 }
4610
4611 /*******************************************************************
4612  Global state for POSIX lock processing - CIFS unix extensions.
4613 ********************************************************************/
4614
4615 bool posix_default_lock_was_set;
4616 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4617
4618 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4619 {
4620         if (posix_default_lock_was_set) {
4621                 return posix_cifsx_locktype;
4622         } else {
4623                 return (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
4624                         POSIX_LOCK : WINDOWS_LOCK;
4625         }
4626 }
4627
4628 /*******************************************************************
4629 ********************************************************************/
4630
4631 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4632 {
4633         posix_default_lock_was_set = true;
4634         posix_cifsx_locktype = val;
4635 }
4636
4637 int lp_min_receive_file_size(void)
4638 {
4639         int min_receivefile_size = lp_min_receivefile_size();
4640
4641         if (min_receivefile_size < 0) {
4642                 return 0;
4643         }
4644         return min_receivefile_size;
4645 }
4646
4647 /*******************************************************************
4648  Safe wide links checks.
4649  This helper function always verify the validity of wide links,
4650  even after a configuration file reload.
4651 ********************************************************************/
4652
4653 void widelinks_warning(int snum)
4654 {
4655         if (lp_allow_insecure_wide_links()) {
4656                 return;
4657         }
4658
4659         if (lp_unix_extensions() && lp_wide_links(snum)) {
4660                 DBG_ERR("Share '%s' has wide links and unix extensions enabled. "
4661                         "These parameters are incompatible. "
4662                         "Wide links will be disabled for this share.\n",
4663                          lp_const_servicename(snum));
4664         }
4665 }
4666
4667 bool lp_widelinks(int snum)
4668 {
4669         /* wide links is always incompatible with unix extensions */
4670         if (lp_unix_extensions()) {
4671                 /*
4672                  * Unless we have "allow insecure widelinks"
4673                  * turned on.
4674                  */
4675                 if (!lp_allow_insecure_wide_links()) {
4676                         return false;
4677                 }
4678         }
4679
4680         return lp_wide_links(snum);
4681 }
4682
4683 int lp_server_role(void)
4684 {
4685         return lp_find_server_role(lp__server_role(),
4686                                    lp__security(),
4687                                    lp__domain_logons(),
4688                                    lp_domain_master_true_or_auto());
4689 }
4690
4691 int lp_security(void)
4692 {
4693         return lp_find_security(lp__server_role(),
4694                                 lp__security());
4695 }
4696
4697 int lp_client_max_protocol(void)
4698 {
4699         int client_max_protocol = lp__client_max_protocol();
4700         if (client_max_protocol == PROTOCOL_DEFAULT) {
4701                 return PROTOCOL_LATEST;
4702         }
4703         return client_max_protocol;
4704 }
4705
4706 int lp_client_ipc_min_protocol(void)
4707 {
4708         int client_ipc_min_protocol = lp__client_ipc_min_protocol();
4709         if (client_ipc_min_protocol == PROTOCOL_DEFAULT) {
4710                 client_ipc_min_protocol = lp_client_min_protocol();
4711         }
4712         if (client_ipc_min_protocol < PROTOCOL_NT1) {
4713                 return PROTOCOL_NT1;
4714         }
4715         return client_ipc_min_protocol;
4716 }
4717
4718 int lp_client_ipc_max_protocol(void)
4719 {
4720         int client_ipc_max_protocol = lp__client_ipc_max_protocol();
4721         if (client_ipc_max_protocol == PROTOCOL_DEFAULT) {
4722                 return PROTOCOL_LATEST;
4723         }
4724         if (client_ipc_max_protocol < PROTOCOL_NT1) {
4725                 return PROTOCOL_NT1;
4726         }
4727         return client_ipc_max_protocol;
4728 }
4729
4730 int lp_client_ipc_signing(void)
4731 {
4732         int client_ipc_signing = lp__client_ipc_signing();
4733         if (client_ipc_signing == SMB_SIGNING_DEFAULT) {
4734                 return SMB_SIGNING_REQUIRED;
4735         }
4736         return client_ipc_signing;
4737 }
4738
4739 enum credentials_use_kerberos lp_client_use_kerberos(void)
4740 {
4741         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
4742                 return CRED_USE_KERBEROS_REQUIRED;
4743         }
4744
4745         return lp__client_use_kerberos();
4746 }
4747
4748
4749 int lp_rpc_low_port(void)
4750 {
4751         return Globals.rpc_low_port;
4752 }
4753
4754 int lp_rpc_high_port(void)
4755 {
4756         return Globals.rpc_high_port;
4757 }
4758
4759 /*
4760  * Do not allow LanMan auth if unless NTLMv1 is also allowed
4761  *
4762  * This also ensures it is disabled if NTLM is totally disabled
4763  */
4764 bool lp_lanman_auth(void)
4765 {
4766         enum ntlm_auth_level ntlm_auth_level = lp_ntlm_auth();
4767
4768         if (ntlm_auth_level == NTLM_AUTH_ON) {
4769                 return lp__lanman_auth();
4770         } else {
4771                 return false;
4772         }
4773 }
4774
4775 struct loadparm_global * get_globals(void)
4776 {
4777         return &Globals;
4778 }
4779
4780 unsigned int * get_flags(void)
4781 {
4782         if (flags_list == NULL) {
4783                 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());
4784         }
4785
4786         return flags_list;
4787 }
4788
4789 enum samba_weak_crypto lp_weak_crypto()
4790 {
4791         if (Globals.weak_crypto == SAMBA_WEAK_CRYPTO_UNKNOWN) {
4792                 Globals.weak_crypto = SAMBA_WEAK_CRYPTO_DISALLOWED;
4793
4794                 if (samba_gnutls_weak_crypto_allowed()) {
4795                         Globals.weak_crypto = SAMBA_WEAK_CRYPTO_ALLOWED;
4796                 }
4797         }
4798
4799         return Globals.weak_crypto;
4800 }
4801
4802 uint32_t lp_get_async_dns_timeout(void)
4803 {
4804         /*
4805          * Clamp minimum async dns timeout to 1 second
4806          * as per the man page.
4807          */
4808         return MAX(Globals.async_dns_timeout, 1);
4809 }