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