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