s3:param: remove unused function lp_parameter_is_canonical()
[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_HIDE)) {
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_HIDE) &&
1686             !(parm_table[parm2].flags & FLAG_HIDE))
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", "P_SEP"};
1717         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
1718                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
1719                 FLAG_HIDE};
1720         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
1721                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
1722                 "FLAG_DEPRECATED", "FLAG_HIDE", NULL};
1723
1724         printf("%s=%s", parm_table[parmIndex].label,
1725                type[parm_table[parmIndex].type]);
1726         if (parm_table[parmIndex].type == P_ENUM) {
1727                 printf(",");
1728                 for (enumIndex=0;
1729                      parm_table[parmIndex].enum_list[enumIndex].name;
1730                      enumIndex++)
1731                 {
1732                         printf("%s%s",
1733                                enumIndex ? "|" : "",
1734                                parm_table[parmIndex].enum_list[enumIndex].name);
1735                 }
1736         }
1737         printf(",");
1738         hadFlag = false;
1739         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1740                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1741                         printf("%s%s",
1742                                 hadFlag ? "|" : "",
1743                                 flag_names[flagIndex]);
1744                         hadFlag = true;
1745                 }
1746         }
1747
1748         /* output synonyms */
1749         hadSyn = false;
1750         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1751                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1752                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1753                                parm_table[parmIndex2].label);
1754                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1755                         if (!hadSyn) {
1756                                 printf(" (synonyms: ");
1757                                 hadSyn = true;
1758                         } else {
1759                                 printf(", ");
1760                         }
1761                         printf("%s%s", parm_table[parmIndex2].label,
1762                                inverse ? "[i]" : "");
1763                 }
1764         }
1765         if (hadSyn) {
1766                 printf(")");
1767         }
1768
1769         printf("\n");
1770 }
1771
1772 /***************************************************************************
1773  Show all parameter's name, type, [values,] and flags.
1774 ***************************************************************************/
1775
1776 void show_parameter_list(void)
1777 {
1778         int classIndex, parmIndex;
1779         const char *section_names[] = { "local", "global", NULL};
1780
1781         for (classIndex=0; section_names[classIndex]; classIndex++) {
1782                 printf("[%s]\n", section_names[classIndex]);
1783                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
1784                         if (parm_table[parmIndex].p_class == classIndex) {
1785                                 show_parameter(parmIndex);
1786                         }
1787                 }
1788         }
1789 }
1790
1791 /***************************************************************************
1792  Get the standard string representation of a boolean value ("yes" or "no")
1793 ***************************************************************************/
1794
1795 static const char *get_boolean(bool bool_value)
1796 {
1797         static const char *yes_str = "yes";
1798         static const char *no_str = "no";
1799
1800         return (bool_value ? yes_str : no_str);
1801 }
1802
1803 /***************************************************************************
1804  Provide the string of the negated boolean value associated to the boolean
1805  given as a string. Returns false if the passed string does not correctly
1806  represent a boolean.
1807 ***************************************************************************/
1808
1809 bool lp_invert_boolean(const char *str, const char **inverse_str)
1810 {
1811         bool val;
1812
1813         if (!set_boolean(str, &val)) {
1814                 return false;
1815         }
1816
1817         *inverse_str = get_boolean(!val);
1818         return true;
1819 }
1820
1821 /***************************************************************************
1822  Provide the canonical string representation of a boolean value given
1823  as a string. Return true on success, false if the string given does
1824  not correctly represent a boolean.
1825 ***************************************************************************/
1826
1827 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
1828 {
1829         bool val;
1830
1831         if (!set_boolean(str, &val)) {
1832                 return false;
1833         }
1834
1835         *canon_str = get_boolean(val);
1836         return true;
1837 }
1838
1839 /***************************************************************************
1840 Find a service by name. Otherwise works like get_service.
1841 ***************************************************************************/
1842
1843 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
1844 {
1845         int iService = -1;
1846         char *canon_name;
1847         TDB_DATA data;
1848         NTSTATUS status;
1849
1850         if (ServiceHash == NULL) {
1851                 return -1;
1852         }
1853
1854         canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
1855
1856         status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
1857                                        &data);
1858
1859         if (NT_STATUS_IS_OK(status) &&
1860             (data.dptr != NULL) &&
1861             (data.dsize == sizeof(iService)))
1862         {
1863                 iService = *(int *)data.dptr;
1864         }
1865
1866         TALLOC_FREE(canon_name);
1867
1868         if ((iService != -1) && (LP_SNUM_OK(iService))
1869             && (pserviceDest != NULL)) {
1870                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1871         }
1872
1873         return (iService);
1874 }
1875
1876 /* Return a pointer to a service by name.  Unlike getservicebyname, it does not copy the service */
1877 struct loadparm_service *lp_service(const char *pszServiceName)
1878 {
1879         int iService = getservicebyname(pszServiceName, NULL);
1880         if (iService == -1 || !LP_SNUM_OK(iService)) {
1881                 return NULL;
1882         }
1883         return ServicePtrs[iService];
1884 }
1885
1886 struct loadparm_service *lp_servicebynum(int snum)
1887 {
1888         if ((snum == -1) || !LP_SNUM_OK(snum)) {
1889                 return NULL;
1890         }
1891         return ServicePtrs[snum];
1892 }
1893
1894 struct loadparm_service *lp_default_loadparm_service()
1895 {
1896         return &sDefault;
1897 }
1898
1899 static struct smbconf_ctx *lp_smbconf_ctx(void)
1900 {
1901         sbcErr err;
1902         static struct smbconf_ctx *conf_ctx = NULL;
1903
1904         if (conf_ctx == NULL) {
1905                 err = smbconf_init(NULL, &conf_ctx, "registry:");
1906                 if (!SBC_ERROR_IS_OK(err)) {
1907                         DEBUG(1, ("error initializing registry configuration: "
1908                                   "%s\n", sbcErrorString(err)));
1909                         conf_ctx = NULL;
1910                 }
1911         }
1912
1913         return conf_ctx;
1914 }
1915
1916 static bool process_smbconf_service(struct smbconf_service *service)
1917 {
1918         uint32_t count;
1919         bool ret;
1920
1921         if (service == NULL) {
1922                 return false;
1923         }
1924
1925         ret = lp_do_section(service->name, NULL);
1926         if (ret != true) {
1927                 return false;
1928         }
1929         for (count = 0; count < service->num_params; count++) {
1930
1931                 if (!bInGlobalSection && bGlobalOnly) {
1932                         ret = true;
1933                 } else {
1934                         const char *pszParmName = service->param_names[count];
1935                         const char *pszParmValue = service->param_values[count];
1936
1937                         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
1938
1939                         ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1940                                               pszParmName, pszParmValue);
1941                 }
1942
1943                 if (ret != true) {
1944                         return false;
1945                 }
1946         }
1947         if (iServiceIndex >= 0) {
1948                 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
1949         }
1950         return true;
1951 }
1952
1953 /**
1954  * load a service from registry and activate it
1955  */
1956 bool process_registry_service(const char *service_name)
1957 {
1958         sbcErr err;
1959         struct smbconf_service *service = NULL;
1960         TALLOC_CTX *mem_ctx = talloc_stackframe();
1961         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
1962         bool ret = false;
1963
1964         if (conf_ctx == NULL) {
1965                 goto done;
1966         }
1967
1968         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
1969
1970         if (!smbconf_share_exists(conf_ctx, service_name)) {
1971                 /*
1972                  * Registry does not contain data for this service (yet),
1973                  * but make sure lp_load doesn't return false.
1974                  */
1975                 ret = true;
1976                 goto done;
1977         }
1978
1979         err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
1980         if (!SBC_ERROR_IS_OK(err)) {
1981                 goto done;
1982         }
1983
1984         ret = process_smbconf_service(service);
1985         if (!ret) {
1986                 goto done;
1987         }
1988
1989         /* store the csn */
1990         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
1991
1992 done:
1993         TALLOC_FREE(mem_ctx);
1994         return ret;
1995 }
1996
1997 /*
1998  * process_registry_globals
1999  */
2000 static bool process_registry_globals(void)
2001 {
2002         bool ret;
2003
2004         add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2005
2006         if (!bInGlobalSection && bGlobalOnly) {
2007                 ret = true;
2008         } else {
2009                 const char *pszParmName = "registry shares";
2010                 const char *pszParmValue = "yes";
2011
2012                 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2013
2014                 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2015                                       pszParmName, pszParmValue);
2016         }
2017
2018         if (!ret) {
2019                 return ret;
2020         }
2021
2022         return process_registry_service(GLOBAL_NAME);
2023 }
2024
2025 bool process_registry_shares(void)
2026 {
2027         sbcErr err;
2028         uint32_t count;
2029         struct smbconf_service **service = NULL;
2030         uint32_t num_shares = 0;
2031         TALLOC_CTX *mem_ctx = talloc_stackframe();
2032         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2033         bool ret = false;
2034
2035         if (conf_ctx == NULL) {
2036                 goto done;
2037         }
2038
2039         err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2040         if (!SBC_ERROR_IS_OK(err)) {
2041                 goto done;
2042         }
2043
2044         ret = true;
2045
2046         for (count = 0; count < num_shares; count++) {
2047                 if (strequal(service[count]->name, GLOBAL_NAME)) {
2048                         continue;
2049                 }
2050                 ret = process_smbconf_service(service[count]);
2051                 if (!ret) {
2052                         goto done;
2053                 }
2054         }
2055
2056         /* store the csn */
2057         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2058
2059 done:
2060         TALLOC_FREE(mem_ctx);
2061         return ret;
2062 }
2063
2064 /**
2065  * reload those shares from registry that are already
2066  * activated in the services array.
2067  */
2068 static bool reload_registry_shares(void)
2069 {
2070         int i;
2071         bool ret = true;
2072
2073         for (i = 0; i < iNumServices; i++) {
2074                 if (!VALID(i)) {
2075                         continue;
2076                 }
2077
2078                 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2079                         continue;
2080                 }
2081
2082                 ret = process_registry_service(ServicePtrs[i]->szService);
2083                 if (!ret) {
2084                         goto done;
2085                 }
2086         }
2087
2088 done:
2089         return ret;
2090 }
2091
2092
2093 #define MAX_INCLUDE_DEPTH 100
2094
2095 static uint8_t include_depth;
2096
2097 /**
2098  * Free the file lists
2099  */
2100 static void free_file_list(void)
2101 {
2102         struct file_lists *f;
2103         struct file_lists *next;
2104
2105         f = file_lists;
2106         while( f ) {
2107                 next = f->next;
2108                 TALLOC_FREE( f );
2109                 f = next;
2110         }
2111         file_lists = NULL;
2112 }
2113
2114
2115 /**
2116  * Utility function for outsiders to check if we're running on registry.
2117  */
2118 bool lp_config_backend_is_registry(void)
2119 {
2120         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2121 }
2122
2123 /**
2124  * Utility function to check if the config backend is FILE.
2125  */
2126 bool lp_config_backend_is_file(void)
2127 {
2128         return (lp_config_backend() == CONFIG_BACKEND_FILE);
2129 }
2130
2131 /*******************************************************************
2132  Check if a config file has changed date.
2133 ********************************************************************/
2134
2135 bool lp_file_list_changed(void)
2136 {
2137         struct file_lists *f = file_lists;
2138
2139         DEBUG(6, ("lp_file_list_changed()\n"));
2140
2141         while (f) {
2142                 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2143                         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2144
2145                         if (conf_ctx == NULL) {
2146                                 return false;
2147                         }
2148                         if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2149                                             NULL))
2150                         {
2151                                 DEBUGADD(6, ("registry config changed\n"));
2152                                 return true;
2153                         }
2154                 } else {
2155                         time_t mod_time;
2156                         char *n2 = NULL;
2157
2158                         n2 = talloc_sub_basic(talloc_tos(),
2159                                               get_current_username(),
2160                                               current_user_info.domain,
2161                                               f->name);
2162                         if (!n2) {
2163                                 return false;
2164                         }
2165                         DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
2166                                      f->name, n2, ctime(&f->modtime)));
2167
2168                         mod_time = file_modtime(n2);
2169
2170                         if (mod_time &&
2171                             ((f->modtime != mod_time) ||
2172                              (f->subfname == NULL) ||
2173                              (strcmp(n2, f->subfname) != 0)))
2174                         {
2175                                 DEBUGADD(6,
2176                                          ("file %s modified: %s\n", n2,
2177                                           ctime(&mod_time)));
2178                                 f->modtime = mod_time;
2179                                 TALLOC_FREE(f->subfname);
2180                                 f->subfname = talloc_strdup(f, n2);
2181                                 if (f->subfname == NULL) {
2182                                         smb_panic("talloc_strdup failed");
2183                                 }
2184                                 TALLOC_FREE(n2);
2185                                 return true;
2186                         }
2187                         TALLOC_FREE(n2);
2188                 }
2189                 f = f->next;
2190         }
2191         return false;
2192 }
2193
2194
2195 /**
2196  * Initialize iconv conversion descriptors.
2197  *
2198  * This is called the first time it is needed, and also called again
2199  * every time the configuration is reloaded, because the charset or
2200  * codepage might have changed.
2201  **/
2202 static void init_iconv(void)
2203 {
2204         global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2205                                                       lp_unix_charset(),
2206                                                       true, global_iconv_handle);
2207 }
2208
2209 /***************************************************************************
2210  Handle the include operation.
2211 ***************************************************************************/
2212 static bool bAllowIncludeRegistry = true;
2213
2214 bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2215                 const char *pszParmValue, char **ptr)
2216 {
2217         char *fname;
2218
2219         if (include_depth >= MAX_INCLUDE_DEPTH) {
2220                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2221                           include_depth));
2222                 return false;
2223         }
2224
2225         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2226                 if (!bAllowIncludeRegistry) {
2227                         return true;
2228                 }
2229                 if (lp_ctx->bInGlobalSection) {
2230                         bool ret;
2231                         include_depth++;
2232                         ret = process_registry_globals();
2233                         include_depth--;
2234                         return ret;
2235                 } else {
2236                         DEBUG(1, ("\"include = registry\" only effective "
2237                                   "in %s section\n", GLOBAL_NAME));
2238                         return false;
2239                 }
2240         }
2241
2242         fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2243                                  current_user_info.domain,
2244                                  pszParmValue);
2245
2246         add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2247
2248         if (service == NULL) {
2249                 string_set(Globals.ctx, ptr, fname);
2250         } else {
2251                 string_set(service, ptr, fname);
2252         }
2253
2254         if (file_exist(fname)) {
2255                 bool ret;
2256                 include_depth++;
2257                 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2258                 include_depth--;
2259                 TALLOC_FREE(fname);
2260                 return ret;
2261         }
2262
2263         DEBUG(2, ("Can't find include file %s\n", fname));
2264         TALLOC_FREE(fname);
2265         return true;
2266 }
2267
2268 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2269 {
2270         char *config_option = NULL;
2271         const char *range = NULL;
2272         bool ret = false;
2273
2274         SMB_ASSERT(low != NULL);
2275         SMB_ASSERT(high != NULL);
2276
2277         if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2278                 domain_name = "*";
2279         }
2280
2281         config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2282                                         domain_name);
2283         if (config_option == NULL) {
2284                 DEBUG(0, ("out of memory\n"));
2285                 return false;
2286         }
2287
2288         range = lp_parm_const_string(-1, config_option, "range", NULL);
2289         if (range == NULL) {
2290                 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2291                 goto done;
2292         }
2293
2294         if (sscanf(range, "%u - %u", low, high) != 2) {
2295                 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2296                           range, domain_name));
2297                 goto done;
2298         }
2299
2300         ret = true;
2301
2302 done:
2303         talloc_free(config_option);
2304         return ret;
2305
2306 }
2307
2308 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2309 {
2310         return lp_idmap_range("*", low, high);
2311 }
2312
2313 const char *lp_idmap_backend(const char *domain_name)
2314 {
2315         char *config_option = NULL;
2316         const char *backend = NULL;
2317
2318         if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2319                 domain_name = "*";
2320         }
2321
2322         config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2323                                         domain_name);
2324         if (config_option == NULL) {
2325                 DEBUG(0, ("out of memory\n"));
2326                 return false;
2327         }
2328
2329         backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2330         if (backend == NULL) {
2331                 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2332                 goto done;
2333         }
2334
2335 done:
2336         talloc_free(config_option);
2337         return backend;
2338 }
2339
2340 const char *lp_idmap_default_backend(void)
2341 {
2342         return lp_idmap_backend("*");
2343 }
2344
2345 /***************************************************************************
2346  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2347 ***************************************************************************/
2348
2349 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2350 {
2351         const char *suffix_string;
2352
2353         suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2354                                         Globals.ldap_suffix );
2355         if ( !suffix_string ) {
2356                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2357                 return "";
2358         }
2359
2360         return suffix_string;
2361 }
2362
2363 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2364 {
2365         if (Globals.szLdapMachineSuffix[0])
2366                 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
2367
2368         return lp_string(ctx, Globals.ldap_suffix);
2369 }
2370
2371 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2372 {
2373         if (Globals.szLdapUserSuffix[0])
2374                 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
2375
2376         return lp_string(ctx, Globals.ldap_suffix);
2377 }
2378
2379 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2380 {
2381         if (Globals.szLdapGroupSuffix[0])
2382                 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
2383
2384         return lp_string(ctx, Globals.ldap_suffix);
2385 }
2386
2387 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2388 {
2389         if (Globals.szLdapIdmapSuffix[0])
2390                 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
2391
2392         return lp_string(ctx, Globals.ldap_suffix);
2393 }
2394
2395 /**
2396   return the parameter pointer for a parameter
2397 */
2398 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2399 {
2400         if (service == NULL) {
2401                 if (parm->p_class == P_LOCAL)
2402                         return (void *)(((char *)&sDefault)+parm->offset);
2403                 else if (parm->p_class == P_GLOBAL)
2404                         return (void *)(((char *)&Globals)+parm->offset);
2405                 else return NULL;
2406         } else {
2407                 return (void *)(((char *)service) + parm->offset);
2408         }
2409 }
2410
2411 /***************************************************************************
2412  Process a parameter for a particular service number. If snum < 0
2413  then assume we are in the globals.
2414 ***************************************************************************/
2415
2416 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2417 {
2418         TALLOC_CTX *frame = talloc_stackframe();
2419         struct loadparm_context *lp_ctx;
2420         bool ok;
2421
2422         lp_ctx = setup_lp_context(frame);
2423         if (lp_ctx == NULL) {
2424                 TALLOC_FREE(frame);
2425                 return false;
2426         }
2427
2428         if (snum < 0) {
2429                 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2430         } else {
2431                 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2432                                                 pszParmName, pszParmValue);
2433         }
2434
2435         TALLOC_FREE(frame);
2436
2437         return ok;
2438 }
2439
2440 /***************************************************************************
2441 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2442 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2443 ***************************************************************************/
2444
2445 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2446 {
2447         int parmnum, i;
2448         parmnum = lpcfg_map_parameter(pszParmName);
2449         if (parmnum >= 0) {
2450                 flags_list[parmnum] &= ~FLAG_CMDLINE;
2451                 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2452                         return false;
2453                 }
2454                 flags_list[parmnum] |= FLAG_CMDLINE;
2455
2456                 /* we have to also set FLAG_CMDLINE on aliases.  Aliases must
2457                  * be grouped in the table, so we don't have to search the
2458                  * whole table */
2459                 for (i=parmnum-1;
2460                      i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2461                              && parm_table[i].p_class == parm_table[parmnum].p_class;
2462                      i--) {
2463                         flags_list[i] |= FLAG_CMDLINE;
2464                 }
2465                 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2466                              && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2467                         flags_list[i] |= FLAG_CMDLINE;
2468                 }
2469
2470                 return true;
2471         }
2472
2473         /* it might be parametric */
2474         if (strchr(pszParmName, ':') != NULL) {
2475                 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2476                 return true;
2477         }
2478
2479         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",  pszParmName));
2480         return false;
2481 }
2482
2483 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2484 {
2485         bool ret;
2486         TALLOC_CTX *frame = talloc_stackframe();
2487         struct loadparm_context *lp_ctx;
2488
2489         lp_ctx = setup_lp_context(frame);
2490         if (lp_ctx == NULL) {
2491                 TALLOC_FREE(frame);
2492                 return false;
2493         }
2494
2495         ret = lpcfg_set_cmdline(lp_ctx, pszParmName, pszParmValue);
2496
2497         TALLOC_FREE(frame);
2498         return ret;
2499 }
2500
2501 /***************************************************************************
2502  Process a parameter.
2503 ***************************************************************************/
2504
2505 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2506                          void *userdata)
2507 {
2508         if (!bInGlobalSection && bGlobalOnly)
2509                 return true;
2510
2511         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2512
2513         if (bInGlobalSection) {
2514                 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2515         } else {
2516                 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2517                                                   pszParmName, pszParmValue);
2518         }
2519 }
2520
2521 /***************************************************************************
2522  Initialize any local variables in the sDefault table, after parsing a
2523  [globals] section.
2524 ***************************************************************************/
2525
2526 static void init_locals(void)
2527 {
2528         /*
2529          * We run this check once the [globals] is parsed, to force
2530          * the VFS objects and other per-share settings we need for
2531          * the standard way a AD DC is operated.  We may change these
2532          * as our code evolves, which is why we force these settings.
2533          *
2534          * We can't do this at the end of lp_load_ex(), as by that
2535          * point the services have been loaded and they will already
2536          * have "" as their vfs objects.
2537          */
2538         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2539                 const char **vfs_objects = lp_vfs_objects(-1);
2540                 if (!vfs_objects || !vfs_objects[0]) {
2541                         if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2542                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2543                         } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2544                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2545                         } else {
2546                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2547                         }
2548                 }
2549
2550                 lp_do_parameter(-1, "map hidden", "no");
2551                 lp_do_parameter(-1, "map system", "no");
2552                 lp_do_parameter(-1, "map readonly", "no");
2553                 lp_do_parameter(-1, "map archive", "no");
2554                 lp_do_parameter(-1, "store dos attributes", "yes");
2555         }
2556 }
2557
2558 /***************************************************************************
2559  Process a new section (service). At this stage all sections are services.
2560  Later we'll have special sections that permit server parameters to be set.
2561  Returns true on success, false on failure.
2562 ***************************************************************************/
2563
2564 bool lp_do_section(const char *pszSectionName, void *userdata)
2565 {
2566         struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2567         bool bRetval;
2568         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2569                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2570         bRetval = false;
2571
2572         /* if we were in a global section then do the local inits */
2573         if (bInGlobalSection && !isglobal)
2574                 init_locals();
2575
2576         /* if we've just struck a global section, note the fact. */
2577         bInGlobalSection = isglobal;
2578         if (lp_ctx != NULL) {
2579                 lp_ctx->bInGlobalSection = isglobal;
2580         }
2581
2582         /* check for multiple global sections */
2583         if (bInGlobalSection) {
2584                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2585                 return true;
2586         }
2587
2588         if (!bInGlobalSection && bGlobalOnly)
2589                 return true;
2590
2591         /* if we have a current service, tidy it up before moving on */
2592         bRetval = true;
2593
2594         if (iServiceIndex >= 0)
2595                 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2596
2597         /* if all is still well, move to the next record in the services array */
2598         if (bRetval) {
2599                 /* We put this here to avoid an odd message order if messages are */
2600                 /* issued by the post-processing of a previous section. */
2601                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2602
2603                 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2604                 if (iServiceIndex < 0) {
2605                         DEBUG(0, ("Failed to add a new service\n"));
2606                         return false;
2607                 }
2608                 /* Clean all parametric options for service */
2609                 /* They will be added during parsing again */
2610                 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2611         }
2612
2613         return bRetval;
2614 }
2615
2616 /***************************************************************************
2617  Display the contents of a parameter of a single services record.
2618 ***************************************************************************/
2619
2620 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2621 {
2622         bool result = false;
2623         struct loadparm_context *lp_ctx;
2624
2625         lp_ctx = setup_lp_context(talloc_tos());
2626         if (lp_ctx == NULL) {
2627                 return false;
2628         }
2629
2630         if (isGlobal) {
2631                 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2632         } else {
2633                 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2634         }
2635         TALLOC_FREE(lp_ctx);
2636         return result;
2637 }
2638
2639 #if 0
2640 /***************************************************************************
2641  Display the contents of a single copy structure.
2642 ***************************************************************************/
2643 static void dump_copy_map(bool *pcopymap)
2644 {
2645         int i;
2646         if (!pcopymap)
2647                 return;
2648
2649         printf("\n\tNon-Copied parameters:\n");
2650
2651         for (i = 0; parm_table[i].label; i++)
2652                 if (parm_table[i].p_class == P_LOCAL &&
2653                     parm_table[i].ptr && !pcopymap[i] &&
2654                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2655                 {
2656                         printf("\t\t%s\n", parm_table[i].label);
2657                 }
2658 }
2659 #endif
2660
2661 /***************************************************************************
2662  Return TRUE if the passed service number is within range.
2663 ***************************************************************************/
2664
2665 bool lp_snum_ok(int iService)
2666 {
2667         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2668 }
2669
2670 /***************************************************************************
2671  Auto-load some home services.
2672 ***************************************************************************/
2673
2674 static void lp_add_auto_services(char *str)
2675 {
2676         char *s;
2677         char *p;
2678         int homes;
2679         char *saveptr;
2680
2681         if (!str)
2682                 return;
2683
2684         s = talloc_strdup(talloc_tos(), str);
2685         if (!s) {
2686                 smb_panic("talloc_strdup failed");
2687                 return;
2688         }
2689
2690         homes = lp_servicenumber(HOMES_NAME);
2691
2692         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
2693              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
2694                 char *home;
2695
2696                 if (lp_servicenumber(p) >= 0)
2697                         continue;
2698
2699                 home = get_user_home_dir(talloc_tos(), p);
2700
2701                 if (home && home[0] && homes >= 0)
2702                         lp_add_home(p, homes, p, home);
2703
2704                 TALLOC_FREE(home);
2705         }
2706         TALLOC_FREE(s);
2707 }
2708
2709 /***************************************************************************
2710  Auto-load one printer.
2711 ***************************************************************************/
2712
2713 void lp_add_one_printer(const char *name, const char *comment,
2714                         const char *location, void *pdata)
2715 {
2716         int printers = lp_servicenumber(PRINTERS_NAME);
2717         int i;
2718
2719         if (lp_servicenumber(name) < 0) {
2720                 lp_add_printer(name, printers);
2721                 if ((i = lp_servicenumber(name)) >= 0) {
2722                         string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
2723                         ServicePtrs[i]->autoloaded = true;
2724                 }
2725         }
2726 }
2727
2728 /***************************************************************************
2729  Have we loaded a services file yet?
2730 ***************************************************************************/
2731
2732 bool lp_loaded(void)
2733 {
2734         return (bLoaded);
2735 }
2736
2737 /***************************************************************************
2738  Unload unused services.
2739 ***************************************************************************/
2740
2741 void lp_killunused(struct smbd_server_connection *sconn,
2742                    bool (*snumused) (struct smbd_server_connection *, int))
2743 {
2744         int i;
2745         for (i = 0; i < iNumServices; i++) {
2746                 if (!VALID(i))
2747                         continue;
2748
2749                 /* don't kill autoloaded or usershare services */
2750                 if ( ServicePtrs[i]->autoloaded ||
2751                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
2752                         continue;
2753                 }
2754
2755                 if (!snumused || !snumused(sconn, i)) {
2756                         free_service_byindex(i);
2757                 }
2758         }
2759 }
2760
2761 /**
2762  * Kill all except autoloaded and usershare services - convenience wrapper
2763  */
2764 void lp_kill_all_services(void)
2765 {
2766         lp_killunused(NULL, NULL);
2767 }
2768
2769 /***************************************************************************
2770  Unload a service.
2771 ***************************************************************************/
2772
2773 void lp_killservice(int iServiceIn)
2774 {
2775         if (VALID(iServiceIn)) {
2776                 free_service_byindex(iServiceIn);
2777         }
2778 }
2779
2780 /***************************************************************************
2781  Save the curent values of all global and sDefault parameters into the 
2782  defaults union. This allows testparm to show only the
2783  changed (ie. non-default) parameters.
2784 ***************************************************************************/
2785
2786 static void lp_save_defaults(void)
2787 {
2788         int i;
2789         struct parmlist_entry * parm;
2790         for (i = 0; parm_table[i].label; i++) {
2791                 if (!(flags_list[i] & FLAG_CMDLINE)) {
2792                         flags_list[i] |= FLAG_DEFAULT;
2793                 }
2794
2795                 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
2796                     && parm_table[i].p_class == parm_table[i - 1].p_class)
2797                         continue;
2798                 switch (parm_table[i].type) {
2799                         case P_LIST:
2800                         case P_CMDLIST:
2801                                 parm_table[i].def.lvalue = str_list_copy(
2802                                         NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
2803                                 break;
2804                         case P_STRING:
2805                         case P_USTRING:
2806                                 parm_table[i].def.svalue = talloc_strdup(Globals.ctx, *(char **)lp_parm_ptr(NULL, &parm_table[i]));
2807                                 if (parm_table[i].def.svalue == NULL) {
2808                                         smb_panic("talloc_strdup failed");
2809                                 }
2810                                 break;
2811                         case P_BOOL:
2812                         case P_BOOLREV:
2813                                 parm_table[i].def.bvalue =
2814                                         *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
2815                                 break;
2816                         case P_CHAR:
2817                                 parm_table[i].def.cvalue =
2818                                         *(char *)lp_parm_ptr(NULL, &parm_table[i]);
2819                                 break;
2820                         case P_INTEGER:
2821                         case P_OCTAL:
2822                         case P_ENUM:
2823                         case P_BYTES:
2824                                 parm_table[i].def.ivalue =
2825                                         *(int *)lp_parm_ptr(NULL, &parm_table[i]);
2826                                 break;
2827                         case P_SEP:
2828                                 break;
2829                 }
2830         }
2831
2832         for (parm=Globals.param_opt; parm; parm=parm->next) {
2833                 if (!(parm->priority & FLAG_CMDLINE)) {
2834                         parm->priority |= FLAG_DEFAULT;
2835                 }
2836         }
2837
2838         for (parm=sDefault.param_opt; parm; parm=parm->next) {
2839                 if (!(parm->priority & FLAG_CMDLINE)) {
2840                         parm->priority |= FLAG_DEFAULT;
2841                 }
2842         }
2843
2844         defaults_saved = true;
2845 }
2846
2847 /***********************************************************
2848  If we should send plaintext/LANMAN passwords in the clinet
2849 ************************************************************/
2850
2851 static void set_allowed_client_auth(void)
2852 {
2853         if (Globals.client_ntlmv2_auth) {
2854                 Globals.client_lanman_auth = false;
2855         }
2856         if (!Globals.client_lanman_auth) {
2857                 Globals.client_plaintext_auth = false;
2858         }
2859 }
2860
2861 /***************************************************************************
2862  JRA.
2863  The following code allows smbd to read a user defined share file.
2864  Yes, this is my intent. Yes, I'm comfortable with that...
2865
2866  THE FOLLOWING IS SECURITY CRITICAL CODE.
2867
2868  It washes your clothes, it cleans your house, it guards you while you sleep...
2869  Do not f%^k with it....
2870 ***************************************************************************/
2871
2872 #define MAX_USERSHARE_FILE_SIZE (10*1024)
2873
2874 /***************************************************************************
2875  Check allowed stat state of a usershare file.
2876  Ensure we print out who is dicking with us so the admin can
2877  get their sorry ass fired.
2878 ***************************************************************************/
2879
2880 static bool check_usershare_stat(const char *fname,
2881                                  const SMB_STRUCT_STAT *psbuf)
2882 {
2883         if (!S_ISREG(psbuf->st_ex_mode)) {
2884                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2885                         "not a regular file\n",
2886                         fname, (unsigned int)psbuf->st_ex_uid ));
2887                 return false;
2888         }
2889
2890         /* Ensure this doesn't have the other write bit set. */
2891         if (psbuf->st_ex_mode & S_IWOTH) {
2892                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
2893                         "public write. Refusing to allow as a usershare file.\n",
2894                         fname, (unsigned int)psbuf->st_ex_uid ));
2895                 return false;
2896         }
2897
2898         /* Should be 10k or less. */
2899         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
2900                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2901                         "too large (%u) to be a user share file.\n",
2902                         fname, (unsigned int)psbuf->st_ex_uid,
2903                         (unsigned int)psbuf->st_ex_size ));
2904                 return false;
2905         }
2906
2907         return true;
2908 }
2909
2910 /***************************************************************************
2911  Parse the contents of a usershare file.
2912 ***************************************************************************/
2913
2914 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
2915                         SMB_STRUCT_STAT *psbuf,
2916                         const char *servicename,
2917                         int snum,
2918                         char **lines,
2919                         int numlines,
2920                         char **pp_sharepath,
2921                         char **pp_comment,
2922                         char **pp_cp_servicename,
2923                         struct security_descriptor **ppsd,
2924                         bool *pallow_guest)
2925 {
2926         const char **prefixallowlist = lp_usershare_prefix_allow_list();
2927         const char **prefixdenylist = lp_usershare_prefix_deny_list();
2928         int us_vers;
2929         DIR *dp;
2930         SMB_STRUCT_STAT sbuf;
2931         char *sharepath = NULL;
2932         char *comment = NULL;
2933
2934         *pp_sharepath = NULL;
2935         *pp_comment = NULL;
2936
2937         *pallow_guest = false;
2938
2939         if (numlines < 4) {
2940                 return USERSHARE_MALFORMED_FILE;
2941         }
2942
2943         if (strcmp(lines[0], "#VERSION 1") == 0) {
2944                 us_vers = 1;
2945         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
2946                 us_vers = 2;
2947                 if (numlines < 5) {
2948                         return USERSHARE_MALFORMED_FILE;
2949                 }
2950         } else {
2951                 return USERSHARE_BAD_VERSION;
2952         }
2953
2954         if (strncmp(lines[1], "path=", 5) != 0) {
2955                 return USERSHARE_MALFORMED_PATH;
2956         }
2957
2958         sharepath = talloc_strdup(ctx, &lines[1][5]);
2959         if (!sharepath) {
2960                 return USERSHARE_POSIX_ERR;
2961         }
2962         trim_string(sharepath, " ", " ");
2963
2964         if (strncmp(lines[2], "comment=", 8) != 0) {
2965                 return USERSHARE_MALFORMED_COMMENT_DEF;
2966         }
2967
2968         comment = talloc_strdup(ctx, &lines[2][8]);
2969         if (!comment) {
2970                 return USERSHARE_POSIX_ERR;
2971         }
2972         trim_string(comment, " ", " ");
2973         trim_char(comment, '"', '"');
2974
2975         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
2976                 return USERSHARE_MALFORMED_ACL_DEF;
2977         }
2978
2979         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
2980                 return USERSHARE_ACL_ERR;
2981         }
2982
2983         if (us_vers == 2) {
2984                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
2985                         return USERSHARE_MALFORMED_ACL_DEF;
2986                 }
2987                 if (lines[4][9] == 'y') {
2988                         *pallow_guest = true;
2989                 }
2990
2991                 /* Backwards compatible extension to file version #2. */
2992                 if (numlines > 5) {
2993                         if (strncmp(lines[5], "sharename=", 10) != 0) {
2994                                 return USERSHARE_MALFORMED_SHARENAME_DEF;
2995                         }
2996                         if (!strequal(&lines[5][10], servicename)) {
2997                                 return USERSHARE_BAD_SHARENAME;
2998                         }
2999                         *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
3000                         if (!*pp_cp_servicename) {
3001                                 return USERSHARE_POSIX_ERR;
3002                         }
3003                 }
3004         }
3005
3006         if (*pp_cp_servicename == NULL) {
3007                 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3008                 if (!*pp_cp_servicename) {
3009                         return USERSHARE_POSIX_ERR;
3010                 }
3011         }
3012
3013         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3014                 /* Path didn't change, no checks needed. */
3015                 *pp_sharepath = sharepath;
3016                 *pp_comment = comment;
3017                 return USERSHARE_OK;
3018         }
3019
3020         /* The path *must* be absolute. */
3021         if (sharepath[0] != '/') {
3022                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3023                         servicename, sharepath));
3024                 return USERSHARE_PATH_NOT_ABSOLUTE;
3025         }
3026
3027         /* If there is a usershare prefix deny list ensure one of these paths
3028            doesn't match the start of the user given path. */
3029         if (prefixdenylist) {
3030                 int i;
3031                 for ( i=0; prefixdenylist[i]; i++ ) {
3032                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3033                                 servicename, i, prefixdenylist[i], sharepath ));
3034                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3035                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3036                                         "usershare prefix deny list entries.\n",
3037                                         servicename, sharepath));
3038                                 return USERSHARE_PATH_IS_DENIED;
3039                         }
3040                 }
3041         }
3042
3043         /* If there is a usershare prefix allow list ensure one of these paths
3044            does match the start of the user given path. */
3045
3046         if (prefixallowlist) {
3047                 int i;
3048                 for ( i=0; prefixallowlist[i]; i++ ) {
3049                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3050                                 servicename, i, prefixallowlist[i], sharepath ));
3051                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3052                                 break;
3053                         }
3054                 }
3055                 if (prefixallowlist[i] == NULL) {
3056                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3057                                 "usershare prefix allow list entries.\n",
3058                                 servicename, sharepath));
3059                         return USERSHARE_PATH_NOT_ALLOWED;
3060                 }
3061         }
3062
3063         /* Ensure this is pointing to a directory. */
3064         dp = opendir(sharepath);
3065
3066         if (!dp) {
3067                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3068                         servicename, sharepath));
3069                 return USERSHARE_PATH_NOT_DIRECTORY;
3070         }
3071
3072         /* Ensure the owner of the usershare file has permission to share
3073            this directory. */
3074
3075         if (sys_stat(sharepath, &sbuf, false) == -1) {
3076                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3077                         servicename, sharepath, strerror(errno) ));
3078                 closedir(dp);
3079                 return USERSHARE_POSIX_ERR;
3080         }
3081
3082         closedir(dp);
3083
3084         if (!S_ISDIR(sbuf.st_ex_mode)) {
3085                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3086                         servicename, sharepath ));
3087                 return USERSHARE_PATH_NOT_DIRECTORY;
3088         }
3089
3090         /* Check if sharing is restricted to owner-only. */
3091         /* psbuf is the stat of the usershare definition file,
3092            sbuf is the stat of the target directory to be shared. */
3093
3094         if (lp_usershare_owner_only()) {
3095                 /* root can share anything. */
3096                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3097                         return USERSHARE_PATH_NOT_ALLOWED;
3098                 }
3099         }
3100
3101         *pp_sharepath = sharepath;
3102         *pp_comment = comment;
3103         return USERSHARE_OK;
3104 }
3105
3106 /***************************************************************************
3107  Deal with a usershare file.
3108  Returns:
3109         >= 0 - snum
3110         -1 - Bad name, invalid contents.
3111            - service name already existed and not a usershare, problem
3112             with permissions to share directory etc.
3113 ***************************************************************************/
3114
3115 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3116 {
3117         SMB_STRUCT_STAT sbuf;
3118         SMB_STRUCT_STAT lsbuf;
3119         char *fname = NULL;
3120         char *sharepath = NULL;
3121         char *comment = NULL;
3122         char *cp_service_name = NULL;
3123         char **lines = NULL;
3124         int numlines = 0;
3125         int fd = -1;
3126         int iService = -1;
3127         TALLOC_CTX *ctx = talloc_stackframe();
3128         struct security_descriptor *psd = NULL;
3129         bool guest_ok = false;
3130         char *canon_name = NULL;
3131         bool added_service = false;
3132         int ret = -1;
3133
3134         /* Ensure share name doesn't contain invalid characters. */
3135         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3136                 DEBUG(0,("process_usershare_file: share name %s contains "
3137                         "invalid characters (any of %s)\n",
3138                         file_name, INVALID_SHARENAME_CHARS ));
3139                 goto out;
3140         }
3141
3142         canon_name = canonicalize_servicename(ctx, file_name);
3143         if (!canon_name) {
3144                 goto out;
3145         }
3146
3147         fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3148         if (!fname) {
3149                 goto out;
3150         }
3151
3152         /* Minimize the race condition by doing an lstat before we
3153            open and fstat. Ensure this isn't a symlink link. */
3154
3155         if (sys_lstat(fname, &lsbuf, false) != 0) {
3156                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3157                         fname, strerror(errno) ));
3158                 goto out;
3159         }
3160
3161         /* This must be a regular file, not a symlink, directory or
3162            other strange filetype. */
3163         if (!check_usershare_stat(fname, &lsbuf)) {
3164                 goto out;
3165         }
3166
3167         {
3168                 TDB_DATA data;
3169                 NTSTATUS status;
3170
3171                 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3172                                                canon_name, &data);
3173
3174                 iService = -1;
3175
3176                 if (NT_STATUS_IS_OK(status) &&
3177                     (data.dptr != NULL) &&
3178                     (data.dsize == sizeof(iService))) {
3179                         memcpy(&iService, data.dptr, sizeof(iService));
3180                 }
3181         }
3182
3183         if (iService != -1 &&
3184             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3185                              &lsbuf.st_ex_mtime) == 0) {
3186                 /* Nothing changed - Mark valid and return. */
3187                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3188                         canon_name ));
3189                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3190                 ret = iService;
3191                 goto out;
3192         }
3193
3194         /* Try and open the file read only - no symlinks allowed. */
3195 #ifdef O_NOFOLLOW
3196         fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3197 #else
3198         fd = open(fname, O_RDONLY, 0);
3199 #endif
3200
3201         if (fd == -1) {
3202                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3203                         fname, strerror(errno) ));
3204                 goto out;
3205         }
3206
3207         /* Now fstat to be *SURE* it's a regular file. */
3208         if (sys_fstat(fd, &sbuf, false) != 0) {
3209                 close(fd);
3210                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3211                         fname, strerror(errno) ));
3212                 goto out;
3213         }
3214
3215         /* Is it the same dev/inode as was lstated ? */
3216         if (!check_same_stat(&lsbuf, &sbuf)) {
3217                 close(fd);
3218                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3219                         "Symlink spoofing going on ?\n", fname ));
3220                 goto out;
3221         }
3222
3223         /* This must be a regular file, not a symlink, directory or
3224            other strange filetype. */
3225         if (!check_usershare_stat(fname, &sbuf)) {
3226                 close(fd);
3227                 goto out;
3228         }
3229
3230         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3231
3232         close(fd);
3233         if (lines == NULL) {
3234                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3235                         fname, (unsigned int)sbuf.st_ex_uid ));
3236                 goto out;
3237         }
3238
3239         if (parse_usershare_file(ctx, &sbuf, file_name,
3240                         iService, lines, numlines, &sharepath,
3241                         &comment, &cp_service_name,
3242                         &psd, &guest_ok) != USERSHARE_OK) {
3243                 goto out;
3244         }
3245
3246         /* Everything ok - add the service possibly using a template. */
3247         if (iService < 0) {
3248                 const struct loadparm_service *sp = &sDefault;
3249                 if (snum_template != -1) {
3250                         sp = ServicePtrs[snum_template];
3251                 }
3252
3253                 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3254                         DEBUG(0, ("process_usershare_file: Failed to add "
3255                                 "new service %s\n", cp_service_name));
3256                         goto out;
3257                 }
3258
3259                 added_service = true;
3260
3261                 /* Read only is controlled by usershare ACL below. */
3262                 ServicePtrs[iService]->read_only = false;
3263         }
3264
3265         /* Write the ACL of the new/modified share. */
3266         if (!set_share_security(canon_name, psd)) {
3267                  DEBUG(0, ("process_usershare_file: Failed to set share "
3268                         "security for user share %s\n",
3269                         canon_name ));
3270                 goto out;
3271         }
3272
3273         /* If from a template it may be marked invalid. */
3274         ServicePtrs[iService]->valid = true;
3275
3276         /* Set the service as a valid usershare. */
3277         ServicePtrs[iService]->usershare = USERSHARE_VALID;
3278
3279         /* Set guest access. */
3280         if (lp_usershare_allow_guests()) {
3281                 ServicePtrs[iService]->guest_ok = guest_ok;
3282         }
3283
3284         /* And note when it was loaded. */
3285         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3286         string_set(ServicePtrs[iService], &ServicePtrs[iService]->path, sharepath);
3287         string_set(ServicePtrs[iService], &ServicePtrs[iService]->comment, comment);
3288
3289         ret = iService;
3290
3291   out:
3292
3293         if (ret == -1 && iService != -1 && added_service) {
3294                 lp_remove_service(iService);
3295         }
3296
3297         TALLOC_FREE(lines);
3298         TALLOC_FREE(ctx);
3299         return ret;
3300 }
3301
3302 /***************************************************************************
3303  Checks if a usershare entry has been modified since last load.
3304 ***************************************************************************/
3305
3306 static bool usershare_exists(int iService, struct timespec *last_mod)
3307 {
3308         SMB_STRUCT_STAT lsbuf;
3309         const char *usersharepath = Globals.usershare_path;
3310         char *fname;
3311
3312         fname = talloc_asprintf(talloc_tos(),
3313                                 "%s/%s",
3314                                 usersharepath,
3315                                 ServicePtrs[iService]->szService);
3316         if (fname == NULL) {
3317                 return false;
3318         }
3319
3320         if (sys_lstat(fname, &lsbuf, false) != 0) {
3321                 TALLOC_FREE(fname);
3322                 return false;
3323         }
3324
3325         if (!S_ISREG(lsbuf.st_ex_mode)) {
3326                 TALLOC_FREE(fname);
3327                 return false;
3328         }
3329
3330         TALLOC_FREE(fname);
3331         *last_mod = lsbuf.st_ex_mtime;
3332         return true;
3333 }
3334
3335 /***************************************************************************
3336  Load a usershare service by name. Returns a valid servicenumber or -1.
3337 ***************************************************************************/
3338
3339 int load_usershare_service(const char *servicename)
3340 {
3341         SMB_STRUCT_STAT sbuf;
3342         const char *usersharepath = Globals.usershare_path;
3343         int max_user_shares = Globals.usershare_max_shares;
3344         int snum_template = -1;
3345
3346         if (*usersharepath == 0 ||  max_user_shares == 0) {
3347                 return -1;
3348         }
3349
3350         if (sys_stat(usersharepath, &sbuf, false) != 0) {
3351                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3352                         usersharepath, strerror(errno) ));
3353                 return -1;
3354         }
3355
3356         if (!S_ISDIR(sbuf.st_ex_mode)) {
3357                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3358                         usersharepath ));
3359                 return -1;
3360         }
3361
3362         /*
3363          * This directory must be owned by root, and have the 't' bit set.
3364          * It also must not be writable by "other".
3365          */
3366
3367 #ifdef S_ISVTX
3368         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3369 #else
3370         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3371 #endif
3372                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3373                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
3374                         usersharepath ));
3375                 return -1;
3376         }
3377
3378         /* Ensure the template share exists if it's set. */
3379         if (Globals.usershare_template_share[0]) {
3380                 /* We can't use lp_servicenumber here as we are recommending that
3381                    template shares have -valid=false set. */
3382                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3383                         if (ServicePtrs[snum_template]->szService &&
3384                                         strequal(ServicePtrs[snum_template]->szService,
3385                                                 Globals.usershare_template_share)) {
3386                                 break;
3387                         }
3388                 }
3389
3390                 if (snum_template == -1) {
3391                         DEBUG(0,("load_usershare_service: usershare template share %s "
3392                                 "does not exist.\n",
3393                                 Globals.usershare_template_share ));
3394                         return -1;
3395                 }
3396         }
3397
3398         return process_usershare_file(usersharepath, servicename, snum_template);
3399 }
3400
3401 /***************************************************************************
3402  Load all user defined shares from the user share directory.
3403  We only do this if we're enumerating the share list.
3404  This is the function that can delete usershares that have
3405  been removed.
3406 ***************************************************************************/
3407
3408 int load_usershare_shares(struct smbd_server_connection *sconn,
3409                           bool (*snumused) (struct smbd_server_connection *, int))
3410 {
3411         DIR *dp;
3412         SMB_STRUCT_STAT sbuf;
3413         struct dirent *de;
3414         int num_usershares = 0;
3415         int max_user_shares = Globals.usershare_max_shares;
3416         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3417         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3418         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3419         int iService;
3420         int snum_template = -1;
3421         const char *usersharepath = Globals.usershare_path;
3422         int ret = lp_numservices();
3423         TALLOC_CTX *tmp_ctx;
3424
3425         if (max_user_shares == 0 || *usersharepath == '\0') {
3426                 return lp_numservices();
3427         }
3428
3429         if (sys_stat(usersharepath, &sbuf, false) != 0) {
3430                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3431                         usersharepath, strerror(errno) ));
3432                 return ret;
3433         }
3434
3435         /*
3436          * This directory must be owned by root, and have the 't' bit set.
3437          * It also must not be writable by "other".
3438          */
3439
3440 #ifdef S_ISVTX
3441         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3442 #else
3443         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3444 #endif
3445                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3446                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
3447                         usersharepath ));
3448                 return ret;
3449         }
3450
3451         /* Ensure the template share exists if it's set. */
3452         if (Globals.usershare_template_share[0]) {
3453                 /* We can't use lp_servicenumber here as we are recommending that
3454                    template shares have -valid=false set. */
3455                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3456                         if (ServicePtrs[snum_template]->szService &&
3457                                         strequal(ServicePtrs[snum_template]->szService,
3458                                                 Globals.usershare_template_share)) {
3459                                 break;
3460                         }
3461                 }
3462
3463                 if (snum_template == -1) {
3464                         DEBUG(0,("load_usershare_shares: usershare template share %s "
3465                                 "does not exist.\n",
3466                                 Globals.usershare_template_share ));
3467                         return ret;
3468                 }
3469         }
3470
3471         /* Mark all existing usershares as pending delete. */
3472         for (iService = iNumServices - 1; iService >= 0; iService--) {
3473                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3474                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3475                 }
3476         }
3477
3478         dp = opendir(usersharepath);
3479         if (!dp) {
3480                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3481                         usersharepath, strerror(errno) ));
3482                 return ret;
3483         }
3484
3485         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3486                         (de = readdir(dp));
3487                         num_dir_entries++ ) {
3488                 int r;
3489                 const char *n = de->d_name;
3490
3491                 /* Ignore . and .. */
3492                 if (*n == '.') {
3493                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3494                                 continue;
3495                         }
3496                 }
3497
3498                 if (n[0] == ':') {
3499                         /* Temporary file used when creating a share. */
3500                         num_tmp_dir_entries++;
3501                 }
3502
3503                 /* Allow 20% tmp entries. */
3504                 if (num_tmp_dir_entries > allowed_tmp_entries) {
3505                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3506                                 "in directory %s\n",
3507                                 num_tmp_dir_entries, usersharepath));
3508                         break;
3509                 }
3510
3511                 r = process_usershare_file(usersharepath, n, snum_template);
3512                 if (r == 0) {
3513                         /* Update the services count. */
3514                         num_usershares++;
3515                         if (num_usershares >= max_user_shares) {
3516                                 DEBUG(0,("load_usershare_shares: max user shares reached "
3517                                         "on file %s in directory %s\n",
3518                                         n, usersharepath ));
3519                                 break;
3520                         }
3521                 } else if (r == -1) {
3522                         num_bad_dir_entries++;
3523                 }
3524
3525                 /* Allow 20% bad entries. */
3526                 if (num_bad_dir_entries > allowed_bad_entries) {
3527                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3528                                 "in directory %s\n",
3529                                 num_bad_dir_entries, usersharepath));
3530                         break;
3531                 }
3532
3533                 /* Allow 20% bad entries. */
3534                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3535                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3536                         "in directory %s\n",
3537                         num_dir_entries, usersharepath));
3538                         break;
3539                 }
3540         }
3541
3542         closedir(dp);
3543
3544         /* Sweep through and delete any non-refreshed usershares that are
3545            not currently in use. */
3546         tmp_ctx = talloc_stackframe();
3547         for (iService = iNumServices - 1; iService >= 0; iService--) {
3548                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3549                         char *servname;
3550
3551                         if (snumused && snumused(sconn, iService)) {
3552                                 continue;
3553                         }
3554
3555                         servname = lp_servicename(tmp_ctx, iService);
3556
3557                         /* Remove from the share ACL db. */
3558                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3559                                   servname ));
3560                         delete_share_security(servname);
3561                         free_service_byindex(iService);
3562                 }
3563         }
3564         talloc_free(tmp_ctx);
3565
3566         return lp_numservices();
3567 }
3568
3569 /********************************************************
3570  Destroy global resources allocated in this file
3571 ********************************************************/
3572
3573 void gfree_loadparm(void)
3574 {
3575         int i;
3576
3577         free_file_list();
3578
3579         /* Free resources allocated to services */
3580
3581         for ( i = 0; i < iNumServices; i++ ) {
3582                 if ( VALID(i) ) {
3583                         free_service_byindex(i);
3584                 }
3585         }
3586
3587         TALLOC_FREE( ServicePtrs );
3588         iNumServices = 0;
3589
3590         /* Now release all resources allocated to global
3591            parameters and the default service */
3592
3593         free_global_parameters();
3594 }
3595
3596
3597 /***************************************************************************
3598  Allow client apps to specify that they are a client
3599 ***************************************************************************/
3600 static void lp_set_in_client(bool b)
3601 {
3602     in_client = b;
3603 }
3604
3605
3606 /***************************************************************************
3607  Determine if we're running in a client app
3608 ***************************************************************************/
3609 static bool lp_is_in_client(void)
3610 {
3611     return in_client;
3612 }
3613
3614 static void lp_enforce_ad_dc_settings(void)
3615 {
3616         lp_do_parameter(GLOBAL_SECTION_SNUM, "passdb backend", "samba_dsdb");
3617         lp_do_parameter(GLOBAL_SECTION_SNUM,
3618                         "winbindd:use external pipes", "true");
3619         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:default", "external");
3620         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:svcctl", "embedded");
3621         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:srvsvc", "embedded");
3622         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:eventlog", "embedded");
3623         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:ntsvcs", "embedded");
3624         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:winreg", "embedded");
3625         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:spoolss", "embedded");
3626         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_daemon:spoolssd", "embedded");
3627         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:tcpip", "no");
3628 }
3629
3630 /***************************************************************************
3631  Load the services array from the services file. Return true on success,
3632  false on failure.
3633 ***************************************************************************/
3634
3635 static bool lp_load_ex(const char *pszFname,
3636                        bool global_only,
3637                        bool save_defaults,
3638                        bool add_ipc,
3639                        bool reinit_globals,
3640                        bool allow_include_registry,
3641                        bool load_all_shares)
3642 {
3643         char *n2 = NULL;
3644         bool bRetval;
3645         TALLOC_CTX *frame = talloc_stackframe();
3646         struct loadparm_context *lp_ctx;
3647
3648         bRetval = false;
3649
3650         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3651
3652         bInGlobalSection = true;
3653         bGlobalOnly = global_only;
3654         bAllowIncludeRegistry = allow_include_registry;
3655
3656         lp_ctx = setup_lp_context(talloc_tos());
3657
3658         init_globals(lp_ctx, reinit_globals);
3659
3660         free_file_list();
3661
3662         if (save_defaults) {
3663                 init_locals();
3664                 lp_save_defaults();
3665         }
3666
3667         if (!reinit_globals) {
3668                 free_param_opts(&Globals.param_opt);
3669                 apply_lp_set_cmdline();
3670         }
3671
3672         lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
3673
3674         /* We get sections first, so have to start 'behind' to make up */
3675         iServiceIndex = -1;
3676
3677         if (lp_config_backend_is_file()) {
3678                 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
3679                                         current_user_info.domain,
3680                                         pszFname);
3681                 if (!n2) {
3682                         smb_panic("lp_load_ex: out of memory");
3683                 }
3684
3685                 add_to_file_list(NULL, &file_lists, pszFname, n2);
3686
3687                 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
3688                 TALLOC_FREE(n2);
3689
3690                 /* finish up the last section */
3691                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3692                 if (bRetval) {
3693                         if (iServiceIndex >= 0) {
3694                                 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
3695                         }
3696                 }
3697
3698                 if (lp_config_backend_is_registry()) {
3699                         bool ok;
3700                         /* config backend changed to registry in config file */
3701                         /*
3702                          * We need to use this extra global variable here to
3703                          * survive restart: init_globals uses this as a default
3704                          * for config_backend. Otherwise, init_globals would
3705                          *  send us into an endless loop here.
3706                          */
3707
3708                         config_backend = CONFIG_BACKEND_REGISTRY;
3709                         /* start over */
3710                         DEBUG(1, ("lp_load_ex: changing to config backend "
3711                                   "registry\n"));
3712                         init_globals(lp_ctx, true);
3713
3714                         TALLOC_FREE(lp_ctx);
3715
3716                         lp_kill_all_services();
3717                         ok = lp_load_ex(pszFname, global_only, save_defaults,
3718                                         add_ipc, reinit_globals,
3719                                         allow_include_registry,
3720                                         load_all_shares);
3721                         TALLOC_FREE(frame);
3722                         return ok;
3723                 }
3724         } else if (lp_config_backend_is_registry()) {
3725                 bRetval = process_registry_globals();
3726         } else {
3727                 DEBUG(0, ("Illegal config  backend given: %d\n",
3728                           lp_config_backend()));
3729                 bRetval = false;
3730         }
3731
3732         if (bRetval && lp_registry_shares()) {
3733                 if (load_all_shares) {
3734                         bRetval = process_registry_shares();
3735                 } else {
3736                         bRetval = reload_registry_shares();
3737                 }
3738         }
3739
3740         {
3741                 char *serv = lp_auto_services(talloc_tos());
3742                 lp_add_auto_services(serv);
3743                 TALLOC_FREE(serv);
3744         }
3745
3746         if (add_ipc) {
3747                 /* When 'restrict anonymous = 2' guest connections to ipc$
3748                    are denied */
3749                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3750                 if ( lp_enable_asu_support() ) {
3751                         lp_add_ipc("ADMIN$", false);
3752                 }
3753         }
3754
3755         set_allowed_client_auth();
3756
3757         if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
3758                 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
3759                           lp_password_server()));
3760         }
3761
3762         bLoaded = true;
3763
3764         /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
3765         /* if we_are_a_wins_server is true and we are in the client            */
3766         if (lp_is_in_client() && Globals.we_are_a_wins_server) {
3767                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
3768         }
3769
3770         init_iconv();
3771
3772         fault_configure(smb_panic_s3);
3773
3774         /*
3775          * We run this check once the whole smb.conf is parsed, to
3776          * force some settings for the standard way a AD DC is
3777          * operated.  We may change these as our code evolves, which
3778          * is why we force these settings.
3779          */
3780         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3781                 lp_enforce_ad_dc_settings();
3782         }
3783
3784         bAllowIncludeRegistry = true;
3785
3786         TALLOC_FREE(frame);
3787         return (bRetval);
3788 }
3789
3790 static bool lp_load(const char *pszFname,
3791                     bool global_only,
3792                     bool save_defaults,
3793                     bool add_ipc,
3794                     bool reinit_globals)
3795 {
3796         return lp_load_ex(pszFname,
3797                           global_only,
3798                           save_defaults,
3799                           add_ipc,
3800                           reinit_globals,
3801                           true,   /* allow_include_registry */
3802                           false); /* load_all_shares*/
3803 }
3804
3805 bool lp_load_initial_only(const char *pszFname)
3806 {
3807         return lp_load_ex(pszFname,
3808                           true,   /* global only */
3809                           true,   /* save_defaults */
3810                           false,  /* add_ipc */
3811                           true,   /* reinit_globals */
3812                           false,  /* allow_include_registry */
3813                           false); /* load_all_shares*/
3814 }
3815
3816 /**
3817  * most common lp_load wrapper, loading only the globals
3818  */
3819 bool lp_load_global(const char *file_name)
3820 {
3821         return lp_load(file_name,
3822                        true,   /* global_only */
3823                        false,  /* save_defaults */
3824                        false,  /* add_ipc */
3825                        true);  /* reinit_globals */
3826 }
3827
3828 /**
3829  * The typical lp_load wrapper with shares, loads global and
3830  * shares, including IPC, but does not force immediate
3831  * loading of all shares from registry.
3832  */
3833 bool lp_load_with_shares(const char *file_name)
3834 {
3835         return lp_load(file_name,
3836                        false,  /* global_only */
3837                        false,  /* save_defaults */
3838                        true,   /* add_ipc */
3839                        true);  /* reinit_globals */
3840 }
3841
3842 /**
3843  * lp_load wrapper, especially for clients
3844  */
3845 bool lp_load_client(const char *file_name)
3846 {
3847         lp_set_in_client(true);
3848
3849         return lp_load_global(file_name);
3850 }
3851
3852 /**
3853  * lp_load wrapper, loading only globals, but intended
3854  * for subsequent calls, not reinitializing the globals
3855  * to default values
3856  */
3857 bool lp_load_global_no_reinit(const char *file_name)
3858 {
3859         return lp_load(file_name,
3860                        true,   /* global_only */
3861                        false,  /* save_defaults */
3862                        false,  /* add_ipc */
3863                        false); /* reinit_globals */
3864 }
3865
3866 /**
3867  * lp_load wrapper, loading globals and shares,
3868  * intended for subsequent calls, i.e. not reinitializing
3869  * the globals to default values.
3870  */
3871 bool lp_load_no_reinit(const char *file_name)
3872 {
3873         return lp_load(file_name,
3874                        false,  /* global_only */
3875                        false,  /* save_defaults */
3876                        false,  /* add_ipc */
3877                        false); /* reinit_globals */
3878 }
3879
3880
3881 /**
3882  * lp_load wrapper, especially for clients, no reinitialization
3883  */
3884 bool lp_load_client_no_reinit(const char *file_name)
3885 {
3886         lp_set_in_client(true);
3887
3888         return lp_load_global_no_reinit(file_name);
3889 }
3890
3891 bool lp_load_with_registry_shares(const char *pszFname)
3892 {
3893         return lp_load_ex(pszFname,
3894                           false, /* global_only */
3895                           true,  /* save_defaults */
3896                           false, /* add_ipc */
3897                           false, /* reinit_globals */
3898                           true,  /* allow_include_registry */
3899                           true); /* load_all_shares*/
3900 }
3901
3902 /***************************************************************************
3903  Return the max number of services.
3904 ***************************************************************************/
3905
3906 int lp_numservices(void)
3907 {
3908         return (iNumServices);
3909 }
3910
3911 /***************************************************************************
3912 Display the contents of the services array in human-readable form.
3913 ***************************************************************************/
3914
3915 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
3916 {
3917         int iService;
3918         struct loadparm_context *lp_ctx;
3919
3920         if (show_defaults)
3921                 defaults_saved = false;
3922
3923         lp_ctx = setup_lp_context(talloc_tos());
3924         if (lp_ctx == NULL) {
3925                 return;
3926         }
3927
3928         lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
3929
3930         lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
3931
3932         for (iService = 0; iService < maxtoprint; iService++) {
3933                 fprintf(f,"\n");
3934                 lp_dump_one(f, show_defaults, iService);
3935         }
3936 }
3937
3938 /***************************************************************************
3939 Display the contents of one service in human-readable form.
3940 ***************************************************************************/
3941
3942 void lp_dump_one(FILE * f, bool show_defaults, int snum)
3943 {
3944         if (VALID(snum)) {
3945                 if (ServicePtrs[snum]->szService[0] == '\0')
3946                         return;
3947                 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
3948                                      flags_list, show_defaults);
3949         }
3950 }
3951
3952 /***************************************************************************
3953 Return the number of the service with the given name, or -1 if it doesn't
3954 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3955 getservicebyname()! This works ONLY if all services have been loaded, and
3956 does not copy the found service.
3957 ***************************************************************************/
3958
3959 int lp_servicenumber(const char *pszServiceName)
3960 {
3961         int iService;
3962         fstring serviceName;
3963
3964         if (!pszServiceName) {
3965                 return GLOBAL_SECTION_SNUM;
3966         }
3967
3968         for (iService = iNumServices - 1; iService >= 0; iService--) {
3969                 if (VALID(iService) && ServicePtrs[iService]->szService) {
3970                         /*
3971                          * The substitution here is used to support %U in
3972                          * service names
3973                          */
3974                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
3975                         standard_sub_basic(get_current_username(),
3976                                            current_user_info.domain,
3977                                            serviceName,sizeof(serviceName));
3978                         if (strequal(serviceName, pszServiceName)) {
3979                                 break;
3980                         }
3981                 }
3982         }
3983
3984         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
3985                 struct timespec last_mod;
3986
3987                 if (!usershare_exists(iService, &last_mod)) {
3988                         /* Remove the share security tdb entry for it. */
3989                         delete_share_security(lp_servicename(talloc_tos(), iService));
3990                         /* Remove it from the array. */
3991                         free_service_byindex(iService);
3992                         /* Doesn't exist anymore. */
3993                         return GLOBAL_SECTION_SNUM;
3994                 }
3995
3996                 /* Has it been modified ? If so delete and reload. */
3997                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3998                                      &last_mod) < 0) {
3999                         /* Remove it from the array. */
4000                         free_service_byindex(iService);
4001                         /* and now reload it. */
4002                         iService = load_usershare_service(pszServiceName);
4003                 }
4004         }
4005
4006         if (iService < 0) {
4007                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4008                 return GLOBAL_SECTION_SNUM;
4009         }
4010
4011         return (iService);
4012 }
4013
4014 /*******************************************************************
4015  A useful volume label function. 
4016 ********************************************************************/
4017
4018 const char *volume_label(TALLOC_CTX *ctx, int snum)
4019 {
4020         char *ret;
4021         const char *label = lp_volume(ctx, snum);
4022         if (!*label) {
4023                 label = lp_servicename(ctx, snum);
4024         }
4025
4026         /* This returns a 33 byte guarenteed null terminated string. */
4027         ret = talloc_strndup(ctx, label, 32);
4028         if (!ret) {
4029                 return "";
4030         }               
4031         return ret;
4032 }
4033
4034 /*******************************************************************
4035  Get the default server type we will announce as via nmbd.
4036 ********************************************************************/
4037
4038 int lp_default_server_announce(void)
4039 {
4040         int default_server_announce = 0;
4041         default_server_announce |= SV_TYPE_WORKSTATION;
4042         default_server_announce |= SV_TYPE_SERVER;
4043         default_server_announce |= SV_TYPE_SERVER_UNIX;
4044
4045         /* note that the flag should be set only if we have a 
4046            printer service but nmbd doesn't actually load the 
4047            services so we can't tell   --jerry */
4048
4049         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4050
4051         default_server_announce |= SV_TYPE_SERVER_NT;
4052         default_server_announce |= SV_TYPE_NT;
4053
4054         switch (lp_server_role()) {
4055                 case ROLE_DOMAIN_MEMBER:
4056                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4057                         break;
4058                 case ROLE_DOMAIN_PDC:
4059                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4060                         break;
4061                 case ROLE_DOMAIN_BDC:
4062                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4063                         break;
4064                 case ROLE_STANDALONE:
4065                 default:
4066                         break;
4067         }
4068         if (lp_time_server())
4069                 default_server_announce |= SV_TYPE_TIME_SOURCE;
4070
4071         if (lp_host_msdfs())
4072                 default_server_announce |= SV_TYPE_DFS_SERVER;
4073
4074         return default_server_announce;
4075 }
4076
4077 /***********************************************************
4078  If we are PDC then prefer us as DMB
4079 ************************************************************/
4080
4081 bool lp_domain_master(void)
4082 {
4083         if (Globals._domain_master == Auto)
4084                 return (lp_server_role() == ROLE_DOMAIN_PDC);
4085
4086         return (bool)Globals._domain_master;
4087 }
4088
4089 /***********************************************************
4090  If we are PDC then prefer us as DMB
4091 ************************************************************/
4092
4093 static bool lp_domain_master_true_or_auto(void)
4094 {
4095         if (Globals._domain_master) /* auto or yes */
4096                 return true;
4097
4098         return false;
4099 }
4100
4101 /***********************************************************
4102  If we are DMB then prefer us as LMB
4103 ************************************************************/
4104
4105 bool lp_preferred_master(void)
4106 {
4107         if (Globals.iPreferredMaster == Auto)
4108                 return (lp_local_master() && lp_domain_master());
4109
4110         return (bool)Globals.iPreferredMaster;
4111 }
4112
4113 /*******************************************************************
4114  Remove a service.
4115 ********************************************************************/
4116
4117 void lp_remove_service(int snum)
4118 {
4119         ServicePtrs[snum]->valid = false;
4120 }
4121
4122 const char *lp_printername(TALLOC_CTX *ctx, int snum)
4123 {
4124         const char *ret = lp__printername(ctx, snum);
4125         if (ret == NULL || *ret == '\0') {
4126                 ret = lp_const_servicename(snum);
4127         }
4128
4129         return ret;
4130 }
4131
4132
4133 /***********************************************************
4134  Allow daemons such as winbindd to fix their logfile name.
4135 ************************************************************/
4136
4137 void lp_set_logfile(const char *name)
4138 {
4139         string_set(Globals.ctx, &Globals.logfile, name);
4140         debug_set_logfile(name);
4141 }
4142
4143 /*******************************************************************
4144  Return the max print jobs per queue.
4145 ********************************************************************/
4146
4147 int lp_maxprintjobs(int snum)
4148 {
4149         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4150         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4151                 maxjobs = PRINT_MAX_JOBID - 1;
4152
4153         return maxjobs;
4154 }
4155
4156 const char *lp_printcapname(void)
4157 {
4158         if ((Globals.szPrintcapname != NULL) &&
4159             (Globals.szPrintcapname[0] != '\0'))
4160                 return Globals.szPrintcapname;
4161
4162         if (sDefault.printing == PRINT_CUPS) {
4163                 return "cups";
4164         }
4165
4166         if (sDefault.printing == PRINT_BSD)
4167                 return "/etc/printcap";
4168
4169         return PRINTCAP_NAME;
4170 }
4171
4172 static uint32_t spoolss_state;
4173
4174 bool lp_disable_spoolss( void )
4175 {
4176         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4177                 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4178
4179         return spoolss_state == SVCCTL_STOPPED ? true : false;
4180 }
4181
4182 void lp_set_spoolss_state( uint32_t state )
4183 {
4184         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4185
4186         spoolss_state = state;
4187 }
4188
4189 uint32_t lp_get_spoolss_state( void )
4190 {
4191         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4192 }
4193
4194 /*******************************************************************
4195  Ensure we don't use sendfile if server smb signing is active.
4196 ********************************************************************/
4197
4198 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
4199 {
4200         bool sign_active = false;
4201
4202         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4203         if (get_Protocol() < PROTOCOL_NT1) {
4204                 return false;
4205         }
4206         if (signing_state) {
4207                 sign_active = smb_signing_is_active(signing_state);
4208         }
4209         return (lp__use_sendfile(snum) &&
4210                         (get_remote_arch() != RA_WIN95) &&
4211                         !sign_active);
4212 }
4213
4214 /*******************************************************************
4215  Turn off sendfile if we find the underlying OS doesn't support it.
4216 ********************************************************************/
4217
4218 void set_use_sendfile(int snum, bool val)
4219 {
4220         if (LP_SNUM_OK(snum))
4221                 ServicePtrs[snum]->_use_sendfile = val;
4222         else
4223                 sDefault._use_sendfile = val;
4224 }
4225
4226 /*******************************************************************
4227  Turn off storing DOS attributes if this share doesn't support it.
4228 ********************************************************************/
4229
4230 void set_store_dos_attributes(int snum, bool val)
4231 {
4232         if (!LP_SNUM_OK(snum))
4233                 return;
4234         ServicePtrs[(snum)]->store_dos_attributes = val;
4235 }
4236
4237 void lp_set_mangling_method(const char *new_method)
4238 {
4239         string_set(Globals.ctx, &Globals.mangling_method, new_method);
4240 }
4241
4242 /*******************************************************************
4243  Global state for POSIX pathname processing.
4244 ********************************************************************/
4245
4246 static bool posix_pathnames;
4247
4248 bool lp_posix_pathnames(void)
4249 {
4250         return posix_pathnames;
4251 }
4252
4253 /*******************************************************************
4254  Change everything needed to ensure POSIX pathname processing (currently
4255  not much).
4256 ********************************************************************/
4257
4258 void lp_set_posix_pathnames(void)
4259 {
4260         posix_pathnames = true;
4261 }
4262
4263 /*******************************************************************
4264  Global state for POSIX lock processing - CIFS unix extensions.
4265 ********************************************************************/
4266
4267 bool posix_default_lock_was_set;
4268 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4269
4270 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4271 {
4272         if (posix_default_lock_was_set) {
4273                 return posix_cifsx_locktype;
4274         } else {
4275                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
4276         }
4277 }
4278
4279 /*******************************************************************
4280 ********************************************************************/
4281
4282 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4283 {
4284         posix_default_lock_was_set = true;
4285         posix_cifsx_locktype = val;
4286 }
4287
4288 int lp_min_receive_file_size(void)
4289 {
4290         if (Globals.iminreceivefile < 0) {
4291                 return 0;
4292         }
4293         return Globals.iminreceivefile;
4294 }
4295
4296 /*******************************************************************
4297  Safe wide links checks.
4298  This helper function always verify the validity of wide links,
4299  even after a configuration file reload.
4300 ********************************************************************/
4301
4302 static bool lp_widelinks_internal(int snum)
4303 {
4304         return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
4305                         sDefault.bWidelinks);
4306 }
4307
4308 void widelinks_warning(int snum)
4309 {
4310         if (lp_allow_insecure_wide_links()) {
4311                 return;
4312         }
4313
4314         if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
4315                 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4316                         "These parameters are incompatible. "
4317                         "Wide links will be disabled for this share.\n",
4318                          lp_servicename(talloc_tos(), snum) ));
4319         }
4320 }
4321
4322 bool lp_widelinks(int snum)
4323 {
4324         /* wide links is always incompatible with unix extensions */
4325         if (lp_unix_extensions()) {
4326                 /*
4327                  * Unless we have "allow insecure widelinks"
4328                  * turned on.
4329                  */
4330                 if (!lp_allow_insecure_wide_links()) {
4331                         return false;
4332                 }
4333         }
4334
4335         return lp_widelinks_internal(snum);
4336 }
4337
4338 int lp_server_role(void)
4339 {
4340         return lp_find_server_role(lp__server_role(),
4341                                    lp__security(),
4342                                    lp__domain_logons(),
4343                                    lp_domain_master_true_or_auto());
4344 }
4345
4346 int lp_security(void)
4347 {
4348         return lp_find_security(lp__server_role(),
4349                                 lp__security());
4350 }
4351
4352 int lp_client_max_protocol(void)
4353 {
4354         int client_max_protocol = lp__client_max_protocol();
4355         if (client_max_protocol == PROTOCOL_DEFAULT) {
4356                 return PROTOCOL_NT1;
4357         }
4358         return client_max_protocol;
4359 }
4360
4361 int lp_winbindd_max_protocol(void)
4362 {
4363         int client_max_protocol = lp__client_max_protocol();
4364         if (client_max_protocol == PROTOCOL_DEFAULT) {
4365                 return PROTOCOL_LATEST;
4366         }
4367         return client_max_protocol;
4368 }
4369
4370 struct loadparm_global * get_globals(void)
4371 {
4372         return &Globals;
4373 }
4374
4375 unsigned int * get_flags(void)
4376 {
4377         if (flags_list == NULL) {
4378                 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());
4379         }
4380
4381         return flags_list;
4382 }