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