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