param: move set_param_opt to lib/param
[mat/samba.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14    Copyright (C) Andrew Bartlett 2011
15
16    This program is free software; you can redistribute it and/or modify
17    it under the terms of the GNU General Public License as published by
18    the Free Software Foundation; either version 3 of the License, or
19    (at your option) any later version.
20
21    This program is distributed in the hope that it will be useful,
22    but WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24    GNU General Public License for more details.
25
26    You should have received a copy of the GNU General Public License
27    along with this program.  If not, see <http://www.gnu.org/licenses/>.
28 */
29
30 /*
31  *  Load parameters.
32  *
33  *  This module provides suitable callback functions for the params
34  *  module. It builds the internal table of service details which is
35  *  then used by the rest of the server.
36  *
37  * To add a parameter:
38  *
39  * 1) add it to the global or service structure definition
40  * 2) add it to the parm_table
41  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42  * 4) If it's a global then initialise it in init_globals. If a local
43  *    (ie. service) parameter then initialise it in the sDefault structure
44  *  
45  *
46  * Notes:
47  *   The configuration file is processed sequentially for speed. It is NOT
48  *   accessed randomly as happens in 'real' Windows. For this reason, there
49  *   is a fair bit of sequence-dependent code here - ie., code which assumes
50  *   that certain things happen before others. In particular, the code which
51  *   happens at the boundary between sections is delicately poised, so be
52  *   careful!
53  *
54  */
55
56 #include "includes.h"
57 #include "system/filesys.h"
58 #include "util_tdb.h"
59 #include "lib/param/loadparm.h"
60 #include "lib/param/param.h"
61 #include "printing.h"
62 #include "lib/smbconf/smbconf.h"
63 #include "lib/smbconf/smbconf_init.h"
64
65 #include "ads.h"
66 #include "../librpc/gen_ndr/svcctl.h"
67 #include "intl.h"
68 #include "../libcli/smb/smb_signing.h"
69 #include "dbwrap/dbwrap.h"
70 #include "dbwrap/dbwrap_rbt.h"
71 #include "../lib/util/bitmap.h"
72
73 #ifdef HAVE_SYS_SYSCTL_H
74 #include <sys/sysctl.h>
75 #endif
76
77 #ifdef HAVE_HTTPCONNECTENCRYPT
78 #include <cups/http.h>
79 #endif
80
81 bool bLoaded = false;
82
83 extern userdom_struct current_user_info;
84
85 /* the special value for the include parameter
86  * to be interpreted not as a file name but to
87  * trigger loading of the global smb.conf options
88  * from registry. */
89 #ifndef INCLUDE_REGISTRY_NAME
90 #define INCLUDE_REGISTRY_NAME "registry"
91 #endif
92
93 static bool in_client = false;          /* Not in the client by default */
94 static struct smbconf_csn conf_last_csn;
95
96 static int config_backend = CONFIG_BACKEND_FILE;
97
98 /* some helpful bits */
99 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
100 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
101
102 #define USERSHARE_VALID 1
103 #define USERSHARE_PENDING_DELETE 2
104
105 static bool defaults_saved = false;
106
107 #include "lib/param/param_global.h"
108
109 static struct loadparm_global Globals;
110
111 /* This is a default service used to prime a services structure */
112 static struct loadparm_service sDefault =
113 {
114         .valid = true,
115         .autoloaded = false,
116         .usershare = 0,
117         .usershare_last_mod = {0, 0},
118         .szService = NULL,
119         .path = NULL,
120         .username = NULL,
121         .invalid_users = NULL,
122         .valid_users = NULL,
123         .admin_users = NULL,
124         .szCopy = NULL,
125         .szInclude = NULL,
126         .preexec = NULL,
127         .postexec = NULL,
128         .root_preexec = NULL,
129         .root_postexec = NULL,
130         .cups_options = NULL,
131         .print_command = NULL,
132         .lpq_command = NULL,
133         .lprm_command = NULL,
134         .lppause_command = NULL,
135         .lpresume_command = NULL,
136         .queuepause_command = NULL,
137         .queueresume_command = NULL,
138         ._printername = NULL,
139         .printjob_username = NULL,
140         .dont_descend = NULL,
141         .hosts_allow = NULL,
142         .hosts_deny = NULL,
143         .magic_script = NULL,
144         .magic_output = NULL,
145         .veto_files = NULL,
146         .hide_files = NULL,
147         .veto_oplock_files = NULL,
148         .comment = NULL,
149         .force_user = NULL,
150         .force_group = NULL,
151         .read_list = NULL,
152         .write_list = NULL,
153         .volume = NULL,
154         .fstype = NULL,
155         .vfs_objects = NULL,
156         .msdfs_proxy = NULL,
157         .aio_write_behind = NULL,
158         .dfree_command = NULL,
159         .min_print_space = 0,
160         .iMaxPrintJobs = 1000,
161         .max_reported_print_jobs = 0,
162         .write_cache_size = 0,
163         .create_mask = 0744,
164         .force_create_mode = 0,
165         .directory_mask = 0755,
166         .force_directory_mode = 0,
167         .max_connections = 0,
168         .default_case = CASE_LOWER,
169         .printing = DEFAULT_PRINTING,
170         .oplock_contention_limit = 2,
171         .csc_policy = 0,
172         .block_size = 1024,
173         .dfree_cache_time = 0,
174         .preexec_close = false,
175         .root_preexec_close = false,
176         .case_sensitive = Auto,
177         .preserve_case = true,
178         .short_preserve_case = true,
179         .hide_dot_files = true,
180         .hide_special_files = false,
181         .hide_unreadable = false,
182         .hide_unwriteable_files = false,
183         .browseable = true,
184         .access_based_share_enum = false,
185         .bAvailable = true,
186         .read_only = true,
187         .guest_only = false,
188         .administrative_share = false,
189         .guest_ok = false,
190         .printable = false,
191         .print_notify_backchannel = false,
192         .map_system = false,
193         .map_hidden = false,
194         .map_archive = true,
195         .store_dos_attributes = false,
196         .dmapi_support = false,
197         .locking = true,
198         .strict_locking = Auto,
199         .posix_locking = true,
200         .oplocks = true,
201         .kernel_oplocks = false,
202         .level2_oplocks = true,
203         .only_user = false,
204         .mangled_names = true,
205         .bWidelinks = false,
206         .follow_symlinks = true,
207         .sync_always = false,
208         .strict_allocate = false,
209         .strict_sync = false,
210         .mangling_char = '~',
211         .copymap = NULL,
212         .delete_readonly = false,
213         .fake_oplocks = false,
214         .delete_veto_files = false,
215         .dos_filemode = false,
216         .dos_filetimes = true,
217         .dos_filetime_resolution = false,
218         .fake_directory_create_times = false,
219         .blocking_locks = true,
220         .inherit_permissions = false,
221         .inherit_acls = false,
222         .inherit_owner = false,
223         .msdfs_root = false,
224         .use_client_driver = false,
225         .default_devmode = true,
226         .force_printername = false,
227         .nt_acl_support = true,
228         .force_unknown_acl_user = false,
229         ._use_sendfile = false,
230         .profile_acls = false,
231         .map_acl_inherit = false,
232         .afs_share = false,
233         .ea_support = false,
234         .acl_check_permissions = true,
235         .acl_map_full_control = true,
236         .acl_group_control = false,
237         .acl_allow_execute_always = false,
238         .change_notify = true,
239         .kernel_change_notify = true,
240         .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
241         .aio_read_size = 0,
242         .aio_write_size = 0,
243         .map_readonly = MAP_READONLY_YES,
244         .directory_name_cache_size = 100,
245         .smb_encrypt = SMB_SIGNING_DEFAULT,
246         .kernel_share_modes = true,
247         .durable_handles = true,
248         .param_opt = NULL,
249         .dummy = ""
250 };
251
252 /* local variables */
253 static struct loadparm_service **ServicePtrs = NULL;
254 static int iNumServices = 0;
255 static int iServiceIndex = 0;
256 static struct db_context *ServiceHash;
257 static bool bInGlobalSection = true;
258 static bool bGlobalOnly = false;
259
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                          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         struct loadparm_service tservice;
1543         int num_to_alloc = iNumServices + 1;
1544         struct loadparm_service **tsp = NULL;
1545
1546         tservice = *pservice;
1547
1548         /* it might already exist */
1549         if (name) {
1550                 i = getservicebyname(name, NULL);
1551                 if (i >= 0) {
1552                         return (i);
1553                 }
1554         }
1555
1556         /* if not, then create one */
1557         i = iNumServices;
1558         tsp = talloc_realloc(NULL, ServicePtrs, struct loadparm_service *, num_to_alloc);
1559         if (tsp == NULL) {
1560                 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1561                 return (-1);
1562         }
1563         ServicePtrs = tsp;
1564         ServicePtrs[iNumServices] = talloc(NULL, struct loadparm_service);
1565         if (!ServicePtrs[iNumServices]) {
1566                 DEBUG(0,("add_a_service: out of memory!\n"));
1567                 return (-1);
1568         }
1569         iNumServices++;
1570
1571         ServicePtrs[i]->valid = true;
1572
1573         init_service(ServicePtrs[i]);
1574         copy_service(ServicePtrs[i], &tservice, NULL);
1575         if (name)
1576                 string_set(ServicePtrs[i], &ServicePtrs[i]->szService, name);
1577
1578         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
1579                 i, ServicePtrs[i]->szService));
1580
1581         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1582                 return (-1);
1583         }
1584
1585         return (i);
1586 }
1587
1588 /***************************************************************************
1589   Convert a string to uppercase and remove whitespaces.
1590 ***************************************************************************/
1591
1592 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1593 {
1594         char *result;
1595
1596         if ( !src ) {
1597                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1598                 return NULL;
1599         }
1600
1601         result = talloc_strdup(ctx, src);
1602         SMB_ASSERT(result != NULL);
1603
1604         if (!strlower_m(result)) {
1605                 TALLOC_FREE(result);
1606                 return NULL;
1607         }
1608         return result;
1609 }
1610
1611 /***************************************************************************
1612   Add a name/index pair for the services array to the hash table.
1613 ***************************************************************************/
1614
1615 static bool hash_a_service(const char *name, int idx)
1616 {
1617         char *canon_name;
1618
1619         if ( !ServiceHash ) {
1620                 DEBUG(10,("hash_a_service: creating servicehash\n"));
1621                 ServiceHash = db_open_rbt(NULL);
1622                 if ( !ServiceHash ) {
1623                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1624                         return false;
1625                 }
1626         }
1627
1628         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1629                 idx, name));
1630
1631         canon_name = canonicalize_servicename(talloc_tos(), name );
1632
1633         dbwrap_store_bystring(ServiceHash, canon_name,
1634                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
1635                               TDB_REPLACE);
1636
1637         TALLOC_FREE(canon_name);
1638
1639         return true;
1640 }
1641
1642 /***************************************************************************
1643  Add a new home service, with the specified home directory, defaults coming
1644  from service ifrom.
1645 ***************************************************************************/
1646
1647 bool lp_add_home(const char *pszHomename, int iDefaultService,
1648                  const char *user, const char *pszHomedir)
1649 {
1650         int i;
1651
1652         if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1653                         pszHomedir[0] == '\0') {
1654                 return false;
1655         }
1656
1657         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1658
1659         if (i < 0)
1660                 return false;
1661
1662         if (!(*(ServicePtrs[iDefaultService]->path))
1663             || strequal(ServicePtrs[iDefaultService]->path,
1664                         lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1665                 string_set(ServicePtrs[i], &ServicePtrs[i]->path, pszHomedir);
1666         }
1667
1668         if (!(*(ServicePtrs[i]->comment))) {
1669                 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1670                 if (comment == NULL) {
1671                         return false;
1672                 }
1673                 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1674                 TALLOC_FREE(comment);
1675         }
1676
1677         /* set the browseable flag from the global default */
1678
1679         ServicePtrs[i]->browseable = sDefault.browseable;
1680         ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1681
1682         ServicePtrs[i]->autoloaded = true;
1683
1684         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
1685                user, ServicePtrs[i]->path ));
1686
1687         return true;
1688 }
1689
1690 /***************************************************************************
1691  Add a new service, based on an old one.
1692 ***************************************************************************/
1693
1694 int lp_add_service(const char *pszService, int iDefaultService)
1695 {
1696         if (iDefaultService < 0) {
1697                 return add_a_service(&sDefault, pszService);
1698         }
1699
1700         return (add_a_service(ServicePtrs[iDefaultService], pszService));
1701 }
1702
1703 /***************************************************************************
1704  Add the IPC service.
1705 ***************************************************************************/
1706
1707 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1708 {
1709         char *comment = NULL;
1710         int i = add_a_service(&sDefault, ipc_name);
1711
1712         if (i < 0)
1713                 return false;
1714
1715         comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1716                                   Globals.server_string);
1717         if (comment == NULL) {
1718                 return false;
1719         }
1720
1721         string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1722         string_set(ServicePtrs[i], &ServicePtrs[i]->username, "");
1723         string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1724         string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1725         ServicePtrs[i]->max_connections = 0;
1726         ServicePtrs[i]->bAvailable = true;
1727         ServicePtrs[i]->read_only = true;
1728         ServicePtrs[i]->guest_only = false;
1729         ServicePtrs[i]->administrative_share = true;
1730         ServicePtrs[i]->guest_ok = guest_ok;
1731         ServicePtrs[i]->printable = false;
1732         ServicePtrs[i]->browseable = sDefault.browseable;
1733
1734         DEBUG(3, ("adding IPC service\n"));
1735
1736         TALLOC_FREE(comment);
1737         return true;
1738 }
1739
1740 /***************************************************************************
1741  Add a new printer service, with defaults coming from service iFrom.
1742 ***************************************************************************/
1743
1744 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1745 {
1746         const char *comment = "From Printcap";
1747         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1748
1749         if (i < 0)
1750                 return false;
1751
1752         /* note that we do NOT default the availability flag to true - */
1753         /* we take it from the default service passed. This allows all */
1754         /* dynamic printers to be disabled by disabling the [printers] */
1755         /* entry (if/when the 'available' keyword is implemented!).    */
1756
1757         /* the printer name is set to the service name. */
1758         string_set(ServicePtrs[i], &ServicePtrs[i]->_printername, pszPrintername);
1759         string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1760
1761         /* set the browseable flag from the gloabl default */
1762         ServicePtrs[i]->browseable = sDefault.browseable;
1763
1764         /* Printers cannot be read_only. */
1765         ServicePtrs[i]->read_only = false;
1766         /* No oplocks on printer services. */
1767         ServicePtrs[i]->oplocks = false;
1768         /* Printer services must be printable. */
1769         ServicePtrs[i]->printable = true;
1770
1771         DEBUG(3, ("adding printer service %s\n", pszPrintername));
1772
1773         return true;
1774 }
1775
1776
1777 /***************************************************************************
1778  Check whether the given parameter name is valid.
1779  Parametric options (names containing a colon) are considered valid.
1780 ***************************************************************************/
1781
1782 bool lp_parameter_is_valid(const char *pszParmName)
1783 {
1784         return ((lpcfg_map_parameter(pszParmName) != -1) ||
1785                 (strchr(pszParmName, ':') != NULL));
1786 }
1787
1788 /***************************************************************************
1789  Check whether the given name is the name of a global parameter.
1790  Returns true for strings belonging to parameters of class
1791  P_GLOBAL, false for all other strings, also for parametric options
1792  and strings not belonging to any option.
1793 ***************************************************************************/
1794
1795 bool lp_parameter_is_global(const char *pszParmName)
1796 {
1797         int num = lpcfg_map_parameter(pszParmName);
1798
1799         if (num >= 0) {
1800                 return (parm_table[num].p_class == P_GLOBAL);
1801         }
1802
1803         return false;
1804 }
1805
1806 /**************************************************************************
1807  Check whether the given name is the canonical name of a parameter.
1808  Returns false if it is not a valid parameter Name.
1809  For parametric options, true is returned.
1810 **************************************************************************/
1811
1812 bool lp_parameter_is_canonical(const char *parm_name)
1813 {
1814         if (!lp_parameter_is_valid(parm_name)) {
1815                 return false;
1816         }
1817
1818         return (lpcfg_map_parameter(parm_name) ==
1819                 map_parameter_canonical(parm_name, NULL));
1820 }
1821
1822 /**************************************************************************
1823  Determine the canonical name for a parameter.
1824  Indicate when it is an inverse (boolean) synonym instead of a
1825  "usual" synonym.
1826 **************************************************************************/
1827
1828 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1829                                bool *inverse)
1830 {
1831         int num;
1832
1833         if (!lp_parameter_is_valid(parm_name)) {
1834                 *canon_parm = NULL;
1835                 return false;
1836         }
1837
1838         num = map_parameter_canonical(parm_name, inverse);
1839         if (num < 0) {
1840                 /* parametric option */
1841                 *canon_parm = parm_name;
1842         } else {
1843                 *canon_parm = parm_table[num].label;
1844         }
1845
1846         return true;
1847
1848 }
1849
1850 /**************************************************************************
1851  Determine the canonical name for a parameter.
1852  Turn the value given into the inverse boolean expression when
1853  the synonym is an invers boolean synonym.
1854
1855  Return true if parm_name is a valid parameter name and
1856  in case it is an invers boolean synonym, if the val string could
1857  successfully be converted to the reverse bool.
1858  Return false in all other cases.
1859 **************************************************************************/
1860
1861 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1862                                           const char *val,
1863                                           const char **canon_parm,
1864                                           const char **canon_val)
1865 {
1866         int num;
1867         bool inverse;
1868
1869         if (!lp_parameter_is_valid(parm_name)) {
1870                 *canon_parm = NULL;
1871                 *canon_val = NULL;
1872                 return false;
1873         }
1874
1875         num = map_parameter_canonical(parm_name, &inverse);
1876         if (num < 0) {
1877                 /* parametric option */
1878                 *canon_parm = parm_name;
1879                 *canon_val = val;
1880         } else {
1881                 *canon_parm = parm_table[num].label;
1882                 if (inverse) {
1883                         if (!lp_invert_boolean(val, canon_val)) {
1884                                 *canon_val = NULL;
1885                                 return false;
1886                         }
1887                 } else {
1888                         *canon_val = val;
1889                 }
1890         }
1891
1892         return true;
1893 }
1894
1895 /***************************************************************************
1896  Map a parameter's string representation to the index of the canonical
1897  form of the parameter (it might be a synonym).
1898  Returns -1 if the parameter string is not recognised.
1899 ***************************************************************************/
1900
1901 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1902 {
1903         int parm_num, canon_num;
1904         bool loc_inverse = false;
1905
1906         parm_num = lpcfg_map_parameter(pszParmName);
1907         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
1908                 /* invalid, parametric or no canidate for synonyms ... */
1909                 goto done;
1910         }
1911
1912         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1913                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1914                         parm_num = canon_num;
1915                         goto done;
1916                 }
1917         }
1918
1919 done:
1920         if (inverse != NULL) {
1921                 *inverse = loc_inverse;
1922         }
1923         return parm_num;
1924 }
1925
1926 /***************************************************************************
1927  return true if parameter number parm1 is a synonym of parameter
1928  number parm2 (parm2 being the principal name).
1929  set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1930  false otherwise.
1931 ***************************************************************************/
1932
1933 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1934 {
1935         if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1936             (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1937             (parm_table[parm1].flags & FLAG_HIDE) &&
1938             !(parm_table[parm2].flags & FLAG_HIDE))
1939         {
1940                 if (inverse != NULL) {
1941                         if ((parm_table[parm1].type == P_BOOLREV) &&
1942                             (parm_table[parm2].type == P_BOOL))
1943                         {
1944                                 *inverse = true;
1945                         } else {
1946                                 *inverse = false;
1947                         }
1948                 }
1949                 return true;
1950         }
1951         return false;
1952 }
1953
1954 /***************************************************************************
1955  Show one parameter's name, type, [values,] and flags.
1956  (helper functions for show_parameter_list)
1957 ***************************************************************************/
1958
1959 static void show_parameter(int parmIndex)
1960 {
1961         int enumIndex, flagIndex;
1962         int parmIndex2;
1963         bool hadFlag;
1964         bool hadSyn;
1965         bool inverse;
1966         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1967                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1968                 "P_ENUM", "P_SEP"};
1969         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
1970                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
1971                 FLAG_HIDE};
1972         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
1973                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
1974                 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
1975
1976         printf("%s=%s", parm_table[parmIndex].label,
1977                type[parm_table[parmIndex].type]);
1978         if (parm_table[parmIndex].type == P_ENUM) {
1979                 printf(",");
1980                 for (enumIndex=0;
1981                      parm_table[parmIndex].enum_list[enumIndex].name;
1982                      enumIndex++)
1983                 {
1984                         printf("%s%s",
1985                                enumIndex ? "|" : "",
1986                                parm_table[parmIndex].enum_list[enumIndex].name);
1987                 }
1988         }
1989         printf(",");
1990         hadFlag = false;
1991         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1992                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1993                         printf("%s%s",
1994                                 hadFlag ? "|" : "",
1995                                 flag_names[flagIndex]);
1996                         hadFlag = true;
1997                 }
1998         }
1999
2000         /* output synonyms */
2001         hadSyn = false;
2002         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
2003                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
2004                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
2005                                parm_table[parmIndex2].label);
2006                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
2007                         if (!hadSyn) {
2008                                 printf(" (synonyms: ");
2009                                 hadSyn = true;
2010                         } else {
2011                                 printf(", ");
2012                         }
2013                         printf("%s%s", parm_table[parmIndex2].label,
2014                                inverse ? "[i]" : "");
2015                 }
2016         }
2017         if (hadSyn) {
2018                 printf(")");
2019         }
2020
2021         printf("\n");
2022 }
2023
2024 /***************************************************************************
2025  Show all parameter's name, type, [values,] and flags.
2026 ***************************************************************************/
2027
2028 void show_parameter_list(void)
2029 {
2030         int classIndex, parmIndex;
2031         const char *section_names[] = { "local", "global", NULL};
2032
2033         for (classIndex=0; section_names[classIndex]; classIndex++) {
2034                 printf("[%s]\n", section_names[classIndex]);
2035                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2036                         if (parm_table[parmIndex].p_class == classIndex) {
2037                                 show_parameter(parmIndex);
2038                         }
2039                 }
2040         }
2041 }
2042
2043 /***************************************************************************
2044  Get the standard string representation of a boolean value ("yes" or "no")
2045 ***************************************************************************/
2046
2047 static const char *get_boolean(bool bool_value)
2048 {
2049         static const char *yes_str = "yes";
2050         static const char *no_str = "no";
2051
2052         return (bool_value ? yes_str : no_str);
2053 }
2054
2055 /***************************************************************************
2056  Provide the string of the negated boolean value associated to the boolean
2057  given as a string. Returns false if the passed string does not correctly
2058  represent a boolean.
2059 ***************************************************************************/
2060
2061 bool lp_invert_boolean(const char *str, const char **inverse_str)
2062 {
2063         bool val;
2064
2065         if (!set_boolean(str, &val)) {
2066                 return false;
2067         }
2068
2069         *inverse_str = get_boolean(!val);
2070         return true;
2071 }
2072
2073 /***************************************************************************
2074  Provide the canonical string representation of a boolean value given
2075  as a string. Return true on success, false if the string given does
2076  not correctly represent a boolean.
2077 ***************************************************************************/
2078
2079 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
2080 {
2081         bool val;
2082
2083         if (!set_boolean(str, &val)) {
2084                 return false;
2085         }
2086
2087         *canon_str = get_boolean(val);
2088         return true;
2089 }
2090
2091 /***************************************************************************
2092 Find a service by name. Otherwise works like get_service.
2093 ***************************************************************************/
2094
2095 static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
2096 {
2097         int iService = -1;
2098         char *canon_name;
2099         TDB_DATA data;
2100         NTSTATUS status;
2101
2102         if (ServiceHash == NULL) {
2103                 return -1;
2104         }
2105
2106         canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
2107
2108         status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
2109                                        &data);
2110
2111         if (NT_STATUS_IS_OK(status) &&
2112             (data.dptr != NULL) &&
2113             (data.dsize == sizeof(iService)))
2114         {
2115                 iService = *(int *)data.dptr;
2116         }
2117
2118         TALLOC_FREE(canon_name);
2119
2120         if ((iService != -1) && (LP_SNUM_OK(iService))
2121             && (pserviceDest != NULL)) {
2122                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2123         }
2124
2125         return (iService);
2126 }
2127
2128 /* Return a pointer to a service by name.  Unlike getservicebyname, it does not copy the service */
2129 struct loadparm_service *lp_service(const char *pszServiceName)
2130 {
2131         int iService = getservicebyname(pszServiceName, NULL);
2132         if (iService == -1 || !LP_SNUM_OK(iService)) {
2133                 return NULL;
2134         }
2135         return ServicePtrs[iService];
2136 }
2137
2138 struct loadparm_service *lp_servicebynum(int snum)
2139 {
2140         if ((snum == -1) || !LP_SNUM_OK(snum)) {
2141                 return NULL;
2142         }
2143         return ServicePtrs[snum];
2144 }
2145
2146 struct loadparm_service *lp_default_loadparm_service()
2147 {
2148         return &sDefault;
2149 }
2150
2151
2152 /***************************************************************************
2153  Copy a service structure to another.
2154  If pcopymapDest is NULL then copy all fields
2155 ***************************************************************************/
2156
2157 static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
2158                          struct bitmap *pcopymapDest)
2159 {
2160         int i;
2161         bool bcopyall = (pcopymapDest == NULL);
2162         struct parmlist_entry *data;
2163
2164         for (i = 0; parm_table[i].label; i++)
2165                 if (parm_table[i].p_class == P_LOCAL &&
2166                     (bcopyall || bitmap_query(pcopymapDest,i))) {
2167                         void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
2168                         void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
2169
2170                         switch (parm_table[i].type) {
2171                                 case P_BOOL:
2172                                 case P_BOOLREV:
2173                                         *(bool *)dest_ptr = *(bool *)src_ptr;
2174                                         break;
2175
2176                                 case P_INTEGER:
2177                                 case P_ENUM:
2178                                 case P_OCTAL:
2179                                 case P_BYTES:
2180                                         *(int *)dest_ptr = *(int *)src_ptr;
2181                                         break;
2182
2183                                 case P_CHAR:
2184                                         *(char *)dest_ptr = *(char *)src_ptr;
2185                                         break;
2186
2187                                 case P_STRING:
2188                                         string_set(pserviceDest, (char **)dest_ptr,
2189                                                    *(char **)src_ptr);
2190                                         break;
2191
2192                                 case P_USTRING:
2193                                 {
2194                                         char *upper_string = strupper_talloc(talloc_tos(), 
2195                                                                              *(char **)src_ptr);
2196                                         string_set(pserviceDest, (char **)dest_ptr,
2197                                                    upper_string);
2198                                         TALLOC_FREE(upper_string);
2199                                         break;
2200                                 }
2201                                 case P_LIST:
2202                                         TALLOC_FREE(*((char ***)dest_ptr));
2203                                         *((char ***)dest_ptr) = str_list_copy(NULL, 
2204                                                       *(const char ***)src_ptr);
2205                                         break;
2206                                 default:
2207                                         break;
2208                         }
2209                 }
2210
2211         if (bcopyall) {
2212                 init_copymap(pserviceDest);
2213                 if (pserviceSource->copymap)
2214                         bitmap_copy(pserviceDest->copymap,
2215                                     pserviceSource->copymap);
2216         }
2217
2218         data = pserviceSource->param_opt;
2219         while (data) {
2220                 set_param_opt(pserviceDest, &pserviceDest->param_opt, data->key, data->value, data->priority);
2221                 data = data->next;
2222         }
2223 }
2224
2225 /***************************************************************************
2226 Check a service for consistency. Return false if the service is in any way
2227 incomplete or faulty, else true.
2228 ***************************************************************************/
2229
2230 bool service_ok(int iService)
2231 {
2232         bool bRetval;
2233
2234         bRetval = true;
2235         if (ServicePtrs[iService]->szService[0] == '\0') {
2236                 DEBUG(0, ("The following message indicates an internal error:\n"));
2237                 DEBUG(0, ("No service name in service entry.\n"));
2238                 bRetval = false;
2239         }
2240
2241         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2242         /* I can't see why you'd want a non-printable printer service...        */
2243         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2244                 if (!ServicePtrs[iService]->printable) {
2245                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2246                                ServicePtrs[iService]->szService));
2247                         ServicePtrs[iService]->printable = true;
2248                 }
2249                 /* [printers] service must also be non-browsable. */
2250                 if (ServicePtrs[iService]->browseable)
2251                         ServicePtrs[iService]->browseable = false;
2252         }
2253
2254         if (ServicePtrs[iService]->path[0] == '\0' &&
2255             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
2256             ServicePtrs[iService]->msdfs_proxy[0] == '\0'
2257             ) {
2258                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2259                         ServicePtrs[iService]->szService));
2260                 ServicePtrs[iService]->bAvailable = false;
2261         }
2262
2263         /* If a service is flagged unavailable, log the fact at level 1. */
2264         if (!ServicePtrs[iService]->bAvailable)
2265                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2266                           ServicePtrs[iService]->szService));
2267
2268         return (bRetval);
2269 }
2270
2271 static struct smbconf_ctx *lp_smbconf_ctx(void)
2272 {
2273         sbcErr err;
2274         static struct smbconf_ctx *conf_ctx = NULL;
2275
2276         if (conf_ctx == NULL) {
2277                 err = smbconf_init(NULL, &conf_ctx, "registry:");
2278                 if (!SBC_ERROR_IS_OK(err)) {
2279                         DEBUG(1, ("error initializing registry configuration: "
2280                                   "%s\n", sbcErrorString(err)));
2281                         conf_ctx = NULL;
2282                 }
2283         }
2284
2285         return conf_ctx;
2286 }
2287
2288 static bool process_smbconf_service(struct smbconf_service *service)
2289 {
2290         uint32_t count;
2291         bool ret;
2292
2293         if (service == NULL) {
2294                 return false;
2295         }
2296
2297         ret = do_section(service->name, NULL);
2298         if (ret != true) {
2299                 return false;
2300         }
2301         for (count = 0; count < service->num_params; count++) {
2302                 ret = do_parameter(service->param_names[count],
2303                                    service->param_values[count],
2304                                    NULL);
2305                 if (ret != true) {
2306                         return false;
2307                 }
2308         }
2309         if (iServiceIndex >= 0) {
2310                 return service_ok(iServiceIndex);
2311         }
2312         return true;
2313 }
2314
2315 /**
2316  * load a service from registry and activate it
2317  */
2318 bool process_registry_service(const char *service_name)
2319 {
2320         sbcErr err;
2321         struct smbconf_service *service = NULL;
2322         TALLOC_CTX *mem_ctx = talloc_stackframe();
2323         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2324         bool ret = false;
2325
2326         if (conf_ctx == NULL) {
2327                 goto done;
2328         }
2329
2330         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
2331
2332         if (!smbconf_share_exists(conf_ctx, service_name)) {
2333                 /*
2334                  * Registry does not contain data for this service (yet),
2335                  * but make sure lp_load doesn't return false.
2336                  */
2337                 ret = true;
2338                 goto done;
2339         }
2340
2341         err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
2342         if (!SBC_ERROR_IS_OK(err)) {
2343                 goto done;
2344         }
2345
2346         ret = process_smbconf_service(service);
2347         if (!ret) {
2348                 goto done;
2349         }
2350
2351         /* store the csn */
2352         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2353
2354 done:
2355         TALLOC_FREE(mem_ctx);
2356         return ret;
2357 }
2358
2359 /*
2360  * process_registry_globals
2361  */
2362 static bool process_registry_globals(void)
2363 {
2364         bool ret;
2365
2366         add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2367
2368         ret = do_parameter("registry shares", "yes", NULL);
2369         if (!ret) {
2370                 return ret;
2371         }
2372
2373         return process_registry_service(GLOBAL_NAME);
2374 }
2375
2376 bool process_registry_shares(void)
2377 {
2378         sbcErr err;
2379         uint32_t count;
2380         struct smbconf_service **service = NULL;
2381         uint32_t num_shares = 0;
2382         TALLOC_CTX *mem_ctx = talloc_stackframe();
2383         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2384         bool ret = false;
2385
2386         if (conf_ctx == NULL) {
2387                 goto done;
2388         }
2389
2390         err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2391         if (!SBC_ERROR_IS_OK(err)) {
2392                 goto done;
2393         }
2394
2395         ret = true;
2396
2397         for (count = 0; count < num_shares; count++) {
2398                 if (strequal(service[count]->name, GLOBAL_NAME)) {
2399                         continue;
2400                 }
2401                 ret = process_smbconf_service(service[count]);
2402                 if (!ret) {
2403                         goto done;
2404                 }
2405         }
2406
2407         /* store the csn */
2408         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2409
2410 done:
2411         TALLOC_FREE(mem_ctx);
2412         return ret;
2413 }
2414
2415 /**
2416  * reload those shares from registry that are already
2417  * activated in the services array.
2418  */
2419 static bool reload_registry_shares(void)
2420 {
2421         int i;
2422         bool ret = true;
2423
2424         for (i = 0; i < iNumServices; i++) {
2425                 if (!VALID(i)) {
2426                         continue;
2427                 }
2428
2429                 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2430                         continue;
2431                 }
2432
2433                 ret = process_registry_service(ServicePtrs[i]->szService);
2434                 if (!ret) {
2435                         goto done;
2436                 }
2437         }
2438
2439 done:
2440         return ret;
2441 }
2442
2443
2444 #define MAX_INCLUDE_DEPTH 100
2445
2446 static uint8_t include_depth;
2447
2448 static struct file_lists {
2449         struct file_lists *next;
2450         char *name;
2451         char *subfname;
2452         time_t modtime;
2453 } *file_lists = NULL;
2454
2455 /*******************************************************************
2456  Keep a linked list of all config files so we know when one has changed 
2457  it's date and needs to be reloaded.
2458 ********************************************************************/
2459
2460 static void add_to_file_list(const char *fname, const char *subfname)
2461 {
2462         struct file_lists *f = file_lists;
2463
2464         while (f) {
2465                 if (f->name && !strcmp(f->name, fname))
2466                         break;
2467                 f = f->next;
2468         }
2469
2470         if (!f) {
2471                 f = talloc(NULL, struct file_lists);
2472                 if (!f) {
2473                         goto fail;
2474                 }
2475                 f->next = file_lists;
2476                 f->name = talloc_strdup(f, fname);
2477                 if (!f->name) {
2478                         TALLOC_FREE(f);
2479                         goto fail;
2480                 }
2481                 f->subfname = talloc_strdup(f, subfname);
2482                 if (!f->subfname) {
2483                         TALLOC_FREE(f);
2484                         goto fail;
2485                 }
2486                 file_lists = f;
2487                 f->modtime = file_modtime(subfname);
2488         } else {
2489                 time_t t = file_modtime(subfname);
2490                 if (t)
2491                         f->modtime = t;
2492         }
2493         return;
2494
2495 fail:
2496         DEBUG(0, ("Unable to add file to file list: %s\n", fname));
2497
2498 }
2499
2500 /**
2501  * Free the file lists
2502  */
2503 static void free_file_list(void)
2504 {
2505         struct file_lists *f;
2506         struct file_lists *next;
2507
2508         f = file_lists;
2509         while( f ) {
2510                 next = f->next;
2511                 TALLOC_FREE( f );
2512                 f = next;
2513         }
2514         file_lists = NULL;
2515 }
2516
2517
2518 /**
2519  * Utility function for outsiders to check if we're running on registry.
2520  */
2521 bool lp_config_backend_is_registry(void)
2522 {
2523         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2524 }
2525
2526 /**
2527  * Utility function to check if the config backend is FILE.
2528  */
2529 bool lp_config_backend_is_file(void)
2530 {
2531         return (lp_config_backend() == CONFIG_BACKEND_FILE);
2532 }
2533
2534 /*******************************************************************
2535  Check if a config file has changed date.
2536 ********************************************************************/
2537
2538 bool lp_file_list_changed(void)
2539 {
2540         struct file_lists *f = file_lists;
2541
2542         DEBUG(6, ("lp_file_list_changed()\n"));
2543
2544         while (f) {
2545                 time_t mod_time;
2546
2547                 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2548                         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2549
2550                         if (conf_ctx == NULL) {
2551                                 return false;
2552                         }
2553                         if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2554                                             NULL))
2555                         {
2556                                 DEBUGADD(6, ("registry config changed\n"));
2557                                 return true;
2558                         }
2559                 } else {
2560                         char *n2 = NULL;
2561                         n2 = talloc_sub_basic(talloc_tos(),
2562                                               get_current_username(),
2563                                               current_user_info.domain,
2564                                               f->name);
2565                         if (!n2) {
2566                                 return false;
2567                         }
2568                         DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
2569                                      f->name, n2, ctime(&f->modtime)));
2570
2571                         mod_time = file_modtime(n2);
2572
2573                         if (mod_time &&
2574                             ((f->modtime != mod_time) ||
2575                              (f->subfname == NULL) ||
2576                              (strcmp(n2, f->subfname) != 0)))
2577                         {
2578                                 DEBUGADD(6,
2579                                          ("file %s modified: %s\n", n2,
2580                                           ctime(&mod_time)));
2581                                 f->modtime = mod_time;
2582                                 TALLOC_FREE(f->subfname);
2583                                 f->subfname = talloc_strdup(f, n2);
2584                                 if (f->subfname == NULL) {
2585                                         smb_panic("talloc_strdup failed");
2586                                 }
2587                                 TALLOC_FREE(n2);
2588                                 return true;
2589                         }
2590                         TALLOC_FREE(n2);
2591                 }
2592                 f = f->next;
2593         }
2594         return false;
2595 }
2596
2597
2598 /**
2599  * Initialize iconv conversion descriptors.
2600  *
2601  * This is called the first time it is needed, and also called again
2602  * every time the configuration is reloaded, because the charset or
2603  * codepage might have changed.
2604  **/
2605 static void init_iconv(void)
2606 {
2607         global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2608                                                       lp_unix_charset(),
2609                                                       true, global_iconv_handle);
2610 }
2611
2612 static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2613 {
2614         if (strcmp(*ptr, pszParmValue) != 0) {
2615                 string_set(Globals.ctx, ptr, pszParmValue);
2616                 init_iconv();
2617         }
2618         return true;
2619 }
2620
2621 static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2622 {
2623         bool is_utf8 = false;
2624         size_t len = strlen(pszParmValue);
2625
2626         if (len == 4 || len == 5) {
2627                 /* Don't use StrCaseCmp here as we don't want to
2628                    initialize iconv. */
2629                 if ((toupper_m(pszParmValue[0]) == 'U') &&
2630                     (toupper_m(pszParmValue[1]) == 'T') &&
2631                     (toupper_m(pszParmValue[2]) == 'F')) {
2632                         if (len == 4) {
2633                                 if (pszParmValue[3] == '8') {
2634                                         is_utf8 = true;
2635                                 }
2636                         } else {
2637                                 if (pszParmValue[3] == '-' &&
2638                                     pszParmValue[4] == '8') {
2639                                         is_utf8 = true;
2640                                 }
2641                         }
2642                 }
2643         }
2644
2645         if (strcmp(*ptr, pszParmValue) != 0) {
2646                 if (is_utf8) {
2647                         DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
2648                                 "be UTF8, using (default value) %s instead.\n",
2649                                 DEFAULT_DOS_CHARSET));
2650                         pszParmValue = DEFAULT_DOS_CHARSET;
2651                 }
2652                 string_set(Globals.ctx, ptr, pszParmValue);
2653                 init_iconv();
2654         }
2655         return true;
2656 }
2657
2658 static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2659 {
2660         TALLOC_FREE(Globals.netbios_aliases);
2661         Globals.netbios_aliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
2662         return set_netbios_aliases(Globals.netbios_aliases);
2663 }
2664
2665 /***************************************************************************
2666  Handle the include operation.
2667 ***************************************************************************/
2668 static bool bAllowIncludeRegistry = true;
2669
2670 static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2671 {
2672         char *fname;
2673
2674         if (include_depth >= MAX_INCLUDE_DEPTH) {
2675                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2676                           include_depth));
2677                 return false;
2678         }
2679
2680         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2681                 if (!bAllowIncludeRegistry) {
2682                         return true;
2683                 }
2684                 if (bInGlobalSection) {
2685                         bool ret;
2686                         include_depth++;
2687                         ret = process_registry_globals();
2688                         include_depth--;
2689                         return ret;
2690                 } else {
2691                         DEBUG(1, ("\"include = registry\" only effective "
2692                                   "in %s section\n", GLOBAL_NAME));
2693                         return false;
2694                 }
2695         }
2696
2697         fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2698                                  current_user_info.domain,
2699                                  pszParmValue);
2700
2701         add_to_file_list(pszParmValue, fname);
2702
2703         if (snum < 0) {
2704                 string_set(Globals.ctx, ptr, fname);
2705         } else {
2706                 string_set(ServicePtrs[snum], ptr, fname);
2707         }
2708
2709         if (file_exist(fname)) {
2710                 bool ret;
2711                 include_depth++;
2712                 ret = pm_process(fname, do_section, do_parameter, NULL);
2713                 include_depth--;
2714                 TALLOC_FREE(fname);
2715                 return ret;
2716         }
2717
2718         DEBUG(2, ("Can't find include file %s\n", fname));
2719         TALLOC_FREE(fname);
2720         return true;
2721 }
2722
2723 /***************************************************************************
2724  Handle the interpretation of the copy parameter.
2725 ***************************************************************************/
2726
2727 static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2728 {
2729         bool bRetval;
2730         int iTemp;
2731
2732         bRetval = false;
2733
2734         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2735
2736         if ((iTemp = getservicebyname(pszParmValue, NULL)) >= 0) {
2737                 if (iTemp == iServiceIndex) {
2738                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2739                 } else {
2740                         copy_service(ServicePtrs[iServiceIndex],
2741                                      ServicePtrs[iTemp],
2742                                      ServicePtrs[iServiceIndex]->copymap);
2743                         string_set(ServicePtrs[iServiceIndex], ptr, pszParmValue);
2744                         bRetval = true;
2745                 }
2746         } else {
2747                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2748                 bRetval = false;
2749         }
2750
2751         return (bRetval);
2752 }
2753
2754 static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2755 {
2756         Globals.ldap_debug_level = lp_int(pszParmValue);
2757         init_ldap_debugging();
2758         return true;
2759 }
2760
2761 /*
2762  * idmap related parameters
2763  */
2764
2765 static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2766 {
2767         lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
2768
2769         return true;
2770 }
2771
2772 static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2773 {
2774         lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2775
2776         return true;
2777 }
2778
2779 static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2780 {
2781         lp_do_parameter(snum, "idmap config * : range", pszParmValue);
2782
2783         return true;
2784 }
2785
2786 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2787 {
2788         char *config_option = NULL;
2789         const char *range = NULL;
2790         bool ret = false;
2791
2792         SMB_ASSERT(low != NULL);
2793         SMB_ASSERT(high != NULL);
2794
2795         if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2796                 domain_name = "*";
2797         }
2798
2799         config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2800                                         domain_name);
2801         if (config_option == NULL) {
2802                 DEBUG(0, ("out of memory\n"));
2803                 return false;
2804         }
2805
2806         range = lp_parm_const_string(-1, config_option, "range", NULL);
2807         if (range == NULL) {
2808                 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2809                 goto done;
2810         }
2811
2812         if (sscanf(range, "%u - %u", low, high) != 2) {
2813                 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2814                           range, domain_name));
2815                 goto done;
2816         }
2817
2818         ret = true;
2819
2820 done:
2821         talloc_free(config_option);
2822         return ret;
2823
2824 }
2825
2826 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2827 {
2828         return lp_idmap_range("*", low, high);
2829 }
2830
2831 const char *lp_idmap_backend(const char *domain_name)
2832 {
2833         char *config_option = NULL;
2834         const char *backend = NULL;
2835
2836         if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2837                 domain_name = "*";
2838         }
2839
2840         config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2841                                         domain_name);
2842         if (config_option == NULL) {
2843                 DEBUG(0, ("out of memory\n"));
2844                 return false;
2845         }
2846
2847         backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2848         if (backend == NULL) {
2849                 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2850                 goto done;
2851         }
2852
2853 done:
2854         talloc_free(config_option);
2855         return backend;
2856 }
2857
2858 const char *lp_idmap_default_backend(void)
2859 {
2860         return lp_idmap_backend("*");
2861 }
2862
2863 /***************************************************************************
2864  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2865 ***************************************************************************/
2866
2867 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2868 {
2869         const char *suffix_string;
2870
2871         suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2872                                         Globals.ldap_suffix );
2873         if ( !suffix_string ) {
2874                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2875                 return "";
2876         }
2877
2878         return suffix_string;
2879 }
2880
2881 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2882 {
2883         if (Globals.szLdapMachineSuffix[0])
2884                 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
2885
2886         return lp_string(ctx, Globals.ldap_suffix);
2887 }
2888
2889 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2890 {
2891         if (Globals.szLdapUserSuffix[0])
2892                 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
2893
2894         return lp_string(ctx, Globals.ldap_suffix);
2895 }
2896
2897 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2898 {
2899         if (Globals.szLdapGroupSuffix[0])
2900                 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
2901
2902         return lp_string(ctx, Globals.ldap_suffix);
2903 }
2904
2905 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2906 {
2907         if (Globals.szLdapIdmapSuffix[0])
2908                 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
2909
2910         return lp_string(ctx, Globals.ldap_suffix);
2911 }
2912
2913 /****************************************************************************
2914  set the value for a P_ENUM
2915  ***************************************************************************/
2916
2917 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
2918                               int *ptr )
2919 {
2920         int i;
2921
2922         for (i = 0; parm->enum_list[i].name; i++) {
2923                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
2924                         *ptr = parm->enum_list[i].value;
2925                         return;
2926                 }
2927         }
2928         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
2929                   pszParmValue, parm->label));
2930 }
2931
2932 /***************************************************************************
2933 ***************************************************************************/
2934
2935 static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
2936 {
2937         static int parm_num = -1;
2938         struct loadparm_service *s;
2939
2940         if ( parm_num == -1 )
2941                 parm_num = lpcfg_map_parameter( "printing" );
2942
2943         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
2944
2945         if ( snum < 0 ) {
2946                 s = &sDefault;
2947                 init_printer_values(Globals.ctx, s);
2948         } else {
2949                 s = ServicePtrs[snum];
2950                 init_printer_values(s, s);
2951         }
2952
2953         return true;
2954 }
2955
2956
2957 /***************************************************************************
2958  Initialise a copymap.
2959 ***************************************************************************/
2960
2961 static void init_copymap(struct loadparm_service *pservice)
2962 {
2963         int i;
2964
2965         TALLOC_FREE(pservice->copymap);
2966
2967         pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
2968         if (!pservice->copymap)
2969                 DEBUG(0,
2970                       ("Couldn't allocate copymap!! (size %d)\n",
2971                        (int)NUMPARAMETERS));
2972         else
2973                 for (i = 0; i < NUMPARAMETERS; i++)
2974                         bitmap_set(pservice->copymap, i);
2975 }
2976
2977 /**
2978   return the parameter pointer for a parameter
2979 */
2980 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2981 {
2982         if (service == NULL) {
2983                 if (parm->p_class == P_LOCAL)
2984                         return (void *)(((char *)&sDefault)+parm->offset);
2985                 else if (parm->p_class == P_GLOBAL)
2986                         return (void *)(((char *)&Globals)+parm->offset);
2987                 else return NULL;
2988         } else {
2989                 return (void *)(((char *)service) + parm->offset);
2990         }
2991 }
2992
2993 /***************************************************************************
2994  Return the local pointer to a parameter given the service number and parameter
2995 ***************************************************************************/
2996
2997 void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm)
2998 {
2999         return lp_parm_ptr(ServicePtrs[snum], parm);
3000 }
3001
3002 /***************************************************************************
3003  Process a parameter for a particular service number. If snum < 0
3004  then assume we are in the globals.
3005 ***************************************************************************/
3006
3007 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3008 {
3009         int parmnum, i;
3010         void *parm_ptr = NULL;  /* where we are going to store the result */
3011         struct parmlist_entry **opt_list;
3012         TALLOC_CTX *mem_ctx;
3013
3014         parmnum = lpcfg_map_parameter(pszParmName);
3015
3016         if (parmnum < 0) {
3017                 if (strchr(pszParmName, ':') == NULL) {
3018                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
3019                                   pszParmName));
3020                         return true;
3021                 }
3022
3023                 /*
3024                  * We've got a parametric option
3025                  */
3026
3027                 if (snum < 0) {
3028                         opt_list = &Globals.param_opt;
3029                         set_param_opt(NULL, opt_list, pszParmName, pszParmValue, 0);
3030                 } else {
3031                         opt_list = &ServicePtrs[snum]->param_opt;
3032                         set_param_opt(ServicePtrs[snum], opt_list, pszParmName, pszParmValue, 0);
3033                 }
3034
3035                 return true;
3036         }
3037
3038         /* if it's already been set by the command line, then we don't
3039            override here */
3040         if (parm_table[parmnum].flags & FLAG_CMDLINE) {
3041                 return true;
3042         }
3043
3044         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3045                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3046                           pszParmName));
3047         }
3048
3049         /* we might point at a service, the default service or a global */
3050         if (snum < 0) {
3051                 parm_ptr = lp_parm_ptr(NULL, &parm_table[parmnum]);
3052         } else {
3053                 if (parm_table[parmnum].p_class == P_GLOBAL) {
3054                         DEBUG(0,
3055                               ("Global parameter %s found in service section!\n",
3056                                pszParmName));
3057                         return true;
3058                 }
3059                 parm_ptr = lp_local_ptr_by_snum(snum, &parm_table[parmnum]);
3060         }
3061
3062         if (snum >= 0) {
3063                 if (!ServicePtrs[snum]->copymap)
3064                         init_copymap(ServicePtrs[snum]);
3065
3066                 /* this handles the aliases - set the copymap for other entries with
3067                    the same data pointer */
3068                 for (i = 0; parm_table[i].label; i++) {
3069                         if ((parm_table[i].offset == parm_table[parmnum].offset)
3070                             && (parm_table[i].p_class == parm_table[parmnum].p_class)) {
3071                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
3072                         }
3073                 }
3074                 mem_ctx = ServicePtrs[snum];
3075         } else {
3076                 mem_ctx = Globals.ctx;
3077         }
3078
3079         /* if it is a special case then go ahead */
3080         if (parm_table[parmnum].special) {
3081                 bool ok;
3082                 struct loadparm_context *lp_ctx = loadparm_init_s3(talloc_tos(),
3083                                                                    loadparm_s3_helpers());
3084                 ok = parm_table[parmnum].special(lp_ctx, snum, pszParmValue,
3085                                                   (char **)parm_ptr);
3086                 TALLOC_FREE(lp_ctx);
3087
3088                 return ok;
3089         }
3090
3091         /* now switch on the type of variable it is */
3092         switch (parm_table[parmnum].type)
3093         {
3094                 case P_BOOL:
3095                         *(bool *)parm_ptr = lp_bool(pszParmValue);
3096                         break;
3097
3098                 case P_BOOLREV:
3099                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
3100                         break;
3101
3102                 case P_INTEGER:
3103                         *(int *)parm_ptr = lp_int(pszParmValue);
3104                         break;
3105
3106                 case P_CHAR:
3107                         *(char *)parm_ptr = *pszParmValue;
3108                         break;
3109
3110                 case P_OCTAL:
3111                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3112                         if ( i != 1 ) {
3113                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3114                         }
3115                         break;
3116
3117                 case P_BYTES:
3118                 {
3119                         uint64_t val;
3120                         if (conv_str_size_error(pszParmValue, &val)) {
3121                                 if (val <= INT_MAX) {
3122                                         *(int *)parm_ptr = (int)val;
3123                                         break;
3124                                 }
3125                         }
3126
3127                         DEBUG(0,("lp_do_parameter(%s): value is not "
3128                             "a valid size specifier!\n", pszParmValue));
3129                         return false;
3130                 }
3131
3132                 case P_LIST:
3133                 case P_CMDLIST:
3134                         TALLOC_FREE(*((char ***)parm_ptr));
3135                         *(char ***)parm_ptr = str_list_make_v3(
3136                                 NULL, pszParmValue, NULL);
3137                         break;
3138
3139                 case P_STRING:
3140                         string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
3141                         break;
3142
3143                 case P_USTRING:
3144                 {
3145                         char *upper_string = strupper_talloc(talloc_tos(), 
3146                                                              pszParmValue);
3147                         string_set(mem_ctx, (char **)parm_ptr, upper_string);
3148                         TALLOC_FREE(upper_string);
3149                         break;
3150                 }
3151                 case P_ENUM:
3152                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3153                         break;
3154                 case P_SEP:
3155                         break;
3156         }
3157
3158         return true;
3159 }
3160
3161 /***************************************************************************
3162 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
3163 FLAG_CMDLINE won't be overridden by loads from smb.conf.
3164 ***************************************************************************/
3165
3166 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
3167 {
3168         int parmnum, i;
3169         parmnum = lpcfg_map_parameter(pszParmName);
3170         if (parmnum >= 0) {
3171                 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
3172                 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
3173                         return false;
3174                 }
3175                 parm_table[parmnum].flags |= FLAG_CMDLINE;
3176
3177                 /* we have to also set FLAG_CMDLINE on aliases.  Aliases must
3178                  * be grouped in the table, so we don't have to search the
3179                  * whole table */
3180                 for (i=parmnum-1;
3181                      i>=0 && parm_table[i].offset == parm_table[parmnum].offset
3182                              && parm_table[i].p_class == parm_table[parmnum].p_class;
3183                      i--) {
3184                         parm_table[i].flags |= FLAG_CMDLINE;
3185                 }
3186                 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset
3187                              && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
3188                         parm_table[i].flags |= FLAG_CMDLINE;
3189                 }
3190
3191                 if (store_values) {
3192                         store_lp_set_cmdline(pszParmName, pszParmValue);
3193                 }
3194                 return true;
3195         }
3196
3197         /* it might be parametric */
3198         if (strchr(pszParmName, ':') != NULL) {
3199                 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
3200                 if (store_values) {
3201                         store_lp_set_cmdline(pszParmName, pszParmValue);
3202                 }
3203                 return true;
3204         }
3205
3206         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",  pszParmName));
3207         return true;
3208 }
3209
3210 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
3211 {
3212         return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
3213 }
3214
3215 /***************************************************************************
3216  Process a parameter.
3217 ***************************************************************************/
3218
3219 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
3220                          void *userdata)
3221 {
3222         if (!bInGlobalSection && bGlobalOnly)
3223                 return true;
3224
3225         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3226
3227         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3228                                 pszParmName, pszParmValue));
3229 }
3230
3231 /*
3232   set a option from the commandline in 'a=b' format. Use to support --option
3233 */
3234 bool lp_set_option(const char *option)
3235 {
3236         char *p, *s;
3237         bool ret;
3238
3239         s = talloc_strdup(NULL, option);
3240         if (!s) {
3241                 return false;
3242         }
3243
3244         p = strchr(s, '=');
3245         if (!p) {
3246                 talloc_free(s);
3247                 return false;
3248         }
3249
3250         *p = 0;
3251
3252         /* skip white spaces after the = sign */
3253         do {
3254                 p++;
3255         } while (*p == ' ');
3256
3257         ret = lp_set_cmdline(s, p);
3258         talloc_free(s);
3259         return ret;
3260 }
3261
3262 /***************************************************************************
3263  Initialize any local variables in the sDefault table, after parsing a
3264  [globals] section.
3265 ***************************************************************************/
3266
3267 static void init_locals(void)
3268 {
3269         /*
3270          * We run this check once the [globals] is parsed, to force
3271          * the VFS objects and other per-share settings we need for
3272          * the standard way a AD DC is operated.  We may change these
3273          * as our code evolves, which is why we force these settings.
3274          *
3275          * We can't do this at the end of lp_load_ex(), as by that
3276          * point the services have been loaded and they will already
3277          * have "" as their vfs objects.
3278          */
3279         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3280                 const char **vfs_objects = lp_vfs_objects(-1);
3281                 if (!vfs_objects || !vfs_objects[0]) {
3282                         if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
3283                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
3284                         } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
3285                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
3286                         } else {
3287                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
3288                         }
3289                 }
3290
3291                 lp_do_parameter(-1, "map hidden", "no");
3292                 lp_do_parameter(-1, "map system", "no");
3293                 lp_do_parameter(-1, "map readonly", "no");
3294                 lp_do_parameter(-1, "map archive", "no");
3295                 lp_do_parameter(-1, "store dos attributes", "yes");
3296         }
3297 }
3298
3299 /***************************************************************************
3300  Process a new section (service). At this stage all sections are services.
3301  Later we'll have special sections that permit server parameters to be set.
3302  Returns true on success, false on failure.
3303 ***************************************************************************/
3304
3305 static bool do_section(const char *pszSectionName, void *userdata)
3306 {
3307         bool bRetval;
3308         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3309                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3310         bRetval = false;
3311
3312         /* if we were in a global section then do the local inits */
3313         if (bInGlobalSection && !isglobal)
3314                 init_locals();
3315
3316         /* if we've just struck a global section, note the fact. */
3317         bInGlobalSection = isglobal;
3318
3319         /* check for multiple global sections */
3320         if (bInGlobalSection) {
3321                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3322                 return true;
3323         }
3324
3325         if (!bInGlobalSection && bGlobalOnly)
3326                 return true;
3327
3328         /* if we have a current service, tidy it up before moving on */
3329         bRetval = true;
3330
3331         if (iServiceIndex >= 0)
3332                 bRetval = service_ok(iServiceIndex);
3333
3334         /* if all is still well, move to the next record in the services array */
3335         if (bRetval) {
3336                 /* We put this here to avoid an odd message order if messages are */
3337                 /* issued by the post-processing of a previous section. */
3338                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3339
3340                 iServiceIndex = add_a_service(&sDefault, pszSectionName);
3341                 if (iServiceIndex < 0) {
3342                         DEBUG(0, ("Failed to add a new service\n"));
3343                         return false;
3344                 }
3345                 /* Clean all parametric options for service */
3346                 /* They will be added during parsing again */
3347                 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
3348         }
3349
3350         return bRetval;
3351 }
3352
3353
3354 /***************************************************************************
3355  Determine if a partcular base parameter is currentl set to the default value.
3356 ***************************************************************************/
3357
3358 static bool is_default(int i)
3359 {
3360         switch (parm_table[i].type) {
3361                 case P_LIST:
3362                 case P_CMDLIST:
3363                         return str_list_equal((const char **)parm_table[i].def.lvalue, 
3364                                               *(const char ***)lp_parm_ptr(NULL, 
3365                                                                            &parm_table[i]));
3366                 case P_STRING:
3367                 case P_USTRING:
3368                         return strequal(parm_table[i].def.svalue,
3369                                         *(char **)lp_parm_ptr(NULL, 
3370                                                               &parm_table[i]));
3371                 case P_BOOL:
3372                 case P_BOOLREV:
3373                         return parm_table[i].def.bvalue ==
3374                                 *(bool *)lp_parm_ptr(NULL, 
3375                                                      &parm_table[i]);
3376                 case P_CHAR:
3377                         return parm_table[i].def.cvalue ==
3378                                 *(char *)lp_parm_ptr(NULL, 
3379                                                      &parm_table[i]);
3380                 case P_INTEGER:
3381                 case P_OCTAL:
3382                 case P_ENUM:
3383                 case P_BYTES:
3384                         return parm_table[i].def.ivalue ==
3385                                 *(int *)lp_parm_ptr(NULL, 
3386                                                     &parm_table[i]);
3387                 case P_SEP:
3388                         break;
3389         }
3390         return false;
3391 }
3392
3393 /***************************************************************************
3394 Display the contents of the global structure.
3395 ***************************************************************************/
3396
3397 static void dump_globals(FILE *f)
3398 {
3399         int i;
3400         struct parmlist_entry *data;
3401
3402         fprintf(f, "[global]\n");
3403
3404         for (i = 0; parm_table[i].label; i++)
3405                 if (parm_table[i].p_class == P_GLOBAL &&
3406                     !(parm_table[i].flags & FLAG_META) &&
3407                     (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
3408                         if (defaults_saved && is_default(i))
3409                                 continue;
3410                         fprintf(f, "\t%s = ", parm_table[i].label);
3411                         lpcfg_print_parameter(&parm_table[i], lp_parm_ptr(NULL,
3412                                                                           &parm_table[i]),
3413                                         f);
3414                         fprintf(f, "\n");
3415         }
3416         if (Globals.param_opt != NULL) {
3417                 data = Globals.param_opt;
3418                 while(data) {
3419                         fprintf(f, "\t%s = %s\n", data->key, data->value);
3420                         data = data->next;
3421                 }
3422         }
3423
3424 }
3425
3426 /***************************************************************************
3427  Display the contents of a single services record.
3428 ***************************************************************************/
3429
3430 static void dump_a_service(struct loadparm_service *pService, FILE * f)
3431 {
3432         int i;
3433         struct parmlist_entry *data;
3434
3435         if (pService != &sDefault)
3436                 fprintf(f, "[%s]\n", pService->szService);
3437
3438         for (i = 0; parm_table[i].label; i++) {
3439
3440                 if (parm_table[i].p_class == P_LOCAL &&
3441                     !(parm_table[i].flags & FLAG_META) &&
3442                     (*parm_table[i].label != '-') &&
3443                     (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) 
3444                 {
3445                         if (pService == &sDefault) {
3446                                 if (defaults_saved && is_default(i))
3447                                         continue;
3448                         } else {
3449                                 if (lpcfg_equal_parameter(parm_table[i].type,
3450                                                           lp_parm_ptr(pService, &parm_table[i]),
3451                                                           lp_parm_ptr(NULL, &parm_table[i])))
3452                                         continue;
3453                         }
3454
3455                         fprintf(f, "\t%s = ", parm_table[i].label);
3456                         lpcfg_print_parameter(&parm_table[i],
3457                                         lp_parm_ptr(pService, &parm_table[i]),
3458                                         f);
3459                         fprintf(f, "\n");
3460                 }
3461         }
3462
3463                 if (pService->param_opt != NULL) {
3464                         data = pService->param_opt;
3465                         while(data) {
3466                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
3467                                 data = data->next;
3468                         }
3469                 }
3470 }
3471
3472 /***************************************************************************
3473  Display the contents of a parameter of a single services record.
3474 ***************************************************************************/
3475
3476 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
3477 {
3478         bool result = false;
3479         fstring local_parm_name;
3480         char *parm_opt;
3481         const char *parm_opt_value;
3482
3483         struct loadparm_context *lp_ctx;
3484
3485         /* check for parametrical option */
3486         fstrcpy( local_parm_name, parm_name);
3487         parm_opt = strchr( local_parm_name, ':');
3488
3489         if (parm_opt) {
3490                 *parm_opt = '\0';
3491                 parm_opt++;
3492                 if (strlen(parm_opt)) {
3493                         parm_opt_value = lp_parm_const_string( snum,
3494                                 local_parm_name, parm_opt, NULL);
3495                         if (parm_opt_value) {
3496                                 printf( "%s\n", parm_opt_value);
3497                                 result = true;
3498                         }
3499                 }
3500                 return result;
3501         }
3502
3503         lp_ctx = loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
3504         if (lp_ctx == NULL) {
3505                 return false;
3506         }
3507
3508         if (isGlobal) {
3509                 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
3510         } else {
3511                 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
3512         }
3513         TALLOC_FREE(lp_ctx);
3514         return result;
3515 }
3516
3517 /***************************************************************************
3518  Return info about the requested parameter (given as a string).
3519  Return NULL when the string is not a valid parameter name.
3520 ***************************************************************************/
3521
3522 struct parm_struct *lp_get_parameter(const char *param_name)
3523 {
3524         int num = lpcfg_map_parameter(param_name);
3525
3526         if (num < 0) {
3527                 return NULL;
3528         }
3529
3530         return &parm_table[num];
3531 }
3532
3533 #if 0
3534 /***************************************************************************
3535  Display the contents of a single copy structure.
3536 ***************************************************************************/
3537 static void dump_copy_map(bool *pcopymap)
3538 {
3539         int i;
3540         if (!pcopymap)
3541                 return;
3542
3543         printf("\n\tNon-Copied parameters:\n");
3544
3545         for (i = 0; parm_table[i].label; i++)
3546                 if (parm_table[i].p_class == P_LOCAL &&
3547                     parm_table[i].ptr && !pcopymap[i] &&
3548                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3549                 {
3550                         printf("\t\t%s\n", parm_table[i].label);
3551                 }
3552 }
3553 #endif
3554
3555 /***************************************************************************
3556  Return TRUE if the passed service number is within range.
3557 ***************************************************************************/
3558
3559 bool lp_snum_ok(int iService)
3560 {
3561         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3562 }
3563
3564 /***************************************************************************
3565  Auto-load some home services.
3566 ***************************************************************************/
3567
3568 static void lp_add_auto_services(char *str)
3569 {
3570         char *s;
3571         char *p;
3572         int homes;
3573         char *saveptr;
3574
3575         if (!str)
3576                 return;
3577
3578         s = talloc_strdup(talloc_tos(), str);
3579         if (!s) {
3580                 smb_panic("talloc_strdup failed");
3581                 return;
3582         }
3583
3584         homes = lp_servicenumber(HOMES_NAME);
3585
3586         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
3587              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
3588                 char *home;
3589
3590                 if (lp_servicenumber(p) >= 0)
3591                         continue;
3592
3593                 home = get_user_home_dir(talloc_tos(), p);
3594
3595                 if (home && home[0] && homes >= 0)
3596                         lp_add_home(p, homes, p, home);
3597
3598                 TALLOC_FREE(home);
3599         }
3600         TALLOC_FREE(s);
3601 }
3602
3603 /***************************************************************************
3604  Auto-load one printer.
3605 ***************************************************************************/
3606
3607 void lp_add_one_printer(const char *name, const char *comment,
3608                         const char *location, void *pdata)
3609 {
3610         int printers = lp_servicenumber(PRINTERS_NAME);
3611         int i;
3612
3613         if (lp_servicenumber(name) < 0) {
3614                 lp_add_printer(name, printers);
3615                 if ((i = lp_servicenumber(name)) >= 0) {
3616                         string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
3617                         ServicePtrs[i]->autoloaded = true;
3618                 }
3619         }
3620 }
3621
3622 /***************************************************************************
3623  Have we loaded a services file yet?
3624 ***************************************************************************/
3625
3626 bool lp_loaded(void)
3627 {
3628         return (bLoaded);
3629 }
3630
3631 /***************************************************************************
3632  Unload unused services.
3633 ***************************************************************************/
3634
3635 void lp_killunused(struct smbd_server_connection *sconn,
3636                    bool (*snumused) (struct smbd_server_connection *, int))
3637 {
3638         int i;
3639         for (i = 0; i < iNumServices; i++) {
3640                 if (!VALID(i))
3641                         continue;
3642
3643                 /* don't kill autoloaded or usershare services */
3644                 if ( ServicePtrs[i]->autoloaded ||
3645                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
3646                         continue;
3647                 }
3648
3649                 if (!snumused || !snumused(sconn, i)) {
3650                         free_service_byindex(i);
3651                 }
3652         }
3653 }
3654
3655 /**
3656  * Kill all except autoloaded and usershare services - convenience wrapper
3657  */
3658 void lp_kill_all_services(void)
3659 {
3660         lp_killunused(NULL, NULL);
3661 }
3662
3663 /***************************************************************************
3664  Unload a service.
3665 ***************************************************************************/
3666
3667 void lp_killservice(int iServiceIn)
3668 {
3669         if (VALID(iServiceIn)) {
3670                 free_service_byindex(iServiceIn);
3671         }
3672 }
3673
3674 /***************************************************************************
3675  Save the curent values of all global and sDefault parameters into the 
3676  defaults union. This allows testparm to show only the
3677  changed (ie. non-default) parameters.
3678 ***************************************************************************/
3679
3680 static void lp_save_defaults(void)
3681 {
3682         int i;
3683         for (i = 0; parm_table[i].label; i++) {
3684                 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
3685                     && parm_table[i].p_class == parm_table[i - 1].p_class)
3686                         continue;
3687                 switch (parm_table[i].type) {
3688                         case P_LIST:
3689                         case P_CMDLIST:
3690                                 parm_table[i].def.lvalue = str_list_copy(
3691                                         NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
3692                                 break;
3693                         case P_STRING:
3694                         case P_USTRING:
3695                                 parm_table[i].def.svalue = talloc_strdup(Globals.ctx, *(char **)lp_parm_ptr(NULL, &parm_table[i]));
3696                                 if (parm_table[i].def.svalue == NULL) {
3697                                         smb_panic("talloc_strdup failed");
3698                                 }
3699                                 break;
3700                         case P_BOOL:
3701                         case P_BOOLREV:
3702                                 parm_table[i].def.bvalue =
3703                                         *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
3704                                 break;
3705                         case P_CHAR:
3706                                 parm_table[i].def.cvalue =
3707                                         *(char *)lp_parm_ptr(NULL, &parm_table[i]);
3708                                 break;
3709                         case P_INTEGER:
3710                         case P_OCTAL:
3711                         case P_ENUM:
3712                         case P_BYTES:
3713                                 parm_table[i].def.ivalue =
3714                                         *(int *)lp_parm_ptr(NULL, &parm_table[i]);
3715                                 break;
3716                         case P_SEP:
3717                                 break;
3718                 }
3719         }
3720         defaults_saved = true;
3721 }
3722
3723 /***********************************************************
3724  If we should send plaintext/LANMAN passwords in the clinet
3725 ************************************************************/
3726
3727 static void set_allowed_client_auth(void)
3728 {
3729         if (Globals.client_ntlmv2_auth) {
3730                 Globals.client_lanman_auth = false;
3731         }
3732         if (!Globals.client_lanman_auth) {
3733                 Globals.client_plaintext_auth = false;
3734         }
3735 }
3736
3737 /***************************************************************************
3738  JRA.
3739  The following code allows smbd to read a user defined share file.
3740  Yes, this is my intent. Yes, I'm comfortable with that...
3741
3742  THE FOLLOWING IS SECURITY CRITICAL CODE.
3743
3744  It washes your clothes, it cleans your house, it guards you while you sleep...
3745  Do not f%^k with it....
3746 ***************************************************************************/
3747
3748 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3749
3750 /***************************************************************************
3751  Check allowed stat state of a usershare file.
3752  Ensure we print out who is dicking with us so the admin can
3753  get their sorry ass fired.
3754 ***************************************************************************/
3755
3756 static bool check_usershare_stat(const char *fname,
3757                                  const SMB_STRUCT_STAT *psbuf)
3758 {
3759         if (!S_ISREG(psbuf->st_ex_mode)) {
3760                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3761                         "not a regular file\n",
3762                         fname, (unsigned int)psbuf->st_ex_uid ));
3763                 return false;
3764         }
3765
3766         /* Ensure this doesn't have the other write bit set. */
3767         if (psbuf->st_ex_mode & S_IWOTH) {
3768                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3769                         "public write. Refusing to allow as a usershare file.\n",
3770                         fname, (unsigned int)psbuf->st_ex_uid ));
3771                 return false;
3772         }
3773
3774         /* Should be 10k or less. */
3775         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
3776                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3777                         "too large (%u) to be a user share file.\n",
3778                         fname, (unsigned int)psbuf->st_ex_uid,
3779                         (unsigned int)psbuf->st_ex_size ));
3780                 return false;
3781         }
3782
3783         return true;
3784 }
3785
3786 /***************************************************************************
3787  Parse the contents of a usershare file.
3788 ***************************************************************************/
3789
3790 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
3791                         SMB_STRUCT_STAT *psbuf,
3792                         const char *servicename,
3793                         int snum,
3794                         char **lines,
3795                         int numlines,
3796                         char **pp_sharepath,
3797                         char **pp_comment,
3798                         char **pp_cp_servicename,
3799                         struct security_descriptor **ppsd,
3800                         bool *pallow_guest)
3801 {
3802         const char **prefixallowlist = lp_usershare_prefix_allow_list();
3803         const char **prefixdenylist = lp_usershare_prefix_deny_list();
3804         int us_vers;
3805         DIR *dp;
3806         SMB_STRUCT_STAT sbuf;
3807         char *sharepath = NULL;
3808         char *comment = NULL;
3809
3810         *pp_sharepath = NULL;
3811         *pp_comment = NULL;
3812
3813         *pallow_guest = false;
3814
3815         if (numlines < 4) {
3816                 return USERSHARE_MALFORMED_FILE;
3817         }
3818
3819         if (strcmp(lines[0], "#VERSION 1") == 0) {
3820                 us_vers = 1;
3821         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
3822                 us_vers = 2;
3823                 if (numlines < 5) {
3824                         return USERSHARE_MALFORMED_FILE;
3825                 }
3826         } else {
3827                 return USERSHARE_BAD_VERSION;
3828         }
3829
3830         if (strncmp(lines[1], "path=", 5) != 0) {
3831                 return USERSHARE_MALFORMED_PATH;
3832         }
3833
3834         sharepath = talloc_strdup(ctx, &lines[1][5]);
3835         if (!sharepath) {
3836                 return USERSHARE_POSIX_ERR;
3837         }
3838         trim_string(sharepath, " ", " ");
3839
3840         if (strncmp(lines[2], "comment=", 8) != 0) {
3841                 return USERSHARE_MALFORMED_COMMENT_DEF;
3842         }
3843
3844         comment = talloc_strdup(ctx, &lines[2][8]);
3845         if (!comment) {
3846                 return USERSHARE_POSIX_ERR;
3847         }
3848         trim_string(comment, " ", " ");
3849         trim_char(comment, '"', '"');
3850
3851         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
3852                 return USERSHARE_MALFORMED_ACL_DEF;
3853         }
3854
3855         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
3856                 return USERSHARE_ACL_ERR;
3857         }
3858
3859         if (us_vers == 2) {
3860                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
3861                         return USERSHARE_MALFORMED_ACL_DEF;
3862                 }
3863                 if (lines[4][9] == 'y') {
3864                         *pallow_guest = true;
3865                 }
3866
3867                 /* Backwards compatible extension to file version #2. */
3868                 if (numlines > 5) {
3869                         if (strncmp(lines[5], "sharename=", 10) != 0) {
3870                                 return USERSHARE_MALFORMED_SHARENAME_DEF;
3871                         }
3872                         if (!strequal(&lines[5][10], servicename)) {
3873                                 return USERSHARE_BAD_SHARENAME;
3874                         }
3875                         *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3876                         if (!*pp_cp_servicename) {
3877                                 return USERSHARE_POSIX_ERR;
3878                         }
3879                 }
3880         }
3881
3882         if (*pp_cp_servicename == NULL) {
3883                 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3884                 if (!*pp_cp_servicename) {
3885                         return USERSHARE_POSIX_ERR;
3886                 }
3887         }
3888
3889         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3890                 /* Path didn't change, no checks needed. */
3891                 *pp_sharepath = sharepath;
3892                 *pp_comment = comment;
3893                 return USERSHARE_OK;
3894         }
3895
3896         /* The path *must* be absolute. */
3897         if (sharepath[0] != '/') {
3898                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3899                         servicename, sharepath));
3900                 return USERSHARE_PATH_NOT_ABSOLUTE;
3901         }
3902
3903         /* If there is a usershare prefix deny list ensure one of these paths
3904            doesn't match the start of the user given path. */
3905         if (prefixdenylist) {
3906                 int i;
3907                 for ( i=0; prefixdenylist[i]; i++ ) {
3908                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3909                                 servicename, i, prefixdenylist[i], sharepath ));
3910                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3911                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3912                                         "usershare prefix deny list entries.\n",
3913                                         servicename, sharepath));
3914                                 return USERSHARE_PATH_IS_DENIED;
3915                         }
3916                 }
3917         }
3918
3919         /* If there is a usershare prefix allow list ensure one of these paths
3920            does match the start of the user given path. */
3921
3922         if (prefixallowlist) {
3923                 int i;
3924                 for ( i=0; prefixallowlist[i]; i++ ) {
3925                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3926                                 servicename, i, prefixallowlist[i], sharepath ));
3927                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3928                                 break;
3929                         }
3930                 }
3931                 if (prefixallowlist[i] == NULL) {
3932                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3933                                 "usershare prefix allow list entries.\n",
3934                                 servicename, sharepath));
3935                         return USERSHARE_PATH_NOT_ALLOWED;
3936                 }
3937         }
3938
3939         /* Ensure this is pointing to a directory. */
3940         dp = opendir(sharepath);
3941
3942         if (!dp) {
3943                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3944                         servicename, sharepath));
3945                 return USERSHARE_PATH_NOT_DIRECTORY;
3946         }
3947
3948         /* Ensure the owner of the usershare file has permission to share
3949            this directory. */
3950
3951         if (sys_stat(sharepath, &sbuf, false) == -1) {
3952                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3953                         servicename, sharepath, strerror(errno) ));
3954                 closedir(dp);
3955                 return USERSHARE_POSIX_ERR;
3956         }
3957
3958         closedir(dp);
3959
3960         if (!S_ISDIR(sbuf.st_ex_mode)) {
3961                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3962                         servicename, sharepath ));
3963                 return USERSHARE_PATH_NOT_DIRECTORY;
3964         }
3965
3966         /* Check if sharing is restricted to owner-only. */
3967         /* psbuf is the stat of the usershare definition file,
3968            sbuf is the stat of the target directory to be shared. */
3969
3970         if (lp_usershare_owner_only()) {
3971                 /* root can share anything. */
3972                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3973                         return USERSHARE_PATH_NOT_ALLOWED;
3974                 }
3975         }
3976
3977         *pp_sharepath = sharepath;
3978         *pp_comment = comment;
3979         return USERSHARE_OK;
3980 }
3981
3982 /***************************************************************************
3983  Deal with a usershare file.
3984  Returns:
3985         >= 0 - snum
3986         -1 - Bad name, invalid contents.
3987            - service name already existed and not a usershare, problem
3988             with permissions to share directory etc.
3989 ***************************************************************************/
3990
3991 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3992 {
3993         SMB_STRUCT_STAT sbuf;
3994         SMB_STRUCT_STAT lsbuf;
3995         char *fname = NULL;
3996         char *sharepath = NULL;
3997         char *comment = NULL;
3998         char *cp_service_name = NULL;
3999         char **lines = NULL;
4000         int numlines = 0;
4001         int fd = -1;
4002         int iService = -1;
4003         TALLOC_CTX *ctx = talloc_stackframe();
4004         struct security_descriptor *psd = NULL;
4005         bool guest_ok = false;
4006         char *canon_name = NULL;
4007         bool added_service = false;
4008         int ret = -1;
4009
4010         /* Ensure share name doesn't contain invalid characters. */
4011         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4012                 DEBUG(0,("process_usershare_file: share name %s contains "
4013                         "invalid characters (any of %s)\n",
4014                         file_name, INVALID_SHARENAME_CHARS ));
4015                 goto out;
4016         }
4017
4018         canon_name = canonicalize_servicename(ctx, file_name);
4019         if (!canon_name) {
4020                 goto out;
4021         }
4022
4023         fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
4024         if (!fname) {
4025                 goto out;
4026         }
4027
4028         /* Minimize the race condition by doing an lstat before we
4029            open and fstat. Ensure this isn't a symlink link. */
4030
4031         if (sys_lstat(fname, &lsbuf, false) != 0) {
4032                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4033                         fname, strerror(errno) ));
4034                 goto out;
4035         }
4036
4037         /* This must be a regular file, not a symlink, directory or
4038            other strange filetype. */
4039         if (!check_usershare_stat(fname, &lsbuf)) {
4040                 goto out;
4041         }
4042
4043         {
4044                 TDB_DATA data;
4045                 NTSTATUS status;
4046
4047                 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
4048                                                canon_name, &data);
4049
4050                 iService = -1;
4051
4052                 if (NT_STATUS_IS_OK(status) &&
4053                     (data.dptr != NULL) &&
4054                     (data.dsize == sizeof(iService))) {
4055                         memcpy(&iService, data.dptr, sizeof(iService));
4056                 }
4057         }
4058
4059         if (iService != -1 &&
4060             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4061                              &lsbuf.st_ex_mtime) == 0) {
4062                 /* Nothing changed - Mark valid and return. */
4063                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4064                         canon_name ));
4065                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4066                 ret = iService;
4067                 goto out;
4068         }
4069
4070         /* Try and open the file read only - no symlinks allowed. */
4071 #ifdef O_NOFOLLOW
4072         fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
4073 #else
4074         fd = open(fname, O_RDONLY, 0);
4075 #endif
4076
4077         if (fd == -1) {
4078                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4079                         fname, strerror(errno) ));
4080                 goto out;
4081         }
4082
4083         /* Now fstat to be *SURE* it's a regular file. */
4084         if (sys_fstat(fd, &sbuf, false) != 0) {
4085                 close(fd);
4086                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4087                         fname, strerror(errno) ));
4088                 goto out;
4089         }
4090
4091         /* Is it the same dev/inode as was lstated ? */
4092         if (!check_same_stat(&lsbuf, &sbuf)) {
4093                 close(fd);
4094                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4095                         "Symlink spoofing going on ?\n", fname ));
4096                 goto out;
4097         }
4098
4099         /* This must be a regular file, not a symlink, directory or
4100            other strange filetype. */
4101         if (!check_usershare_stat(fname, &sbuf)) {
4102                 close(fd);
4103                 goto out;
4104         }
4105
4106         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
4107
4108         close(fd);
4109         if (lines == NULL) {
4110                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4111                         fname, (unsigned int)sbuf.st_ex_uid ));
4112                 goto out;
4113         }
4114
4115         if (parse_usershare_file(ctx, &sbuf, file_name,
4116                         iService, lines, numlines, &sharepath,
4117                         &comment, &cp_service_name,
4118                         &psd, &guest_ok) != USERSHARE_OK) {
4119                 goto out;
4120         }
4121
4122         /* Everything ok - add the service possibly using a template. */
4123         if (iService < 0) {
4124                 const struct loadparm_service *sp = &sDefault;
4125                 if (snum_template != -1) {
4126                         sp = ServicePtrs[snum_template];
4127                 }
4128
4129                 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
4130                         DEBUG(0, ("process_usershare_file: Failed to add "
4131                                 "new service %s\n", cp_service_name));
4132                         goto out;
4133                 }
4134
4135                 added_service = true;
4136
4137                 /* Read only is controlled by usershare ACL below. */
4138                 ServicePtrs[iService]->read_only = false;
4139         }
4140
4141         /* Write the ACL of the new/modified share. */
4142         if (!set_share_security(canon_name, psd)) {
4143                  DEBUG(0, ("process_usershare_file: Failed to set share "
4144                         "security for user share %s\n",
4145                         canon_name ));
4146                 goto out;
4147         }
4148
4149         /* If from a template it may be marked invalid. */
4150         ServicePtrs[iService]->valid = true;
4151
4152         /* Set the service as a valid usershare. */
4153         ServicePtrs[iService]->usershare = USERSHARE_VALID;
4154
4155         /* Set guest access. */
4156         if (lp_usershare_allow_guests()) {
4157                 ServicePtrs[iService]->guest_ok = guest_ok;
4158         }
4159
4160         /* And note when it was loaded. */
4161         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
4162         string_set(ServicePtrs[iService], &ServicePtrs[iService]->path, sharepath);
4163         string_set(ServicePtrs[iService], &ServicePtrs[iService]->comment, comment);
4164
4165         ret = iService;
4166
4167   out:
4168
4169         if (ret == -1 && iService != -1 && added_service) {
4170                 lp_remove_service(iService);
4171         }
4172
4173         TALLOC_FREE(lines);
4174         TALLOC_FREE(ctx);
4175         return ret;
4176 }
4177
4178 /***************************************************************************
4179  Checks if a usershare entry has been modified since last load.
4180 ***************************************************************************/
4181
4182 static bool usershare_exists(int iService, struct timespec *last_mod)
4183 {
4184         SMB_STRUCT_STAT lsbuf;
4185         const char *usersharepath = Globals.usershare_path;
4186         char *fname;
4187
4188         fname = talloc_asprintf(talloc_tos(),
4189                                 "%s/%s",
4190                                 usersharepath,
4191                                 ServicePtrs[iService]->szService);
4192         if (fname == NULL) {
4193                 return false;
4194         }
4195
4196         if (sys_lstat(fname, &lsbuf, false) != 0) {
4197                 TALLOC_FREE(fname);
4198                 return false;
4199         }
4200
4201         if (!S_ISREG(lsbuf.st_ex_mode)) {
4202                 TALLOC_FREE(fname);
4203                 return false;
4204         }
4205
4206         TALLOC_FREE(fname);
4207         *last_mod = lsbuf.st_ex_mtime;
4208         return true;
4209 }
4210
4211 /***************************************************************************
4212  Load a usershare service by name. Returns a valid servicenumber or -1.
4213 ***************************************************************************/
4214
4215 int load_usershare_service(const char *servicename)
4216 {
4217         SMB_STRUCT_STAT sbuf;
4218         const char *usersharepath = Globals.usershare_path;
4219         int max_user_shares = Globals.usershare_max_shares;
4220         int snum_template = -1;
4221
4222         if (*usersharepath == 0 ||  max_user_shares == 0) {
4223                 return -1;
4224         }
4225
4226         if (sys_stat(usersharepath, &sbuf, false) != 0) {
4227                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4228                         usersharepath, strerror(errno) ));
4229                 return -1;
4230         }
4231
4232         if (!S_ISDIR(sbuf.st_ex_mode)) {
4233                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4234                         usersharepath ));
4235                 return -1;
4236         }
4237
4238         /*
4239          * This directory must be owned by root, and have the 't' bit set.
4240          * It also must not be writable by "other".
4241          */
4242
4243 #ifdef S_ISVTX
4244         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4245 #else
4246         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4247 #endif
4248                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4249                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
4250                         usersharepath ));
4251                 return -1;
4252         }
4253
4254         /* Ensure the template share exists if it's set. */
4255         if (Globals.usershare_template_share[0]) {
4256                 /* We can't use lp_servicenumber here as we are recommending that
4257                    template shares have -valid=false set. */
4258                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4259                         if (ServicePtrs[snum_template]->szService &&
4260                                         strequal(ServicePtrs[snum_template]->szService,
4261                                                 Globals.usershare_template_share)) {
4262                                 break;
4263                         }
4264                 }
4265
4266                 if (snum_template == -1) {
4267                         DEBUG(0,("load_usershare_service: usershare template share %s "
4268                                 "does not exist.\n",
4269                                 Globals.usershare_template_share ));
4270                         return -1;
4271                 }
4272         }
4273
4274         return process_usershare_file(usersharepath, servicename, snum_template);
4275 }
4276
4277 /***************************************************************************
4278  Load all user defined shares from the user share directory.
4279  We only do this if we're enumerating the share list.
4280  This is the function that can delete usershares that have
4281  been removed.
4282 ***************************************************************************/
4283
4284 int load_usershare_shares(struct smbd_server_connection *sconn,
4285                           bool (*snumused) (struct smbd_server_connection *, int))
4286 {
4287         DIR *dp;
4288         SMB_STRUCT_STAT sbuf;
4289         struct dirent *de;
4290         int num_usershares = 0;
4291         int max_user_shares = Globals.usershare_max_shares;
4292         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4293         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4294         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4295         int iService;
4296         int snum_template = -1;
4297         const char *usersharepath = Globals.usershare_path;
4298         int ret = lp_numservices();
4299         TALLOC_CTX *tmp_ctx;
4300
4301         if (max_user_shares == 0 || *usersharepath == '\0') {
4302                 return lp_numservices();
4303         }
4304
4305         if (sys_stat(usersharepath, &sbuf, false) != 0) {
4306                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4307                         usersharepath, strerror(errno) ));
4308                 return ret;
4309         }
4310
4311         /*
4312          * This directory must be owned by root, and have the 't' bit set.
4313          * It also must not be writable by "other".
4314          */
4315
4316 #ifdef S_ISVTX
4317         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
4318 #else
4319         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
4320 #endif
4321                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4322                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
4323                         usersharepath ));
4324                 return ret;
4325         }
4326
4327         /* Ensure the template share exists if it's set. */
4328         if (Globals.usershare_template_share[0]) {
4329                 /* We can't use lp_servicenumber here as we are recommending that
4330                    template shares have -valid=false set. */
4331                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4332                         if (ServicePtrs[snum_template]->szService &&
4333                                         strequal(ServicePtrs[snum_template]->szService,
4334                                                 Globals.usershare_template_share)) {
4335                                 break;
4336                         }
4337                 }
4338
4339                 if (snum_template == -1) {
4340                         DEBUG(0,("load_usershare_shares: usershare template share %s "
4341                                 "does not exist.\n",
4342                                 Globals.usershare_template_share ));
4343                         return ret;
4344                 }
4345         }
4346
4347         /* Mark all existing usershares as pending delete. */
4348         for (iService = iNumServices - 1; iService >= 0; iService--) {
4349                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4350                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4351                 }
4352         }
4353
4354         dp = opendir(usersharepath);
4355         if (!dp) {
4356                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4357                         usersharepath, strerror(errno) ));
4358                 return ret;
4359         }
4360
4361         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4362                         (de = readdir(dp));
4363                         num_dir_entries++ ) {
4364                 int r;
4365                 const char *n = de->d_name;
4366
4367                 /* Ignore . and .. */
4368                 if (*n == '.') {
4369                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4370                                 continue;
4371                         }
4372                 }
4373
4374                 if (n[0] == ':') {
4375                         /* Temporary file used when creating a share. */
4376                         num_tmp_dir_entries++;
4377                 }
4378
4379                 /* Allow 20% tmp entries. */
4380                 if (num_tmp_dir_entries > allowed_tmp_entries) {
4381                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4382                                 "in directory %s\n",
4383                                 num_tmp_dir_entries, usersharepath));
4384                         break;
4385                 }
4386
4387                 r = process_usershare_file(usersharepath, n, snum_template);
4388                 if (r == 0) {
4389                         /* Update the services count. */
4390                         num_usershares++;
4391                         if (num_usershares >= max_user_shares) {
4392                                 DEBUG(0,("load_usershare_shares: max user shares reached "
4393                                         "on file %s in directory %s\n",
4394                                         n, usersharepath ));
4395                                 break;
4396                         }
4397                 } else if (r == -1) {
4398                         num_bad_dir_entries++;
4399                 }
4400
4401                 /* Allow 20% bad entries. */
4402                 if (num_bad_dir_entries > allowed_bad_entries) {
4403                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4404                                 "in directory %s\n",
4405                                 num_bad_dir_entries, usersharepath));
4406                         break;
4407                 }
4408
4409                 /* Allow 20% bad entries. */
4410                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4411                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4412                         "in directory %s\n",
4413                         num_dir_entries, usersharepath));
4414                         break;
4415                 }
4416         }
4417
4418         closedir(dp);
4419
4420         /* Sweep through and delete any non-refreshed usershares that are
4421            not currently in use. */
4422         tmp_ctx = talloc_stackframe();
4423         for (iService = iNumServices - 1; iService >= 0; iService--) {
4424                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4425                         char *servname;
4426
4427                         if (snumused && snumused(sconn, iService)) {
4428                                 continue;
4429                         }
4430
4431                         servname = lp_servicename(tmp_ctx, iService);
4432
4433                         /* Remove from the share ACL db. */
4434                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4435                                   servname ));
4436                         delete_share_security(servname);
4437                         free_service_byindex(iService);
4438                 }
4439         }
4440         talloc_free(tmp_ctx);
4441
4442         return lp_numservices();
4443 }
4444
4445 /********************************************************
4446  Destroy global resources allocated in this file
4447 ********************************************************/
4448
4449 void gfree_loadparm(void)
4450 {
4451         int i;
4452
4453         free_file_list();
4454
4455         /* Free resources allocated to services */
4456
4457         for ( i = 0; i < iNumServices; i++ ) {
4458                 if ( VALID(i) ) {
4459                         free_service_byindex(i);
4460                 }
4461         }
4462
4463         TALLOC_FREE( ServicePtrs );
4464         iNumServices = 0;
4465
4466         /* Now release all resources allocated to global
4467            parameters and the default service */
4468
4469         free_global_parameters();
4470 }
4471
4472
4473 /***************************************************************************
4474  Allow client apps to specify that they are a client
4475 ***************************************************************************/
4476 static void lp_set_in_client(bool b)
4477 {
4478     in_client = b;
4479 }
4480
4481
4482 /***************************************************************************
4483  Determine if we're running in a client app
4484 ***************************************************************************/
4485 static bool lp_is_in_client(void)
4486 {
4487     return in_client;
4488 }
4489
4490 /***************************************************************************
4491  Load the services array from the services file. Return true on success,
4492  false on failure.
4493 ***************************************************************************/
4494
4495 static bool lp_load_ex(const char *pszFname,
4496                        bool global_only,
4497                        bool save_defaults,
4498                        bool add_ipc,
4499                        bool initialize_globals,
4500                        bool allow_include_registry,
4501                        bool load_all_shares)
4502 {
4503         char *n2 = NULL;
4504         bool bRetval;
4505
4506         bRetval = false;
4507
4508         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4509
4510         bInGlobalSection = true;
4511         bGlobalOnly = global_only;
4512         bAllowIncludeRegistry = allow_include_registry;
4513
4514         init_globals(initialize_globals);
4515
4516         free_file_list();
4517
4518         if (save_defaults) {
4519                 init_locals();
4520                 lp_save_defaults();
4521         }
4522
4523         if (!initialize_globals) {
4524                 free_param_opts(&Globals.param_opt);
4525                 apply_lp_set_cmdline();
4526         }
4527
4528         lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
4529
4530         /* We get sections first, so have to start 'behind' to make up */
4531         iServiceIndex = -1;
4532
4533         if (lp_config_backend_is_file()) {
4534                 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
4535                                         current_user_info.domain,
4536                                         pszFname);
4537                 if (!n2) {
4538                         smb_panic("lp_load_ex: out of memory");
4539                 }
4540
4541                 add_to_file_list(pszFname, n2);
4542
4543                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
4544                 TALLOC_FREE(n2);
4545
4546                 /* finish up the last section */
4547                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4548                 if (bRetval) {
4549                         if (iServiceIndex >= 0) {
4550                                 bRetval = service_ok(iServiceIndex);
4551                         }
4552                 }
4553
4554                 if (lp_config_backend_is_registry()) {
4555                         /* config backend changed to registry in config file */
4556                         /*
4557                          * We need to use this extra global variable here to
4558                          * survive restart: init_globals uses this as a default
4559                          * for config_backend. Otherwise, init_globals would
4560                          *  send us into an endless loop here.
4561                          */
4562                         config_backend = CONFIG_BACKEND_REGISTRY;
4563                         /* start over */
4564                         DEBUG(1, ("lp_load_ex: changing to config backend "
4565                                   "registry\n"));
4566                         init_globals(true);
4567                         lp_kill_all_services();
4568                         return lp_load_ex(pszFname, global_only, save_defaults,
4569                                           add_ipc, initialize_globals,
4570                                           allow_include_registry,
4571                                           load_all_shares);
4572                 }
4573         } else if (lp_config_backend_is_registry()) {
4574                 bRetval = process_registry_globals();
4575         } else {
4576                 DEBUG(0, ("Illegal config  backend given: %d\n",
4577                           lp_config_backend()));
4578                 bRetval = false;
4579         }
4580
4581         if (bRetval && lp_registry_shares()) {
4582                 if (load_all_shares) {
4583                         bRetval = process_registry_shares();
4584                 } else {
4585                         bRetval = reload_registry_shares();
4586                 }
4587         }
4588
4589         {
4590                 char *serv = lp_auto_services(talloc_tos());
4591                 lp_add_auto_services(serv);
4592                 TALLOC_FREE(serv);
4593         }
4594
4595         if (add_ipc) {
4596                 /* When 'restrict anonymous = 2' guest connections to ipc$
4597                    are denied */
4598                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4599                 if ( lp_enable_asu_support() ) {
4600                         lp_add_ipc("ADMIN$", false);
4601                 }
4602         }
4603
4604         set_allowed_client_auth();
4605
4606         if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
4607                 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4608                           lp_password_server()));
4609         }
4610
4611         bLoaded = true;
4612
4613         /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4614         /* if we_are_a_wins_server is true and we are in the client            */
4615         if (lp_is_in_client() && Globals.we_are_a_wins_server) {
4616                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
4617         }
4618
4619         init_iconv();
4620
4621         fault_configure(smb_panic_s3);
4622
4623         /*
4624          * We run this check once the whole smb.conf is parsed, to
4625          * force some settings for the standard way a AD DC is
4626          * operated.  We may changed these as our code evolves, which
4627          * is why we force these settings.
4628          */
4629         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
4630                 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4631
4632                 lp_do_parameter(-1, "rpc_server:default", "external");
4633                 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4634                 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4635                 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4636                 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4637                 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4638                 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4639                 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4640                 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4641         }
4642
4643         bAllowIncludeRegistry = true;
4644
4645         return (bRetval);
4646 }
4647
4648 bool lp_load(const char *pszFname,
4649              bool global_only,
4650              bool save_defaults,
4651              bool add_ipc,
4652              bool initialize_globals)
4653 {
4654         return lp_load_ex(pszFname,
4655                           global_only,
4656                           save_defaults,
4657                           add_ipc,
4658                           initialize_globals,
4659                           true,   /* allow_include_registry */
4660                           false); /* load_all_shares*/
4661 }
4662
4663 bool lp_load_initial_only(const char *pszFname)
4664 {
4665         return lp_load_ex(pszFname,
4666                           true,   /* global only */
4667                           false,  /* save_defaults */
4668                           false,  /* add_ipc */
4669                           true,   /* initialize_globals */
4670                           false,  /* allow_include_registry */
4671                           false); /* load_all_shares*/
4672 }
4673
4674 /**
4675  * most common lp_load wrapper, loading only the globals
4676  */
4677 bool lp_load_global(const char *file_name)
4678 {
4679         return lp_load_ex(file_name,
4680                           true,   /* global_only */
4681                           false,  /* save_defaults */
4682                           false,  /* add_ipc */
4683                           true,   /* initialize_globals */
4684                           true,   /* allow_include_registry */
4685                           false); /* load_all_shares*/
4686 }
4687
4688 /**
4689  * lp_load wrapper, especially for clients
4690  */
4691 bool lp_load_client(const char *file_name)
4692 {
4693         lp_set_in_client(true);
4694
4695         return lp_load_global(file_name);
4696 }
4697
4698 /**
4699  * lp_load wrapper, loading only globals, but intended
4700  * for subsequent calls, not reinitializing the globals
4701  * to default values
4702  */
4703 bool lp_load_global_no_reinit(const char *file_name)
4704 {
4705         return lp_load_ex(file_name,
4706                           true,   /* global_only */
4707                           false,  /* save_defaults */
4708                           false,  /* add_ipc */
4709                           false,  /* initialize_globals */
4710                           true,   /* allow_include_registry */
4711                           false); /* load_all_shares*/
4712 }
4713
4714 /**
4715  * lp_load wrapper, especially for clients, no reinitialization
4716  */
4717 bool lp_load_client_no_reinit(const char *file_name)
4718 {
4719         lp_set_in_client(true);
4720
4721         return lp_load_global_no_reinit(file_name);
4722 }
4723
4724 bool lp_load_with_registry_shares(const char *pszFname,
4725                                   bool global_only,
4726                                   bool save_defaults,
4727                                   bool add_ipc,
4728                                   bool initialize_globals)
4729 {
4730         return lp_load_ex(pszFname,
4731                           global_only,
4732                           save_defaults,
4733                           add_ipc,
4734                           initialize_globals,
4735                           true,  /* allow_include_registry */
4736                           true); /* load_all_shares*/
4737 }
4738
4739 /***************************************************************************
4740  Return the max number of services.
4741 ***************************************************************************/
4742
4743 int lp_numservices(void)
4744 {
4745         return (iNumServices);
4746 }
4747
4748 /***************************************************************************
4749 Display the contents of the services array in human-readable form.
4750 ***************************************************************************/
4751
4752 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
4753 {
4754         int iService;
4755
4756         if (show_defaults)
4757                 defaults_saved = false;
4758
4759         dump_globals(f);
4760
4761         dump_a_service(&sDefault, f);
4762
4763         for (iService = 0; iService < maxtoprint; iService++) {
4764                 fprintf(f,"\n");
4765                 lp_dump_one(f, show_defaults, iService);
4766         }
4767 }
4768
4769 /***************************************************************************
4770 Display the contents of one service in human-readable form.
4771 ***************************************************************************/
4772
4773 void lp_dump_one(FILE * f, bool show_defaults, int snum)
4774 {
4775         if (VALID(snum)) {
4776                 if (ServicePtrs[snum]->szService[0] == '\0')
4777                         return;
4778                 dump_a_service(ServicePtrs[snum], f);
4779         }
4780 }
4781
4782 /***************************************************************************
4783 Return the number of the service with the given name, or -1 if it doesn't
4784 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4785 getservicebyname()! This works ONLY if all services have been loaded, and
4786 does not copy the found service.
4787 ***************************************************************************/
4788
4789 int lp_servicenumber(const char *pszServiceName)
4790 {
4791         int iService;
4792         fstring serviceName;
4793
4794         if (!pszServiceName) {
4795                 return GLOBAL_SECTION_SNUM;
4796         }
4797
4798         for (iService = iNumServices - 1; iService >= 0; iService--) {
4799                 if (VALID(iService) && ServicePtrs[iService]->szService) {
4800                         /*
4801                          * The substitution here is used to support %U is
4802                          * service names
4803                          */
4804                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
4805                         standard_sub_basic(get_current_username(),
4806                                            current_user_info.domain,
4807                                            serviceName,sizeof(serviceName));
4808                         if (strequal(serviceName, pszServiceName)) {
4809                                 break;
4810                         }
4811                 }
4812         }
4813
4814         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
4815                 struct timespec last_mod;
4816
4817                 if (!usershare_exists(iService, &last_mod)) {
4818                         /* Remove the share security tdb entry for it. */
4819                         delete_share_security(lp_servicename(talloc_tos(), iService));
4820                         /* Remove it from the array. */
4821                         free_service_byindex(iService);
4822                         /* Doesn't exist anymore. */
4823                         return GLOBAL_SECTION_SNUM;
4824                 }
4825
4826                 /* Has it been modified ? If so delete and reload. */
4827                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
4828                                      &last_mod) < 0) {
4829                         /* Remove it from the array. */
4830                         free_service_byindex(iService);
4831                         /* and now reload it. */
4832                         iService = load_usershare_service(pszServiceName);
4833                 }
4834         }
4835
4836         if (iService < 0) {
4837                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4838                 return GLOBAL_SECTION_SNUM;
4839         }
4840
4841         return (iService);
4842 }
4843
4844 /*******************************************************************
4845  A useful volume label function. 
4846 ********************************************************************/
4847
4848 const char *volume_label(TALLOC_CTX *ctx, int snum)
4849 {
4850         char *ret;
4851         const char *label = lp_volume(ctx, snum);
4852         if (!*label) {
4853                 label = lp_servicename(ctx, snum);
4854         }
4855
4856         /* This returns a 33 byte guarenteed null terminated string. */
4857         ret = talloc_strndup(ctx, label, 32);
4858         if (!ret) {
4859                 return "";
4860         }               
4861         return ret;
4862 }
4863
4864 /*******************************************************************
4865  Get the default server type we will announce as via nmbd.
4866 ********************************************************************/
4867
4868 int lp_default_server_announce(void)
4869 {
4870         int default_server_announce = 0;
4871         default_server_announce |= SV_TYPE_WORKSTATION;
4872         default_server_announce |= SV_TYPE_SERVER;
4873         default_server_announce |= SV_TYPE_SERVER_UNIX;
4874
4875         /* note that the flag should be set only if we have a 
4876            printer service but nmbd doesn't actually load the 
4877            services so we can't tell   --jerry */
4878
4879         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4880
4881         default_server_announce |= SV_TYPE_SERVER_NT;
4882         default_server_announce |= SV_TYPE_NT;
4883
4884         switch (lp_server_role()) {
4885                 case ROLE_DOMAIN_MEMBER:
4886                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4887                         break;
4888                 case ROLE_DOMAIN_PDC:
4889                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4890                         break;
4891                 case ROLE_DOMAIN_BDC:
4892                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4893                         break;
4894                 case ROLE_STANDALONE:
4895                 default:
4896                         break;
4897         }
4898         if (lp_time_server())
4899                 default_server_announce |= SV_TYPE_TIME_SOURCE;
4900
4901         if (lp_host_msdfs())
4902                 default_server_announce |= SV_TYPE_DFS_SERVER;
4903
4904         return default_server_announce;
4905 }
4906
4907 /***********************************************************
4908  If we are PDC then prefer us as DMB
4909 ************************************************************/
4910
4911 bool lp_domain_master(void)
4912 {
4913         if (Globals._domain_master == Auto)
4914                 return (lp_server_role() == ROLE_DOMAIN_PDC);
4915
4916         return (bool)Globals._domain_master;
4917 }
4918
4919 /***********************************************************
4920  If we are PDC then prefer us as DMB
4921 ************************************************************/
4922
4923 static bool lp_domain_master_true_or_auto(void)
4924 {
4925         if (Globals._domain_master) /* auto or yes */
4926                 return true;
4927
4928         return false;
4929 }
4930
4931 /***********************************************************
4932  If we are DMB then prefer us as LMB
4933 ************************************************************/
4934
4935 bool lp_preferred_master(void)
4936 {
4937         if (Globals.iPreferredMaster == Auto)
4938                 return (lp_local_master() && lp_domain_master());
4939
4940         return (bool)Globals.iPreferredMaster;
4941 }
4942
4943 /*******************************************************************
4944  Remove a service.
4945 ********************************************************************/
4946
4947 void lp_remove_service(int snum)
4948 {
4949         ServicePtrs[snum]->valid = false;
4950 }
4951
4952 /*******************************************************************
4953  Copy a service.
4954 ********************************************************************/
4955
4956 void lp_copy_service(int snum, const char *new_name)
4957 {
4958         do_section(new_name, NULL);
4959         if (snum >= 0) {
4960                 snum = lp_servicenumber(new_name);
4961                 if (snum >= 0) {
4962                         char *name = lp_servicename(talloc_tos(), snum);
4963                         lp_do_parameter(snum, "copy", name);
4964                 }
4965         }
4966 }
4967
4968 const char *lp_printername(TALLOC_CTX *ctx, int snum)
4969 {
4970         const char *ret = lp__printername(ctx, snum);
4971         if (ret == NULL || *ret == '\0') {
4972                 ret = lp_const_servicename(snum);
4973         }
4974
4975         return ret;
4976 }
4977
4978
4979 /***********************************************************
4980  Allow daemons such as winbindd to fix their logfile name.
4981 ************************************************************/
4982
4983 void lp_set_logfile(const char *name)
4984 {
4985         string_set(Globals.ctx, &Globals.logfile, name);
4986         debug_set_logfile(name);
4987 }
4988
4989 /*******************************************************************
4990  Return the max print jobs per queue.
4991 ********************************************************************/
4992
4993 int lp_maxprintjobs(int snum)
4994 {
4995         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4996         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4997                 maxjobs = PRINT_MAX_JOBID - 1;
4998
4999         return maxjobs;
5000 }
5001
5002 const char *lp_printcapname(void)
5003 {
5004         if ((Globals.szPrintcapname != NULL) &&
5005             (Globals.szPrintcapname[0] != '\0'))
5006                 return Globals.szPrintcapname;
5007
5008         if (sDefault.printing == PRINT_CUPS) {
5009                 return "cups";
5010         }
5011
5012         if (sDefault.printing == PRINT_BSD)
5013                 return "/etc/printcap";
5014
5015         return PRINTCAP_NAME;
5016 }
5017
5018 static uint32 spoolss_state;
5019
5020 bool lp_disable_spoolss( void )
5021 {
5022         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5023                 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5024
5025         return spoolss_state == SVCCTL_STOPPED ? true : false;
5026 }
5027
5028 void lp_set_spoolss_state( uint32 state )
5029 {
5030         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5031
5032         spoolss_state = state;
5033 }
5034
5035 uint32 lp_get_spoolss_state( void )
5036 {
5037         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5038 }
5039
5040 /*******************************************************************
5041  Ensure we don't use sendfile if server smb signing is active.
5042 ********************************************************************/
5043
5044 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
5045 {
5046         bool sign_active = false;
5047
5048         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5049         if (get_Protocol() < PROTOCOL_NT1) {
5050                 return false;
5051         }
5052         if (signing_state) {
5053                 sign_active = smb_signing_is_active(signing_state);
5054         }
5055         return (lp__use_sendfile(snum) &&
5056                         (get_remote_arch() != RA_WIN95) &&
5057                         !sign_active);
5058 }
5059
5060 /*******************************************************************
5061  Turn off sendfile if we find the underlying OS doesn't support it.
5062 ********************************************************************/
5063
5064 void set_use_sendfile(int snum, bool val)
5065 {
5066         if (LP_SNUM_OK(snum))
5067                 ServicePtrs[snum]->_use_sendfile = val;
5068         else
5069                 sDefault._use_sendfile = val;
5070 }
5071
5072 /*******************************************************************
5073  Turn off storing DOS attributes if this share doesn't support it.
5074 ********************************************************************/
5075
5076 void set_store_dos_attributes(int snum, bool val)
5077 {
5078         if (!LP_SNUM_OK(snum))
5079                 return;
5080         ServicePtrs[(snum)]->store_dos_attributes = val;
5081 }
5082
5083 void lp_set_mangling_method(const char *new_method)
5084 {
5085         string_set(Globals.ctx, &Globals.mangling_method, new_method);
5086 }
5087
5088 /*******************************************************************
5089  Global state for POSIX pathname processing.
5090 ********************************************************************/
5091
5092 static bool posix_pathnames;
5093
5094 bool lp_posix_pathnames(void)
5095 {
5096         return posix_pathnames;
5097 }
5098
5099 /*******************************************************************
5100  Change everything needed to ensure POSIX pathname processing (currently
5101  not much).
5102 ********************************************************************/
5103
5104 void lp_set_posix_pathnames(void)
5105 {
5106         posix_pathnames = true;
5107 }
5108
5109 /*******************************************************************
5110  Global state for POSIX lock processing - CIFS unix extensions.
5111 ********************************************************************/
5112
5113 bool posix_default_lock_was_set;
5114 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5115
5116 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5117 {
5118         if (posix_default_lock_was_set) {
5119                 return posix_cifsx_locktype;
5120         } else {
5121                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5122         }
5123 }
5124
5125 /*******************************************************************
5126 ********************************************************************/
5127
5128 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5129 {
5130         posix_default_lock_was_set = true;
5131         posix_cifsx_locktype = val;
5132 }
5133
5134 int lp_min_receive_file_size(void)
5135 {
5136         if (Globals.iminreceivefile < 0) {
5137                 return 0;
5138         }
5139         return Globals.iminreceivefile;
5140 }
5141
5142 /*******************************************************************
5143  Safe wide links checks.
5144  This helper function always verify the validity of wide links,
5145  even after a configuration file reload.
5146 ********************************************************************/
5147
5148 static bool lp_widelinks_internal(int snum)
5149 {
5150         return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
5151                         sDefault.bWidelinks);
5152 }
5153
5154 void widelinks_warning(int snum)
5155 {
5156         if (lp_allow_insecure_wide_links()) {
5157                 return;
5158         }
5159
5160         if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
5161                 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
5162                         "These parameters are incompatible. "
5163                         "Wide links will be disabled for this share.\n",
5164                          lp_servicename(talloc_tos(), snum) ));
5165         }
5166 }
5167
5168 bool lp_widelinks(int snum)
5169 {
5170         /* wide links is always incompatible with unix extensions */
5171         if (lp_unix_extensions()) {
5172                 /*
5173                  * Unless we have "allow insecure widelinks"
5174                  * turned on.
5175                  */
5176                 if (!lp_allow_insecure_wide_links()) {
5177                         return false;
5178                 }
5179         }
5180
5181         return lp_widelinks_internal(snum);
5182 }
5183
5184 int lp_server_role(void)
5185 {
5186         return lp_find_server_role(lp__server_role(),
5187                                    lp__security(),
5188                                    lp__domain_logons(),
5189                                    lp_domain_master_true_or_auto());
5190 }
5191
5192 int lp_security(void)
5193 {
5194         return lp_find_security(lp__server_role(),
5195                                 lp__security());
5196 }
5197
5198 struct loadparm_global * get_globals(void)
5199 {
5200         return &Globals;
5201 }