2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
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
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.
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.
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/>.
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.
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
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
57 #include "system/filesys.h"
59 #include "lib/param/loadparm.h"
60 #include "lib/param/param.h"
62 #include "lib/smbconf/smbconf.h"
63 #include "lib/smbconf/smbconf_init.h"
66 #include "../librpc/gen_ndr/svcctl.h"
68 #include "../libcli/smb/smb_signing.h"
69 #include "dbwrap/dbwrap.h"
70 #include "dbwrap/dbwrap_rbt.h"
71 #include "../lib/util/bitmap.h"
73 #ifdef HAVE_SYS_SYSCTL_H
74 #include <sys/sysctl.h>
77 #ifdef HAVE_HTTPCONNECTENCRYPT
78 #include <cups/http.h>
83 extern userdom_struct current_user_info
;
85 /* the special value for the include parameter
86 * to be interpreted not as a file name but to
87 * trigger loading of the global smb.conf options
89 #ifndef INCLUDE_REGISTRY_NAME
90 #define INCLUDE_REGISTRY_NAME "registry"
93 static bool in_client
= false; /* Not in the client by default */
94 static struct smbconf_csn conf_last_csn
;
96 static int config_backend
= CONFIG_BACKEND_FILE
;
98 /* some helpful bits */
99 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
100 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
102 #define USERSHARE_VALID 1
103 #define USERSHARE_PENDING_DELETE 2
105 static bool defaults_saved
= false;
107 #include "lib/param/param_global.h"
109 static struct loadparm_global Globals
;
111 /* This is a default service used to prime a services structure */
112 static struct loadparm_service sDefault
=
117 .usershare_last_mod
= {0, 0},
121 .invalid_users
= NULL
,
128 .root_preexec
= NULL
,
129 .root_postexec
= NULL
,
130 .cups_options
= NULL
,
131 .print_command
= NULL
,
133 .lprm_command
= NULL
,
134 .lppause_command
= NULL
,
135 .lpresume_command
= NULL
,
136 .queuepause_command
= NULL
,
137 .queueresume_command
= NULL
,
138 ._printername
= NULL
,
139 .printjob_username
= NULL
,
140 .dont_descend
= NULL
,
143 .magic_script
= NULL
,
144 .magic_output
= NULL
,
147 .veto_oplock_files
= NULL
,
157 .aio_write_behind
= NULL
,
158 .dfree_command
= NULL
,
159 .min_print_space
= 0,
160 .iMaxPrintJobs
= 1000,
161 .max_reported_print_jobs
= 0,
162 .write_cache_size
= 0,
164 .force_create_mode
= 0,
165 .directory_mask
= 0755,
166 .force_directory_mode
= 0,
167 .max_connections
= 0,
168 .default_case
= CASE_LOWER
,
169 .printing
= DEFAULT_PRINTING
,
170 .oplock_contention_limit
= 2,
173 .dfree_cache_time
= 0,
174 .preexec_close
= false,
175 .root_preexec_close
= false,
176 .case_sensitive
= Auto
,
177 .preserve_case
= true,
178 .short_preserve_case
= true,
179 .hide_dot_files
= true,
180 .hide_special_files
= false,
181 .hide_unreadable
= false,
182 .hide_unwriteable_files
= false,
184 .access_based_share_enum
= false,
188 .administrative_share
= false,
191 .print_notify_backchannel
= false,
195 .store_dos_attributes
= false,
196 .dmapi_support
= false,
198 .strict_locking
= Auto
,
199 .posix_locking
= true,
201 .kernel_oplocks
= false,
202 .level2_oplocks
= true,
204 .mangled_names
= true,
206 .follow_symlinks
= true,
207 .sync_always
= false,
208 .strict_allocate
= false,
209 .strict_sync
= false,
210 .mangling_char
= '~',
212 .delete_readonly
= false,
213 .fake_oplocks
= false,
214 .delete_veto_files
= false,
215 .dos_filemode
= false,
216 .dos_filetimes
= true,
217 .dos_filetime_resolution
= false,
218 .fake_directory_create_times
= false,
219 .blocking_locks
= true,
220 .inherit_permissions
= false,
221 .inherit_acls
= false,
222 .inherit_owner
= false,
224 .use_client_driver
= false,
225 .default_devmode
= true,
226 .force_printername
= false,
227 .nt_acl_support
= true,
228 .force_unknown_acl_user
= false,
229 ._use_sendfile
= false,
230 .profile_acls
= false,
231 .map_acl_inherit
= false,
234 .acl_check_permissions
= true,
235 .acl_map_full_control
= true,
236 .acl_group_control
= false,
237 .acl_allow_execute_always
= false,
238 .change_notify
= true,
239 .kernel_change_notify
= true,
240 .allocation_roundup_size
= SMB_ROUNDUP_ALLOCATION_SIZE
,
243 .map_readonly
= MAP_READONLY_YES
,
244 .directory_name_cache_size
= 100,
245 .smb_encrypt
= SMB_SIGNING_DEFAULT
,
246 .kernel_share_modes
= true,
247 .durable_handles
= true,
252 /* local variables */
253 static struct loadparm_service
**ServicePtrs
= NULL
;
254 static int iNumServices
= 0;
255 static int iServiceIndex
= 0;
256 static struct db_context
*ServiceHash
;
257 static bool bInGlobalSection
= true;
258 static bool bGlobalOnly
= false;
260 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
262 /* prototypes for the special type handlers */
263 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
264 static bool handle_idmap_backend(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
265 static bool handle_idmap_uid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
266 static bool handle_idmap_gid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
267 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
268 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
269 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
270 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
271 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
273 static void set_allowed_client_auth(void);
275 static void add_to_file_list(const char *fname
, const char *subfname
);
276 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
);
277 static void free_param_opts(struct parmlist_entry
**popts
);
279 #include "lib/param/param_table.c"
281 /* this is used to prevent lots of mallocs of size 1 */
282 static const char null_string
[] = "";
288 static void string_free(char **s
)
292 if (*s
== null_string
)
298 Set a string value, deallocating any existing space, and allocing the space
302 static bool string_set(TALLOC_CTX
*mem_ctx
, char **dest
,const char *src
)
310 (*dest
) = talloc_strdup(mem_ctx
, src
);
311 if ((*dest
) == NULL
) {
312 DEBUG(0,("Out of memory in string_init\n"));
319 bool lp_string_set(char **dest
, const char *src
) {
320 return string_set(Globals
.ctx
, dest
, src
);
323 /***************************************************************************
324 Initialise the sDefault parameter structure for the printer values.
325 ***************************************************************************/
327 static void init_printer_values(TALLOC_CTX
*ctx
, struct loadparm_service
*pService
)
329 /* choose defaults depending on the type of printing */
330 switch (pService
->printing
) {
335 string_set(ctx
, &pService
->lpq_command
, "lpq -P'%p'");
336 string_set(ctx
, &pService
->lprm_command
, "lprm -P'%p' %j");
337 string_set(ctx
, &pService
->print_command
, "lpr -r -P'%p' %s");
342 string_set(ctx
, &pService
->lpq_command
, "lpq -P'%p'");
343 string_set(ctx
, &pService
->lprm_command
, "lprm -P'%p' %j");
344 string_set(ctx
, &pService
->print_command
, "lpr -r -P'%p' %s");
345 string_set(ctx
, &pService
->queuepause_command
, "lpc stop '%p'");
346 string_set(ctx
, &pService
->queueresume_command
, "lpc start '%p'");
347 string_set(ctx
, &pService
->lppause_command
, "lpc hold '%p' %j");
348 string_set(ctx
, &pService
->lpresume_command
, "lpc release '%p' %j");
353 /* set the lpq command to contain the destination printer
354 name only. This is used by cups_queue_get() */
355 string_set(ctx
, &pService
->lpq_command
, "%p");
356 string_set(ctx
, &pService
->lprm_command
, "");
357 string_set(ctx
, &pService
->print_command
, "");
358 string_set(ctx
, &pService
->lppause_command
, "");
359 string_set(ctx
, &pService
->lpresume_command
, "");
360 string_set(ctx
, &pService
->queuepause_command
, "");
361 string_set(ctx
, &pService
->queueresume_command
, "");
366 string_set(ctx
, &pService
->lpq_command
, "lpstat -o%p");
367 string_set(ctx
, &pService
->lprm_command
, "cancel %p-%j");
368 string_set(ctx
, &pService
->print_command
, "lp -c -d%p %s; rm %s");
369 string_set(ctx
, &pService
->queuepause_command
, "disable %p");
370 string_set(ctx
, &pService
->queueresume_command
, "enable %p");
372 string_set(ctx
, &pService
->lppause_command
, "lp -i %p-%j -H hold");
373 string_set(ctx
, &pService
->lpresume_command
, "lp -i %p-%j -H resume");
378 string_set(ctx
, &pService
->lpq_command
, "lpq -P%p");
379 string_set(ctx
, &pService
->lprm_command
, "lprm -P%p %j");
380 string_set(ctx
, &pService
->print_command
, "lp -r -P%p %s");
383 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
388 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
391 tdbfile
= talloc_asprintf(
392 tmp_ctx
, "tdbfile=%s",
393 lp_parm_const_string(-1, "vlp", "tdbfile",
395 if (tdbfile
== NULL
) {
396 tdbfile
="tdbfile=/tmp/vlp.tdb";
399 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s print %%p %%s",
401 string_set(ctx
, &pService
->print_command
,
402 tmp
? tmp
: "vlp print %p %s");
404 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpq %%p",
406 string_set(ctx
, &pService
->lpq_command
,
407 tmp
? tmp
: "vlp lpq %p");
409 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lprm %%p %%j",
411 string_set(ctx
, &pService
->lprm_command
,
412 tmp
? tmp
: "vlp lprm %p %j");
414 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lppause %%p %%j",
416 string_set(ctx
, &pService
->lppause_command
,
417 tmp
? tmp
: "vlp lppause %p %j");
419 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpresume %%p %%j",
421 string_set(ctx
, &pService
->lpresume_command
,
422 tmp
? tmp
: "vlp lpresume %p %j");
424 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queuepause %%p",
426 string_set(ctx
, &pService
->queuepause_command
,
427 tmp
? tmp
: "vlp queuepause %p");
429 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queueresume %%p",
431 string_set(ctx
, &pService
->queueresume_command
,
432 tmp
? tmp
: "vlp queueresume %p");
433 TALLOC_FREE(tmp_ctx
);
437 #endif /* DEVELOPER */
442 * Function to return the default value for the maximum number of open
443 * file descriptors permitted. This function tries to consult the
444 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
445 * the smaller of those.
447 static int max_open_files(void)
449 int sysctl_max
= MAX_OPEN_FILES
;
450 int rlimit_max
= MAX_OPEN_FILES
;
452 #ifdef HAVE_SYSCTLBYNAME
454 size_t size
= sizeof(sysctl_max
);
455 sysctlbyname("kern.maxfilesperproc", &sysctl_max
, &size
, NULL
,
460 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
466 if (getrlimit(RLIMIT_NOFILE
, &rl
) == 0)
467 rlimit_max
= rl
.rlim_cur
;
469 #if defined(RLIM_INFINITY)
470 if(rl
.rlim_cur
== RLIM_INFINITY
)
471 rlimit_max
= MAX_OPEN_FILES
;
476 if (sysctl_max
< MIN_OPEN_FILES_WINDOWS
) {
477 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
478 "minimum Windows limit (%d)\n",
480 MIN_OPEN_FILES_WINDOWS
));
481 sysctl_max
= MIN_OPEN_FILES_WINDOWS
;
484 if (rlimit_max
< MIN_OPEN_FILES_WINDOWS
) {
485 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
486 "minimum Windows limit (%d)\n",
488 MIN_OPEN_FILES_WINDOWS
));
489 rlimit_max
= MIN_OPEN_FILES_WINDOWS
;
492 return MIN(sysctl_max
, rlimit_max
);
496 * Common part of freeing allocated data for one parameter.
498 static void free_one_parameter_common(void *parm_ptr
,
499 struct parm_struct parm
)
501 if ((parm
.type
== P_STRING
) ||
502 (parm
.type
== P_USTRING
))
504 string_free((char**)parm_ptr
);
505 } else if (parm
.type
== P_LIST
) {
506 TALLOC_FREE(*((char***)parm_ptr
));
511 * Free the allocated data for one parameter for a share
512 * given as a service struct.
514 static void free_one_parameter(struct loadparm_service
*service
,
515 struct parm_struct parm
)
519 if (parm
.p_class
!= P_LOCAL
) {
523 parm_ptr
= lp_parm_ptr(service
, &parm
);
525 free_one_parameter_common(parm_ptr
, parm
);
529 * Free the allocated parameter data of a share given
530 * as a service struct.
532 static void free_parameters(struct loadparm_service
*service
)
536 for (i
=0; parm_table
[i
].label
; i
++) {
537 free_one_parameter(service
, parm_table
[i
]);
542 * Free the allocated data for one parameter for a given share
543 * specified by an snum.
545 static void free_one_parameter_by_snum(int snum
, struct parm_struct parm
)
550 parm_ptr
= lp_parm_ptr(NULL
, &parm
);
551 } else if (parm
.p_class
!= P_LOCAL
) {
554 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm
);
557 free_one_parameter_common(parm_ptr
, parm
);
561 * Free the allocated parameter data for a share specified
564 static void free_parameters_by_snum(int snum
)
568 for (i
=0; parm_table
[i
].label
; i
++) {
569 free_one_parameter_by_snum(snum
, parm_table
[i
]);
574 * Free the allocated global parameters.
576 static void free_global_parameters(void)
578 free_param_opts(&Globals
.param_opt
);
579 free_parameters_by_snum(GLOBAL_SECTION_SNUM
);
580 TALLOC_FREE(Globals
.ctx
);
583 struct lp_stored_option
{
584 struct lp_stored_option
*prev
, *next
;
589 static struct lp_stored_option
*stored_options
;
592 save options set by lp_set_cmdline() into a list. This list is
593 re-applied when we do a globals reset, so that cmdline set options
594 are sticky across reloads of smb.conf
596 static bool store_lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
598 struct lp_stored_option
*entry
, *entry_next
;
599 for (entry
= stored_options
; entry
!= NULL
; entry
= entry_next
) {
600 entry_next
= entry
->next
;
601 if (strcmp(pszParmName
, entry
->label
) == 0) {
602 DLIST_REMOVE(stored_options
, entry
);
608 entry
= talloc(NULL
, struct lp_stored_option
);
613 entry
->label
= talloc_strdup(entry
, pszParmName
);
619 entry
->value
= talloc_strdup(entry
, pszParmValue
);
625 DLIST_ADD_END(stored_options
, entry
, struct lp_stored_option
);
630 static bool apply_lp_set_cmdline(void)
632 struct lp_stored_option
*entry
= NULL
;
633 for (entry
= stored_options
; entry
!= NULL
; entry
= entry
->next
) {
634 if (!lp_set_cmdline_helper(entry
->label
, entry
->value
, false)) {
635 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
636 entry
->label
, entry
->value
));
643 /***************************************************************************
644 Initialise the global parameter structure.
645 ***************************************************************************/
647 static void init_globals(bool reinit_globals
)
649 static bool done_init
= false;
653 /* If requested to initialize only once and we've already done it... */
654 if (!reinit_globals
&& done_init
) {
655 /* ... then we have nothing more to do */
660 /* The logfile can be set before this is invoked. Free it if so. */
661 if (Globals
.logfile
!= NULL
) {
662 string_free(&Globals
.logfile
);
663 Globals
.logfile
= NULL
;
667 free_global_parameters();
670 /* This memset and the free_global_parameters() above will
671 * wipe out smb.conf options set with lp_set_cmdline(). The
672 * apply_lp_set_cmdline() call puts these values back in the
673 * table once the defaults are set */
674 ZERO_STRUCT(Globals
);
676 Globals
.ctx
= talloc_pooled_object(NULL
, char, 272, 2048);
678 for (i
= 0; parm_table
[i
].label
; i
++) {
679 if ((parm_table
[i
].type
== P_STRING
||
680 parm_table
[i
].type
== P_USTRING
))
682 string_set(Globals
.ctx
, (char **)lp_parm_ptr(NULL
, &parm_table
[i
]), "");
687 string_set(Globals
.ctx
, &sDefault
.fstype
, FSTYPE_STRING
);
688 string_set(Globals
.ctx
, &sDefault
.printjob_username
, "%U");
690 init_printer_values(Globals
.ctx
, &sDefault
);
692 sDefault
.ntvfs_handler
= (const char **)str_list_make_v3(NULL
, "unixuid default", NULL
);
694 DEBUG(3, ("Initialising global parameters\n"));
696 /* Must manually force to upper case here, as this does not go via the handler */
697 string_set(Globals
.ctx
, &Globals
.netbios_name
, myhostname_upper());
699 string_set(Globals
.ctx
, &Globals
.smb_passwd_file
, get_dyn_SMB_PASSWD_FILE());
700 string_set(Globals
.ctx
, &Globals
.private_dir
, get_dyn_PRIVATE_DIR());
702 /* use the new 'hash2' method by default, with a prefix of 1 */
703 string_set(Globals
.ctx
, &Globals
.mangling_method
, "hash2");
704 Globals
.mangle_prefix
= 1;
706 string_set(Globals
.ctx
, &Globals
.guest_account
, GUEST_ACCOUNT
);
708 /* using UTF8 by default allows us to support all chars */
709 string_set(Globals
.ctx
, &Globals
.unix_charset
, DEFAULT_UNIX_CHARSET
);
711 /* Use codepage 850 as a default for the dos character set */
712 string_set(Globals
.ctx
, &Globals
.dos_charset
, DEFAULT_DOS_CHARSET
);
715 * Allow the default PASSWD_CHAT to be overridden in local.h.
717 string_set(Globals
.ctx
, &Globals
.passwd_chat
, DEFAULT_PASSWD_CHAT
);
719 string_set(Globals
.ctx
, &Globals
.workgroup
, DEFAULT_WORKGROUP
);
721 string_set(Globals
.ctx
, &Globals
.passwd_program
, "");
722 string_set(Globals
.ctx
, &Globals
.lock_directory
, get_dyn_LOCKDIR());
723 string_set(Globals
.ctx
, &Globals
.state_directory
, get_dyn_STATEDIR());
724 string_set(Globals
.ctx
, &Globals
.cache_directory
, get_dyn_CACHEDIR());
725 string_set(Globals
.ctx
, &Globals
.pid_directory
, get_dyn_PIDDIR());
726 string_set(Globals
.ctx
, &Globals
.nbt_client_socket_address
, "0.0.0.0");
728 * By default support explicit binding to broadcast
731 Globals
.nmbd_bind_explicit_broadcast
= true;
733 s
= talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
735 smb_panic("init_globals: ENOMEM");
737 string_set(Globals
.ctx
, &Globals
.server_string
, s
);
740 string_set(Globals
.ctx
, &Globals
.panic_action
, "/bin/sleep 999999999");
743 string_set(Globals
.ctx
, &Globals
.socket_options
, DEFAULT_SOCKET_OPTIONS
);
745 string_set(Globals
.ctx
, &Globals
.logon_drive
, "");
746 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
747 string_set(Globals
.ctx
, &Globals
.logon_home
, "\\\\%N\\%U");
748 string_set(Globals
.ctx
, &Globals
.logon_path
, "\\\\%N\\%U\\profile");
750 Globals
.name_resolve_order
= (const char **)str_list_make_v3(NULL
, "lmhosts wins host bcast", NULL
);
751 string_set(Globals
.ctx
, &Globals
.password_server
, "*");
753 Globals
.algorithmic_rid_base
= BASE_RID
;
755 Globals
.load_printers
= true;
756 Globals
.printcap_cache_time
= 750; /* 12.5 minutes */
758 Globals
.config_backend
= config_backend
;
759 Globals
._server_role
= ROLE_AUTO
;
761 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
762 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
763 Globals
.max_xmit
= 0x4104;
764 Globals
.max_mux
= 50; /* This is *needed* for profile support. */
765 Globals
.lpq_cache_time
= 30; /* changed to handle large print servers better -- jerry */
766 Globals
._disable_spoolss
= false;
767 Globals
.max_smbd_processes
= 0;/* no limit specified */
768 Globals
.username_level
= 0;
769 Globals
.deadtime
= 0;
770 Globals
.getwd_cache
= true;
771 Globals
.large_readwrite
= true;
772 Globals
.max_log_size
= 5000;
773 Globals
.max_open_files
= max_open_files();
774 Globals
.server_max_protocol
= PROTOCOL_SMB3_00
;
775 Globals
.server_min_protocol
= PROTOCOL_LANMAN1
;
776 Globals
.client_max_protocol
= PROTOCOL_NT1
;
777 Globals
.client_min_protocol
= PROTOCOL_CORE
;
778 Globals
._security
= SEC_AUTO
;
779 Globals
.encrypt_passwords
= true;
780 Globals
.client_schannel
= Auto
;
781 Globals
.winbind_sealed_pipes
= true;
782 Globals
.require_strong_key
= true;
783 Globals
.server_schannel
= Auto
;
784 Globals
.read_raw
= true;
785 Globals
.write_raw
= true;
786 Globals
.null_passwords
= false;
787 Globals
.old_password_allowed_period
= 60;
788 Globals
.obey_pam_restrictions
= false;
790 Globals
.syslog_only
= false;
791 Globals
.timestamp_logs
= true;
792 string_set(Globals
.ctx
, &Globals
.log_level
, "0");
793 Globals
.debug_prefix_timestamp
= false;
794 Globals
.debug_hires_timestamp
= true;
795 Globals
.debug_pid
= false;
796 Globals
.debug_uid
= false;
797 Globals
.debug_class
= false;
798 Globals
.enable_core_files
= true;
799 Globals
.max_ttl
= 60 * 60 * 24 * 3; /* 3 days default. */
800 Globals
.max_wins_ttl
= 60 * 60 * 24 * 6; /* 6 days default. */
801 Globals
.min_wins_ttl
= 60 * 60 * 6; /* 6 hours default. */
802 Globals
.machine_password_timeout
= 60 * 60 * 24 * 7; /* 7 days default. */
803 Globals
.lm_announce
= Auto
; /* = Auto: send only if LM clients found */
804 Globals
.lm_interval
= 60;
805 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
806 Globals
.nis_homedir
= false;
807 #ifdef WITH_NISPLUS_HOME
808 string_set(Globals
.ctx
, &Globals
.homedir_map
, "auto_home.org_dir");
810 string_set(Globals
.ctx
, &Globals
.homedir_map
, "auto.home");
813 Globals
.time_server
= false;
814 Globals
.bind_interfaces_only
= false;
815 Globals
.unix_password_sync
= false;
816 Globals
.pam_password_change
= false;
817 Globals
.passwd_chat_debug
= false;
818 Globals
.passwd_chat_timeout
= 2; /* 2 second default. */
819 Globals
.nt_pipe_support
= true; /* Do NT pipes by default. */
820 Globals
.nt_status_support
= true; /* Use NT status by default. */
821 Globals
.stat_cache
= true; /* use stat cache by default */
822 Globals
.max_stat_cache_size
= 256; /* 256k by default */
823 Globals
.restrict_anonymous
= 0;
824 Globals
.client_lanman_auth
= false; /* Do NOT use the LanMan hash if it is available */
825 Globals
.client_plaintext_auth
= false; /* Do NOT use a plaintext password even if is requested by the server */
826 Globals
.lanman_auth
= false; /* Do NOT use the LanMan hash, even if it is supplied */
827 Globals
.ntlm_auth
= true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
828 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 */
829 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
831 Globals
.map_to_guest
= 0; /* By Default, "Never" */
832 Globals
.oplock_break_wait_time
= 0; /* By Default, 0 msecs. */
833 Globals
.enhanced_browsing
= true;
834 Globals
.lock_spin_time
= WINDOWS_MINIMUM_LOCK_TIMEOUT_MS
; /* msec. */
835 #ifdef MMAP_BLACKLIST
836 Globals
.use_mmap
= false;
838 Globals
.use_mmap
= true;
840 Globals
.unicode
= true;
841 Globals
.unix_extensions
= true;
842 Globals
.reset_on_zero_vc
= false;
843 Globals
.log_writeable_files_on_exit
= false;
844 Globals
.create_krb5_conf
= true;
845 Globals
.winbindMaxDomainConnections
= 1;
847 /* hostname lookups can be very expensive and are broken on
848 a large number of sites (tridge) */
849 Globals
.hostname_lookups
= false;
851 string_set(Globals
.ctx
, &Globals
.passdb_backend
, "tdbsam");
852 string_set(Globals
.ctx
, &Globals
.ldap_suffix
, "");
853 string_set(Globals
.ctx
, &Globals
.szLdapMachineSuffix
, "");
854 string_set(Globals
.ctx
, &Globals
.szLdapUserSuffix
, "");
855 string_set(Globals
.ctx
, &Globals
.szLdapGroupSuffix
, "");
856 string_set(Globals
.ctx
, &Globals
.szLdapIdmapSuffix
, "");
858 string_set(Globals
.ctx
, &Globals
.ldap_admin_dn
, "");
859 Globals
.ldap_ssl
= LDAP_SSL_START_TLS
;
860 Globals
.ldap_ssl_ads
= false;
861 Globals
.ldap_deref
= -1;
862 Globals
.ldap_passwd_sync
= LDAP_PASSWD_SYNC_OFF
;
863 Globals
.ldap_delete_dn
= false;
864 Globals
.ldap_replication_sleep
= 1000; /* wait 1 sec for replication */
865 Globals
.ldap_follow_referral
= Auto
;
866 Globals
.ldap_timeout
= LDAP_DEFAULT_TIMEOUT
;
867 Globals
.ldap_connection_timeout
= LDAP_CONNECTION_DEFAULT_TIMEOUT
;
868 Globals
.ldap_page_size
= LDAP_PAGE_SIZE
;
870 Globals
.ldap_debug_level
= 0;
871 Globals
.ldap_debug_threshold
= 10;
873 /* This is what we tell the afs client. in reality we set the token
874 * to never expire, though, when this runs out the afs client will
875 * forget the token. Set to 0 to get NEVERDATE.*/
876 Globals
.afs_token_lifetime
= 604800;
877 Globals
.cups_connection_timeout
= CUPS_DEFAULT_CONNECTION_TIMEOUT
;
879 /* these parameters are set to defaults that are more appropriate
880 for the increasing samba install base:
882 as a member of the workgroup, that will possibly become a
883 _local_ master browser (lm = true). this is opposed to a forced
884 local master browser startup (pm = true).
886 doesn't provide WINS server service by default (wsupp = false),
887 and doesn't provide domain master browser services by default, either.
891 Globals
.show_add_printer_wizard
= true;
892 Globals
.os_level
= 20;
893 Globals
.local_master
= true;
894 Globals
._domain_master
= Auto
; /* depending on _domain_logons */
895 Globals
._domain_logons
= false;
896 Globals
.browse_list
= true;
897 Globals
.we_are_a_wins_server
= false;
898 Globals
.wins_proxy
= false;
900 TALLOC_FREE(Globals
.init_logon_delayed_hosts
);
901 Globals
.init_logon_delay
= 100; /* 100 ms default delay */
903 Globals
.wins_dns_proxy
= true;
905 Globals
.allow_trusted_domains
= true;
906 string_set(Globals
.ctx
, &Globals
.szIdmapBackend
, "tdb");
908 string_set(Globals
.ctx
, &Globals
.template_shell
, "/bin/false");
909 string_set(Globals
.ctx
, &Globals
.template_homedir
, "/home/%D/%U");
910 string_set(Globals
.ctx
, &Globals
.winbind_separator
, "\\");
911 string_set(Globals
.ctx
, &Globals
.winbindd_socket_directory
, dyn_WINBINDD_SOCKET_DIR
);
913 string_set(Globals
.ctx
, &Globals
.cups_server
, "");
914 string_set(Globals
.ctx
, &Globals
.iprint_server
, "");
916 string_set(Globals
.ctx
, &Globals
._ctdbd_socket
, "");
918 Globals
.cluster_addresses
= NULL
;
919 Globals
.clustering
= false;
920 Globals
.ctdb_timeout
= 0;
921 Globals
.ctdb_locktime_warn_threshold
= 0;
923 Globals
.winbind_cache_time
= 300; /* 5 minutes */
924 Globals
.winbind_reconnect_delay
= 30; /* 30 seconds */
925 Globals
.winbind_max_clients
= 200;
926 Globals
.winbind_enum_users
= false;
927 Globals
.winbind_enum_groups
= false;
928 Globals
.winbind_use_default_domain
= false;
929 Globals
.winbind_trusted_domains_only
= false;
930 Globals
.winbind_nested_groups
= true;
931 Globals
.winbind_expand_groups
= 1;
932 Globals
.winbind_nss_info
= (const char **)str_list_make_v3(NULL
, "template", NULL
);
933 Globals
.winbind_refresh_tickets
= false;
934 Globals
.winbind_offline_logon
= false;
936 Globals
.idmap_cache_time
= 86400 * 7; /* a week by default */
937 Globals
.idmap_negative_cache_time
= 120; /* 2 minutes by default */
939 Globals
.passdb_expand_explicit
= false;
941 Globals
.name_cache_timeout
= 660; /* In seconds */
943 Globals
.use_spnego
= true;
944 Globals
.client_use_spnego
= true;
946 Globals
.client_signing
= SMB_SIGNING_DEFAULT
;
947 Globals
.server_signing
= SMB_SIGNING_DEFAULT
;
949 Globals
.defer_sharing_violations
= true;
950 Globals
.smb_ports
= (const char **)str_list_make_v3(NULL
, SMB_PORTS
, NULL
);
952 Globals
.enable_privileges
= true;
953 Globals
.host_msdfs
= true;
954 Globals
.enable_asu_support
= false;
956 /* User defined shares. */
957 s
= talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
959 smb_panic("init_globals: ENOMEM");
961 string_set(Globals
.ctx
, &Globals
.usershare_path
, s
);
963 string_set(Globals
.ctx
, &Globals
.usershare_template_share
, "");
964 Globals
.usershare_max_shares
= 0;
965 /* By default disallow sharing of directories not owned by the sharer. */
966 Globals
.usershare_owner_only
= true;
967 /* By default disallow guest access to usershares. */
968 Globals
.usershare_allow_guests
= false;
970 Globals
.keepalive
= DEFAULT_KEEPALIVE
;
972 /* By default no shares out of the registry */
973 Globals
.registry_shares
= false;
975 Globals
.iminreceivefile
= 0;
977 Globals
.map_untrusted_to_domain
= false;
978 Globals
.multicast_dns_register
= true;
980 Globals
.smb2_max_read
= DEFAULT_SMB2_MAX_READ
;
981 Globals
.smb2_max_write
= DEFAULT_SMB2_MAX_WRITE
;
982 Globals
.smb2_max_trans
= DEFAULT_SMB2_MAX_TRANSACT
;
983 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
985 string_set(Globals
.ctx
, &Globals
.ncalrpc_dir
, get_dyn_NCALRPCDIR());
987 Globals
.server_services
= (const char **)str_list_make_v3(NULL
, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbind ntp_signd kcc dnsupdate dns", NULL
);
989 Globals
.dcerpc_endpoint_servers
= (const char **)str_list_make_v3(NULL
, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL
);
991 Globals
.tls_enabled
= true;
993 string_set(Globals
.ctx
, &Globals
._tls_keyfile
, "tls/key.pem");
994 string_set(Globals
.ctx
, &Globals
._tls_certfile
, "tls/cert.pem");
995 string_set(Globals
.ctx
, &Globals
._tls_cafile
, "tls/ca.pem");
997 string_set(Globals
.ctx
, &Globals
.share_backend
, "classic");
999 Globals
.iPreferredMaster
= Auto
;
1001 Globals
.allow_dns_updates
= DNS_UPDATE_SIGNED
;
1003 string_set(Globals
.ctx
, &Globals
.ntp_signd_socket_directory
, get_dyn_NTP_SIGND_SOCKET_DIR());
1005 string_set(Globals
.ctx
, &Globals
.winbindd_privileged_socket_directory
, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
1007 s
= talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
1009 smb_panic("init_globals: ENOMEM");
1011 Globals
.samba_kcc_command
= (const char **)str_list_make_v3(NULL
, s
, NULL
);
1014 s
= talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
1016 smb_panic("init_globals: ENOMEM");
1018 Globals
.dns_update_command
= (const char **)str_list_make_v3(NULL
, s
, NULL
);
1021 s
= talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
1023 smb_panic("init_globals: ENOMEM");
1025 Globals
.spn_update_command
= (const char **)str_list_make_v3(NULL
, s
, NULL
);
1028 Globals
.nsupdate_command
= (const char **)str_list_make_v3(NULL
, "/usr/bin/nsupdate -g", NULL
);
1030 Globals
.rndc_command
= (const char **)str_list_make_v3(NULL
, "/usr/sbin/rndc", NULL
);
1032 Globals
.cldap_port
= 389;
1034 Globals
.dgram_port
= 138;
1036 Globals
.nbt_port
= 137;
1038 Globals
.krb5_port
= 88;
1040 Globals
.kpasswd_port
= 464;
1042 Globals
.web_port
= 901;
1044 /* Now put back the settings that were set with lp_set_cmdline() */
1045 apply_lp_set_cmdline();
1048 /*******************************************************************
1049 Convenience routine to grab string parameters into talloced memory
1050 and run standard_sub_basic on them. The buffers can be written to by
1051 callers without affecting the source string.
1052 ********************************************************************/
1054 char *lp_string(TALLOC_CTX
*ctx
, const char *s
)
1058 /* The follow debug is useful for tracking down memory problems
1059 especially if you have an inner loop that is calling a lp_*()
1060 function that returns a string. Perhaps this debug should be
1061 present all the time? */
1064 DEBUG(10, ("lp_string(%s)\n", s
));
1070 ret
= talloc_sub_basic(ctx
,
1071 get_current_username(),
1072 current_user_info
.domain
,
1074 if (trim_char(ret
, '\"', '\"')) {
1075 if (strchr(ret
,'\"') != NULL
) {
1077 ret
= talloc_sub_basic(ctx
,
1078 get_current_username(),
1079 current_user_info
.domain
,
1087 In this section all the functions that are used to access the
1088 parameters from the rest of the program are defined
1091 #define FN_GLOBAL_STRING(fn_name,ptr) \
1092 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1093 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1094 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1095 #define FN_GLOBAL_LIST(fn_name,ptr) \
1096 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1097 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1098 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1099 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1100 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1101 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1102 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1104 #define FN_LOCAL_STRING(fn_name,val) \
1105 char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1106 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1107 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1108 #define FN_LOCAL_LIST(fn_name,val) \
1109 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1110 #define FN_LOCAL_BOOL(fn_name,val) \
1111 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1112 #define FN_LOCAL_INTEGER(fn_name,val) \
1113 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1115 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1116 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1117 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1118 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1119 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1120 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1122 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int
,
1123 winbindMaxDomainConnections
)
1125 int lp_winbind_max_domain_connections(void)
1127 if (lp_winbind_offline_logon() &&
1128 lp_winbind_max_domain_connections_int() > 1) {
1129 DEBUG(1, ("offline logons active, restricting max domain "
1130 "connections to 1\n"));
1133 return MAX(1, lp_winbind_max_domain_connections_int());
1136 int lp_smb2_max_credits(void)
1138 if (Globals
.ismb2_max_credits
== 0) {
1139 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
1141 return Globals
.ismb2_max_credits
;
1143 int lp_cups_encrypt(void)
1146 #ifdef HAVE_HTTPCONNECTENCRYPT
1147 switch (Globals
.CupsEncrypt
) {
1149 result
= HTTP_ENCRYPT_REQUIRED
;
1152 result
= HTTP_ENCRYPT_ALWAYS
;
1155 result
= HTTP_ENCRYPT_NEVER
;
1162 /* These functions remain in source3/param for now */
1164 #include "lib/param/param_functions.c"
1166 FN_LOCAL_STRING(servicename
, szService
)
1167 FN_LOCAL_CONST_STRING(const_servicename
, szService
)
1169 /* These functions cannot be auto-generated */
1170 FN_LOCAL_BOOL(autoloaded
, autoloaded
)
1172 /* local prototypes */
1174 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
);
1175 static const char *get_boolean(bool bool_value
);
1176 static int getservicebyname(const char *pszServiceName
,
1177 struct loadparm_service
*pserviceDest
);
1178 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
1180 static bool do_section(const char *pszSectionName
, void *userdata
);
1181 static void init_copymap(struct loadparm_service
*pservice
);
1182 static bool hash_a_service(const char *name
, int number
);
1183 static void free_service_byindex(int iService
);
1184 static void show_parameter(int parmIndex
);
1185 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
);
1188 * This is a helper function for parametrical options support. It returns a
1189 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1190 * parametrical functions are quite simple
1192 static struct parmlist_entry
*get_parametrics_by_service(struct loadparm_service
*service
, const char *type
,
1195 bool global_section
= false;
1197 struct parmlist_entry
*data
;
1198 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
1200 if (service
== NULL
) {
1201 data
= Globals
.param_opt
;
1202 global_section
= true;
1204 data
= service
->param_opt
;
1207 param_key
= talloc_asprintf(mem_ctx
, "%s:%s", type
, option
);
1208 if (param_key
== NULL
) {
1209 DEBUG(0,("asprintf failed!\n"));
1210 TALLOC_FREE(mem_ctx
);
1215 if (strwicmp(data
->key
, param_key
) == 0) {
1216 TALLOC_FREE(mem_ctx
);
1222 if (!global_section
) {
1223 /* Try to fetch the same option but from globals */
1224 /* but only if we are not already working with Globals */
1225 data
= Globals
.param_opt
;
1227 if (strwicmp(data
->key
, param_key
) == 0) {
1228 TALLOC_FREE(mem_ctx
);
1235 TALLOC_FREE(mem_ctx
);
1241 * This is a helper function for parametrical options support. It returns a
1242 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1243 * parametrical functions are quite simple
1245 static struct parmlist_entry
*get_parametrics(int snum
, const char *type
,
1248 if (snum
>= iNumServices
) return NULL
;
1251 return get_parametrics_by_service(NULL
, type
, option
);
1253 return get_parametrics_by_service(ServicePtrs
[snum
], type
, option
);
1258 #define MISSING_PARAMETER(name) \
1259 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1261 /*******************************************************************
1262 convenience routine to return int parameters.
1263 ********************************************************************/
1264 static int lp_int(const char *s
)
1268 MISSING_PARAMETER(lp_int
);
1272 return (int)strtol(s
, NULL
, 0);
1275 /*******************************************************************
1276 convenience routine to return unsigned long parameters.
1277 ********************************************************************/
1278 static unsigned long lp_ulong(const char *s
)
1282 MISSING_PARAMETER(lp_ulong
);
1286 return strtoul(s
, NULL
, 0);
1289 /*******************************************************************
1290 convenience routine to return boolean parameters.
1291 ********************************************************************/
1292 static bool lp_bool(const char *s
)
1297 MISSING_PARAMETER(lp_bool
);
1301 if (!set_boolean(s
, &ret
)) {
1302 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s
));
1309 /*******************************************************************
1310 convenience routine to return enum parameters.
1311 ********************************************************************/
1312 static int lp_enum(const char *s
,const struct enum_list
*_enum
)
1316 if (!s
|| !*s
|| !_enum
) {
1317 MISSING_PARAMETER(lp_enum
);
1321 for (i
=0; _enum
[i
].name
; i
++) {
1322 if (strequal(_enum
[i
].name
,s
))
1323 return _enum
[i
].value
;
1326 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s
));
1330 #undef MISSING_PARAMETER
1332 /* Return parametric option from a given service. Type is a part of option before ':' */
1333 /* Parametric option has following syntax: 'Type: option = value' */
1334 char *lp_parm_talloc_string(TALLOC_CTX
*ctx
, int snum
, const char *type
, const char *option
, const char *def
)
1336 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1338 if (data
== NULL
||data
->value
==NULL
) {
1340 return lp_string(ctx
, def
);
1346 return lp_string(ctx
, data
->value
);
1349 /* Return parametric option from a given service. Type is a part of option before ':' */
1350 /* Parametric option has following syntax: 'Type: option = value' */
1351 const char *lp_parm_const_string(int snum
, const char *type
, const char *option
, const char *def
)
1353 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1355 if (data
== NULL
||data
->value
==NULL
)
1361 const char *lp_parm_const_string_service(struct loadparm_service
*service
, const char *type
, const char *option
)
1363 struct parmlist_entry
*data
= get_parametrics_by_service(service
, type
, option
);
1365 if (data
== NULL
||data
->value
==NULL
)
1372 /* Return parametric option from a given service. Type is a part of option before ':' */
1373 /* Parametric option has following syntax: 'Type: option = value' */
1375 const char **lp_parm_string_list(int snum
, const char *type
, const char *option
, const char **def
)
1377 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1379 if (data
== NULL
||data
->value
==NULL
)
1380 return (const char **)def
;
1382 if (data
->list
==NULL
) {
1383 data
->list
= str_list_make_v3(NULL
, data
->value
, NULL
);
1386 return (const char **)data
->list
;
1389 /* Return parametric option from a given service. Type is a part of option before ':' */
1390 /* Parametric option has following syntax: 'Type: option = value' */
1392 int lp_parm_int(int snum
, const char *type
, const char *option
, int def
)
1394 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1396 if (data
&& data
->value
&& *data
->value
)
1397 return lp_int(data
->value
);
1402 /* Return parametric option from a given service. Type is a part of option before ':' */
1403 /* Parametric option has following syntax: 'Type: option = value' */
1405 unsigned long lp_parm_ulong(int snum
, const char *type
, const char *option
, unsigned long def
)
1407 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1409 if (data
&& data
->value
&& *data
->value
)
1410 return lp_ulong(data
->value
);
1415 /* Return parametric option from a given service. Type is a part of option before ':' */
1416 /* Parametric option has following syntax: 'Type: option = value' */
1418 bool lp_parm_bool(int snum
, const char *type
, const char *option
, bool def
)
1420 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1422 if (data
&& data
->value
&& *data
->value
)
1423 return lp_bool(data
->value
);
1428 /* Return parametric option from a given service. Type is a part of option before ':' */
1429 /* Parametric option has following syntax: 'Type: option = value' */
1431 int lp_parm_enum(int snum
, const char *type
, const char *option
,
1432 const struct enum_list
*_enum
, int def
)
1434 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1436 if (data
&& data
->value
&& *data
->value
&& _enum
)
1437 return lp_enum(data
->value
, _enum
);
1443 * free a param_opts structure.
1444 * param_opts handling should be moved to talloc;
1445 * then this whole functions reduces to a TALLOC_FREE().
1448 static void free_param_opts(struct parmlist_entry
**popts
)
1450 struct parmlist_entry
*opt
, *next_opt
;
1452 if (*popts
!= NULL
) {
1453 DEBUG(5, ("Freeing parametrics:\n"));
1456 while (opt
!= NULL
) {
1457 string_free(&opt
->key
);
1458 string_free(&opt
->value
);
1459 TALLOC_FREE(opt
->list
);
1460 next_opt
= opt
->next
;
1467 /***************************************************************************
1468 Free the dynamically allocated parts of a service struct.
1469 ***************************************************************************/
1471 static void free_service(struct loadparm_service
*pservice
)
1476 if (pservice
->szService
)
1477 DEBUG(5, ("free_service: Freeing service %s\n",
1478 pservice
->szService
));
1480 free_parameters(pservice
);
1482 string_free(&pservice
->szService
);
1483 TALLOC_FREE(pservice
->copymap
);
1485 free_param_opts(&pservice
->param_opt
);
1487 ZERO_STRUCTP(pservice
);
1491 /***************************************************************************
1492 remove a service indexed in the ServicePtrs array from the ServiceHash
1493 and free the dynamically allocated parts
1494 ***************************************************************************/
1496 static void free_service_byindex(int idx
)
1498 if ( !LP_SNUM_OK(idx
) )
1501 ServicePtrs
[idx
]->valid
= false;
1503 /* we have to cleanup the hash record */
1505 if (ServicePtrs
[idx
]->szService
) {
1506 char *canon_name
= canonicalize_servicename(
1508 ServicePtrs
[idx
]->szService
);
1510 dbwrap_delete_bystring(ServiceHash
, canon_name
);
1511 TALLOC_FREE(canon_name
);
1514 free_service(ServicePtrs
[idx
]);
1515 talloc_free_children(ServicePtrs
[idx
]);
1518 /***************************************************************************
1519 Add a new service to the services array initialising it with the given
1521 ***************************************************************************/
1523 static int add_a_service(const struct loadparm_service
*pservice
, const char *name
)
1526 int num_to_alloc
= iNumServices
+ 1;
1527 struct loadparm_service
**tsp
= NULL
;
1529 /* it might already exist */
1531 i
= getservicebyname(name
, NULL
);
1537 /* if not, then create one */
1539 tsp
= talloc_realloc(NULL
, ServicePtrs
, struct loadparm_service
*, num_to_alloc
);
1541 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1545 ServicePtrs
[iNumServices
] = talloc_zero(NULL
, struct loadparm_service
);
1546 if (!ServicePtrs
[iNumServices
]) {
1547 DEBUG(0,("add_a_service: out of memory!\n"));
1552 ServicePtrs
[i
]->valid
= true;
1554 copy_service(ServicePtrs
[i
], pservice
, NULL
);
1556 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->szService
, name
);
1558 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1559 i
, ServicePtrs
[i
]->szService
));
1561 if (!hash_a_service(ServicePtrs
[i
]->szService
, i
)) {
1568 /***************************************************************************
1569 Convert a string to uppercase and remove whitespaces.
1570 ***************************************************************************/
1572 char *canonicalize_servicename(TALLOC_CTX
*ctx
, const char *src
)
1577 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1581 result
= talloc_strdup(ctx
, src
);
1582 SMB_ASSERT(result
!= NULL
);
1584 if (!strlower_m(result
)) {
1585 TALLOC_FREE(result
);
1591 /***************************************************************************
1592 Add a name/index pair for the services array to the hash table.
1593 ***************************************************************************/
1595 static bool hash_a_service(const char *name
, int idx
)
1599 if ( !ServiceHash
) {
1600 DEBUG(10,("hash_a_service: creating servicehash\n"));
1601 ServiceHash
= db_open_rbt(NULL
);
1602 if ( !ServiceHash
) {
1603 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1608 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1611 canon_name
= canonicalize_servicename(talloc_tos(), name
);
1613 dbwrap_store_bystring(ServiceHash
, canon_name
,
1614 make_tdb_data((uint8
*)&idx
, sizeof(idx
)),
1617 TALLOC_FREE(canon_name
);
1622 /***************************************************************************
1623 Add a new home service, with the specified home directory, defaults coming
1625 ***************************************************************************/
1627 bool lp_add_home(const char *pszHomename
, int iDefaultService
,
1628 const char *user
, const char *pszHomedir
)
1632 if (pszHomename
== NULL
|| user
== NULL
|| pszHomedir
== NULL
||
1633 pszHomedir
[0] == '\0') {
1637 i
= add_a_service(ServicePtrs
[iDefaultService
], pszHomename
);
1642 if (!(*(ServicePtrs
[iDefaultService
]->path
))
1643 || strequal(ServicePtrs
[iDefaultService
]->path
,
1644 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM
))) {
1645 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->path
, pszHomedir
);
1648 if (!(*(ServicePtrs
[i
]->comment
))) {
1649 char *comment
= talloc_asprintf(talloc_tos(), "Home directory of %s", user
);
1650 if (comment
== NULL
) {
1653 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->comment
, comment
);
1654 TALLOC_FREE(comment
);
1657 /* set the browseable flag from the global default */
1659 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1660 ServicePtrs
[i
]->access_based_share_enum
= sDefault
.access_based_share_enum
;
1662 ServicePtrs
[i
]->autoloaded
= true;
1664 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename
,
1665 user
, ServicePtrs
[i
]->path
));
1670 /***************************************************************************
1671 Add a new service, based on an old one.
1672 ***************************************************************************/
1674 int lp_add_service(const char *pszService
, int iDefaultService
)
1676 if (iDefaultService
< 0) {
1677 return add_a_service(&sDefault
, pszService
);
1680 return (add_a_service(ServicePtrs
[iDefaultService
], pszService
));
1683 /***************************************************************************
1684 Add the IPC service.
1685 ***************************************************************************/
1687 static bool lp_add_ipc(const char *ipc_name
, bool guest_ok
)
1689 char *comment
= NULL
;
1690 int i
= add_a_service(&sDefault
, ipc_name
);
1695 comment
= talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1696 Globals
.server_string
);
1697 if (comment
== NULL
) {
1701 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->path
, tmpdir());
1702 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->username
, "");
1703 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->comment
, comment
);
1704 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->fstype
, "IPC");
1705 ServicePtrs
[i
]->max_connections
= 0;
1706 ServicePtrs
[i
]->bAvailable
= true;
1707 ServicePtrs
[i
]->read_only
= true;
1708 ServicePtrs
[i
]->guest_only
= false;
1709 ServicePtrs
[i
]->administrative_share
= true;
1710 ServicePtrs
[i
]->guest_ok
= guest_ok
;
1711 ServicePtrs
[i
]->printable
= false;
1712 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1714 DEBUG(3, ("adding IPC service\n"));
1716 TALLOC_FREE(comment
);
1720 /***************************************************************************
1721 Add a new printer service, with defaults coming from service iFrom.
1722 ***************************************************************************/
1724 bool lp_add_printer(const char *pszPrintername
, int iDefaultService
)
1726 const char *comment
= "From Printcap";
1727 int i
= add_a_service(ServicePtrs
[iDefaultService
], pszPrintername
);
1732 /* note that we do NOT default the availability flag to true - */
1733 /* we take it from the default service passed. This allows all */
1734 /* dynamic printers to be disabled by disabling the [printers] */
1735 /* entry (if/when the 'available' keyword is implemented!). */
1737 /* the printer name is set to the service name. */
1738 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->_printername
, pszPrintername
);
1739 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->comment
, comment
);
1741 /* set the browseable flag from the gloabl default */
1742 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1744 /* Printers cannot be read_only. */
1745 ServicePtrs
[i
]->read_only
= false;
1746 /* No oplocks on printer services. */
1747 ServicePtrs
[i
]->oplocks
= false;
1748 /* Printer services must be printable. */
1749 ServicePtrs
[i
]->printable
= true;
1751 DEBUG(3, ("adding printer service %s\n", pszPrintername
));
1757 /***************************************************************************
1758 Check whether the given parameter name is valid.
1759 Parametric options (names containing a colon) are considered valid.
1760 ***************************************************************************/
1762 bool lp_parameter_is_valid(const char *pszParmName
)
1764 return ((lpcfg_map_parameter(pszParmName
) != -1) ||
1765 (strchr(pszParmName
, ':') != NULL
));
1768 /***************************************************************************
1769 Check whether the given name is the name of a global parameter.
1770 Returns true for strings belonging to parameters of class
1771 P_GLOBAL, false for all other strings, also for parametric options
1772 and strings not belonging to any option.
1773 ***************************************************************************/
1775 bool lp_parameter_is_global(const char *pszParmName
)
1777 int num
= lpcfg_map_parameter(pszParmName
);
1780 return (parm_table
[num
].p_class
== P_GLOBAL
);
1786 /**************************************************************************
1787 Check whether the given name is the canonical name of a parameter.
1788 Returns false if it is not a valid parameter Name.
1789 For parametric options, true is returned.
1790 **************************************************************************/
1792 bool lp_parameter_is_canonical(const char *parm_name
)
1794 if (!lp_parameter_is_valid(parm_name
)) {
1798 return (lpcfg_map_parameter(parm_name
) ==
1799 map_parameter_canonical(parm_name
, NULL
));
1802 /**************************************************************************
1803 Determine the canonical name for a parameter.
1804 Indicate when it is an inverse (boolean) synonym instead of a
1806 **************************************************************************/
1808 bool lp_canonicalize_parameter(const char *parm_name
, const char **canon_parm
,
1813 if (!lp_parameter_is_valid(parm_name
)) {
1818 num
= map_parameter_canonical(parm_name
, inverse
);
1820 /* parametric option */
1821 *canon_parm
= parm_name
;
1823 *canon_parm
= parm_table
[num
].label
;
1830 /**************************************************************************
1831 Determine the canonical name for a parameter.
1832 Turn the value given into the inverse boolean expression when
1833 the synonym is an invers boolean synonym.
1835 Return true if parm_name is a valid parameter name and
1836 in case it is an invers boolean synonym, if the val string could
1837 successfully be converted to the reverse bool.
1838 Return false in all other cases.
1839 **************************************************************************/
1841 bool lp_canonicalize_parameter_with_value(const char *parm_name
,
1843 const char **canon_parm
,
1844 const char **canon_val
)
1849 if (!lp_parameter_is_valid(parm_name
)) {
1855 num
= map_parameter_canonical(parm_name
, &inverse
);
1857 /* parametric option */
1858 *canon_parm
= parm_name
;
1861 *canon_parm
= parm_table
[num
].label
;
1863 if (!lp_invert_boolean(val
, canon_val
)) {
1875 /***************************************************************************
1876 Map a parameter's string representation to the index of the canonical
1877 form of the parameter (it might be a synonym).
1878 Returns -1 if the parameter string is not recognised.
1879 ***************************************************************************/
1881 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
)
1883 int parm_num
, canon_num
;
1884 bool loc_inverse
= false;
1886 parm_num
= lpcfg_map_parameter(pszParmName
);
1887 if ((parm_num
< 0) || !(parm_table
[parm_num
].flags
& FLAG_HIDE
)) {
1888 /* invalid, parametric or no canidate for synonyms ... */
1892 for (canon_num
= 0; parm_table
[canon_num
].label
; canon_num
++) {
1893 if (is_synonym_of(parm_num
, canon_num
, &loc_inverse
)) {
1894 parm_num
= canon_num
;
1900 if (inverse
!= NULL
) {
1901 *inverse
= loc_inverse
;
1906 /***************************************************************************
1907 return true if parameter number parm1 is a synonym of parameter
1908 number parm2 (parm2 being the principal name).
1909 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1911 ***************************************************************************/
1913 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
)
1915 if ((parm_table
[parm1
].offset
== parm_table
[parm2
].offset
) &&
1916 (parm_table
[parm1
].p_class
== parm_table
[parm2
].p_class
) &&
1917 (parm_table
[parm1
].flags
& FLAG_HIDE
) &&
1918 !(parm_table
[parm2
].flags
& FLAG_HIDE
))
1920 if (inverse
!= NULL
) {
1921 if ((parm_table
[parm1
].type
== P_BOOLREV
) &&
1922 (parm_table
[parm2
].type
== P_BOOL
))
1934 /***************************************************************************
1935 Show one parameter's name, type, [values,] and flags.
1936 (helper functions for show_parameter_list)
1937 ***************************************************************************/
1939 static void show_parameter(int parmIndex
)
1941 int enumIndex
, flagIndex
;
1946 const char *type
[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1947 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1949 unsigned flags
[] = { FLAG_BASIC
, FLAG_SHARE
, FLAG_PRINT
, FLAG_GLOBAL
,
1950 FLAG_WIZARD
, FLAG_ADVANCED
, FLAG_DEVELOPER
, FLAG_DEPRECATED
,
1952 const char *flag_names
[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
1953 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
1954 "FLAG_DEPRECATED", "FLAG_HIDE", NULL
};
1956 printf("%s=%s", parm_table
[parmIndex
].label
,
1957 type
[parm_table
[parmIndex
].type
]);
1958 if (parm_table
[parmIndex
].type
== P_ENUM
) {
1961 parm_table
[parmIndex
].enum_list
[enumIndex
].name
;
1965 enumIndex
? "|" : "",
1966 parm_table
[parmIndex
].enum_list
[enumIndex
].name
);
1971 for (flagIndex
=0; flag_names
[flagIndex
]; flagIndex
++) {
1972 if (parm_table
[parmIndex
].flags
& flags
[flagIndex
]) {
1975 flag_names
[flagIndex
]);
1980 /* output synonyms */
1982 for (parmIndex2
=0; parm_table
[parmIndex2
].label
; parmIndex2
++) {
1983 if (is_synonym_of(parmIndex
, parmIndex2
, &inverse
)) {
1984 printf(" (%ssynonym of %s)", inverse
? "inverse " : "",
1985 parm_table
[parmIndex2
].label
);
1986 } else if (is_synonym_of(parmIndex2
, parmIndex
, &inverse
)) {
1988 printf(" (synonyms: ");
1993 printf("%s%s", parm_table
[parmIndex2
].label
,
1994 inverse
? "[i]" : "");
2004 /***************************************************************************
2005 Show all parameter's name, type, [values,] and flags.
2006 ***************************************************************************/
2008 void show_parameter_list(void)
2010 int classIndex
, parmIndex
;
2011 const char *section_names
[] = { "local", "global", NULL
};
2013 for (classIndex
=0; section_names
[classIndex
]; classIndex
++) {
2014 printf("[%s]\n", section_names
[classIndex
]);
2015 for (parmIndex
= 0; parm_table
[parmIndex
].label
; parmIndex
++) {
2016 if (parm_table
[parmIndex
].p_class
== classIndex
) {
2017 show_parameter(parmIndex
);
2023 /***************************************************************************
2024 Get the standard string representation of a boolean value ("yes" or "no")
2025 ***************************************************************************/
2027 static const char *get_boolean(bool bool_value
)
2029 static const char *yes_str
= "yes";
2030 static const char *no_str
= "no";
2032 return (bool_value
? yes_str
: no_str
);
2035 /***************************************************************************
2036 Provide the string of the negated boolean value associated to the boolean
2037 given as a string. Returns false if the passed string does not correctly
2038 represent a boolean.
2039 ***************************************************************************/
2041 bool lp_invert_boolean(const char *str
, const char **inverse_str
)
2045 if (!set_boolean(str
, &val
)) {
2049 *inverse_str
= get_boolean(!val
);
2053 /***************************************************************************
2054 Provide the canonical string representation of a boolean value given
2055 as a string. Return true on success, false if the string given does
2056 not correctly represent a boolean.
2057 ***************************************************************************/
2059 bool lp_canonicalize_boolean(const char *str
, const char**canon_str
)
2063 if (!set_boolean(str
, &val
)) {
2067 *canon_str
= get_boolean(val
);
2071 /***************************************************************************
2072 Find a service by name. Otherwise works like get_service.
2073 ***************************************************************************/
2075 static int getservicebyname(const char *pszServiceName
, struct loadparm_service
*pserviceDest
)
2082 if (ServiceHash
== NULL
) {
2086 canon_name
= canonicalize_servicename(talloc_tos(), pszServiceName
);
2088 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
, canon_name
,
2091 if (NT_STATUS_IS_OK(status
) &&
2092 (data
.dptr
!= NULL
) &&
2093 (data
.dsize
== sizeof(iService
)))
2095 iService
= *(int *)data
.dptr
;
2098 TALLOC_FREE(canon_name
);
2100 if ((iService
!= -1) && (LP_SNUM_OK(iService
))
2101 && (pserviceDest
!= NULL
)) {
2102 copy_service(pserviceDest
, ServicePtrs
[iService
], NULL
);
2108 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2109 struct loadparm_service
*lp_service(const char *pszServiceName
)
2111 int iService
= getservicebyname(pszServiceName
, NULL
);
2112 if (iService
== -1 || !LP_SNUM_OK(iService
)) {
2115 return ServicePtrs
[iService
];
2118 struct loadparm_service
*lp_servicebynum(int snum
)
2120 if ((snum
== -1) || !LP_SNUM_OK(snum
)) {
2123 return ServicePtrs
[snum
];
2126 struct loadparm_service
*lp_default_loadparm_service()
2131 /***************************************************************************
2132 Check a service for consistency. Return false if the service is in any way
2133 incomplete or faulty, else true.
2134 ***************************************************************************/
2136 bool service_ok(int iService
)
2141 if (ServicePtrs
[iService
]->szService
[0] == '\0') {
2142 DEBUG(0, ("The following message indicates an internal error:\n"));
2143 DEBUG(0, ("No service name in service entry.\n"));
2147 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2148 /* I can't see why you'd want a non-printable printer service... */
2149 if (strwicmp(ServicePtrs
[iService
]->szService
, PRINTERS_NAME
) == 0) {
2150 if (!ServicePtrs
[iService
]->printable
) {
2151 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2152 ServicePtrs
[iService
]->szService
));
2153 ServicePtrs
[iService
]->printable
= true;
2155 /* [printers] service must also be non-browsable. */
2156 if (ServicePtrs
[iService
]->browseable
)
2157 ServicePtrs
[iService
]->browseable
= false;
2160 if (ServicePtrs
[iService
]->path
[0] == '\0' &&
2161 strwicmp(ServicePtrs
[iService
]->szService
, HOMES_NAME
) != 0 &&
2162 ServicePtrs
[iService
]->msdfs_proxy
[0] == '\0'
2164 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2165 ServicePtrs
[iService
]->szService
));
2166 ServicePtrs
[iService
]->bAvailable
= false;
2169 /* If a service is flagged unavailable, log the fact at level 1. */
2170 if (!ServicePtrs
[iService
]->bAvailable
)
2171 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2172 ServicePtrs
[iService
]->szService
));
2177 static struct smbconf_ctx
*lp_smbconf_ctx(void)
2180 static struct smbconf_ctx
*conf_ctx
= NULL
;
2182 if (conf_ctx
== NULL
) {
2183 err
= smbconf_init(NULL
, &conf_ctx
, "registry:");
2184 if (!SBC_ERROR_IS_OK(err
)) {
2185 DEBUG(1, ("error initializing registry configuration: "
2186 "%s\n", sbcErrorString(err
)));
2194 static bool process_smbconf_service(struct smbconf_service
*service
)
2199 if (service
== NULL
) {
2203 ret
= do_section(service
->name
, NULL
);
2207 for (count
= 0; count
< service
->num_params
; count
++) {
2208 ret
= do_parameter(service
->param_names
[count
],
2209 service
->param_values
[count
],
2215 if (iServiceIndex
>= 0) {
2216 return service_ok(iServiceIndex
);
2222 * load a service from registry and activate it
2224 bool process_registry_service(const char *service_name
)
2227 struct smbconf_service
*service
= NULL
;
2228 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
2229 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2232 if (conf_ctx
== NULL
) {
2236 DEBUG(5, ("process_registry_service: service name %s\n", service_name
));
2238 if (!smbconf_share_exists(conf_ctx
, service_name
)) {
2240 * Registry does not contain data for this service (yet),
2241 * but make sure lp_load doesn't return false.
2247 err
= smbconf_get_share(conf_ctx
, mem_ctx
, service_name
, &service
);
2248 if (!SBC_ERROR_IS_OK(err
)) {
2252 ret
= process_smbconf_service(service
);
2258 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
2261 TALLOC_FREE(mem_ctx
);
2266 * process_registry_globals
2268 static bool process_registry_globals(void)
2272 add_to_file_list(INCLUDE_REGISTRY_NAME
, INCLUDE_REGISTRY_NAME
);
2274 ret
= do_parameter("registry shares", "yes", NULL
);
2279 return process_registry_service(GLOBAL_NAME
);
2282 bool process_registry_shares(void)
2286 struct smbconf_service
**service
= NULL
;
2287 uint32_t num_shares
= 0;
2288 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
2289 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2292 if (conf_ctx
== NULL
) {
2296 err
= smbconf_get_config(conf_ctx
, mem_ctx
, &num_shares
, &service
);
2297 if (!SBC_ERROR_IS_OK(err
)) {
2303 for (count
= 0; count
< num_shares
; count
++) {
2304 if (strequal(service
[count
]->name
, GLOBAL_NAME
)) {
2307 ret
= process_smbconf_service(service
[count
]);
2314 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
2317 TALLOC_FREE(mem_ctx
);
2322 * reload those shares from registry that are already
2323 * activated in the services array.
2325 static bool reload_registry_shares(void)
2330 for (i
= 0; i
< iNumServices
; i
++) {
2335 if (ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
2339 ret
= process_registry_service(ServicePtrs
[i
]->szService
);
2350 #define MAX_INCLUDE_DEPTH 100
2352 static uint8_t include_depth
;
2354 static struct file_lists
{
2355 struct file_lists
*next
;
2359 } *file_lists
= NULL
;
2361 /*******************************************************************
2362 Keep a linked list of all config files so we know when one has changed
2363 it's date and needs to be reloaded.
2364 ********************************************************************/
2366 static void add_to_file_list(const char *fname
, const char *subfname
)
2368 struct file_lists
*f
= file_lists
;
2371 if (f
->name
&& !strcmp(f
->name
, fname
))
2377 f
= talloc(NULL
, struct file_lists
);
2381 f
->next
= file_lists
;
2382 f
->name
= talloc_strdup(f
, fname
);
2387 f
->subfname
= talloc_strdup(f
, subfname
);
2393 f
->modtime
= file_modtime(subfname
);
2395 time_t t
= file_modtime(subfname
);
2402 DEBUG(0, ("Unable to add file to file list: %s\n", fname
));
2407 * Free the file lists
2409 static void free_file_list(void)
2411 struct file_lists
*f
;
2412 struct file_lists
*next
;
2425 * Utility function for outsiders to check if we're running on registry.
2427 bool lp_config_backend_is_registry(void)
2429 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY
);
2433 * Utility function to check if the config backend is FILE.
2435 bool lp_config_backend_is_file(void)
2437 return (lp_config_backend() == CONFIG_BACKEND_FILE
);
2440 /*******************************************************************
2441 Check if a config file has changed date.
2442 ********************************************************************/
2444 bool lp_file_list_changed(void)
2446 struct file_lists
*f
= file_lists
;
2448 DEBUG(6, ("lp_file_list_changed()\n"));
2453 if (strequal(f
->name
, INCLUDE_REGISTRY_NAME
)) {
2454 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2456 if (conf_ctx
== NULL
) {
2459 if (smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
,
2462 DEBUGADD(6, ("registry config changed\n"));
2467 n2
= talloc_sub_basic(talloc_tos(),
2468 get_current_username(),
2469 current_user_info
.domain
,
2474 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2475 f
->name
, n2
, ctime(&f
->modtime
)));
2477 mod_time
= file_modtime(n2
);
2480 ((f
->modtime
!= mod_time
) ||
2481 (f
->subfname
== NULL
) ||
2482 (strcmp(n2
, f
->subfname
) != 0)))
2485 ("file %s modified: %s\n", n2
,
2487 f
->modtime
= mod_time
;
2488 TALLOC_FREE(f
->subfname
);
2489 f
->subfname
= talloc_strdup(f
, n2
);
2490 if (f
->subfname
== NULL
) {
2491 smb_panic("talloc_strdup failed");
2505 * Initialize iconv conversion descriptors.
2507 * This is called the first time it is needed, and also called again
2508 * every time the configuration is reloaded, because the charset or
2509 * codepage might have changed.
2511 static void init_iconv(void)
2513 global_iconv_handle
= smb_iconv_handle_reinit(NULL
, lp_dos_charset(),
2515 true, global_iconv_handle
);
2518 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2520 if (strcmp(*ptr
, pszParmValue
) != 0) {
2521 string_set(Globals
.ctx
, ptr
, pszParmValue
);
2527 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2529 bool is_utf8
= false;
2530 size_t len
= strlen(pszParmValue
);
2532 if (len
== 4 || len
== 5) {
2533 /* Don't use StrCaseCmp here as we don't want to
2534 initialize iconv. */
2535 if ((toupper_m(pszParmValue
[0]) == 'U') &&
2536 (toupper_m(pszParmValue
[1]) == 'T') &&
2537 (toupper_m(pszParmValue
[2]) == 'F')) {
2539 if (pszParmValue
[3] == '8') {
2543 if (pszParmValue
[3] == '-' &&
2544 pszParmValue
[4] == '8') {
2551 if (strcmp(*ptr
, pszParmValue
) != 0) {
2553 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
2554 "be UTF8, using (default value) %s instead.\n",
2555 DEFAULT_DOS_CHARSET
));
2556 pszParmValue
= DEFAULT_DOS_CHARSET
;
2558 string_set(Globals
.ctx
, ptr
, pszParmValue
);
2564 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2566 TALLOC_FREE(Globals
.netbios_aliases
);
2567 Globals
.netbios_aliases
= (const char **)str_list_make_v3(NULL
, pszParmValue
, NULL
);
2568 return set_netbios_aliases(Globals
.netbios_aliases
);
2571 /***************************************************************************
2572 Handle the include operation.
2573 ***************************************************************************/
2574 static bool bAllowIncludeRegistry
= true;
2576 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2580 if (include_depth
>= MAX_INCLUDE_DEPTH
) {
2581 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2586 if (strequal(pszParmValue
, INCLUDE_REGISTRY_NAME
)) {
2587 if (!bAllowIncludeRegistry
) {
2590 if (bInGlobalSection
) {
2593 ret
= process_registry_globals();
2597 DEBUG(1, ("\"include = registry\" only effective "
2598 "in %s section\n", GLOBAL_NAME
));
2603 fname
= talloc_sub_basic(talloc_tos(), get_current_username(),
2604 current_user_info
.domain
,
2607 add_to_file_list(pszParmValue
, fname
);
2610 string_set(Globals
.ctx
, ptr
, fname
);
2612 string_set(ServicePtrs
[snum
], ptr
, fname
);
2615 if (file_exist(fname
)) {
2618 ret
= pm_process(fname
, do_section
, do_parameter
, NULL
);
2624 DEBUG(2, ("Can't find include file %s\n", fname
));
2629 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2631 Globals
.ldap_debug_level
= lp_int(pszParmValue
);
2632 init_ldap_debugging();
2637 * idmap related parameters
2640 static bool handle_idmap_backend(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2642 lp_do_parameter(snum
, "idmap config * : backend", pszParmValue
);
2647 static bool handle_idmap_uid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2649 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
2654 static bool handle_idmap_gid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2656 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
2661 bool lp_idmap_range(const char *domain_name
, uint32_t *low
, uint32_t *high
)
2663 char *config_option
= NULL
;
2664 const char *range
= NULL
;
2667 SMB_ASSERT(low
!= NULL
);
2668 SMB_ASSERT(high
!= NULL
);
2670 if ((domain_name
== NULL
) || (domain_name
[0] == '\0')) {
2674 config_option
= talloc_asprintf(talloc_tos(), "idmap config %s",
2676 if (config_option
== NULL
) {
2677 DEBUG(0, ("out of memory\n"));
2681 range
= lp_parm_const_string(-1, config_option
, "range", NULL
);
2682 if (range
== NULL
) {
2683 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name
));
2687 if (sscanf(range
, "%u - %u", low
, high
) != 2) {
2688 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2689 range
, domain_name
));
2696 talloc_free(config_option
);
2701 bool lp_idmap_default_range(uint32_t *low
, uint32_t *high
)
2703 return lp_idmap_range("*", low
, high
);
2706 const char *lp_idmap_backend(const char *domain_name
)
2708 char *config_option
= NULL
;
2709 const char *backend
= NULL
;
2711 if ((domain_name
== NULL
) || (domain_name
[0] == '\0')) {
2715 config_option
= talloc_asprintf(talloc_tos(), "idmap config %s",
2717 if (config_option
== NULL
) {
2718 DEBUG(0, ("out of memory\n"));
2722 backend
= lp_parm_const_string(-1, config_option
, "backend", NULL
);
2723 if (backend
== NULL
) {
2724 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name
));
2729 talloc_free(config_option
);
2733 const char *lp_idmap_default_backend(void)
2735 return lp_idmap_backend("*");
2738 /***************************************************************************
2739 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2740 ***************************************************************************/
2742 static const char *append_ldap_suffix(TALLOC_CTX
*ctx
, const char *str
)
2744 const char *suffix_string
;
2746 suffix_string
= talloc_asprintf(ctx
, "%s,%s", str
,
2747 Globals
.ldap_suffix
);
2748 if ( !suffix_string
) {
2749 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2753 return suffix_string
;
2756 const char *lp_ldap_machine_suffix(TALLOC_CTX
*ctx
)
2758 if (Globals
.szLdapMachineSuffix
[0])
2759 return append_ldap_suffix(ctx
, Globals
.szLdapMachineSuffix
);
2761 return lp_string(ctx
, Globals
.ldap_suffix
);
2764 const char *lp_ldap_user_suffix(TALLOC_CTX
*ctx
)
2766 if (Globals
.szLdapUserSuffix
[0])
2767 return append_ldap_suffix(ctx
, Globals
.szLdapUserSuffix
);
2769 return lp_string(ctx
, Globals
.ldap_suffix
);
2772 const char *lp_ldap_group_suffix(TALLOC_CTX
*ctx
)
2774 if (Globals
.szLdapGroupSuffix
[0])
2775 return append_ldap_suffix(ctx
, Globals
.szLdapGroupSuffix
);
2777 return lp_string(ctx
, Globals
.ldap_suffix
);
2780 const char *lp_ldap_idmap_suffix(TALLOC_CTX
*ctx
)
2782 if (Globals
.szLdapIdmapSuffix
[0])
2783 return append_ldap_suffix(ctx
, Globals
.szLdapIdmapSuffix
);
2785 return lp_string(ctx
, Globals
.ldap_suffix
);
2788 /****************************************************************************
2789 set the value for a P_ENUM
2790 ***************************************************************************/
2792 static void lp_set_enum_parm( struct parm_struct
*parm
, const char *pszParmValue
,
2797 for (i
= 0; parm
->enum_list
[i
].name
; i
++) {
2798 if ( strequal(pszParmValue
, parm
->enum_list
[i
].name
)) {
2799 *ptr
= parm
->enum_list
[i
].value
;
2803 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
2804 pszParmValue
, parm
->label
));
2807 /***************************************************************************
2808 ***************************************************************************/
2810 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2812 static int parm_num
= -1;
2813 struct loadparm_service
*s
;
2815 if ( parm_num
== -1 )
2816 parm_num
= lpcfg_map_parameter( "printing" );
2818 lp_set_enum_parm( &parm_table
[parm_num
], pszParmValue
, (int*)ptr
);
2822 init_printer_values(Globals
.ctx
, s
);
2824 s
= ServicePtrs
[snum
];
2825 init_printer_values(s
, s
);
2832 /***************************************************************************
2833 Initialise a copymap.
2834 ***************************************************************************/
2836 static void init_copymap(struct loadparm_service
*pservice
)
2840 TALLOC_FREE(pservice
->copymap
);
2842 pservice
->copymap
= bitmap_talloc(NULL
, NUMPARAMETERS
);
2843 if (!pservice
->copymap
)
2845 ("Couldn't allocate copymap!! (size %d)\n",
2846 (int)NUMPARAMETERS
));
2848 for (i
= 0; i
< NUMPARAMETERS
; i
++)
2849 bitmap_set(pservice
->copymap
, i
);
2853 return the parameter pointer for a parameter
2855 void *lp_parm_ptr(struct loadparm_service
*service
, struct parm_struct
*parm
)
2857 if (service
== NULL
) {
2858 if (parm
->p_class
== P_LOCAL
)
2859 return (void *)(((char *)&sDefault
)+parm
->offset
);
2860 else if (parm
->p_class
== P_GLOBAL
)
2861 return (void *)(((char *)&Globals
)+parm
->offset
);
2864 return (void *)(((char *)service
) + parm
->offset
);
2868 /***************************************************************************
2869 Return the local pointer to a parameter given the service number and parameter
2870 ***************************************************************************/
2872 void *lp_local_ptr_by_snum(int snum
, struct parm_struct
*parm
)
2874 return lp_parm_ptr(ServicePtrs
[snum
], parm
);
2877 /***************************************************************************
2878 Process a parameter for a particular service number. If snum < 0
2879 then assume we are in the globals.
2880 ***************************************************************************/
2882 bool lp_do_parameter(int snum
, const char *pszParmName
, const char *pszParmValue
)
2885 void *parm_ptr
= NULL
; /* where we are going to store the result */
2886 struct parmlist_entry
**opt_list
;
2887 TALLOC_CTX
*mem_ctx
;
2889 parmnum
= lpcfg_map_parameter(pszParmName
);
2892 if (strchr(pszParmName
, ':') == NULL
) {
2893 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
2899 * We've got a parametric option
2903 opt_list
= &Globals
.param_opt
;
2904 set_param_opt(NULL
, opt_list
, pszParmName
, pszParmValue
, 0);
2906 opt_list
= &ServicePtrs
[snum
]->param_opt
;
2907 set_param_opt(ServicePtrs
[snum
], opt_list
, pszParmName
, pszParmValue
, 0);
2913 /* if it's already been set by the command line, then we don't
2915 if (parm_table
[parmnum
].flags
& FLAG_CMDLINE
) {
2919 if (parm_table
[parmnum
].flags
& FLAG_DEPRECATED
) {
2920 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2924 /* we might point at a service, the default service or a global */
2926 parm_ptr
= lp_parm_ptr(NULL
, &parm_table
[parmnum
]);
2928 if (parm_table
[parmnum
].p_class
== P_GLOBAL
) {
2930 ("Global parameter %s found in service section!\n",
2934 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm_table
[parmnum
]);
2938 if (!ServicePtrs
[snum
]->copymap
)
2939 init_copymap(ServicePtrs
[snum
]);
2941 /* this handles the aliases - set the copymap for other entries with
2942 the same data pointer */
2943 for (i
= 0; parm_table
[i
].label
; i
++) {
2944 if ((parm_table
[i
].offset
== parm_table
[parmnum
].offset
)
2945 && (parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
)) {
2946 bitmap_clear(ServicePtrs
[snum
]->copymap
, i
);
2949 mem_ctx
= ServicePtrs
[snum
];
2951 mem_ctx
= Globals
.ctx
;
2954 /* if it is a special case then go ahead */
2955 if (parm_table
[parmnum
].special
) {
2957 struct loadparm_context
*lp_ctx
= loadparm_init_s3(talloc_tos(),
2958 loadparm_s3_helpers());
2959 ok
= parm_table
[parmnum
].special(lp_ctx
, snum
, pszParmValue
,
2961 TALLOC_FREE(lp_ctx
);
2966 /* now switch on the type of variable it is */
2967 switch (parm_table
[parmnum
].type
)
2970 *(bool *)parm_ptr
= lp_bool(pszParmValue
);
2974 *(bool *)parm_ptr
= !lp_bool(pszParmValue
);
2978 *(int *)parm_ptr
= lp_int(pszParmValue
);
2982 *(char *)parm_ptr
= *pszParmValue
;
2986 i
= sscanf(pszParmValue
, "%o", (int *)parm_ptr
);
2988 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName
));
2995 if (conv_str_size_error(pszParmValue
, &val
)) {
2996 if (val
<= INT_MAX
) {
2997 *(int *)parm_ptr
= (int)val
;
3002 DEBUG(0,("lp_do_parameter(%s): value is not "
3003 "a valid size specifier!\n", pszParmValue
));
3009 TALLOC_FREE(*((char ***)parm_ptr
));
3010 *(char ***)parm_ptr
= str_list_make_v3(
3011 NULL
, pszParmValue
, NULL
);
3015 string_set(mem_ctx
, (char **)parm_ptr
, pszParmValue
);
3020 char *upper_string
= strupper_talloc(talloc_tos(),
3022 string_set(mem_ctx
, (char **)parm_ptr
, upper_string
);
3023 TALLOC_FREE(upper_string
);
3027 lp_set_enum_parm( &parm_table
[parmnum
], pszParmValue
, (int*)parm_ptr
);
3036 /***************************************************************************
3037 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
3038 FLAG_CMDLINE won't be overridden by loads from smb.conf.
3039 ***************************************************************************/
3041 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
)
3044 parmnum
= lpcfg_map_parameter(pszParmName
);
3046 parm_table
[parmnum
].flags
&= ~FLAG_CMDLINE
;
3047 if (!lp_do_parameter(-1, pszParmName
, pszParmValue
)) {
3050 parm_table
[parmnum
].flags
|= FLAG_CMDLINE
;
3052 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
3053 * be grouped in the table, so we don't have to search the
3056 i
>=0 && parm_table
[i
].offset
== parm_table
[parmnum
].offset
3057 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;
3059 parm_table
[i
].flags
|= FLAG_CMDLINE
;
3061 for (i
=parmnum
+1;i
<NUMPARAMETERS
&& parm_table
[i
].offset
== parm_table
[parmnum
].offset
3062 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;i
++) {
3063 parm_table
[i
].flags
|= FLAG_CMDLINE
;
3067 store_lp_set_cmdline(pszParmName
, pszParmValue
);
3072 /* it might be parametric */
3073 if (strchr(pszParmName
, ':') != NULL
) {
3074 set_param_opt(NULL
, &Globals
.param_opt
, pszParmName
, pszParmValue
, FLAG_CMDLINE
);
3076 store_lp_set_cmdline(pszParmName
, pszParmValue
);
3081 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName
));
3085 bool lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
3087 return lp_set_cmdline_helper(pszParmName
, pszParmValue
, true);
3090 /***************************************************************************
3091 Process a parameter.
3092 ***************************************************************************/
3094 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
3097 if (!bInGlobalSection
&& bGlobalOnly
)
3100 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName
, pszParmValue
));
3102 return (lp_do_parameter(bInGlobalSection
? -2 : iServiceIndex
,
3103 pszParmName
, pszParmValue
));
3107 set a option from the commandline in 'a=b' format. Use to support --option
3109 bool lp_set_option(const char *option
)
3114 s
= talloc_strdup(NULL
, option
);
3127 /* skip white spaces after the = sign */
3130 } while (*p
== ' ');
3132 ret
= lp_set_cmdline(s
, p
);
3137 /***************************************************************************
3138 Initialize any local variables in the sDefault table, after parsing a
3140 ***************************************************************************/
3142 static void init_locals(void)
3145 * We run this check once the [globals] is parsed, to force
3146 * the VFS objects and other per-share settings we need for
3147 * the standard way a AD DC is operated. We may change these
3148 * as our code evolves, which is why we force these settings.
3150 * We can't do this at the end of lp_load_ex(), as by that
3151 * point the services have been loaded and they will already
3152 * have "" as their vfs objects.
3154 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
3155 const char **vfs_objects
= lp_vfs_objects(-1);
3156 if (!vfs_objects
|| !vfs_objects
[0]) {
3157 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL
)) {
3158 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
3159 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL
)) {
3160 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
3162 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
3166 lp_do_parameter(-1, "map hidden", "no");
3167 lp_do_parameter(-1, "map system", "no");
3168 lp_do_parameter(-1, "map readonly", "no");
3169 lp_do_parameter(-1, "map archive", "no");
3170 lp_do_parameter(-1, "store dos attributes", "yes");
3174 /***************************************************************************
3175 Process a new section (service). At this stage all sections are services.
3176 Later we'll have special sections that permit server parameters to be set.
3177 Returns true on success, false on failure.
3178 ***************************************************************************/
3180 static bool do_section(const char *pszSectionName
, void *userdata
)
3183 bool isglobal
= ((strwicmp(pszSectionName
, GLOBAL_NAME
) == 0) ||
3184 (strwicmp(pszSectionName
, GLOBAL_NAME2
) == 0));
3187 /* if we were in a global section then do the local inits */
3188 if (bInGlobalSection
&& !isglobal
)
3191 /* if we've just struck a global section, note the fact. */
3192 bInGlobalSection
= isglobal
;
3194 /* check for multiple global sections */
3195 if (bInGlobalSection
) {
3196 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName
));
3200 if (!bInGlobalSection
&& bGlobalOnly
)
3203 /* if we have a current service, tidy it up before moving on */
3206 if (iServiceIndex
>= 0)
3207 bRetval
= service_ok(iServiceIndex
);
3209 /* if all is still well, move to the next record in the services array */
3211 /* We put this here to avoid an odd message order if messages are */
3212 /* issued by the post-processing of a previous section. */
3213 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName
));
3215 iServiceIndex
= add_a_service(&sDefault
, pszSectionName
);
3216 if (iServiceIndex
< 0) {
3217 DEBUG(0, ("Failed to add a new service\n"));
3220 /* Clean all parametric options for service */
3221 /* They will be added during parsing again */
3222 free_param_opts(&ServicePtrs
[iServiceIndex
]->param_opt
);
3229 /***************************************************************************
3230 Determine if a partcular base parameter is currentl set to the default value.
3231 ***************************************************************************/
3233 static bool is_default(int i
)
3235 switch (parm_table
[i
].type
) {
3238 return str_list_equal((const char * const *)parm_table
[i
].def
.lvalue
,
3239 *(const char ***)lp_parm_ptr(NULL
,
3243 return strequal(parm_table
[i
].def
.svalue
,
3244 *(char **)lp_parm_ptr(NULL
,
3248 return parm_table
[i
].def
.bvalue
==
3249 *(bool *)lp_parm_ptr(NULL
,
3252 return parm_table
[i
].def
.cvalue
==
3253 *(char *)lp_parm_ptr(NULL
,
3259 return parm_table
[i
].def
.ivalue
==
3260 *(int *)lp_parm_ptr(NULL
,
3268 /***************************************************************************
3269 Display the contents of the global structure.
3270 ***************************************************************************/
3272 static void dump_globals(FILE *f
)
3275 struct parmlist_entry
*data
;
3277 fprintf(f
, "[global]\n");
3279 for (i
= 0; parm_table
[i
].label
; i
++)
3280 if (parm_table
[i
].p_class
== P_GLOBAL
&&
3281 !(parm_table
[i
].flags
& FLAG_META
) &&
3282 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
))) {
3283 if (defaults_saved
&& is_default(i
))
3285 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
3286 lpcfg_print_parameter(&parm_table
[i
], lp_parm_ptr(NULL
,
3291 if (Globals
.param_opt
!= NULL
) {
3292 data
= Globals
.param_opt
;
3294 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
3301 /***************************************************************************
3302 Display the contents of a single services record.
3303 ***************************************************************************/
3305 static void dump_a_service(struct loadparm_service
*pService
, FILE * f
)
3308 struct parmlist_entry
*data
;
3310 if (pService
!= &sDefault
)
3311 fprintf(f
, "[%s]\n", pService
->szService
);
3313 for (i
= 0; parm_table
[i
].label
; i
++) {
3315 if (parm_table
[i
].p_class
== P_LOCAL
&&
3316 !(parm_table
[i
].flags
& FLAG_META
) &&
3317 (*parm_table
[i
].label
!= '-') &&
3318 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
)))
3320 if (pService
== &sDefault
) {
3321 if (defaults_saved
&& is_default(i
))
3324 if (lpcfg_equal_parameter(parm_table
[i
].type
,
3325 lp_parm_ptr(pService
, &parm_table
[i
]),
3326 lp_parm_ptr(NULL
, &parm_table
[i
])))
3330 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
3331 lpcfg_print_parameter(&parm_table
[i
],
3332 lp_parm_ptr(pService
, &parm_table
[i
]),
3338 if (pService
->param_opt
!= NULL
) {
3339 data
= pService
->param_opt
;
3341 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
3347 /***************************************************************************
3348 Display the contents of a parameter of a single services record.
3349 ***************************************************************************/
3351 bool dump_a_parameter(int snum
, char *parm_name
, FILE * f
, bool isGlobal
)
3353 bool result
= false;
3354 fstring local_parm_name
;
3356 const char *parm_opt_value
;
3358 struct loadparm_context
*lp_ctx
;
3360 /* check for parametrical option */
3361 fstrcpy( local_parm_name
, parm_name
);
3362 parm_opt
= strchr( local_parm_name
, ':');
3367 if (strlen(parm_opt
)) {
3368 parm_opt_value
= lp_parm_const_string( snum
,
3369 local_parm_name
, parm_opt
, NULL
);
3370 if (parm_opt_value
) {
3371 printf( "%s\n", parm_opt_value
);
3378 lp_ctx
= loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
3379 if (lp_ctx
== NULL
) {
3384 result
= lpcfg_dump_a_parameter(lp_ctx
, NULL
, parm_name
, f
);
3386 result
= lpcfg_dump_a_parameter(lp_ctx
, ServicePtrs
[snum
], parm_name
, f
);
3388 TALLOC_FREE(lp_ctx
);
3392 /***************************************************************************
3393 Return info about the requested parameter (given as a string).
3394 Return NULL when the string is not a valid parameter name.
3395 ***************************************************************************/
3397 struct parm_struct
*lp_get_parameter(const char *param_name
)
3399 int num
= lpcfg_map_parameter(param_name
);
3405 return &parm_table
[num
];
3409 /***************************************************************************
3410 Display the contents of a single copy structure.
3411 ***************************************************************************/
3412 static void dump_copy_map(bool *pcopymap
)
3418 printf("\n\tNon-Copied parameters:\n");
3420 for (i
= 0; parm_table
[i
].label
; i
++)
3421 if (parm_table
[i
].p_class
== P_LOCAL
&&
3422 parm_table
[i
].ptr
&& !pcopymap
[i
] &&
3423 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
- 1].ptr
)))
3425 printf("\t\t%s\n", parm_table
[i
].label
);
3430 /***************************************************************************
3431 Return TRUE if the passed service number is within range.
3432 ***************************************************************************/
3434 bool lp_snum_ok(int iService
)
3436 return (LP_SNUM_OK(iService
) && ServicePtrs
[iService
]->bAvailable
);
3439 /***************************************************************************
3440 Auto-load some home services.
3441 ***************************************************************************/
3443 static void lp_add_auto_services(char *str
)
3453 s
= talloc_strdup(talloc_tos(), str
);
3455 smb_panic("talloc_strdup failed");
3459 homes
= lp_servicenumber(HOMES_NAME
);
3461 for (p
= strtok_r(s
, LIST_SEP
, &saveptr
); p
;
3462 p
= strtok_r(NULL
, LIST_SEP
, &saveptr
)) {
3465 if (lp_servicenumber(p
) >= 0)
3468 home
= get_user_home_dir(talloc_tos(), p
);
3470 if (home
&& home
[0] && homes
>= 0)
3471 lp_add_home(p
, homes
, p
, home
);
3478 /***************************************************************************
3479 Auto-load one printer.
3480 ***************************************************************************/
3482 void lp_add_one_printer(const char *name
, const char *comment
,
3483 const char *location
, void *pdata
)
3485 int printers
= lp_servicenumber(PRINTERS_NAME
);
3488 if (lp_servicenumber(name
) < 0) {
3489 lp_add_printer(name
, printers
);
3490 if ((i
= lp_servicenumber(name
)) >= 0) {
3491 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->comment
, comment
);
3492 ServicePtrs
[i
]->autoloaded
= true;
3497 /***************************************************************************
3498 Have we loaded a services file yet?
3499 ***************************************************************************/
3501 bool lp_loaded(void)
3506 /***************************************************************************
3507 Unload unused services.
3508 ***************************************************************************/
3510 void lp_killunused(struct smbd_server_connection
*sconn
,
3511 bool (*snumused
) (struct smbd_server_connection
*, int))
3514 for (i
= 0; i
< iNumServices
; i
++) {
3518 /* don't kill autoloaded or usershare services */
3519 if ( ServicePtrs
[i
]->autoloaded
||
3520 ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
3524 if (!snumused
|| !snumused(sconn
, i
)) {
3525 free_service_byindex(i
);
3531 * Kill all except autoloaded and usershare services - convenience wrapper
3533 void lp_kill_all_services(void)
3535 lp_killunused(NULL
, NULL
);
3538 /***************************************************************************
3540 ***************************************************************************/
3542 void lp_killservice(int iServiceIn
)
3544 if (VALID(iServiceIn
)) {
3545 free_service_byindex(iServiceIn
);
3549 /***************************************************************************
3550 Save the curent values of all global and sDefault parameters into the
3551 defaults union. This allows testparm to show only the
3552 changed (ie. non-default) parameters.
3553 ***************************************************************************/
3555 static void lp_save_defaults(void)
3558 for (i
= 0; parm_table
[i
].label
; i
++) {
3559 if (i
> 0 && parm_table
[i
].offset
== parm_table
[i
- 1].offset
3560 && parm_table
[i
].p_class
== parm_table
[i
- 1].p_class
)
3562 switch (parm_table
[i
].type
) {
3565 parm_table
[i
].def
.lvalue
= str_list_copy(
3566 NULL
, *(const char ***)lp_parm_ptr(NULL
, &parm_table
[i
]));
3570 parm_table
[i
].def
.svalue
= talloc_strdup(Globals
.ctx
, *(char **)lp_parm_ptr(NULL
, &parm_table
[i
]));
3571 if (parm_table
[i
].def
.svalue
== NULL
) {
3572 smb_panic("talloc_strdup failed");
3577 parm_table
[i
].def
.bvalue
=
3578 *(bool *)lp_parm_ptr(NULL
, &parm_table
[i
]);
3581 parm_table
[i
].def
.cvalue
=
3582 *(char *)lp_parm_ptr(NULL
, &parm_table
[i
]);
3588 parm_table
[i
].def
.ivalue
=
3589 *(int *)lp_parm_ptr(NULL
, &parm_table
[i
]);
3595 defaults_saved
= true;
3598 /***********************************************************
3599 If we should send plaintext/LANMAN passwords in the clinet
3600 ************************************************************/
3602 static void set_allowed_client_auth(void)
3604 if (Globals
.client_ntlmv2_auth
) {
3605 Globals
.client_lanman_auth
= false;
3607 if (!Globals
.client_lanman_auth
) {
3608 Globals
.client_plaintext_auth
= false;
3612 /***************************************************************************
3614 The following code allows smbd to read a user defined share file.
3615 Yes, this is my intent. Yes, I'm comfortable with that...
3617 THE FOLLOWING IS SECURITY CRITICAL CODE.
3619 It washes your clothes, it cleans your house, it guards you while you sleep...
3620 Do not f%^k with it....
3621 ***************************************************************************/
3623 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3625 /***************************************************************************
3626 Check allowed stat state of a usershare file.
3627 Ensure we print out who is dicking with us so the admin can
3628 get their sorry ass fired.
3629 ***************************************************************************/
3631 static bool check_usershare_stat(const char *fname
,
3632 const SMB_STRUCT_STAT
*psbuf
)
3634 if (!S_ISREG(psbuf
->st_ex_mode
)) {
3635 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3636 "not a regular file\n",
3637 fname
, (unsigned int)psbuf
->st_ex_uid
));
3641 /* Ensure this doesn't have the other write bit set. */
3642 if (psbuf
->st_ex_mode
& S_IWOTH
) {
3643 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3644 "public write. Refusing to allow as a usershare file.\n",
3645 fname
, (unsigned int)psbuf
->st_ex_uid
));
3649 /* Should be 10k or less. */
3650 if (psbuf
->st_ex_size
> MAX_USERSHARE_FILE_SIZE
) {
3651 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3652 "too large (%u) to be a user share file.\n",
3653 fname
, (unsigned int)psbuf
->st_ex_uid
,
3654 (unsigned int)psbuf
->st_ex_size
));
3661 /***************************************************************************
3662 Parse the contents of a usershare file.
3663 ***************************************************************************/
3665 enum usershare_err
parse_usershare_file(TALLOC_CTX
*ctx
,
3666 SMB_STRUCT_STAT
*psbuf
,
3667 const char *servicename
,
3671 char **pp_sharepath
,
3673 char **pp_cp_servicename
,
3674 struct security_descriptor
**ppsd
,
3677 const char **prefixallowlist
= lp_usershare_prefix_allow_list();
3678 const char **prefixdenylist
= lp_usershare_prefix_deny_list();
3681 SMB_STRUCT_STAT sbuf
;
3682 char *sharepath
= NULL
;
3683 char *comment
= NULL
;
3685 *pp_sharepath
= NULL
;
3688 *pallow_guest
= false;
3691 return USERSHARE_MALFORMED_FILE
;
3694 if (strcmp(lines
[0], "#VERSION 1") == 0) {
3696 } else if (strcmp(lines
[0], "#VERSION 2") == 0) {
3699 return USERSHARE_MALFORMED_FILE
;
3702 return USERSHARE_BAD_VERSION
;
3705 if (strncmp(lines
[1], "path=", 5) != 0) {
3706 return USERSHARE_MALFORMED_PATH
;
3709 sharepath
= talloc_strdup(ctx
, &lines
[1][5]);
3711 return USERSHARE_POSIX_ERR
;
3713 trim_string(sharepath
, " ", " ");
3715 if (strncmp(lines
[2], "comment=", 8) != 0) {
3716 return USERSHARE_MALFORMED_COMMENT_DEF
;
3719 comment
= talloc_strdup(ctx
, &lines
[2][8]);
3721 return USERSHARE_POSIX_ERR
;
3723 trim_string(comment
, " ", " ");
3724 trim_char(comment
, '"', '"');
3726 if (strncmp(lines
[3], "usershare_acl=", 14) != 0) {
3727 return USERSHARE_MALFORMED_ACL_DEF
;
3730 if (!parse_usershare_acl(ctx
, &lines
[3][14], ppsd
)) {
3731 return USERSHARE_ACL_ERR
;
3735 if (strncmp(lines
[4], "guest_ok=", 9) != 0) {
3736 return USERSHARE_MALFORMED_ACL_DEF
;
3738 if (lines
[4][9] == 'y') {
3739 *pallow_guest
= true;
3742 /* Backwards compatible extension to file version #2. */
3744 if (strncmp(lines
[5], "sharename=", 10) != 0) {
3745 return USERSHARE_MALFORMED_SHARENAME_DEF
;
3747 if (!strequal(&lines
[5][10], servicename
)) {
3748 return USERSHARE_BAD_SHARENAME
;
3750 *pp_cp_servicename
= talloc_strdup(ctx
, &lines
[5][10]);
3751 if (!*pp_cp_servicename
) {
3752 return USERSHARE_POSIX_ERR
;
3757 if (*pp_cp_servicename
== NULL
) {
3758 *pp_cp_servicename
= talloc_strdup(ctx
, servicename
);
3759 if (!*pp_cp_servicename
) {
3760 return USERSHARE_POSIX_ERR
;
3764 if (snum
!= -1 && (strcmp(sharepath
, ServicePtrs
[snum
]->path
) == 0)) {
3765 /* Path didn't change, no checks needed. */
3766 *pp_sharepath
= sharepath
;
3767 *pp_comment
= comment
;
3768 return USERSHARE_OK
;
3771 /* The path *must* be absolute. */
3772 if (sharepath
[0] != '/') {
3773 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3774 servicename
, sharepath
));
3775 return USERSHARE_PATH_NOT_ABSOLUTE
;
3778 /* If there is a usershare prefix deny list ensure one of these paths
3779 doesn't match the start of the user given path. */
3780 if (prefixdenylist
) {
3782 for ( i
=0; prefixdenylist
[i
]; i
++ ) {
3783 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3784 servicename
, i
, prefixdenylist
[i
], sharepath
));
3785 if (memcmp( sharepath
, prefixdenylist
[i
], strlen(prefixdenylist
[i
])) == 0) {
3786 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3787 "usershare prefix deny list entries.\n",
3788 servicename
, sharepath
));
3789 return USERSHARE_PATH_IS_DENIED
;
3794 /* If there is a usershare prefix allow list ensure one of these paths
3795 does match the start of the user given path. */
3797 if (prefixallowlist
) {
3799 for ( i
=0; prefixallowlist
[i
]; i
++ ) {
3800 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3801 servicename
, i
, prefixallowlist
[i
], sharepath
));
3802 if (memcmp( sharepath
, prefixallowlist
[i
], strlen(prefixallowlist
[i
])) == 0) {
3806 if (prefixallowlist
[i
] == NULL
) {
3807 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3808 "usershare prefix allow list entries.\n",
3809 servicename
, sharepath
));
3810 return USERSHARE_PATH_NOT_ALLOWED
;
3814 /* Ensure this is pointing to a directory. */
3815 dp
= opendir(sharepath
);
3818 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3819 servicename
, sharepath
));
3820 return USERSHARE_PATH_NOT_DIRECTORY
;
3823 /* Ensure the owner of the usershare file has permission to share
3826 if (sys_stat(sharepath
, &sbuf
, false) == -1) {
3827 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3828 servicename
, sharepath
, strerror(errno
) ));
3830 return USERSHARE_POSIX_ERR
;
3835 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
3836 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3837 servicename
, sharepath
));
3838 return USERSHARE_PATH_NOT_DIRECTORY
;
3841 /* Check if sharing is restricted to owner-only. */
3842 /* psbuf is the stat of the usershare definition file,
3843 sbuf is the stat of the target directory to be shared. */
3845 if (lp_usershare_owner_only()) {
3846 /* root can share anything. */
3847 if ((psbuf
->st_ex_uid
!= 0) && (sbuf
.st_ex_uid
!= psbuf
->st_ex_uid
)) {
3848 return USERSHARE_PATH_NOT_ALLOWED
;
3852 *pp_sharepath
= sharepath
;
3853 *pp_comment
= comment
;
3854 return USERSHARE_OK
;
3857 /***************************************************************************
3858 Deal with a usershare file.
3861 -1 - Bad name, invalid contents.
3862 - service name already existed and not a usershare, problem
3863 with permissions to share directory etc.
3864 ***************************************************************************/
3866 static int process_usershare_file(const char *dir_name
, const char *file_name
, int snum_template
)
3868 SMB_STRUCT_STAT sbuf
;
3869 SMB_STRUCT_STAT lsbuf
;
3871 char *sharepath
= NULL
;
3872 char *comment
= NULL
;
3873 char *cp_service_name
= NULL
;
3874 char **lines
= NULL
;
3878 TALLOC_CTX
*ctx
= talloc_stackframe();
3879 struct security_descriptor
*psd
= NULL
;
3880 bool guest_ok
= false;
3881 char *canon_name
= NULL
;
3882 bool added_service
= false;
3885 /* Ensure share name doesn't contain invalid characters. */
3886 if (!validate_net_name(file_name
, INVALID_SHARENAME_CHARS
, strlen(file_name
))) {
3887 DEBUG(0,("process_usershare_file: share name %s contains "
3888 "invalid characters (any of %s)\n",
3889 file_name
, INVALID_SHARENAME_CHARS
));
3893 canon_name
= canonicalize_servicename(ctx
, file_name
);
3898 fname
= talloc_asprintf(ctx
, "%s/%s", dir_name
, file_name
);
3903 /* Minimize the race condition by doing an lstat before we
3904 open and fstat. Ensure this isn't a symlink link. */
3906 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
3907 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3908 fname
, strerror(errno
) ));
3912 /* This must be a regular file, not a symlink, directory or
3913 other strange filetype. */
3914 if (!check_usershare_stat(fname
, &lsbuf
)) {
3922 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
,
3927 if (NT_STATUS_IS_OK(status
) &&
3928 (data
.dptr
!= NULL
) &&
3929 (data
.dsize
== sizeof(iService
))) {
3930 memcpy(&iService
, data
.dptr
, sizeof(iService
));
3934 if (iService
!= -1 &&
3935 timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
3936 &lsbuf
.st_ex_mtime
) == 0) {
3937 /* Nothing changed - Mark valid and return. */
3938 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3940 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
3945 /* Try and open the file read only - no symlinks allowed. */
3947 fd
= open(fname
, O_RDONLY
|O_NOFOLLOW
, 0);
3949 fd
= open(fname
, O_RDONLY
, 0);
3953 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3954 fname
, strerror(errno
) ));
3958 /* Now fstat to be *SURE* it's a regular file. */
3959 if (sys_fstat(fd
, &sbuf
, false) != 0) {
3961 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3962 fname
, strerror(errno
) ));
3966 /* Is it the same dev/inode as was lstated ? */
3967 if (!check_same_stat(&lsbuf
, &sbuf
)) {
3969 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3970 "Symlink spoofing going on ?\n", fname
));
3974 /* This must be a regular file, not a symlink, directory or
3975 other strange filetype. */
3976 if (!check_usershare_stat(fname
, &sbuf
)) {
3981 lines
= fd_lines_load(fd
, &numlines
, MAX_USERSHARE_FILE_SIZE
, NULL
);
3984 if (lines
== NULL
) {
3985 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3986 fname
, (unsigned int)sbuf
.st_ex_uid
));
3990 if (parse_usershare_file(ctx
, &sbuf
, file_name
,
3991 iService
, lines
, numlines
, &sharepath
,
3992 &comment
, &cp_service_name
,
3993 &psd
, &guest_ok
) != USERSHARE_OK
) {
3997 /* Everything ok - add the service possibly using a template. */
3999 const struct loadparm_service
*sp
= &sDefault
;
4000 if (snum_template
!= -1) {
4001 sp
= ServicePtrs
[snum_template
];
4004 if ((iService
= add_a_service(sp
, cp_service_name
)) < 0) {
4005 DEBUG(0, ("process_usershare_file: Failed to add "
4006 "new service %s\n", cp_service_name
));
4010 added_service
= true;
4012 /* Read only is controlled by usershare ACL below. */
4013 ServicePtrs
[iService
]->read_only
= false;
4016 /* Write the ACL of the new/modified share. */
4017 if (!set_share_security(canon_name
, psd
)) {
4018 DEBUG(0, ("process_usershare_file: Failed to set share "
4019 "security for user share %s\n",
4024 /* If from a template it may be marked invalid. */
4025 ServicePtrs
[iService
]->valid
= true;
4027 /* Set the service as a valid usershare. */
4028 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
4030 /* Set guest access. */
4031 if (lp_usershare_allow_guests()) {
4032 ServicePtrs
[iService
]->guest_ok
= guest_ok
;
4035 /* And note when it was loaded. */
4036 ServicePtrs
[iService
]->usershare_last_mod
= sbuf
.st_ex_mtime
;
4037 string_set(ServicePtrs
[iService
], &ServicePtrs
[iService
]->path
, sharepath
);
4038 string_set(ServicePtrs
[iService
], &ServicePtrs
[iService
]->comment
, comment
);
4044 if (ret
== -1 && iService
!= -1 && added_service
) {
4045 lp_remove_service(iService
);
4053 /***************************************************************************
4054 Checks if a usershare entry has been modified since last load.
4055 ***************************************************************************/
4057 static bool usershare_exists(int iService
, struct timespec
*last_mod
)
4059 SMB_STRUCT_STAT lsbuf
;
4060 const char *usersharepath
= Globals
.usershare_path
;
4063 fname
= talloc_asprintf(talloc_tos(),
4066 ServicePtrs
[iService
]->szService
);
4067 if (fname
== NULL
) {
4071 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
4076 if (!S_ISREG(lsbuf
.st_ex_mode
)) {
4082 *last_mod
= lsbuf
.st_ex_mtime
;
4086 /***************************************************************************
4087 Load a usershare service by name. Returns a valid servicenumber or -1.
4088 ***************************************************************************/
4090 int load_usershare_service(const char *servicename
)
4092 SMB_STRUCT_STAT sbuf
;
4093 const char *usersharepath
= Globals
.usershare_path
;
4094 int max_user_shares
= Globals
.usershare_max_shares
;
4095 int snum_template
= -1;
4097 if (*usersharepath
== 0 || max_user_shares
== 0) {
4101 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
4102 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4103 usersharepath
, strerror(errno
) ));
4107 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
4108 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4114 * This directory must be owned by root, and have the 't' bit set.
4115 * It also must not be writable by "other".
4119 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4121 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4123 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4124 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4129 /* Ensure the template share exists if it's set. */
4130 if (Globals
.usershare_template_share
[0]) {
4131 /* We can't use lp_servicenumber here as we are recommending that
4132 template shares have -valid=false set. */
4133 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
4134 if (ServicePtrs
[snum_template
]->szService
&&
4135 strequal(ServicePtrs
[snum_template
]->szService
,
4136 Globals
.usershare_template_share
)) {
4141 if (snum_template
== -1) {
4142 DEBUG(0,("load_usershare_service: usershare template share %s "
4143 "does not exist.\n",
4144 Globals
.usershare_template_share
));
4149 return process_usershare_file(usersharepath
, servicename
, snum_template
);
4152 /***************************************************************************
4153 Load all user defined shares from the user share directory.
4154 We only do this if we're enumerating the share list.
4155 This is the function that can delete usershares that have
4157 ***************************************************************************/
4159 int load_usershare_shares(struct smbd_server_connection
*sconn
,
4160 bool (*snumused
) (struct smbd_server_connection
*, int))
4163 SMB_STRUCT_STAT sbuf
;
4165 int num_usershares
= 0;
4166 int max_user_shares
= Globals
.usershare_max_shares
;
4167 unsigned int num_dir_entries
, num_bad_dir_entries
, num_tmp_dir_entries
;
4168 unsigned int allowed_bad_entries
= ((2*max_user_shares
)/10);
4169 unsigned int allowed_tmp_entries
= ((2*max_user_shares
)/10);
4171 int snum_template
= -1;
4172 const char *usersharepath
= Globals
.usershare_path
;
4173 int ret
= lp_numservices();
4174 TALLOC_CTX
*tmp_ctx
;
4176 if (max_user_shares
== 0 || *usersharepath
== '\0') {
4177 return lp_numservices();
4180 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
4181 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4182 usersharepath
, strerror(errno
) ));
4187 * This directory must be owned by root, and have the 't' bit set.
4188 * It also must not be writable by "other".
4192 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4194 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4196 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4197 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4202 /* Ensure the template share exists if it's set. */
4203 if (Globals
.usershare_template_share
[0]) {
4204 /* We can't use lp_servicenumber here as we are recommending that
4205 template shares have -valid=false set. */
4206 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
4207 if (ServicePtrs
[snum_template
]->szService
&&
4208 strequal(ServicePtrs
[snum_template
]->szService
,
4209 Globals
.usershare_template_share
)) {
4214 if (snum_template
== -1) {
4215 DEBUG(0,("load_usershare_shares: usershare template share %s "
4216 "does not exist.\n",
4217 Globals
.usershare_template_share
));
4222 /* Mark all existing usershares as pending delete. */
4223 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4224 if (VALID(iService
) && ServicePtrs
[iService
]->usershare
) {
4225 ServicePtrs
[iService
]->usershare
= USERSHARE_PENDING_DELETE
;
4229 dp
= opendir(usersharepath
);
4231 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4232 usersharepath
, strerror(errno
) ));
4236 for (num_dir_entries
= 0, num_bad_dir_entries
= 0, num_tmp_dir_entries
= 0;
4238 num_dir_entries
++ ) {
4240 const char *n
= de
->d_name
;
4242 /* Ignore . and .. */
4244 if ((n
[1] == '\0') || (n
[1] == '.' && n
[2] == '\0')) {
4250 /* Temporary file used when creating a share. */
4251 num_tmp_dir_entries
++;
4254 /* Allow 20% tmp entries. */
4255 if (num_tmp_dir_entries
> allowed_tmp_entries
) {
4256 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4257 "in directory %s\n",
4258 num_tmp_dir_entries
, usersharepath
));
4262 r
= process_usershare_file(usersharepath
, n
, snum_template
);
4264 /* Update the services count. */
4266 if (num_usershares
>= max_user_shares
) {
4267 DEBUG(0,("load_usershare_shares: max user shares reached "
4268 "on file %s in directory %s\n",
4269 n
, usersharepath
));
4272 } else if (r
== -1) {
4273 num_bad_dir_entries
++;
4276 /* Allow 20% bad entries. */
4277 if (num_bad_dir_entries
> allowed_bad_entries
) {
4278 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4279 "in directory %s\n",
4280 num_bad_dir_entries
, usersharepath
));
4284 /* Allow 20% bad entries. */
4285 if (num_dir_entries
> max_user_shares
+ allowed_bad_entries
) {
4286 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4287 "in directory %s\n",
4288 num_dir_entries
, usersharepath
));
4295 /* Sweep through and delete any non-refreshed usershares that are
4296 not currently in use. */
4297 tmp_ctx
= talloc_stackframe();
4298 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4299 if (VALID(iService
) && (ServicePtrs
[iService
]->usershare
== USERSHARE_PENDING_DELETE
)) {
4302 if (snumused
&& snumused(sconn
, iService
)) {
4306 servname
= lp_servicename(tmp_ctx
, iService
);
4308 /* Remove from the share ACL db. */
4309 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4311 delete_share_security(servname
);
4312 free_service_byindex(iService
);
4315 talloc_free(tmp_ctx
);
4317 return lp_numservices();
4320 /********************************************************
4321 Destroy global resources allocated in this file
4322 ********************************************************/
4324 void gfree_loadparm(void)
4330 /* Free resources allocated to services */
4332 for ( i
= 0; i
< iNumServices
; i
++ ) {
4334 free_service_byindex(i
);
4338 TALLOC_FREE( ServicePtrs
);
4341 /* Now release all resources allocated to global
4342 parameters and the default service */
4344 free_global_parameters();
4348 /***************************************************************************
4349 Allow client apps to specify that they are a client
4350 ***************************************************************************/
4351 static void lp_set_in_client(bool b
)
4357 /***************************************************************************
4358 Determine if we're running in a client app
4359 ***************************************************************************/
4360 static bool lp_is_in_client(void)
4365 /***************************************************************************
4366 Load the services array from the services file. Return true on success,
4368 ***************************************************************************/
4370 static bool lp_load_ex(const char *pszFname
,
4374 bool initialize_globals
,
4375 bool allow_include_registry
,
4376 bool load_all_shares
)
4383 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4385 bInGlobalSection
= true;
4386 bGlobalOnly
= global_only
;
4387 bAllowIncludeRegistry
= allow_include_registry
;
4389 init_globals(initialize_globals
);
4393 if (save_defaults
) {
4398 if (!initialize_globals
) {
4399 free_param_opts(&Globals
.param_opt
);
4400 apply_lp_set_cmdline();
4403 lp_do_parameter(-1, "idmap config * : backend", Globals
.szIdmapBackend
);
4405 /* We get sections first, so have to start 'behind' to make up */
4408 if (lp_config_backend_is_file()) {
4409 n2
= talloc_sub_basic(talloc_tos(), get_current_username(),
4410 current_user_info
.domain
,
4413 smb_panic("lp_load_ex: out of memory");
4416 add_to_file_list(pszFname
, n2
);
4418 bRetval
= pm_process(n2
, do_section
, do_parameter
, NULL
);
4421 /* finish up the last section */
4422 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval
)));
4424 if (iServiceIndex
>= 0) {
4425 bRetval
= service_ok(iServiceIndex
);
4429 if (lp_config_backend_is_registry()) {
4430 /* config backend changed to registry in config file */
4432 * We need to use this extra global variable here to
4433 * survive restart: init_globals uses this as a default
4434 * for config_backend. Otherwise, init_globals would
4435 * send us into an endless loop here.
4437 config_backend
= CONFIG_BACKEND_REGISTRY
;
4439 DEBUG(1, ("lp_load_ex: changing to config backend "
4442 lp_kill_all_services();
4443 return lp_load_ex(pszFname
, global_only
, save_defaults
,
4444 add_ipc
, initialize_globals
,
4445 allow_include_registry
,
4448 } else if (lp_config_backend_is_registry()) {
4449 bRetval
= process_registry_globals();
4451 DEBUG(0, ("Illegal config backend given: %d\n",
4452 lp_config_backend()));
4456 if (bRetval
&& lp_registry_shares()) {
4457 if (load_all_shares
) {
4458 bRetval
= process_registry_shares();
4460 bRetval
= reload_registry_shares();
4465 char *serv
= lp_auto_services(talloc_tos());
4466 lp_add_auto_services(serv
);
4471 /* When 'restrict anonymous = 2' guest connections to ipc$
4473 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4474 if ( lp_enable_asu_support() ) {
4475 lp_add_ipc("ADMIN$", false);
4479 set_allowed_client_auth();
4481 if (lp_security() == SEC_ADS
&& strchr(lp_password_server(), ':')) {
4482 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4483 lp_password_server()));
4488 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4489 /* if we_are_a_wins_server is true and we are in the client */
4490 if (lp_is_in_client() && Globals
.we_are_a_wins_server
) {
4491 lp_do_parameter(GLOBAL_SECTION_SNUM
, "wins server", "127.0.0.1");
4496 fault_configure(smb_panic_s3
);
4499 * We run this check once the whole smb.conf is parsed, to
4500 * force some settings for the standard way a AD DC is
4501 * operated. We may changed these as our code evolves, which
4502 * is why we force these settings.
4504 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
4505 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4507 lp_do_parameter(-1, "rpc_server:default", "external");
4508 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4509 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4510 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4511 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4512 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4513 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4514 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4515 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4518 bAllowIncludeRegistry
= true;
4523 bool lp_load(const char *pszFname
,
4527 bool initialize_globals
)
4529 return lp_load_ex(pszFname
,
4534 true, /* allow_include_registry */
4535 false); /* load_all_shares*/
4538 bool lp_load_initial_only(const char *pszFname
)
4540 return lp_load_ex(pszFname
,
4541 true, /* global only */
4542 false, /* save_defaults */
4543 false, /* add_ipc */
4544 true, /* initialize_globals */
4545 false, /* allow_include_registry */
4546 false); /* load_all_shares*/
4550 * most common lp_load wrapper, loading only the globals
4552 bool lp_load_global(const char *file_name
)
4554 return lp_load_ex(file_name
,
4555 true, /* global_only */
4556 false, /* save_defaults */
4557 false, /* add_ipc */
4558 true, /* initialize_globals */
4559 true, /* allow_include_registry */
4560 false); /* load_all_shares*/
4564 * lp_load wrapper, especially for clients
4566 bool lp_load_client(const char *file_name
)
4568 lp_set_in_client(true);
4570 return lp_load_global(file_name
);
4574 * lp_load wrapper, loading only globals, but intended
4575 * for subsequent calls, not reinitializing the globals
4578 bool lp_load_global_no_reinit(const char *file_name
)
4580 return lp_load_ex(file_name
,
4581 true, /* global_only */
4582 false, /* save_defaults */
4583 false, /* add_ipc */
4584 false, /* initialize_globals */
4585 true, /* allow_include_registry */
4586 false); /* load_all_shares*/
4590 * lp_load wrapper, especially for clients, no reinitialization
4592 bool lp_load_client_no_reinit(const char *file_name
)
4594 lp_set_in_client(true);
4596 return lp_load_global_no_reinit(file_name
);
4599 bool lp_load_with_registry_shares(const char *pszFname
,
4603 bool initialize_globals
)
4605 return lp_load_ex(pszFname
,
4610 true, /* allow_include_registry */
4611 true); /* load_all_shares*/
4614 /***************************************************************************
4615 Return the max number of services.
4616 ***************************************************************************/
4618 int lp_numservices(void)
4620 return (iNumServices
);
4623 /***************************************************************************
4624 Display the contents of the services array in human-readable form.
4625 ***************************************************************************/
4627 void lp_dump(FILE *f
, bool show_defaults
, int maxtoprint
)
4632 defaults_saved
= false;
4636 dump_a_service(&sDefault
, f
);
4638 for (iService
= 0; iService
< maxtoprint
; iService
++) {
4640 lp_dump_one(f
, show_defaults
, iService
);
4644 /***************************************************************************
4645 Display the contents of one service in human-readable form.
4646 ***************************************************************************/
4648 void lp_dump_one(FILE * f
, bool show_defaults
, int snum
)
4651 if (ServicePtrs
[snum
]->szService
[0] == '\0')
4653 dump_a_service(ServicePtrs
[snum
], f
);
4657 /***************************************************************************
4658 Return the number of the service with the given name, or -1 if it doesn't
4659 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4660 getservicebyname()! This works ONLY if all services have been loaded, and
4661 does not copy the found service.
4662 ***************************************************************************/
4664 int lp_servicenumber(const char *pszServiceName
)
4667 fstring serviceName
;
4669 if (!pszServiceName
) {
4670 return GLOBAL_SECTION_SNUM
;
4673 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4674 if (VALID(iService
) && ServicePtrs
[iService
]->szService
) {
4676 * The substitution here is used to support %U is
4679 fstrcpy(serviceName
, ServicePtrs
[iService
]->szService
);
4680 standard_sub_basic(get_current_username(),
4681 current_user_info
.domain
,
4682 serviceName
,sizeof(serviceName
));
4683 if (strequal(serviceName
, pszServiceName
)) {
4689 if (iService
>= 0 && ServicePtrs
[iService
]->usershare
== USERSHARE_VALID
) {
4690 struct timespec last_mod
;
4692 if (!usershare_exists(iService
, &last_mod
)) {
4693 /* Remove the share security tdb entry for it. */
4694 delete_share_security(lp_servicename(talloc_tos(), iService
));
4695 /* Remove it from the array. */
4696 free_service_byindex(iService
);
4697 /* Doesn't exist anymore. */
4698 return GLOBAL_SECTION_SNUM
;
4701 /* Has it been modified ? If so delete and reload. */
4702 if (timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
4704 /* Remove it from the array. */
4705 free_service_byindex(iService
);
4706 /* and now reload it. */
4707 iService
= load_usershare_service(pszServiceName
);
4712 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName
));
4713 return GLOBAL_SECTION_SNUM
;
4719 /*******************************************************************
4720 A useful volume label function.
4721 ********************************************************************/
4723 const char *volume_label(TALLOC_CTX
*ctx
, int snum
)
4726 const char *label
= lp_volume(ctx
, snum
);
4728 label
= lp_servicename(ctx
, snum
);
4731 /* This returns a 33 byte guarenteed null terminated string. */
4732 ret
= talloc_strndup(ctx
, label
, 32);
4739 /*******************************************************************
4740 Get the default server type we will announce as via nmbd.
4741 ********************************************************************/
4743 int lp_default_server_announce(void)
4745 int default_server_announce
= 0;
4746 default_server_announce
|= SV_TYPE_WORKSTATION
;
4747 default_server_announce
|= SV_TYPE_SERVER
;
4748 default_server_announce
|= SV_TYPE_SERVER_UNIX
;
4750 /* note that the flag should be set only if we have a
4751 printer service but nmbd doesn't actually load the
4752 services so we can't tell --jerry */
4754 default_server_announce
|= SV_TYPE_PRINTQ_SERVER
;
4756 default_server_announce
|= SV_TYPE_SERVER_NT
;
4757 default_server_announce
|= SV_TYPE_NT
;
4759 switch (lp_server_role()) {
4760 case ROLE_DOMAIN_MEMBER
:
4761 default_server_announce
|= SV_TYPE_DOMAIN_MEMBER
;
4763 case ROLE_DOMAIN_PDC
:
4764 default_server_announce
|= SV_TYPE_DOMAIN_CTRL
;
4766 case ROLE_DOMAIN_BDC
:
4767 default_server_announce
|= SV_TYPE_DOMAIN_BAKCTRL
;
4769 case ROLE_STANDALONE
:
4773 if (lp_time_server())
4774 default_server_announce
|= SV_TYPE_TIME_SOURCE
;
4776 if (lp_host_msdfs())
4777 default_server_announce
|= SV_TYPE_DFS_SERVER
;
4779 return default_server_announce
;
4782 /***********************************************************
4783 If we are PDC then prefer us as DMB
4784 ************************************************************/
4786 bool lp_domain_master(void)
4788 if (Globals
._domain_master
== Auto
)
4789 return (lp_server_role() == ROLE_DOMAIN_PDC
);
4791 return (bool)Globals
._domain_master
;
4794 /***********************************************************
4795 If we are PDC then prefer us as DMB
4796 ************************************************************/
4798 static bool lp_domain_master_true_or_auto(void)
4800 if (Globals
._domain_master
) /* auto or yes */
4806 /***********************************************************
4807 If we are DMB then prefer us as LMB
4808 ************************************************************/
4810 bool lp_preferred_master(void)
4812 if (Globals
.iPreferredMaster
== Auto
)
4813 return (lp_local_master() && lp_domain_master());
4815 return (bool)Globals
.iPreferredMaster
;
4818 /*******************************************************************
4820 ********************************************************************/
4822 void lp_remove_service(int snum
)
4824 ServicePtrs
[snum
]->valid
= false;
4827 /*******************************************************************
4829 ********************************************************************/
4831 void lp_copy_service(int snum
, const char *new_name
)
4833 do_section(new_name
, NULL
);
4835 snum
= lp_servicenumber(new_name
);
4837 char *name
= lp_servicename(talloc_tos(), snum
);
4838 lp_do_parameter(snum
, "copy", name
);
4843 const char *lp_printername(TALLOC_CTX
*ctx
, int snum
)
4845 const char *ret
= lp__printername(ctx
, snum
);
4846 if (ret
== NULL
|| *ret
== '\0') {
4847 ret
= lp_const_servicename(snum
);
4854 /***********************************************************
4855 Allow daemons such as winbindd to fix their logfile name.
4856 ************************************************************/
4858 void lp_set_logfile(const char *name
)
4860 string_set(Globals
.ctx
, &Globals
.logfile
, name
);
4861 debug_set_logfile(name
);
4864 /*******************************************************************
4865 Return the max print jobs per queue.
4866 ********************************************************************/
4868 int lp_maxprintjobs(int snum
)
4870 int maxjobs
= LP_SNUM_OK(snum
) ? ServicePtrs
[snum
]->iMaxPrintJobs
: sDefault
.iMaxPrintJobs
;
4871 if (maxjobs
<= 0 || maxjobs
>= PRINT_MAX_JOBID
)
4872 maxjobs
= PRINT_MAX_JOBID
- 1;
4877 const char *lp_printcapname(void)
4879 if ((Globals
.szPrintcapname
!= NULL
) &&
4880 (Globals
.szPrintcapname
[0] != '\0'))
4881 return Globals
.szPrintcapname
;
4883 if (sDefault
.printing
== PRINT_CUPS
) {
4887 if (sDefault
.printing
== PRINT_BSD
)
4888 return "/etc/printcap";
4890 return PRINTCAP_NAME
;
4893 static uint32 spoolss_state
;
4895 bool lp_disable_spoolss( void )
4897 if ( spoolss_state
== SVCCTL_STATE_UNKNOWN
)
4898 spoolss_state
= lp__disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
4900 return spoolss_state
== SVCCTL_STOPPED
? true : false;
4903 void lp_set_spoolss_state( uint32 state
)
4905 SMB_ASSERT( (state
== SVCCTL_STOPPED
) || (state
== SVCCTL_RUNNING
) );
4907 spoolss_state
= state
;
4910 uint32
lp_get_spoolss_state( void )
4912 return lp_disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
4915 /*******************************************************************
4916 Ensure we don't use sendfile if server smb signing is active.
4917 ********************************************************************/
4919 bool lp_use_sendfile(int snum
, struct smb_signing_state
*signing_state
)
4921 bool sign_active
= false;
4923 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4924 if (get_Protocol() < PROTOCOL_NT1
) {
4927 if (signing_state
) {
4928 sign_active
= smb_signing_is_active(signing_state
);
4930 return (lp__use_sendfile(snum
) &&
4931 (get_remote_arch() != RA_WIN95
) &&
4935 /*******************************************************************
4936 Turn off sendfile if we find the underlying OS doesn't support it.
4937 ********************************************************************/
4939 void set_use_sendfile(int snum
, bool val
)
4941 if (LP_SNUM_OK(snum
))
4942 ServicePtrs
[snum
]->_use_sendfile
= val
;
4944 sDefault
._use_sendfile
= val
;
4947 /*******************************************************************
4948 Turn off storing DOS attributes if this share doesn't support it.
4949 ********************************************************************/
4951 void set_store_dos_attributes(int snum
, bool val
)
4953 if (!LP_SNUM_OK(snum
))
4955 ServicePtrs
[(snum
)]->store_dos_attributes
= val
;
4958 void lp_set_mangling_method(const char *new_method
)
4960 string_set(Globals
.ctx
, &Globals
.mangling_method
, new_method
);
4963 /*******************************************************************
4964 Global state for POSIX pathname processing.
4965 ********************************************************************/
4967 static bool posix_pathnames
;
4969 bool lp_posix_pathnames(void)
4971 return posix_pathnames
;
4974 /*******************************************************************
4975 Change everything needed to ensure POSIX pathname processing (currently
4977 ********************************************************************/
4979 void lp_set_posix_pathnames(void)
4981 posix_pathnames
= true;
4984 /*******************************************************************
4985 Global state for POSIX lock processing - CIFS unix extensions.
4986 ********************************************************************/
4988 bool posix_default_lock_was_set
;
4989 static enum brl_flavour posix_cifsx_locktype
; /* By default 0 == WINDOWS_LOCK */
4991 enum brl_flavour
lp_posix_cifsu_locktype(files_struct
*fsp
)
4993 if (posix_default_lock_was_set
) {
4994 return posix_cifsx_locktype
;
4996 return fsp
->posix_open
? POSIX_LOCK
: WINDOWS_LOCK
;
5000 /*******************************************************************
5001 ********************************************************************/
5003 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val
)
5005 posix_default_lock_was_set
= true;
5006 posix_cifsx_locktype
= val
;
5009 int lp_min_receive_file_size(void)
5011 if (Globals
.iminreceivefile
< 0) {
5014 return Globals
.iminreceivefile
;
5017 /*******************************************************************
5018 Safe wide links checks.
5019 This helper function always verify the validity of wide links,
5020 even after a configuration file reload.
5021 ********************************************************************/
5023 static bool lp_widelinks_internal(int snum
)
5025 return (bool)(LP_SNUM_OK(snum
)? ServicePtrs
[(snum
)]->bWidelinks
:
5026 sDefault
.bWidelinks
);
5029 void widelinks_warning(int snum
)
5031 if (lp_allow_insecure_wide_links()) {
5035 if (lp_unix_extensions() && lp_widelinks_internal(snum
)) {
5036 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
5037 "These parameters are incompatible. "
5038 "Wide links will be disabled for this share.\n",
5039 lp_servicename(talloc_tos(), snum
) ));
5043 bool lp_widelinks(int snum
)
5045 /* wide links is always incompatible with unix extensions */
5046 if (lp_unix_extensions()) {
5048 * Unless we have "allow insecure widelinks"
5051 if (!lp_allow_insecure_wide_links()) {
5056 return lp_widelinks_internal(snum
);
5059 int lp_server_role(void)
5061 return lp_find_server_role(lp__server_role(),
5063 lp__domain_logons(),
5064 lp_domain_master_true_or_auto());
5067 int lp_security(void)
5069 return lp_find_security(lp__server_role(),
5073 struct loadparm_global
* get_globals(void)