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