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