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