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