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