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