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"
72 #include "librpc/gen_ndr/nbt.h"
74 #ifdef HAVE_SYS_SYSCTL_H
75 #include <sys/sysctl.h>
80 extern userdom_struct current_user_info
;
82 /* the special value for the include parameter
83 * to be interpreted not as a file name but to
84 * trigger loading of the global smb.conf options
86 #ifndef INCLUDE_REGISTRY_NAME
87 #define INCLUDE_REGISTRY_NAME "registry"
90 static bool in_client
= false; /* Not in the client by default */
91 static struct smbconf_csn conf_last_csn
;
93 static int config_backend
= CONFIG_BACKEND_FILE
;
95 /* some helpful bits */
96 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
97 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
99 #define USERSHARE_VALID 1
100 #define USERSHARE_PENDING_DELETE 2
102 static bool defaults_saved
= false;
104 #include "lib/param/param_global.h"
106 static struct loadparm_global Globals
;
108 /* This is a default service used to prime a services structure */
109 static struct loadparm_service sDefault
=
114 .usershare_last_mod
= {0, 0},
118 .invalid_users
= NULL
,
125 .root_preexec
= NULL
,
126 .root_postexec
= NULL
,
127 .cups_options
= NULL
,
128 .print_command
= NULL
,
130 .lprm_command
= NULL
,
131 .lppause_command
= NULL
,
132 .lpresume_command
= NULL
,
133 .queuepause_command
= NULL
,
134 .queueresume_command
= NULL
,
135 ._printername
= NULL
,
136 .printjob_username
= NULL
,
137 .dont_descend
= NULL
,
140 .magic_script
= NULL
,
141 .magic_output
= NULL
,
144 .veto_oplock_files
= NULL
,
154 .aio_write_behind
= NULL
,
155 .dfree_command
= NULL
,
156 .min_print_space
= 0,
157 .max_print_jobs
= 1000,
158 .max_reported_print_jobs
= 0,
159 .write_cache_size
= 0,
161 .force_create_mode
= 0,
162 .directory_mask
= 0755,
163 .force_directory_mode
= 0,
164 .max_connections
= 0,
165 .default_case
= CASE_LOWER
,
166 .printing
= DEFAULT_PRINTING
,
167 .oplock_contention_limit
= 2,
170 .dfree_cache_time
= 0,
171 .preexec_close
= false,
172 .root_preexec_close
= false,
173 .case_sensitive
= Auto
,
174 .preserve_case
= true,
175 .short_preserve_case
= true,
176 .hide_dot_files
= true,
177 .hide_special_files
= false,
178 .hide_unreadable
= false,
179 .hide_unwriteable_files
= false,
181 .access_based_share_enum
= false,
186 .administrative_share
= false,
189 .print_notify_backchannel
= false,
193 .store_dos_attributes
= false,
194 .dmapi_support
= false,
196 .strict_locking
= Auto
,
197 .posix_locking
= true,
199 .kernel_oplocks
= false,
200 .level2_oplocks
= true,
202 .mangled_names
= true,
204 .follow_symlinks
= true,
205 .sync_always
= false,
206 .strict_allocate
= false,
207 .strict_rename
= false,
208 .strict_sync
= false,
209 .mangling_char
= '~',
211 .delete_readonly
= false,
212 .fake_oplocks
= false,
213 .delete_veto_files
= false,
214 .dos_filemode
= false,
215 .dos_filetimes
= true,
216 .dos_filetime_resolution
= false,
217 .fake_directory_create_times
= false,
218 .blocking_locks
= true,
219 .inherit_permissions
= false,
220 .inherit_acls
= false,
221 .inherit_owner
= false,
223 .msdfs_shuffle_referrals
= 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 .allocation_roundup_size
= SMB_ROUNDUP_ALLOCATION_SIZE
,
241 .map_readonly
= MAP_READONLY_YES
,
242 .directory_name_cache_size
= 100,
243 .smb_encrypt
= SMB_SIGNING_DEFAULT
,
244 .kernel_share_modes
= true,
245 .durable_handles
= true,
250 /* local variables */
251 static struct loadparm_service
**ServicePtrs
= NULL
;
252 static int iNumServices
= 0;
253 static int iServiceIndex
= 0;
254 static struct db_context
*ServiceHash
;
255 static bool bInGlobalSection
= true;
256 static bool bGlobalOnly
= false;
257 static struct file_lists
*file_lists
= NULL
;
258 static unsigned int *flags_list
= NULL
;
260 static void set_allowed_client_auth(void);
262 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
);
263 static void free_param_opts(struct parmlist_entry
**popts
);
265 /* this is used to prevent lots of mallocs of size 1 */
266 static const char null_string
[] = "";
272 static void string_free(char **s
)
276 if (*s
== null_string
)
282 Set a string value, deallocating any existing space, and allocing the space
286 static bool string_set(TALLOC_CTX
*mem_ctx
, char **dest
,const char *src
)
294 (*dest
) = talloc_strdup(mem_ctx
, src
);
295 if ((*dest
) == NULL
) {
296 DEBUG(0,("Out of memory in string_init\n"));
304 * Function to return the default value for the maximum number of open
305 * file descriptors permitted. This function tries to consult the
306 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
307 * the smaller of those.
309 static int max_open_files(void)
311 int sysctl_max
= MAX_OPEN_FILES
;
312 int rlimit_max
= MAX_OPEN_FILES
;
314 #ifdef HAVE_SYSCTLBYNAME
316 size_t size
= sizeof(sysctl_max
);
317 sysctlbyname("kern.maxfilesperproc", &sysctl_max
, &size
, NULL
,
322 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
328 if (getrlimit(RLIMIT_NOFILE
, &rl
) == 0)
329 rlimit_max
= rl
.rlim_cur
;
331 #if defined(RLIM_INFINITY)
332 if(rl
.rlim_cur
== RLIM_INFINITY
)
333 rlimit_max
= MAX_OPEN_FILES
;
338 if (sysctl_max
< MIN_OPEN_FILES_WINDOWS
) {
339 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
340 "minimum Windows limit (%d)\n",
342 MIN_OPEN_FILES_WINDOWS
));
343 sysctl_max
= MIN_OPEN_FILES_WINDOWS
;
346 if (rlimit_max
< MIN_OPEN_FILES_WINDOWS
) {
347 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
348 "minimum Windows limit (%d)\n",
350 MIN_OPEN_FILES_WINDOWS
));
351 rlimit_max
= MIN_OPEN_FILES_WINDOWS
;
354 return MIN(sysctl_max
, rlimit_max
);
358 * Common part of freeing allocated data for one parameter.
360 static void free_one_parameter_common(void *parm_ptr
,
361 struct parm_struct parm
)
363 if ((parm
.type
== P_STRING
) ||
364 (parm
.type
== P_USTRING
))
366 string_free((char**)parm_ptr
);
367 } else if (parm
.type
== P_LIST
|| parm
.type
== P_CMDLIST
) {
368 TALLOC_FREE(*((char***)parm_ptr
));
373 * Free the allocated data for one parameter for a share
374 * given as a service struct.
376 static void free_one_parameter(struct loadparm_service
*service
,
377 struct parm_struct parm
)
381 if (parm
.p_class
!= P_LOCAL
) {
385 parm_ptr
= lp_parm_ptr(service
, &parm
);
387 free_one_parameter_common(parm_ptr
, parm
);
391 * Free the allocated parameter data of a share given
392 * as a service struct.
394 static void free_parameters(struct loadparm_service
*service
)
398 for (i
=0; parm_table
[i
].label
; i
++) {
399 free_one_parameter(service
, parm_table
[i
]);
404 * Free the allocated data for one parameter for a given share
405 * specified by an snum.
407 static void free_one_parameter_by_snum(int snum
, struct parm_struct parm
)
412 parm_ptr
= lp_parm_ptr(NULL
, &parm
);
413 } else if (parm
.p_class
!= P_LOCAL
) {
416 parm_ptr
= lp_parm_ptr(ServicePtrs
[snum
], &parm
);
419 free_one_parameter_common(parm_ptr
, parm
);
423 * Free the allocated parameter data for a share specified
426 static void free_parameters_by_snum(int snum
)
430 for (i
=0; parm_table
[i
].label
; i
++) {
431 free_one_parameter_by_snum(snum
, parm_table
[i
]);
436 * Free the allocated global parameters.
438 static void free_global_parameters(void)
440 free_param_opts(&Globals
.param_opt
);
441 free_parameters_by_snum(GLOBAL_SECTION_SNUM
);
442 TALLOC_FREE(Globals
.ctx
);
445 struct lp_stored_option
{
446 struct lp_stored_option
*prev
, *next
;
451 static struct lp_stored_option
*stored_options
;
454 save options set by lp_set_cmdline() into a list. This list is
455 re-applied when we do a globals reset, so that cmdline set options
456 are sticky across reloads of smb.conf
458 bool store_lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
460 struct lp_stored_option
*entry
, *entry_next
;
461 for (entry
= stored_options
; entry
!= NULL
; entry
= entry_next
) {
462 entry_next
= entry
->next
;
463 if (strcmp(pszParmName
, entry
->label
) == 0) {
464 DLIST_REMOVE(stored_options
, entry
);
470 entry
= talloc(NULL
, struct lp_stored_option
);
475 entry
->label
= talloc_strdup(entry
, pszParmName
);
481 entry
->value
= talloc_strdup(entry
, pszParmValue
);
487 DLIST_ADD_END(stored_options
, entry
, struct lp_stored_option
);
492 static bool apply_lp_set_cmdline(void)
494 struct lp_stored_option
*entry
= NULL
;
495 for (entry
= stored_options
; entry
!= NULL
; entry
= entry
->next
) {
496 if (!lp_set_cmdline_helper(entry
->label
, entry
->value
)) {
497 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
498 entry
->label
, entry
->value
));
505 /***************************************************************************
506 Initialise the global parameter structure.
507 ***************************************************************************/
509 static void init_globals(struct loadparm_context
*lp_ctx
, bool reinit_globals
)
511 static bool done_init
= false;
515 /* If requested to initialize only once and we've already done it... */
516 if (!reinit_globals
&& done_init
) {
517 /* ... then we have nothing more to do */
522 /* The logfile can be set before this is invoked. Free it if so. */
523 if (Globals
.logfile
!= NULL
) {
524 string_free(&Globals
.logfile
);
525 Globals
.logfile
= NULL
;
529 free_global_parameters();
532 /* This memset and the free_global_parameters() above will
533 * wipe out smb.conf options set with lp_set_cmdline(). The
534 * apply_lp_set_cmdline() call puts these values back in the
535 * table once the defaults are set */
536 ZERO_STRUCT(Globals
);
538 Globals
.ctx
= talloc_pooled_object(NULL
, char, 272, 2048);
540 /* Initialize the flags list if necessary */
541 if (flags_list
== NULL
) {
545 for (i
= 0; parm_table
[i
].label
; i
++) {
546 if ((parm_table
[i
].type
== P_STRING
||
547 parm_table
[i
].type
== P_USTRING
))
549 string_set(Globals
.ctx
, (char **)lp_parm_ptr(NULL
, &parm_table
[i
]), "");
554 string_set(Globals
.ctx
, &sDefault
.fstype
, FSTYPE_STRING
);
555 string_set(Globals
.ctx
, &sDefault
.printjob_username
, "%U");
557 init_printer_values(lp_ctx
, Globals
.ctx
, &sDefault
);
559 sDefault
.ntvfs_handler
= str_list_make_v3_const(NULL
, "unixuid default", NULL
);
561 DEBUG(3, ("Initialising global parameters\n"));
563 /* Must manually force to upper case here, as this does not go via the handler */
564 string_set(Globals
.ctx
, &Globals
.netbios_name
, myhostname_upper());
566 string_set(Globals
.ctx
, &Globals
.smb_passwd_file
, get_dyn_SMB_PASSWD_FILE());
567 string_set(Globals
.ctx
, &Globals
.private_dir
, get_dyn_PRIVATE_DIR());
569 /* use the new 'hash2' method by default, with a prefix of 1 */
570 string_set(Globals
.ctx
, &Globals
.mangling_method
, "hash2");
571 Globals
.mangle_prefix
= 1;
573 string_set(Globals
.ctx
, &Globals
.guest_account
, GUEST_ACCOUNT
);
575 /* using UTF8 by default allows us to support all chars */
576 string_set(Globals
.ctx
, &Globals
.unix_charset
, DEFAULT_UNIX_CHARSET
);
578 /* Use codepage 850 as a default for the dos character set */
579 string_set(Globals
.ctx
, &Globals
.dos_charset
, DEFAULT_DOS_CHARSET
);
582 * Allow the default PASSWD_CHAT to be overridden in local.h.
584 string_set(Globals
.ctx
, &Globals
.passwd_chat
, DEFAULT_PASSWD_CHAT
);
586 string_set(Globals
.ctx
, &Globals
.workgroup
, DEFAULT_WORKGROUP
);
588 string_set(Globals
.ctx
, &Globals
.passwd_program
, "");
589 string_set(Globals
.ctx
, &Globals
.lock_directory
, get_dyn_LOCKDIR());
590 string_set(Globals
.ctx
, &Globals
.state_directory
, get_dyn_STATEDIR());
591 string_set(Globals
.ctx
, &Globals
.cache_directory
, get_dyn_CACHEDIR());
592 string_set(Globals
.ctx
, &Globals
.pid_directory
, get_dyn_PIDDIR());
593 string_set(Globals
.ctx
, &Globals
.nbt_client_socket_address
, "0.0.0.0");
595 * By default support explicit binding to broadcast
598 Globals
.nmbd_bind_explicit_broadcast
= true;
600 s
= talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
602 smb_panic("init_globals: ENOMEM");
604 string_set(Globals
.ctx
, &Globals
.server_string
, s
);
607 string_set(Globals
.ctx
, &Globals
.panic_action
, "/bin/sleep 999999999");
610 string_set(Globals
.ctx
, &Globals
.socket_options
, DEFAULT_SOCKET_OPTIONS
);
612 string_set(Globals
.ctx
, &Globals
.logon_drive
, "");
613 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
614 string_set(Globals
.ctx
, &Globals
.logon_home
, "\\\\%N\\%U");
615 string_set(Globals
.ctx
, &Globals
.logon_path
, "\\\\%N\\%U\\profile");
617 Globals
.name_resolve_order
= str_list_make_v3_const(NULL
, "lmhosts wins host bcast", NULL
);
618 string_set(Globals
.ctx
, &Globals
.password_server
, "*");
620 Globals
.algorithmic_rid_base
= BASE_RID
;
622 Globals
.load_printers
= true;
623 Globals
.printcap_cache_time
= 750; /* 12.5 minutes */
625 Globals
.config_backend
= config_backend
;
626 Globals
._server_role
= ROLE_AUTO
;
628 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
629 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
630 Globals
.max_xmit
= 0x4104;
631 Globals
.max_mux
= 50; /* This is *needed* for profile support. */
632 Globals
.lpq_cache_time
= 30; /* changed to handle large print servers better -- jerry */
633 Globals
._disable_spoolss
= false;
634 Globals
.max_smbd_processes
= 0;/* no limit specified */
635 Globals
.username_level
= 0;
636 Globals
.deadtime
= 0;
637 Globals
.getwd_cache
= true;
638 Globals
.large_readwrite
= true;
639 Globals
.max_log_size
= 5000;
640 Globals
.max_open_files
= max_open_files();
641 Globals
.server_max_protocol
= PROTOCOL_SMB3_11
;
642 Globals
.server_min_protocol
= PROTOCOL_LANMAN1
;
643 Globals
._client_max_protocol
= PROTOCOL_DEFAULT
;
644 Globals
.client_min_protocol
= PROTOCOL_CORE
;
645 Globals
._security
= SEC_AUTO
;
646 Globals
.encrypt_passwords
= true;
647 Globals
.client_schannel
= Auto
;
648 Globals
.winbind_sealed_pipes
= true;
649 Globals
.require_strong_key
= true;
650 Globals
.server_schannel
= Auto
;
651 Globals
.read_raw
= true;
652 Globals
.write_raw
= true;
653 Globals
.null_passwords
= false;
654 Globals
.old_password_allowed_period
= 60;
655 Globals
.obey_pam_restrictions
= false;
657 Globals
.syslog_only
= false;
658 Globals
.timestamp_logs
= true;
659 string_set(Globals
.ctx
, &Globals
.log_level
, "0");
660 Globals
.debug_prefix_timestamp
= false;
661 Globals
.debug_hires_timestamp
= true;
662 Globals
.debug_pid
= false;
663 Globals
.debug_uid
= false;
664 Globals
.debug_class
= false;
665 Globals
.enable_core_files
= true;
666 Globals
.max_ttl
= 60 * 60 * 24 * 3; /* 3 days default. */
667 Globals
.max_wins_ttl
= 60 * 60 * 24 * 6; /* 6 days default. */
668 Globals
.min_wins_ttl
= 60 * 60 * 6; /* 6 hours default. */
669 Globals
.machine_password_timeout
= 60 * 60 * 24 * 7; /* 7 days default. */
670 Globals
.lm_announce
= Auto
; /* = Auto: send only if LM clients found */
671 Globals
.lm_interval
= 60;
672 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
673 Globals
.nis_homedir
= false;
674 #ifdef WITH_NISPLUS_HOME
675 string_set(Globals
.ctx
, &Globals
.homedir_map
, "auto_home.org_dir");
677 string_set(Globals
.ctx
, &Globals
.homedir_map
, "auto.home");
680 Globals
.time_server
= false;
681 Globals
.bind_interfaces_only
= false;
682 Globals
.unix_password_sync
= false;
683 Globals
.pam_password_change
= false;
684 Globals
.passwd_chat_debug
= false;
685 Globals
.passwd_chat_timeout
= 2; /* 2 second default. */
686 Globals
.nt_pipe_support
= true; /* Do NT pipes by default. */
687 Globals
.nt_status_support
= true; /* Use NT status by default. */
688 Globals
.smbd_profiling_level
= 0;
689 Globals
.stat_cache
= true; /* use stat cache by default */
690 Globals
.max_stat_cache_size
= 256; /* 256k by default */
691 Globals
.restrict_anonymous
= 0;
692 Globals
.client_lanman_auth
= false; /* Do NOT use the LanMan hash if it is available */
693 Globals
.client_plaintext_auth
= false; /* Do NOT use a plaintext password even if is requested by the server */
694 Globals
.lanman_auth
= false; /* Do NOT use the LanMan hash, even if it is supplied */
695 Globals
.ntlm_auth
= true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
696 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 */
697 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
699 Globals
.map_to_guest
= 0; /* By Default, "Never" */
700 Globals
.oplock_break_wait_time
= 0; /* By Default, 0 msecs. */
701 Globals
.enhanced_browsing
= true;
702 Globals
.lock_spin_time
= WINDOWS_MINIMUM_LOCK_TIMEOUT_MS
; /* msec. */
703 #ifdef MMAP_BLACKLIST
704 Globals
.use_mmap
= false;
706 Globals
.use_mmap
= true;
708 Globals
.unicode
= true;
709 Globals
.unix_extensions
= true;
710 Globals
.reset_on_zero_vc
= false;
711 Globals
.log_writeable_files_on_exit
= false;
712 Globals
.create_krb5_conf
= true;
713 Globals
._winbind_max_domain_connections
= 1;
715 /* hostname lookups can be very expensive and are broken on
716 a large number of sites (tridge) */
717 Globals
.hostname_lookups
= false;
719 Globals
.change_notify
= true,
720 Globals
.kernel_change_notify
= true,
722 string_set(Globals
.ctx
, &Globals
.passdb_backend
, "tdbsam");
723 string_set(Globals
.ctx
, &Globals
.ldap_suffix
, "");
724 string_set(Globals
.ctx
, &Globals
._ldap_machine_suffix
, "");
725 string_set(Globals
.ctx
, &Globals
._ldap_user_suffix
, "");
726 string_set(Globals
.ctx
, &Globals
._ldap_group_suffix
, "");
727 string_set(Globals
.ctx
, &Globals
._ldap_idmap_suffix
, "");
729 string_set(Globals
.ctx
, &Globals
.ldap_admin_dn
, "");
730 Globals
.ldap_ssl
= LDAP_SSL_START_TLS
;
731 Globals
.ldap_ssl_ads
= false;
732 Globals
.ldap_deref
= -1;
733 Globals
.ldap_passwd_sync
= LDAP_PASSWD_SYNC_OFF
;
734 Globals
.ldap_delete_dn
= false;
735 Globals
.ldap_replication_sleep
= 1000; /* wait 1 sec for replication */
736 Globals
.ldap_follow_referral
= Auto
;
737 Globals
.ldap_timeout
= LDAP_DEFAULT_TIMEOUT
;
738 Globals
.ldap_connection_timeout
= LDAP_CONNECTION_DEFAULT_TIMEOUT
;
739 Globals
.ldap_page_size
= LDAP_PAGE_SIZE
;
741 Globals
.ldap_debug_level
= 0;
742 Globals
.ldap_debug_threshold
= 10;
744 Globals
.client_ldap_sasl_wrapping
= ADS_AUTH_SASL_SIGN
;
746 /* This is what we tell the afs client. in reality we set the token
747 * to never expire, though, when this runs out the afs client will
748 * forget the token. Set to 0 to get NEVERDATE.*/
749 Globals
.afs_token_lifetime
= 604800;
750 Globals
.cups_connection_timeout
= CUPS_DEFAULT_CONNECTION_TIMEOUT
;
752 /* these parameters are set to defaults that are more appropriate
753 for the increasing samba install base:
755 as a member of the workgroup, that will possibly become a
756 _local_ master browser (lm = true). this is opposed to a forced
757 local master browser startup (pm = true).
759 doesn't provide WINS server service by default (wsupp = false),
760 and doesn't provide domain master browser services by default, either.
764 Globals
.show_add_printer_wizard
= true;
765 Globals
.os_level
= 20;
766 Globals
.local_master
= true;
767 Globals
._domain_master
= Auto
; /* depending on _domain_logons */
768 Globals
._domain_logons
= false;
769 Globals
.browse_list
= true;
770 Globals
.we_are_a_wins_server
= false;
771 Globals
.wins_proxy
= false;
773 TALLOC_FREE(Globals
.init_logon_delayed_hosts
);
774 Globals
.init_logon_delay
= 100; /* 100 ms default delay */
776 Globals
.wins_dns_proxy
= true;
778 Globals
.allow_trusted_domains
= true;
779 string_set(Globals
.ctx
, &Globals
.idmap_backend
, "tdb");
781 string_set(Globals
.ctx
, &Globals
.template_shell
, "/bin/false");
782 string_set(Globals
.ctx
, &Globals
.template_homedir
, "/home/%D/%U");
783 string_set(Globals
.ctx
, &Globals
.winbind_separator
, "\\");
784 string_set(Globals
.ctx
, &Globals
.winbindd_socket_directory
, dyn_WINBINDD_SOCKET_DIR
);
786 string_set(Globals
.ctx
, &Globals
.cups_server
, "");
787 string_set(Globals
.ctx
, &Globals
.iprint_server
, "");
789 string_set(Globals
.ctx
, &Globals
._ctdbd_socket
, "");
791 Globals
.cluster_addresses
= NULL
;
792 Globals
.clustering
= false;
793 Globals
.ctdb_timeout
= 0;
794 Globals
.ctdb_locktime_warn_threshold
= 0;
796 Globals
.winbind_cache_time
= 300; /* 5 minutes */
797 Globals
.winbind_reconnect_delay
= 30; /* 30 seconds */
798 Globals
.winbind_request_timeout
= 60; /* 60 seconds */
799 Globals
.winbind_max_clients
= 200;
800 Globals
.winbind_enum_users
= false;
801 Globals
.winbind_enum_groups
= false;
802 Globals
.winbind_use_default_domain
= false;
803 Globals
.winbind_trusted_domains_only
= false;
804 Globals
.winbind_nested_groups
= true;
805 Globals
.winbind_expand_groups
= 0;
806 Globals
.winbind_nss_info
= str_list_make_v3_const(NULL
, "template", NULL
);
807 Globals
.winbind_refresh_tickets
= false;
808 Globals
.winbind_offline_logon
= false;
810 Globals
.idmap_cache_time
= 86400 * 7; /* a week by default */
811 Globals
.idmap_negative_cache_time
= 120; /* 2 minutes by default */
813 Globals
.passdb_expand_explicit
= false;
815 Globals
.name_cache_timeout
= 660; /* In seconds */
817 Globals
.use_spnego
= true;
818 Globals
.client_use_spnego
= true;
820 Globals
.client_signing
= SMB_SIGNING_DEFAULT
;
821 Globals
.server_signing
= SMB_SIGNING_DEFAULT
;
823 Globals
.defer_sharing_violations
= true;
824 Globals
.smb_ports
= str_list_make_v3_const(NULL
, SMB_PORTS
, NULL
);
826 Globals
.enable_privileges
= true;
827 Globals
.host_msdfs
= true;
828 Globals
.enable_asu_support
= false;
830 /* User defined shares. */
831 s
= talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
833 smb_panic("init_globals: ENOMEM");
835 string_set(Globals
.ctx
, &Globals
.usershare_path
, s
);
837 string_set(Globals
.ctx
, &Globals
.usershare_template_share
, "");
838 Globals
.usershare_max_shares
= 0;
839 /* By default disallow sharing of directories not owned by the sharer. */
840 Globals
.usershare_owner_only
= true;
841 /* By default disallow guest access to usershares. */
842 Globals
.usershare_allow_guests
= false;
844 Globals
.keepalive
= DEFAULT_KEEPALIVE
;
846 /* By default no shares out of the registry */
847 Globals
.registry_shares
= false;
849 Globals
.min_receivefile_size
= 0;
851 Globals
.map_untrusted_to_domain
= false;
852 Globals
.multicast_dns_register
= true;
854 Globals
.smb2_max_read
= DEFAULT_SMB2_MAX_READ
;
855 Globals
.smb2_max_write
= DEFAULT_SMB2_MAX_WRITE
;
856 Globals
.smb2_max_trans
= DEFAULT_SMB2_MAX_TRANSACT
;
857 Globals
.smb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
858 Globals
.smb2_leases
= false;
860 string_set(Globals
.ctx
, &Globals
.ncalrpc_dir
, get_dyn_NCALRPCDIR());
862 Globals
.server_services
= str_list_make_v3_const(NULL
, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL
);
864 Globals
.dcerpc_endpoint_servers
= str_list_make_v3_const(NULL
, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL
);
866 Globals
.tls_enabled
= true;
868 string_set(Globals
.ctx
, &Globals
._tls_keyfile
, "tls/key.pem");
869 string_set(Globals
.ctx
, &Globals
._tls_certfile
, "tls/cert.pem");
870 string_set(Globals
.ctx
, &Globals
._tls_cafile
, "tls/ca.pem");
871 string_set(Globals
.ctx
, &Globals
.tls_priority
, "NORMAL:-VERS-SSL3.0");
873 string_set(Globals
.ctx
, &Globals
.share_backend
, "classic");
875 Globals
._preferred_master
= Auto
;
877 Globals
.allow_dns_updates
= DNS_UPDATE_SIGNED
;
879 string_set(Globals
.ctx
, &Globals
.ntp_signd_socket_directory
, get_dyn_NTP_SIGND_SOCKET_DIR());
881 string_set(Globals
.ctx
, &Globals
.winbindd_privileged_socket_directory
, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
883 s
= talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
885 smb_panic("init_globals: ENOMEM");
887 Globals
.samba_kcc_command
= str_list_make_v3_const(NULL
, s
, NULL
);
890 s
= talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
892 smb_panic("init_globals: ENOMEM");
894 Globals
.dns_update_command
= str_list_make_v3_const(NULL
, s
, NULL
);
897 s
= talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
899 smb_panic("init_globals: ENOMEM");
901 Globals
.spn_update_command
= str_list_make_v3_const(NULL
, s
, NULL
);
904 Globals
.nsupdate_command
= str_list_make_v3_const(NULL
, "/usr/bin/nsupdate -g", NULL
);
906 Globals
.rndc_command
= str_list_make_v3_const(NULL
, "/usr/sbin/rndc", NULL
);
908 Globals
.cldap_port
= 389;
910 Globals
.dgram_port
= NBT_DGRAM_SERVICE_PORT
;
912 Globals
.nbt_port
= NBT_NAME_SERVICE_PORT
;
914 Globals
.krb5_port
= 88;
916 Globals
.kpasswd_port
= 464;
918 Globals
.web_port
= 901;
920 /* Now put back the settings that were set with lp_set_cmdline() */
921 apply_lp_set_cmdline();
924 /* Convenience routine to setup an lp_context with additional s3 variables */
925 static struct loadparm_context
*setup_lp_context(TALLOC_CTX
*mem_ctx
)
927 struct loadparm_context
*lp_ctx
;
929 lp_ctx
= loadparm_init_s3(mem_ctx
,
930 loadparm_s3_helpers());
931 if (lp_ctx
== NULL
) {
932 DEBUG(0, ("loadparm_init_s3 failed\n"));
936 lp_ctx
->sDefault
= &sDefault
;
937 lp_ctx
->services
= NULL
; /* We do not want to access this directly */
938 lp_ctx
->bInGlobalSection
= bInGlobalSection
;
939 lp_ctx
->flags
= flags_list
;
944 /*******************************************************************
945 Convenience routine to grab string parameters into talloced memory
946 and run standard_sub_basic on them. The buffers can be written to by
947 callers without affecting the source string.
948 ********************************************************************/
950 char *lp_string(TALLOC_CTX
*ctx
, const char *s
)
954 /* The follow debug is useful for tracking down memory problems
955 especially if you have an inner loop that is calling a lp_*()
956 function that returns a string. Perhaps this debug should be
957 present all the time? */
960 DEBUG(10, ("lp_string(%s)\n", s
));
966 ret
= talloc_sub_basic(ctx
,
967 get_current_username(),
968 current_user_info
.domain
,
970 if (trim_char(ret
, '\"', '\"')) {
971 if (strchr(ret
,'\"') != NULL
) {
973 ret
= talloc_sub_basic(ctx
,
974 get_current_username(),
975 current_user_info
.domain
,
983 In this section all the functions that are used to access the
984 parameters from the rest of the program are defined
987 #define FN_GLOBAL_STRING(fn_name,ptr) \
988 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
989 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
990 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
991 #define FN_GLOBAL_LIST(fn_name,ptr) \
992 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
993 #define FN_GLOBAL_BOOL(fn_name,ptr) \
994 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
995 #define FN_GLOBAL_CHAR(fn_name,ptr) \
996 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
997 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
998 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1000 #define FN_LOCAL_STRING(fn_name,val) \
1001 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));}
1002 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1003 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1004 #define FN_LOCAL_LIST(fn_name,val) \
1005 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1006 #define FN_LOCAL_BOOL(fn_name,val) \
1007 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1008 #define FN_LOCAL_INTEGER(fn_name,val) \
1009 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1011 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1012 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1013 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1014 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1015 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1016 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1018 int lp_winbind_max_domain_connections(void)
1020 if (lp_winbind_offline_logon() &&
1021 lp__winbind_max_domain_connections() > 1) {
1022 DEBUG(1, ("offline logons active, restricting max domain "
1023 "connections to 1\n"));
1026 return MAX(1, lp__winbind_max_domain_connections());
1029 /* These functions remain in source3/param for now */
1031 #include "lib/param/param_functions.c"
1033 FN_LOCAL_STRING(servicename
, szService
)
1034 FN_LOCAL_CONST_STRING(const_servicename
, szService
)
1036 /* These functions cannot be auto-generated */
1037 FN_LOCAL_BOOL(autoloaded
, autoloaded
)
1038 FN_GLOBAL_CONST_STRING(dnsdomain
, dnsdomain
)
1040 /* local prototypes */
1042 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
);
1043 static const char *get_boolean(bool bool_value
);
1044 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
1046 static bool hash_a_service(const char *name
, int number
);
1047 static void free_service_byindex(int iService
);
1048 static void show_parameter(int parmIndex
);
1049 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
);
1052 * This is a helper function for parametrical options support. It returns a
1053 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1054 * parametrical functions are quite simple
1056 static struct parmlist_entry
*get_parametrics(int snum
, const char *type
,
1059 if (snum
>= iNumServices
) return NULL
;
1062 return get_parametric_helper(NULL
, type
, option
, Globals
.param_opt
);
1064 return get_parametric_helper(ServicePtrs
[snum
],
1065 type
, option
, Globals
.param_opt
);
1069 static void discard_whitespace(char *str
)
1071 size_t len
= strlen(str
);
1075 if (isspace(str
[i
])) {
1076 memmove(&str
[i
], &str
[i
+1], len
-i
);
1085 * @brief Go through all global parametric parameters
1087 * @param regex_str A regular expression to scan param for
1088 * @param max_matches Max number of submatches the regexp expects
1089 * @param cb Function to call on match. Should return true
1090 * when it wants wi_scan_global_parametrics to stop
1092 * @param private_data Anonymous pointer passed to cb
1094 * @return 0: success, regcomp/regexec return value on error.
1095 * See "man regexec" for possible errors
1098 int lp_wi_scan_global_parametrics(
1099 const char *regex_str
, size_t max_matches
,
1100 bool (*cb
)(const char *string
, regmatch_t matches
[],
1101 void *private_data
),
1104 struct parmlist_entry
*data
;
1108 ret
= regcomp(®ex
, regex_str
, REG_ICASE
);
1113 for (data
= Globals
.param_opt
; data
!= NULL
; data
= data
->next
) {
1114 size_t keylen
= strlen(data
->key
);
1116 regmatch_t matches
[max_matches
];
1119 memcpy(key
, data
->key
, sizeof(key
));
1120 discard_whitespace(key
);
1122 ret
= regexec(®ex
, key
, max_matches
, matches
, 0);
1123 if (ret
== REG_NOMATCH
) {
1130 stop
= cb(key
, matches
, private_data
);
1143 #define MISSING_PARAMETER(name) \
1144 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1146 /*******************************************************************
1147 convenience routine to return enum parameters.
1148 ********************************************************************/
1149 static int lp_enum(const char *s
,const struct enum_list
*_enum
)
1153 if (!s
|| !*s
|| !_enum
) {
1154 MISSING_PARAMETER(lp_enum
);
1158 for (i
=0; _enum
[i
].name
; i
++) {
1159 if (strequal(_enum
[i
].name
,s
))
1160 return _enum
[i
].value
;
1163 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s
));
1167 #undef MISSING_PARAMETER
1169 /* Return parametric option from a given service. Type is a part of option before ':' */
1170 /* Parametric option has following syntax: 'Type: option = value' */
1171 char *lp_parm_talloc_string(TALLOC_CTX
*ctx
, int snum
, const char *type
, const char *option
, const char *def
)
1173 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1175 if (data
== NULL
||data
->value
==NULL
) {
1177 return lp_string(ctx
, def
);
1183 return lp_string(ctx
, data
->value
);
1186 /* Return parametric option from a given service. Type is a part of option before ':' */
1187 /* Parametric option has following syntax: 'Type: option = value' */
1188 const char *lp_parm_const_string(int snum
, const char *type
, const char *option
, const char *def
)
1190 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1192 if (data
== NULL
||data
->value
==NULL
)
1199 /* Return parametric option from a given service. Type is a part of option before ':' */
1200 /* Parametric option has following syntax: 'Type: option = value' */
1202 const char **lp_parm_string_list(int snum
, const char *type
, const char *option
, const char **def
)
1204 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1206 if (data
== NULL
||data
->value
==NULL
)
1207 return (const char **)def
;
1209 if (data
->list
==NULL
) {
1210 data
->list
= str_list_make_v3(NULL
, data
->value
, NULL
);
1213 return discard_const_p(const char *, data
->list
);
1216 /* Return parametric option from a given service. Type is a part of option before ':' */
1217 /* Parametric option has following syntax: 'Type: option = value' */
1219 int lp_parm_int(int snum
, const char *type
, const char *option
, int def
)
1221 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1223 if (data
&& data
->value
&& *data
->value
)
1224 return lp_int(data
->value
);
1229 /* Return parametric option from a given service. Type is a part of option before ':' */
1230 /* Parametric option has following syntax: 'Type: option = value' */
1232 unsigned long lp_parm_ulong(int snum
, const char *type
, const char *option
, unsigned long def
)
1234 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1236 if (data
&& data
->value
&& *data
->value
)
1237 return lp_ulong(data
->value
);
1242 /* Return parametric option from a given service. Type is a part of option before ':' */
1243 /* Parametric option has following syntax: 'Type: option = value' */
1245 bool lp_parm_bool(int snum
, const char *type
, const char *option
, bool def
)
1247 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1249 if (data
&& data
->value
&& *data
->value
)
1250 return lp_bool(data
->value
);
1255 /* Return parametric option from a given service. Type is a part of option before ':' */
1256 /* Parametric option has following syntax: 'Type: option = value' */
1258 int lp_parm_enum(int snum
, const char *type
, const char *option
,
1259 const struct enum_list
*_enum
, int def
)
1261 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1263 if (data
&& data
->value
&& *data
->value
&& _enum
)
1264 return lp_enum(data
->value
, _enum
);
1270 * free a param_opts structure.
1271 * param_opts handling should be moved to talloc;
1272 * then this whole functions reduces to a TALLOC_FREE().
1275 static void free_param_opts(struct parmlist_entry
**popts
)
1277 struct parmlist_entry
*opt
, *next_opt
;
1279 if (*popts
!= NULL
) {
1280 DEBUG(5, ("Freeing parametrics:\n"));
1283 while (opt
!= NULL
) {
1284 string_free(&opt
->key
);
1285 string_free(&opt
->value
);
1286 TALLOC_FREE(opt
->list
);
1287 next_opt
= opt
->next
;
1294 /***************************************************************************
1295 Free the dynamically allocated parts of a service struct.
1296 ***************************************************************************/
1298 static void free_service(struct loadparm_service
*pservice
)
1303 if (pservice
->szService
)
1304 DEBUG(5, ("free_service: Freeing service %s\n",
1305 pservice
->szService
));
1307 free_parameters(pservice
);
1309 string_free(&pservice
->szService
);
1310 TALLOC_FREE(pservice
->copymap
);
1312 free_param_opts(&pservice
->param_opt
);
1314 ZERO_STRUCTP(pservice
);
1318 /***************************************************************************
1319 remove a service indexed in the ServicePtrs array from the ServiceHash
1320 and free the dynamically allocated parts
1321 ***************************************************************************/
1323 static void free_service_byindex(int idx
)
1325 if ( !LP_SNUM_OK(idx
) )
1328 ServicePtrs
[idx
]->valid
= false;
1330 /* we have to cleanup the hash record */
1332 if (ServicePtrs
[idx
]->szService
) {
1333 char *canon_name
= canonicalize_servicename(
1335 ServicePtrs
[idx
]->szService
);
1337 dbwrap_delete_bystring(ServiceHash
, canon_name
);
1338 TALLOC_FREE(canon_name
);
1341 free_service(ServicePtrs
[idx
]);
1342 talloc_free_children(ServicePtrs
[idx
]);
1345 /***************************************************************************
1346 Add a new service to the services array initialising it with the given
1348 ***************************************************************************/
1350 static int add_a_service(const struct loadparm_service
*pservice
, const char *name
)
1353 int num_to_alloc
= iNumServices
+ 1;
1354 struct loadparm_service
**tsp
= NULL
;
1356 /* it might already exist */
1358 i
= getservicebyname(name
, NULL
);
1364 /* if not, then create one */
1366 tsp
= talloc_realloc(NULL
, ServicePtrs
, struct loadparm_service
*, num_to_alloc
);
1368 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1372 ServicePtrs
[iNumServices
] = talloc_zero(NULL
, struct loadparm_service
);
1373 if (!ServicePtrs
[iNumServices
]) {
1374 DEBUG(0,("add_a_service: out of memory!\n"));
1379 ServicePtrs
[i
]->valid
= true;
1381 copy_service(ServicePtrs
[i
], pservice
, NULL
);
1383 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->szService
, name
);
1385 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1386 i
, ServicePtrs
[i
]->szService
));
1388 if (!hash_a_service(ServicePtrs
[i
]->szService
, i
)) {
1395 /***************************************************************************
1396 Convert a string to uppercase and remove whitespaces.
1397 ***************************************************************************/
1399 char *canonicalize_servicename(TALLOC_CTX
*ctx
, const char *src
)
1404 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1408 result
= talloc_strdup(ctx
, src
);
1409 SMB_ASSERT(result
!= NULL
);
1411 if (!strlower_m(result
)) {
1412 TALLOC_FREE(result
);
1418 /***************************************************************************
1419 Add a name/index pair for the services array to the hash table.
1420 ***************************************************************************/
1422 static bool hash_a_service(const char *name
, int idx
)
1426 if ( !ServiceHash
) {
1427 DEBUG(10,("hash_a_service: creating servicehash\n"));
1428 ServiceHash
= db_open_rbt(NULL
);
1429 if ( !ServiceHash
) {
1430 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1435 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1438 canon_name
= canonicalize_servicename(talloc_tos(), name
);
1440 dbwrap_store_bystring(ServiceHash
, canon_name
,
1441 make_tdb_data((uint8_t *)&idx
, sizeof(idx
)),
1444 TALLOC_FREE(canon_name
);
1449 /***************************************************************************
1450 Add a new home service, with the specified home directory, defaults coming
1452 ***************************************************************************/
1454 bool lp_add_home(const char *pszHomename
, int iDefaultService
,
1455 const char *user
, const char *pszHomedir
)
1459 if (pszHomename
== NULL
|| user
== NULL
|| pszHomedir
== NULL
||
1460 pszHomedir
[0] == '\0') {
1464 i
= add_a_service(ServicePtrs
[iDefaultService
], pszHomename
);
1469 if (!(*(ServicePtrs
[iDefaultService
]->path
))
1470 || strequal(ServicePtrs
[iDefaultService
]->path
,
1471 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM
))) {
1472 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->path
, pszHomedir
);
1475 if (!(*(ServicePtrs
[i
]->comment
))) {
1476 char *comment
= talloc_asprintf(talloc_tos(), "Home directory of %s", user
);
1477 if (comment
== NULL
) {
1480 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->comment
, comment
);
1481 TALLOC_FREE(comment
);
1484 /* set the browseable flag from the global default */
1486 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1487 ServicePtrs
[i
]->access_based_share_enum
= sDefault
.access_based_share_enum
;
1489 ServicePtrs
[i
]->autoloaded
= true;
1491 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename
,
1492 user
, ServicePtrs
[i
]->path
));
1497 /***************************************************************************
1498 Add a new service, based on an old one.
1499 ***************************************************************************/
1501 int lp_add_service(const char *pszService
, int iDefaultService
)
1503 if (iDefaultService
< 0) {
1504 return add_a_service(&sDefault
, pszService
);
1507 return (add_a_service(ServicePtrs
[iDefaultService
], pszService
));
1510 /***************************************************************************
1511 Add the IPC service.
1512 ***************************************************************************/
1514 static bool lp_add_ipc(const char *ipc_name
, bool guest_ok
)
1516 char *comment
= NULL
;
1517 int i
= add_a_service(&sDefault
, ipc_name
);
1522 comment
= talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1523 Globals
.server_string
);
1524 if (comment
== NULL
) {
1528 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->path
, tmpdir());
1529 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->username
, "");
1530 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->comment
, comment
);
1531 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->fstype
, "IPC");
1532 ServicePtrs
[i
]->max_connections
= 0;
1533 ServicePtrs
[i
]->available
= true;
1534 ServicePtrs
[i
]->read_only
= true;
1535 ServicePtrs
[i
]->guest_only
= false;
1536 ServicePtrs
[i
]->administrative_share
= true;
1537 ServicePtrs
[i
]->guest_ok
= guest_ok
;
1538 ServicePtrs
[i
]->printable
= false;
1539 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1541 DEBUG(3, ("adding IPC service\n"));
1543 TALLOC_FREE(comment
);
1547 /***************************************************************************
1548 Add a new printer service, with defaults coming from service iFrom.
1549 ***************************************************************************/
1551 bool lp_add_printer(const char *pszPrintername
, int iDefaultService
)
1553 const char *comment
= "From Printcap";
1554 int i
= add_a_service(ServicePtrs
[iDefaultService
], pszPrintername
);
1559 /* note that we do NOT default the availability flag to true - */
1560 /* we take it from the default service passed. This allows all */
1561 /* dynamic printers to be disabled by disabling the [printers] */
1562 /* entry (if/when the 'available' keyword is implemented!). */
1564 /* the printer name is set to the service name. */
1565 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->_printername
, pszPrintername
);
1566 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->comment
, comment
);
1568 /* set the browseable flag from the gloabl default */
1569 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1571 /* Printers cannot be read_only. */
1572 ServicePtrs
[i
]->read_only
= false;
1573 /* No oplocks on printer services. */
1574 ServicePtrs
[i
]->oplocks
= false;
1575 /* Printer services must be printable. */
1576 ServicePtrs
[i
]->printable
= true;
1578 DEBUG(3, ("adding printer service %s\n", pszPrintername
));
1584 /***************************************************************************
1585 Check whether the given parameter name is valid.
1586 Parametric options (names containing a colon) are considered valid.
1587 ***************************************************************************/
1589 bool lp_parameter_is_valid(const char *pszParmName
)
1591 return ((lpcfg_map_parameter(pszParmName
) != -1) ||
1592 (strchr(pszParmName
, ':') != NULL
));
1595 /***************************************************************************
1596 Check whether the given name is the name of a global parameter.
1597 Returns true for strings belonging to parameters of class
1598 P_GLOBAL, false for all other strings, also for parametric options
1599 and strings not belonging to any option.
1600 ***************************************************************************/
1602 bool lp_parameter_is_global(const char *pszParmName
)
1604 int num
= lpcfg_map_parameter(pszParmName
);
1607 return (parm_table
[num
].p_class
== P_GLOBAL
);
1613 /**************************************************************************
1614 Determine the canonical name for a parameter.
1615 Indicate when it is an inverse (boolean) synonym instead of a
1617 **************************************************************************/
1619 bool lp_canonicalize_parameter(const char *parm_name
, const char **canon_parm
,
1624 if (!lp_parameter_is_valid(parm_name
)) {
1629 num
= map_parameter_canonical(parm_name
, inverse
);
1631 /* parametric option */
1632 *canon_parm
= parm_name
;
1634 *canon_parm
= parm_table
[num
].label
;
1641 /**************************************************************************
1642 Determine the canonical name for a parameter.
1643 Turn the value given into the inverse boolean expression when
1644 the synonym is an invers boolean synonym.
1646 Return true if parm_name is a valid parameter name and
1647 in case it is an invers boolean synonym, if the val string could
1648 successfully be converted to the reverse bool.
1649 Return false in all other cases.
1650 **************************************************************************/
1652 bool lp_canonicalize_parameter_with_value(const char *parm_name
,
1654 const char **canon_parm
,
1655 const char **canon_val
)
1660 if (!lp_parameter_is_valid(parm_name
)) {
1666 num
= map_parameter_canonical(parm_name
, &inverse
);
1668 /* parametric option */
1669 *canon_parm
= parm_name
;
1672 *canon_parm
= parm_table
[num
].label
;
1674 if (!lp_invert_boolean(val
, canon_val
)) {
1686 /***************************************************************************
1687 Map a parameter's string representation to the index of the canonical
1688 form of the parameter (it might be a synonym).
1689 Returns -1 if the parameter string is not recognised.
1690 ***************************************************************************/
1692 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
)
1694 int parm_num
, canon_num
;
1695 bool loc_inverse
= false;
1697 parm_num
= lpcfg_map_parameter(pszParmName
);
1698 if ((parm_num
< 0) || !(parm_table
[parm_num
].flags
& FLAG_SYNONYM
)) {
1699 /* invalid, parametric or no canidate for synonyms ... */
1703 for (canon_num
= 0; parm_table
[canon_num
].label
; canon_num
++) {
1704 if (is_synonym_of(parm_num
, canon_num
, &loc_inverse
)) {
1705 parm_num
= canon_num
;
1711 if (inverse
!= NULL
) {
1712 *inverse
= loc_inverse
;
1717 /***************************************************************************
1718 return true if parameter number parm1 is a synonym of parameter
1719 number parm2 (parm2 being the principal name).
1720 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1722 ***************************************************************************/
1724 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
)
1726 if ((parm_table
[parm1
].offset
== parm_table
[parm2
].offset
) &&
1727 (parm_table
[parm1
].p_class
== parm_table
[parm2
].p_class
) &&
1728 (parm_table
[parm1
].flags
& FLAG_SYNONYM
) &&
1729 !(parm_table
[parm2
].flags
& FLAG_SYNONYM
))
1731 if (inverse
!= NULL
) {
1732 if ((parm_table
[parm1
].type
== P_BOOLREV
) &&
1733 (parm_table
[parm2
].type
== P_BOOL
))
1745 /***************************************************************************
1746 Show one parameter's name, type, [values,] and flags.
1747 (helper functions for show_parameter_list)
1748 ***************************************************************************/
1750 static void show_parameter(int parmIndex
)
1752 int enumIndex
, flagIndex
;
1757 const char *type
[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1758 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1759 "P_ENUM", "P_BYTES", "P_CMDLIST" };
1760 unsigned flags
[] = { FLAG_DEPRECATED
, FLAG_SYNONYM
};
1761 const char *flag_names
[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL
};
1763 printf("%s=%s", parm_table
[parmIndex
].label
,
1764 type
[parm_table
[parmIndex
].type
]);
1765 if (parm_table
[parmIndex
].type
== P_ENUM
) {
1768 parm_table
[parmIndex
].enum_list
[enumIndex
].name
;
1772 enumIndex
? "|" : "",
1773 parm_table
[parmIndex
].enum_list
[enumIndex
].name
);
1778 for (flagIndex
=0; flag_names
[flagIndex
]; flagIndex
++) {
1779 if (parm_table
[parmIndex
].flags
& flags
[flagIndex
]) {
1782 flag_names
[flagIndex
]);
1787 /* output synonyms */
1789 for (parmIndex2
=0; parm_table
[parmIndex2
].label
; parmIndex2
++) {
1790 if (is_synonym_of(parmIndex
, parmIndex2
, &inverse
)) {
1791 printf(" (%ssynonym of %s)", inverse
? "inverse " : "",
1792 parm_table
[parmIndex2
].label
);
1793 } else if (is_synonym_of(parmIndex2
, parmIndex
, &inverse
)) {
1795 printf(" (synonyms: ");
1800 printf("%s%s", parm_table
[parmIndex2
].label
,
1801 inverse
? "[i]" : "");
1811 /***************************************************************************
1812 Show all parameter's name, type, [values,] and flags.
1813 ***************************************************************************/
1815 void show_parameter_list(void)
1817 int classIndex
, parmIndex
;
1818 const char *section_names
[] = { "local", "global", NULL
};
1820 for (classIndex
=0; section_names
[classIndex
]; classIndex
++) {
1821 printf("[%s]\n", section_names
[classIndex
]);
1822 for (parmIndex
= 0; parm_table
[parmIndex
].label
; parmIndex
++) {
1823 if (parm_table
[parmIndex
].p_class
== classIndex
) {
1824 show_parameter(parmIndex
);
1830 /***************************************************************************
1831 Get the standard string representation of a boolean value ("yes" or "no")
1832 ***************************************************************************/
1834 static const char *get_boolean(bool bool_value
)
1836 static const char *yes_str
= "yes";
1837 static const char *no_str
= "no";
1839 return (bool_value
? yes_str
: no_str
);
1842 /***************************************************************************
1843 Provide the string of the negated boolean value associated to the boolean
1844 given as a string. Returns false if the passed string does not correctly
1845 represent a boolean.
1846 ***************************************************************************/
1848 bool lp_invert_boolean(const char *str
, const char **inverse_str
)
1852 if (!set_boolean(str
, &val
)) {
1856 *inverse_str
= get_boolean(!val
);
1860 /***************************************************************************
1861 Provide the canonical string representation of a boolean value given
1862 as a string. Return true on success, false if the string given does
1863 not correctly represent a boolean.
1864 ***************************************************************************/
1866 bool lp_canonicalize_boolean(const char *str
, const char**canon_str
)
1870 if (!set_boolean(str
, &val
)) {
1874 *canon_str
= get_boolean(val
);
1878 /***************************************************************************
1879 Find a service by name. Otherwise works like get_service.
1880 ***************************************************************************/
1882 int getservicebyname(const char *pszServiceName
, struct loadparm_service
*pserviceDest
)
1889 if (ServiceHash
== NULL
) {
1893 canon_name
= canonicalize_servicename(talloc_tos(), pszServiceName
);
1895 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
, canon_name
,
1898 if (NT_STATUS_IS_OK(status
) &&
1899 (data
.dptr
!= NULL
) &&
1900 (data
.dsize
== sizeof(iService
)))
1902 iService
= *(int *)data
.dptr
;
1905 TALLOC_FREE(canon_name
);
1907 if ((iService
!= -1) && (LP_SNUM_OK(iService
))
1908 && (pserviceDest
!= NULL
)) {
1909 copy_service(pserviceDest
, ServicePtrs
[iService
], NULL
);
1915 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
1916 struct loadparm_service
*lp_service(const char *pszServiceName
)
1918 int iService
= getservicebyname(pszServiceName
, NULL
);
1919 if (iService
== -1 || !LP_SNUM_OK(iService
)) {
1922 return ServicePtrs
[iService
];
1925 struct loadparm_service
*lp_servicebynum(int snum
)
1927 if ((snum
== -1) || !LP_SNUM_OK(snum
)) {
1930 return ServicePtrs
[snum
];
1933 struct loadparm_service
*lp_default_loadparm_service()
1938 static struct smbconf_ctx
*lp_smbconf_ctx(void)
1941 static struct smbconf_ctx
*conf_ctx
= NULL
;
1943 if (conf_ctx
== NULL
) {
1944 err
= smbconf_init(NULL
, &conf_ctx
, "registry:");
1945 if (!SBC_ERROR_IS_OK(err
)) {
1946 DEBUG(1, ("error initializing registry configuration: "
1947 "%s\n", sbcErrorString(err
)));
1955 static bool process_smbconf_service(struct smbconf_service
*service
)
1960 if (service
== NULL
) {
1964 ret
= lp_do_section(service
->name
, NULL
);
1968 for (count
= 0; count
< service
->num_params
; count
++) {
1970 if (!bInGlobalSection
&& bGlobalOnly
) {
1973 const char *pszParmName
= service
->param_names
[count
];
1974 const char *pszParmValue
= service
->param_values
[count
];
1976 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName
, pszParmValue
));
1978 ret
= lp_do_parameter(bInGlobalSection
? -2 : iServiceIndex
,
1979 pszParmName
, pszParmValue
);
1986 if (iServiceIndex
>= 0) {
1987 return lpcfg_service_ok(ServicePtrs
[iServiceIndex
]);
1993 * load a service from registry and activate it
1995 bool process_registry_service(const char *service_name
)
1998 struct smbconf_service
*service
= NULL
;
1999 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
2000 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2003 if (conf_ctx
== NULL
) {
2007 DEBUG(5, ("process_registry_service: service name %s\n", service_name
));
2009 if (!smbconf_share_exists(conf_ctx
, service_name
)) {
2011 * Registry does not contain data for this service (yet),
2012 * but make sure lp_load doesn't return false.
2018 err
= smbconf_get_share(conf_ctx
, mem_ctx
, service_name
, &service
);
2019 if (!SBC_ERROR_IS_OK(err
)) {
2023 ret
= process_smbconf_service(service
);
2029 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
2032 TALLOC_FREE(mem_ctx
);
2037 * process_registry_globals
2039 static bool process_registry_globals(void)
2043 add_to_file_list(NULL
, &file_lists
, INCLUDE_REGISTRY_NAME
, INCLUDE_REGISTRY_NAME
);
2045 if (!bInGlobalSection
&& bGlobalOnly
) {
2048 const char *pszParmName
= "registry shares";
2049 const char *pszParmValue
= "yes";
2051 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName
, pszParmValue
));
2053 ret
= lp_do_parameter(bInGlobalSection
? -2 : iServiceIndex
,
2054 pszParmName
, pszParmValue
);
2061 return process_registry_service(GLOBAL_NAME
);
2064 bool process_registry_shares(void)
2068 struct smbconf_service
**service
= NULL
;
2069 uint32_t num_shares
= 0;
2070 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
2071 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2074 if (conf_ctx
== NULL
) {
2078 err
= smbconf_get_config(conf_ctx
, mem_ctx
, &num_shares
, &service
);
2079 if (!SBC_ERROR_IS_OK(err
)) {
2085 for (count
= 0; count
< num_shares
; count
++) {
2086 if (strequal(service
[count
]->name
, GLOBAL_NAME
)) {
2089 ret
= process_smbconf_service(service
[count
]);
2096 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
2099 TALLOC_FREE(mem_ctx
);
2104 * reload those shares from registry that are already
2105 * activated in the services array.
2107 static bool reload_registry_shares(void)
2112 for (i
= 0; i
< iNumServices
; i
++) {
2117 if (ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
2121 ret
= process_registry_service(ServicePtrs
[i
]->szService
);
2132 #define MAX_INCLUDE_DEPTH 100
2134 static uint8_t include_depth
;
2137 * Free the file lists
2139 static void free_file_list(void)
2141 struct file_lists
*f
;
2142 struct file_lists
*next
;
2155 * Utility function for outsiders to check if we're running on registry.
2157 bool lp_config_backend_is_registry(void)
2159 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY
);
2163 * Utility function to check if the config backend is FILE.
2165 bool lp_config_backend_is_file(void)
2167 return (lp_config_backend() == CONFIG_BACKEND_FILE
);
2170 /*******************************************************************
2171 Check if a config file has changed date.
2172 ********************************************************************/
2174 bool lp_file_list_changed(void)
2176 struct file_lists
*f
= file_lists
;
2178 DEBUG(6, ("lp_file_list_changed()\n"));
2181 if (strequal(f
->name
, INCLUDE_REGISTRY_NAME
)) {
2182 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2184 if (conf_ctx
== NULL
) {
2187 if (smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
,
2190 DEBUGADD(6, ("registry config changed\n"));
2197 n2
= talloc_sub_basic(talloc_tos(),
2198 get_current_username(),
2199 current_user_info
.domain
,
2204 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2205 f
->name
, n2
, ctime(&f
->modtime
)));
2207 mod_time
= file_modtime(n2
);
2210 ((f
->modtime
!= mod_time
) ||
2211 (f
->subfname
== NULL
) ||
2212 (strcmp(n2
, f
->subfname
) != 0)))
2215 ("file %s modified: %s\n", n2
,
2217 f
->modtime
= mod_time
;
2218 TALLOC_FREE(f
->subfname
);
2219 f
->subfname
= talloc_strdup(f
, n2
);
2220 if (f
->subfname
== NULL
) {
2221 smb_panic("talloc_strdup failed");
2235 * Initialize iconv conversion descriptors.
2237 * This is called the first time it is needed, and also called again
2238 * every time the configuration is reloaded, because the charset or
2239 * codepage might have changed.
2241 static void init_iconv(void)
2243 global_iconv_handle
= smb_iconv_handle_reinit(NULL
, lp_dos_charset(),
2245 true, global_iconv_handle
);
2248 /***************************************************************************
2249 Handle the include operation.
2250 ***************************************************************************/
2251 static bool bAllowIncludeRegistry
= true;
2253 bool lp_include(struct loadparm_context
*lp_ctx
, struct loadparm_service
*service
,
2254 const char *pszParmValue
, char **ptr
)
2258 if (include_depth
>= MAX_INCLUDE_DEPTH
) {
2259 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2264 if (strequal(pszParmValue
, INCLUDE_REGISTRY_NAME
)) {
2265 if (!bAllowIncludeRegistry
) {
2268 if (lp_ctx
->bInGlobalSection
) {
2271 ret
= process_registry_globals();
2275 DEBUG(1, ("\"include = registry\" only effective "
2276 "in %s section\n", GLOBAL_NAME
));
2281 fname
= talloc_sub_basic(talloc_tos(), get_current_username(),
2282 current_user_info
.domain
,
2285 add_to_file_list(NULL
, &file_lists
, pszParmValue
, fname
);
2287 if (service
== NULL
) {
2288 string_set(Globals
.ctx
, ptr
, fname
);
2290 string_set(service
, ptr
, fname
);
2293 if (file_exist(fname
)) {
2296 ret
= pm_process(fname
, lp_do_section
, do_parameter
, lp_ctx
);
2302 DEBUG(2, ("Can't find include file %s\n", fname
));
2307 bool lp_idmap_range(const char *domain_name
, uint32_t *low
, uint32_t *high
)
2309 char *config_option
= NULL
;
2310 const char *range
= NULL
;
2313 SMB_ASSERT(low
!= NULL
);
2314 SMB_ASSERT(high
!= NULL
);
2316 if ((domain_name
== NULL
) || (domain_name
[0] == '\0')) {
2320 config_option
= talloc_asprintf(talloc_tos(), "idmap config %s",
2322 if (config_option
== NULL
) {
2323 DEBUG(0, ("out of memory\n"));
2327 range
= lp_parm_const_string(-1, config_option
, "range", NULL
);
2328 if (range
== NULL
) {
2329 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name
));
2333 if (sscanf(range
, "%u - %u", low
, high
) != 2) {
2334 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2335 range
, domain_name
));
2342 talloc_free(config_option
);
2347 bool lp_idmap_default_range(uint32_t *low
, uint32_t *high
)
2349 return lp_idmap_range("*", low
, high
);
2352 const char *lp_idmap_backend(const char *domain_name
)
2354 char *config_option
= NULL
;
2355 const char *backend
= NULL
;
2357 if ((domain_name
== NULL
) || (domain_name
[0] == '\0')) {
2361 config_option
= talloc_asprintf(talloc_tos(), "idmap config %s",
2363 if (config_option
== NULL
) {
2364 DEBUG(0, ("out of memory\n"));
2368 backend
= lp_parm_const_string(-1, config_option
, "backend", NULL
);
2369 if (backend
== NULL
) {
2370 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name
));
2375 talloc_free(config_option
);
2379 const char *lp_idmap_default_backend(void)
2381 return lp_idmap_backend("*");
2384 /***************************************************************************
2385 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2386 ***************************************************************************/
2388 static const char *append_ldap_suffix(TALLOC_CTX
*ctx
, const char *str
)
2390 const char *suffix_string
;
2392 suffix_string
= talloc_asprintf(ctx
, "%s,%s", str
,
2393 Globals
.ldap_suffix
);
2394 if ( !suffix_string
) {
2395 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2399 return suffix_string
;
2402 const char *lp_ldap_machine_suffix(TALLOC_CTX
*ctx
)
2404 if (Globals
._ldap_machine_suffix
[0])
2405 return append_ldap_suffix(ctx
, Globals
._ldap_machine_suffix
);
2407 return lp_string(ctx
, Globals
.ldap_suffix
);
2410 const char *lp_ldap_user_suffix(TALLOC_CTX
*ctx
)
2412 if (Globals
._ldap_user_suffix
[0])
2413 return append_ldap_suffix(ctx
, Globals
._ldap_user_suffix
);
2415 return lp_string(ctx
, Globals
.ldap_suffix
);
2418 const char *lp_ldap_group_suffix(TALLOC_CTX
*ctx
)
2420 if (Globals
._ldap_group_suffix
[0])
2421 return append_ldap_suffix(ctx
, Globals
._ldap_group_suffix
);
2423 return lp_string(ctx
, Globals
.ldap_suffix
);
2426 const char *lp_ldap_idmap_suffix(TALLOC_CTX
*ctx
)
2428 if (Globals
._ldap_idmap_suffix
[0])
2429 return append_ldap_suffix(ctx
, Globals
._ldap_idmap_suffix
);
2431 return lp_string(ctx
, Globals
.ldap_suffix
);
2435 return the parameter pointer for a parameter
2437 void *lp_parm_ptr(struct loadparm_service
*service
, struct parm_struct
*parm
)
2439 if (service
== NULL
) {
2440 if (parm
->p_class
== P_LOCAL
)
2441 return (void *)(((char *)&sDefault
)+parm
->offset
);
2442 else if (parm
->p_class
== P_GLOBAL
)
2443 return (void *)(((char *)&Globals
)+parm
->offset
);
2446 return (void *)(((char *)service
) + parm
->offset
);
2450 /***************************************************************************
2451 Process a parameter for a particular service number. If snum < 0
2452 then assume we are in the globals.
2453 ***************************************************************************/
2455 bool lp_do_parameter(int snum
, const char *pszParmName
, const char *pszParmValue
)
2457 TALLOC_CTX
*frame
= talloc_stackframe();
2458 struct loadparm_context
*lp_ctx
;
2461 lp_ctx
= setup_lp_context(frame
);
2462 if (lp_ctx
== NULL
) {
2468 ok
= lpcfg_do_global_parameter(lp_ctx
, pszParmName
, pszParmValue
);
2470 ok
= lpcfg_do_service_parameter(lp_ctx
, ServicePtrs
[snum
],
2471 pszParmName
, pszParmValue
);
2479 /***************************************************************************
2480 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2481 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2482 ***************************************************************************/
2484 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
)
2487 parmnum
= lpcfg_map_parameter(pszParmName
);
2489 flags_list
[parmnum
] &= ~FLAG_CMDLINE
;
2490 if (!lp_do_parameter(-1, pszParmName
, pszParmValue
)) {
2493 flags_list
[parmnum
] |= FLAG_CMDLINE
;
2495 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2496 * be grouped in the table, so we don't have to search the
2499 i
>=0 && parm_table
[i
].offset
== parm_table
[parmnum
].offset
2500 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;
2502 flags_list
[i
] |= FLAG_CMDLINE
;
2504 for (i
=parmnum
+1;i
<num_parameters() && parm_table
[i
].offset
== parm_table
[parmnum
].offset
2505 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;i
++) {
2506 flags_list
[i
] |= FLAG_CMDLINE
;
2512 /* it might be parametric */
2513 if (strchr(pszParmName
, ':') != NULL
) {
2514 set_param_opt(NULL
, &Globals
.param_opt
, pszParmName
, pszParmValue
, FLAG_CMDLINE
);
2518 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName
));
2522 bool lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
2525 TALLOC_CTX
*frame
= talloc_stackframe();
2526 struct loadparm_context
*lp_ctx
;
2528 lp_ctx
= setup_lp_context(frame
);
2529 if (lp_ctx
== NULL
) {
2534 ret
= lpcfg_set_cmdline(lp_ctx
, pszParmName
, pszParmValue
);
2540 /***************************************************************************
2541 Process a parameter.
2542 ***************************************************************************/
2544 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
2547 if (!bInGlobalSection
&& bGlobalOnly
)
2550 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName
, pszParmValue
));
2552 if (bInGlobalSection
) {
2553 return lpcfg_do_global_parameter(userdata
, pszParmName
, pszParmValue
);
2555 return lpcfg_do_service_parameter(userdata
, ServicePtrs
[iServiceIndex
],
2556 pszParmName
, pszParmValue
);
2560 /***************************************************************************
2561 Initialize any local variables in the sDefault table, after parsing a
2563 ***************************************************************************/
2565 static void init_locals(void)
2568 * We run this check once the [globals] is parsed, to force
2569 * the VFS objects and other per-share settings we need for
2570 * the standard way a AD DC is operated. We may change these
2571 * as our code evolves, which is why we force these settings.
2573 * We can't do this at the end of lp_load_ex(), as by that
2574 * point the services have been loaded and they will already
2575 * have "" as their vfs objects.
2577 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
2578 const char **vfs_objects
= lp_vfs_objects(-1);
2579 if (!vfs_objects
|| !vfs_objects
[0]) {
2580 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL
)) {
2581 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2582 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL
)) {
2583 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2585 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2589 lp_do_parameter(-1, "map hidden", "no");
2590 lp_do_parameter(-1, "map system", "no");
2591 lp_do_parameter(-1, "map readonly", "no");
2592 lp_do_parameter(-1, "map archive", "no");
2593 lp_do_parameter(-1, "store dos attributes", "yes");
2597 /***************************************************************************
2598 Process a new section (service). At this stage all sections are services.
2599 Later we'll have special sections that permit server parameters to be set.
2600 Returns true on success, false on failure.
2601 ***************************************************************************/
2603 bool lp_do_section(const char *pszSectionName
, void *userdata
)
2605 struct loadparm_context
*lp_ctx
= (struct loadparm_context
*)userdata
;
2607 bool isglobal
= ((strwicmp(pszSectionName
, GLOBAL_NAME
) == 0) ||
2608 (strwicmp(pszSectionName
, GLOBAL_NAME2
) == 0));
2611 /* if we were in a global section then do the local inits */
2612 if (bInGlobalSection
&& !isglobal
)
2615 /* if we've just struck a global section, note the fact. */
2616 bInGlobalSection
= isglobal
;
2617 if (lp_ctx
!= NULL
) {
2618 lp_ctx
->bInGlobalSection
= isglobal
;
2621 /* check for multiple global sections */
2622 if (bInGlobalSection
) {
2623 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName
));
2627 if (!bInGlobalSection
&& bGlobalOnly
)
2630 /* if we have a current service, tidy it up before moving on */
2633 if (iServiceIndex
>= 0)
2634 bRetval
= lpcfg_service_ok(ServicePtrs
[iServiceIndex
]);
2636 /* if all is still well, move to the next record in the services array */
2638 /* We put this here to avoid an odd message order if messages are */
2639 /* issued by the post-processing of a previous section. */
2640 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName
));
2642 iServiceIndex
= add_a_service(&sDefault
, pszSectionName
);
2643 if (iServiceIndex
< 0) {
2644 DEBUG(0, ("Failed to add a new service\n"));
2647 /* Clean all parametric options for service */
2648 /* They will be added during parsing again */
2649 free_param_opts(&ServicePtrs
[iServiceIndex
]->param_opt
);
2655 /***************************************************************************
2656 Display the contents of a parameter of a single services record.
2657 ***************************************************************************/
2659 bool dump_a_parameter(int snum
, char *parm_name
, FILE * f
, bool isGlobal
)
2661 bool result
= false;
2662 struct loadparm_context
*lp_ctx
;
2664 lp_ctx
= setup_lp_context(talloc_tos());
2665 if (lp_ctx
== NULL
) {
2670 result
= lpcfg_dump_a_parameter(lp_ctx
, NULL
, parm_name
, f
);
2672 result
= lpcfg_dump_a_parameter(lp_ctx
, ServicePtrs
[snum
], parm_name
, f
);
2674 TALLOC_FREE(lp_ctx
);
2679 /***************************************************************************
2680 Display the contents of a single copy structure.
2681 ***************************************************************************/
2682 static void dump_copy_map(bool *pcopymap
)
2688 printf("\n\tNon-Copied parameters:\n");
2690 for (i
= 0; parm_table
[i
].label
; i
++)
2691 if (parm_table
[i
].p_class
== P_LOCAL
&&
2692 parm_table
[i
].ptr
&& !pcopymap
[i
] &&
2693 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
- 1].ptr
)))
2695 printf("\t\t%s\n", parm_table
[i
].label
);
2700 /***************************************************************************
2701 Return TRUE if the passed service number is within range.
2702 ***************************************************************************/
2704 bool lp_snum_ok(int iService
)
2706 return (LP_SNUM_OK(iService
) && ServicePtrs
[iService
]->available
);
2709 /***************************************************************************
2710 Auto-load some home services.
2711 ***************************************************************************/
2713 static void lp_add_auto_services(char *str
)
2723 s
= talloc_strdup(talloc_tos(), str
);
2725 smb_panic("talloc_strdup failed");
2729 homes
= lp_servicenumber(HOMES_NAME
);
2731 for (p
= strtok_r(s
, LIST_SEP
, &saveptr
); p
;
2732 p
= strtok_r(NULL
, LIST_SEP
, &saveptr
)) {
2735 if (lp_servicenumber(p
) >= 0)
2738 home
= get_user_home_dir(talloc_tos(), p
);
2740 if (home
&& home
[0] && homes
>= 0)
2741 lp_add_home(p
, homes
, p
, home
);
2748 /***************************************************************************
2749 Auto-load one printer.
2750 ***************************************************************************/
2752 void lp_add_one_printer(const char *name
, const char *comment
,
2753 const char *location
, void *pdata
)
2755 int printers
= lp_servicenumber(PRINTERS_NAME
);
2758 if (lp_servicenumber(name
) < 0) {
2759 lp_add_printer(name
, printers
);
2760 if ((i
= lp_servicenumber(name
)) >= 0) {
2761 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->comment
, comment
);
2762 ServicePtrs
[i
]->autoloaded
= true;
2767 /***************************************************************************
2768 Have we loaded a services file yet?
2769 ***************************************************************************/
2771 bool lp_loaded(void)
2776 /***************************************************************************
2777 Unload unused services.
2778 ***************************************************************************/
2780 void lp_killunused(struct smbd_server_connection
*sconn
,
2781 bool (*snumused
) (struct smbd_server_connection
*, int))
2784 for (i
= 0; i
< iNumServices
; i
++) {
2788 /* don't kill autoloaded or usershare services */
2789 if ( ServicePtrs
[i
]->autoloaded
||
2790 ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
2794 if (!snumused
|| !snumused(sconn
, i
)) {
2795 free_service_byindex(i
);
2801 * Kill all except autoloaded and usershare services - convenience wrapper
2803 void lp_kill_all_services(void)
2805 lp_killunused(NULL
, NULL
);
2808 /***************************************************************************
2810 ***************************************************************************/
2812 void lp_killservice(int iServiceIn
)
2814 if (VALID(iServiceIn
)) {
2815 free_service_byindex(iServiceIn
);
2819 /***************************************************************************
2820 Save the curent values of all global and sDefault parameters into the
2821 defaults union. This allows testparm to show only the
2822 changed (ie. non-default) parameters.
2823 ***************************************************************************/
2825 static void lp_save_defaults(void)
2828 struct parmlist_entry
* parm
;
2829 for (i
= 0; parm_table
[i
].label
; i
++) {
2830 if (!(flags_list
[i
] & FLAG_CMDLINE
)) {
2831 flags_list
[i
] |= FLAG_DEFAULT
;
2834 if (i
> 0 && parm_table
[i
].offset
== parm_table
[i
- 1].offset
2835 && parm_table
[i
].p_class
== parm_table
[i
- 1].p_class
)
2837 switch (parm_table
[i
].type
) {
2840 parm_table
[i
].def
.lvalue
= str_list_copy(
2841 NULL
, *(const char ***)lp_parm_ptr(NULL
, &parm_table
[i
]));
2845 parm_table
[i
].def
.svalue
= talloc_strdup(Globals
.ctx
, *(char **)lp_parm_ptr(NULL
, &parm_table
[i
]));
2846 if (parm_table
[i
].def
.svalue
== NULL
) {
2847 smb_panic("talloc_strdup failed");
2852 parm_table
[i
].def
.bvalue
=
2853 *(bool *)lp_parm_ptr(NULL
, &parm_table
[i
]);
2856 parm_table
[i
].def
.cvalue
=
2857 *(char *)lp_parm_ptr(NULL
, &parm_table
[i
]);
2863 parm_table
[i
].def
.ivalue
=
2864 *(int *)lp_parm_ptr(NULL
, &parm_table
[i
]);
2869 for (parm
=Globals
.param_opt
; parm
; parm
=parm
->next
) {
2870 if (!(parm
->priority
& FLAG_CMDLINE
)) {
2871 parm
->priority
|= FLAG_DEFAULT
;
2875 for (parm
=sDefault
.param_opt
; parm
; parm
=parm
->next
) {
2876 if (!(parm
->priority
& FLAG_CMDLINE
)) {
2877 parm
->priority
|= FLAG_DEFAULT
;
2881 defaults_saved
= true;
2884 /***********************************************************
2885 If we should send plaintext/LANMAN passwords in the clinet
2886 ************************************************************/
2888 static void set_allowed_client_auth(void)
2890 if (Globals
.client_ntlmv2_auth
) {
2891 Globals
.client_lanman_auth
= false;
2893 if (!Globals
.client_lanman_auth
) {
2894 Globals
.client_plaintext_auth
= false;
2898 /***************************************************************************
2900 The following code allows smbd to read a user defined share file.
2901 Yes, this is my intent. Yes, I'm comfortable with that...
2903 THE FOLLOWING IS SECURITY CRITICAL CODE.
2905 It washes your clothes, it cleans your house, it guards you while you sleep...
2906 Do not f%^k with it....
2907 ***************************************************************************/
2909 #define MAX_USERSHARE_FILE_SIZE (10*1024)
2911 /***************************************************************************
2912 Check allowed stat state of a usershare file.
2913 Ensure we print out who is dicking with us so the admin can
2914 get their sorry ass fired.
2915 ***************************************************************************/
2917 static bool check_usershare_stat(const char *fname
,
2918 const SMB_STRUCT_STAT
*psbuf
)
2920 if (!S_ISREG(psbuf
->st_ex_mode
)) {
2921 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2922 "not a regular file\n",
2923 fname
, (unsigned int)psbuf
->st_ex_uid
));
2927 /* Ensure this doesn't have the other write bit set. */
2928 if (psbuf
->st_ex_mode
& S_IWOTH
) {
2929 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
2930 "public write. Refusing to allow as a usershare file.\n",
2931 fname
, (unsigned int)psbuf
->st_ex_uid
));
2935 /* Should be 10k or less. */
2936 if (psbuf
->st_ex_size
> MAX_USERSHARE_FILE_SIZE
) {
2937 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2938 "too large (%u) to be a user share file.\n",
2939 fname
, (unsigned int)psbuf
->st_ex_uid
,
2940 (unsigned int)psbuf
->st_ex_size
));
2947 /***************************************************************************
2948 Parse the contents of a usershare file.
2949 ***************************************************************************/
2951 enum usershare_err
parse_usershare_file(TALLOC_CTX
*ctx
,
2952 SMB_STRUCT_STAT
*psbuf
,
2953 const char *servicename
,
2957 char **pp_sharepath
,
2959 char **pp_cp_servicename
,
2960 struct security_descriptor
**ppsd
,
2963 const char **prefixallowlist
= lp_usershare_prefix_allow_list();
2964 const char **prefixdenylist
= lp_usershare_prefix_deny_list();
2967 SMB_STRUCT_STAT sbuf
;
2968 char *sharepath
= NULL
;
2969 char *comment
= NULL
;
2971 *pp_sharepath
= NULL
;
2974 *pallow_guest
= false;
2977 return USERSHARE_MALFORMED_FILE
;
2980 if (strcmp(lines
[0], "#VERSION 1") == 0) {
2982 } else if (strcmp(lines
[0], "#VERSION 2") == 0) {
2985 return USERSHARE_MALFORMED_FILE
;
2988 return USERSHARE_BAD_VERSION
;
2991 if (strncmp(lines
[1], "path=", 5) != 0) {
2992 return USERSHARE_MALFORMED_PATH
;
2995 sharepath
= talloc_strdup(ctx
, &lines
[1][5]);
2997 return USERSHARE_POSIX_ERR
;
2999 trim_string(sharepath
, " ", " ");
3001 if (strncmp(lines
[2], "comment=", 8) != 0) {
3002 return USERSHARE_MALFORMED_COMMENT_DEF
;
3005 comment
= talloc_strdup(ctx
, &lines
[2][8]);
3007 return USERSHARE_POSIX_ERR
;
3009 trim_string(comment
, " ", " ");
3010 trim_char(comment
, '"', '"');
3012 if (strncmp(lines
[3], "usershare_acl=", 14) != 0) {
3013 return USERSHARE_MALFORMED_ACL_DEF
;
3016 if (!parse_usershare_acl(ctx
, &lines
[3][14], ppsd
)) {
3017 return USERSHARE_ACL_ERR
;
3021 if (strncmp(lines
[4], "guest_ok=", 9) != 0) {
3022 return USERSHARE_MALFORMED_ACL_DEF
;
3024 if (lines
[4][9] == 'y') {
3025 *pallow_guest
= true;
3028 /* Backwards compatible extension to file version #2. */
3030 if (strncmp(lines
[5], "sharename=", 10) != 0) {
3031 return USERSHARE_MALFORMED_SHARENAME_DEF
;
3033 if (!strequal(&lines
[5][10], servicename
)) {
3034 return USERSHARE_BAD_SHARENAME
;
3036 *pp_cp_servicename
= talloc_strdup(ctx
, &lines
[5][10]);
3037 if (!*pp_cp_servicename
) {
3038 return USERSHARE_POSIX_ERR
;
3043 if (*pp_cp_servicename
== NULL
) {
3044 *pp_cp_servicename
= talloc_strdup(ctx
, servicename
);
3045 if (!*pp_cp_servicename
) {
3046 return USERSHARE_POSIX_ERR
;
3050 if (snum
!= -1 && (strcmp(sharepath
, ServicePtrs
[snum
]->path
) == 0)) {
3051 /* Path didn't change, no checks needed. */
3052 *pp_sharepath
= sharepath
;
3053 *pp_comment
= comment
;
3054 return USERSHARE_OK
;
3057 /* The path *must* be absolute. */
3058 if (sharepath
[0] != '/') {
3059 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3060 servicename
, sharepath
));
3061 return USERSHARE_PATH_NOT_ABSOLUTE
;
3064 /* If there is a usershare prefix deny list ensure one of these paths
3065 doesn't match the start of the user given path. */
3066 if (prefixdenylist
) {
3068 for ( i
=0; prefixdenylist
[i
]; i
++ ) {
3069 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3070 servicename
, i
, prefixdenylist
[i
], sharepath
));
3071 if (memcmp( sharepath
, prefixdenylist
[i
], strlen(prefixdenylist
[i
])) == 0) {
3072 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3073 "usershare prefix deny list entries.\n",
3074 servicename
, sharepath
));
3075 return USERSHARE_PATH_IS_DENIED
;
3080 /* If there is a usershare prefix allow list ensure one of these paths
3081 does match the start of the user given path. */
3083 if (prefixallowlist
) {
3085 for ( i
=0; prefixallowlist
[i
]; i
++ ) {
3086 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3087 servicename
, i
, prefixallowlist
[i
], sharepath
));
3088 if (memcmp( sharepath
, prefixallowlist
[i
], strlen(prefixallowlist
[i
])) == 0) {
3092 if (prefixallowlist
[i
] == NULL
) {
3093 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3094 "usershare prefix allow list entries.\n",
3095 servicename
, sharepath
));
3096 return USERSHARE_PATH_NOT_ALLOWED
;
3100 /* Ensure this is pointing to a directory. */
3101 dp
= opendir(sharepath
);
3104 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3105 servicename
, sharepath
));
3106 return USERSHARE_PATH_NOT_DIRECTORY
;
3109 /* Ensure the owner of the usershare file has permission to share
3112 if (sys_stat(sharepath
, &sbuf
, false) == -1) {
3113 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3114 servicename
, sharepath
, strerror(errno
) ));
3116 return USERSHARE_POSIX_ERR
;
3121 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
3122 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3123 servicename
, sharepath
));
3124 return USERSHARE_PATH_NOT_DIRECTORY
;
3127 /* Check if sharing is restricted to owner-only. */
3128 /* psbuf is the stat of the usershare definition file,
3129 sbuf is the stat of the target directory to be shared. */
3131 if (lp_usershare_owner_only()) {
3132 /* root can share anything. */
3133 if ((psbuf
->st_ex_uid
!= 0) && (sbuf
.st_ex_uid
!= psbuf
->st_ex_uid
)) {
3134 return USERSHARE_PATH_NOT_ALLOWED
;
3138 *pp_sharepath
= sharepath
;
3139 *pp_comment
= comment
;
3140 return USERSHARE_OK
;
3143 /***************************************************************************
3144 Deal with a usershare file.
3147 -1 - Bad name, invalid contents.
3148 - service name already existed and not a usershare, problem
3149 with permissions to share directory etc.
3150 ***************************************************************************/
3152 static int process_usershare_file(const char *dir_name
, const char *file_name
, int snum_template
)
3154 SMB_STRUCT_STAT sbuf
;
3155 SMB_STRUCT_STAT lsbuf
;
3157 char *sharepath
= NULL
;
3158 char *comment
= NULL
;
3159 char *cp_service_name
= NULL
;
3160 char **lines
= NULL
;
3164 TALLOC_CTX
*ctx
= talloc_stackframe();
3165 struct security_descriptor
*psd
= NULL
;
3166 bool guest_ok
= false;
3167 char *canon_name
= NULL
;
3168 bool added_service
= false;
3171 /* Ensure share name doesn't contain invalid characters. */
3172 if (!validate_net_name(file_name
, INVALID_SHARENAME_CHARS
, strlen(file_name
))) {
3173 DEBUG(0,("process_usershare_file: share name %s contains "
3174 "invalid characters (any of %s)\n",
3175 file_name
, INVALID_SHARENAME_CHARS
));
3179 canon_name
= canonicalize_servicename(ctx
, file_name
);
3184 fname
= talloc_asprintf(ctx
, "%s/%s", dir_name
, file_name
);
3189 /* Minimize the race condition by doing an lstat before we
3190 open and fstat. Ensure this isn't a symlink link. */
3192 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
3193 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3194 fname
, strerror(errno
) ));
3198 /* This must be a regular file, not a symlink, directory or
3199 other strange filetype. */
3200 if (!check_usershare_stat(fname
, &lsbuf
)) {
3208 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
,
3213 if (NT_STATUS_IS_OK(status
) &&
3214 (data
.dptr
!= NULL
) &&
3215 (data
.dsize
== sizeof(iService
))) {
3216 memcpy(&iService
, data
.dptr
, sizeof(iService
));
3220 if (iService
!= -1 &&
3221 timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
3222 &lsbuf
.st_ex_mtime
) == 0) {
3223 /* Nothing changed - Mark valid and return. */
3224 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3226 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
3231 /* Try and open the file read only - no symlinks allowed. */
3233 fd
= open(fname
, O_RDONLY
|O_NOFOLLOW
, 0);
3235 fd
= open(fname
, O_RDONLY
, 0);
3239 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3240 fname
, strerror(errno
) ));
3244 /* Now fstat to be *SURE* it's a regular file. */
3245 if (sys_fstat(fd
, &sbuf
, false) != 0) {
3247 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3248 fname
, strerror(errno
) ));
3252 /* Is it the same dev/inode as was lstated ? */
3253 if (!check_same_stat(&lsbuf
, &sbuf
)) {
3255 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3256 "Symlink spoofing going on ?\n", fname
));
3260 /* This must be a regular file, not a symlink, directory or
3261 other strange filetype. */
3262 if (!check_usershare_stat(fname
, &sbuf
)) {
3267 lines
= fd_lines_load(fd
, &numlines
, MAX_USERSHARE_FILE_SIZE
, NULL
);
3270 if (lines
== NULL
) {
3271 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3272 fname
, (unsigned int)sbuf
.st_ex_uid
));
3276 if (parse_usershare_file(ctx
, &sbuf
, file_name
,
3277 iService
, lines
, numlines
, &sharepath
,
3278 &comment
, &cp_service_name
,
3279 &psd
, &guest_ok
) != USERSHARE_OK
) {
3283 /* Everything ok - add the service possibly using a template. */
3285 const struct loadparm_service
*sp
= &sDefault
;
3286 if (snum_template
!= -1) {
3287 sp
= ServicePtrs
[snum_template
];
3290 if ((iService
= add_a_service(sp
, cp_service_name
)) < 0) {
3291 DEBUG(0, ("process_usershare_file: Failed to add "
3292 "new service %s\n", cp_service_name
));
3296 added_service
= true;
3298 /* Read only is controlled by usershare ACL below. */
3299 ServicePtrs
[iService
]->read_only
= false;
3302 /* Write the ACL of the new/modified share. */
3303 if (!set_share_security(canon_name
, psd
)) {
3304 DEBUG(0, ("process_usershare_file: Failed to set share "
3305 "security for user share %s\n",
3310 /* If from a template it may be marked invalid. */
3311 ServicePtrs
[iService
]->valid
= true;
3313 /* Set the service as a valid usershare. */
3314 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
3316 /* Set guest access. */
3317 if (lp_usershare_allow_guests()) {
3318 ServicePtrs
[iService
]->guest_ok
= guest_ok
;
3321 /* And note when it was loaded. */
3322 ServicePtrs
[iService
]->usershare_last_mod
= sbuf
.st_ex_mtime
;
3323 string_set(ServicePtrs
[iService
], &ServicePtrs
[iService
]->path
, sharepath
);
3324 string_set(ServicePtrs
[iService
], &ServicePtrs
[iService
]->comment
, comment
);
3330 if (ret
== -1 && iService
!= -1 && added_service
) {
3331 lp_remove_service(iService
);
3339 /***************************************************************************
3340 Checks if a usershare entry has been modified since last load.
3341 ***************************************************************************/
3343 static bool usershare_exists(int iService
, struct timespec
*last_mod
)
3345 SMB_STRUCT_STAT lsbuf
;
3346 const char *usersharepath
= Globals
.usershare_path
;
3349 fname
= talloc_asprintf(talloc_tos(),
3352 ServicePtrs
[iService
]->szService
);
3353 if (fname
== NULL
) {
3357 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
3362 if (!S_ISREG(lsbuf
.st_ex_mode
)) {
3368 *last_mod
= lsbuf
.st_ex_mtime
;
3372 /***************************************************************************
3373 Load a usershare service by name. Returns a valid servicenumber or -1.
3374 ***************************************************************************/
3376 int load_usershare_service(const char *servicename
)
3378 SMB_STRUCT_STAT sbuf
;
3379 const char *usersharepath
= Globals
.usershare_path
;
3380 int max_user_shares
= Globals
.usershare_max_shares
;
3381 int snum_template
= -1;
3383 if (*usersharepath
== 0 || max_user_shares
== 0) {
3387 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
3388 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3389 usersharepath
, strerror(errno
) ));
3393 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
3394 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3400 * This directory must be owned by root, and have the 't' bit set.
3401 * It also must not be writable by "other".
3405 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
3407 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
3409 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3410 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3415 /* Ensure the template share exists if it's set. */
3416 if (Globals
.usershare_template_share
[0]) {
3417 /* We can't use lp_servicenumber here as we are recommending that
3418 template shares have -valid=false set. */
3419 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
3420 if (ServicePtrs
[snum_template
]->szService
&&
3421 strequal(ServicePtrs
[snum_template
]->szService
,
3422 Globals
.usershare_template_share
)) {
3427 if (snum_template
== -1) {
3428 DEBUG(0,("load_usershare_service: usershare template share %s "
3429 "does not exist.\n",
3430 Globals
.usershare_template_share
));
3435 return process_usershare_file(usersharepath
, servicename
, snum_template
);
3438 /***************************************************************************
3439 Load all user defined shares from the user share directory.
3440 We only do this if we're enumerating the share list.
3441 This is the function that can delete usershares that have
3443 ***************************************************************************/
3445 int load_usershare_shares(struct smbd_server_connection
*sconn
,
3446 bool (*snumused
) (struct smbd_server_connection
*, int))
3449 SMB_STRUCT_STAT sbuf
;
3451 int num_usershares
= 0;
3452 int max_user_shares
= Globals
.usershare_max_shares
;
3453 unsigned int num_dir_entries
, num_bad_dir_entries
, num_tmp_dir_entries
;
3454 unsigned int allowed_bad_entries
= ((2*max_user_shares
)/10);
3455 unsigned int allowed_tmp_entries
= ((2*max_user_shares
)/10);
3457 int snum_template
= -1;
3458 const char *usersharepath
= Globals
.usershare_path
;
3459 int ret
= lp_numservices();
3460 TALLOC_CTX
*tmp_ctx
;
3462 if (max_user_shares
== 0 || *usersharepath
== '\0') {
3463 return lp_numservices();
3466 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
3467 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3468 usersharepath
, strerror(errno
) ));
3473 * This directory must be owned by root, and have the 't' bit set.
3474 * It also must not be writable by "other".
3478 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
3480 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
3482 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3483 "or does not have the sticky bit 't' set or is writable by anyone.\n",
3488 /* Ensure the template share exists if it's set. */
3489 if (Globals
.usershare_template_share
[0]) {
3490 /* We can't use lp_servicenumber here as we are recommending that
3491 template shares have -valid=false set. */
3492 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
3493 if (ServicePtrs
[snum_template
]->szService
&&
3494 strequal(ServicePtrs
[snum_template
]->szService
,
3495 Globals
.usershare_template_share
)) {
3500 if (snum_template
== -1) {
3501 DEBUG(0,("load_usershare_shares: usershare template share %s "
3502 "does not exist.\n",
3503 Globals
.usershare_template_share
));
3508 /* Mark all existing usershares as pending delete. */
3509 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
3510 if (VALID(iService
) && ServicePtrs
[iService
]->usershare
) {
3511 ServicePtrs
[iService
]->usershare
= USERSHARE_PENDING_DELETE
;
3515 dp
= opendir(usersharepath
);
3517 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3518 usersharepath
, strerror(errno
) ));
3522 for (num_dir_entries
= 0, num_bad_dir_entries
= 0, num_tmp_dir_entries
= 0;
3524 num_dir_entries
++ ) {
3526 const char *n
= de
->d_name
;
3528 /* Ignore . and .. */
3530 if ((n
[1] == '\0') || (n
[1] == '.' && n
[2] == '\0')) {
3536 /* Temporary file used when creating a share. */
3537 num_tmp_dir_entries
++;
3540 /* Allow 20% tmp entries. */
3541 if (num_tmp_dir_entries
> allowed_tmp_entries
) {
3542 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3543 "in directory %s\n",
3544 num_tmp_dir_entries
, usersharepath
));
3548 r
= process_usershare_file(usersharepath
, n
, snum_template
);
3550 /* Update the services count. */
3552 if (num_usershares
>= max_user_shares
) {
3553 DEBUG(0,("load_usershare_shares: max user shares reached "
3554 "on file %s in directory %s\n",
3555 n
, usersharepath
));
3558 } else if (r
== -1) {
3559 num_bad_dir_entries
++;
3562 /* Allow 20% bad entries. */
3563 if (num_bad_dir_entries
> allowed_bad_entries
) {
3564 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3565 "in directory %s\n",
3566 num_bad_dir_entries
, usersharepath
));
3570 /* Allow 20% bad entries. */
3571 if (num_dir_entries
> max_user_shares
+ allowed_bad_entries
) {
3572 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3573 "in directory %s\n",
3574 num_dir_entries
, usersharepath
));
3581 /* Sweep through and delete any non-refreshed usershares that are
3582 not currently in use. */
3583 tmp_ctx
= talloc_stackframe();
3584 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
3585 if (VALID(iService
) && (ServicePtrs
[iService
]->usershare
== USERSHARE_PENDING_DELETE
)) {
3588 if (snumused
&& snumused(sconn
, iService
)) {
3592 servname
= lp_servicename(tmp_ctx
, iService
);
3594 /* Remove from the share ACL db. */
3595 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3597 delete_share_security(servname
);
3598 free_service_byindex(iService
);
3601 talloc_free(tmp_ctx
);
3603 return lp_numservices();
3606 /********************************************************
3607 Destroy global resources allocated in this file
3608 ********************************************************/
3610 void gfree_loadparm(void)
3616 /* Free resources allocated to services */
3618 for ( i
= 0; i
< iNumServices
; i
++ ) {
3620 free_service_byindex(i
);
3624 TALLOC_FREE( ServicePtrs
);
3627 /* Now release all resources allocated to global
3628 parameters and the default service */
3630 free_global_parameters();
3634 /***************************************************************************
3635 Allow client apps to specify that they are a client
3636 ***************************************************************************/
3637 static void lp_set_in_client(bool b
)
3643 /***************************************************************************
3644 Determine if we're running in a client app
3645 ***************************************************************************/
3646 static bool lp_is_in_client(void)
3651 static void lp_enforce_ad_dc_settings(void)
3653 lp_do_parameter(GLOBAL_SECTION_SNUM
, "passdb backend", "samba_dsdb");
3654 lp_do_parameter(GLOBAL_SECTION_SNUM
,
3655 "winbindd:use external pipes", "true");
3656 lp_do_parameter(GLOBAL_SECTION_SNUM
, "rpc_server:default", "external");
3657 lp_do_parameter(GLOBAL_SECTION_SNUM
, "rpc_server:svcctl", "embedded");
3658 lp_do_parameter(GLOBAL_SECTION_SNUM
, "rpc_server:srvsvc", "embedded");
3659 lp_do_parameter(GLOBAL_SECTION_SNUM
, "rpc_server:eventlog", "embedded");
3660 lp_do_parameter(GLOBAL_SECTION_SNUM
, "rpc_server:ntsvcs", "embedded");
3661 lp_do_parameter(GLOBAL_SECTION_SNUM
, "rpc_server:winreg", "embedded");
3662 lp_do_parameter(GLOBAL_SECTION_SNUM
, "rpc_server:spoolss", "embedded");
3663 lp_do_parameter(GLOBAL_SECTION_SNUM
, "rpc_daemon:spoolssd", "embedded");
3664 lp_do_parameter(GLOBAL_SECTION_SNUM
, "rpc_server:tcpip", "no");
3667 /***************************************************************************
3668 Load the services array from the services file. Return true on success,
3670 ***************************************************************************/
3672 static bool lp_load_ex(const char *pszFname
,
3676 bool reinit_globals
,
3677 bool allow_include_registry
,
3678 bool load_all_shares
)
3682 TALLOC_CTX
*frame
= talloc_stackframe();
3683 struct loadparm_context
*lp_ctx
;
3687 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3689 bInGlobalSection
= true;
3690 bGlobalOnly
= global_only
;
3691 bAllowIncludeRegistry
= allow_include_registry
;
3693 lp_ctx
= setup_lp_context(talloc_tos());
3695 init_globals(lp_ctx
, reinit_globals
);
3699 if (save_defaults
) {
3704 if (!reinit_globals
) {
3705 free_param_opts(&Globals
.param_opt
);
3706 apply_lp_set_cmdline();
3709 lp_do_parameter(-1, "idmap config * : backend", Globals
.idmap_backend
);
3711 /* We get sections first, so have to start 'behind' to make up */
3714 if (lp_config_backend_is_file()) {
3715 n2
= talloc_sub_basic(talloc_tos(), get_current_username(),
3716 current_user_info
.domain
,
3719 smb_panic("lp_load_ex: out of memory");
3722 add_to_file_list(NULL
, &file_lists
, pszFname
, n2
);
3724 bRetval
= pm_process(n2
, lp_do_section
, do_parameter
, lp_ctx
);
3727 /* finish up the last section */
3728 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval
)));
3730 if (iServiceIndex
>= 0) {
3731 bRetval
= lpcfg_service_ok(ServicePtrs
[iServiceIndex
]);
3735 if (lp_config_backend_is_registry()) {
3737 /* config backend changed to registry in config file */
3739 * We need to use this extra global variable here to
3740 * survive restart: init_globals uses this as a default
3741 * for config_backend. Otherwise, init_globals would
3742 * send us into an endless loop here.
3745 config_backend
= CONFIG_BACKEND_REGISTRY
;
3747 DEBUG(1, ("lp_load_ex: changing to config backend "
3749 init_globals(lp_ctx
, true);
3751 TALLOC_FREE(lp_ctx
);
3753 lp_kill_all_services();
3754 ok
= lp_load_ex(pszFname
, global_only
, save_defaults
,
3755 add_ipc
, reinit_globals
,
3756 allow_include_registry
,
3761 } else if (lp_config_backend_is_registry()) {
3762 bRetval
= process_registry_globals();
3764 DEBUG(0, ("Illegal config backend given: %d\n",
3765 lp_config_backend()));
3769 if (bRetval
&& lp_registry_shares()) {
3770 if (load_all_shares
) {
3771 bRetval
= process_registry_shares();
3773 bRetval
= reload_registry_shares();
3778 char *serv
= lp_auto_services(talloc_tos());
3779 lp_add_auto_services(serv
);
3784 /* When 'restrict anonymous = 2' guest connections to ipc$
3786 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3787 if ( lp_enable_asu_support() ) {
3788 lp_add_ipc("ADMIN$", false);
3792 set_allowed_client_auth();
3794 if (lp_security() == SEC_ADS
&& strchr(lp_password_server(), ':')) {
3795 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
3796 lp_password_server()));
3801 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
3802 /* if we_are_a_wins_server is true and we are in the client */
3803 if (lp_is_in_client() && Globals
.we_are_a_wins_server
) {
3804 lp_do_parameter(GLOBAL_SECTION_SNUM
, "wins server", "127.0.0.1");
3809 fault_configure(smb_panic_s3
);
3812 * We run this check once the whole smb.conf is parsed, to
3813 * force some settings for the standard way a AD DC is
3814 * operated. We may change these as our code evolves, which
3815 * is why we force these settings.
3817 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
3818 lp_enforce_ad_dc_settings();
3821 bAllowIncludeRegistry
= true;
3827 static bool lp_load(const char *pszFname
,
3831 bool reinit_globals
)
3833 return lp_load_ex(pszFname
,
3838 true, /* allow_include_registry */
3839 false); /* load_all_shares*/
3842 bool lp_load_initial_only(const char *pszFname
)
3844 return lp_load_ex(pszFname
,
3845 true, /* global only */
3846 true, /* save_defaults */
3847 false, /* add_ipc */
3848 true, /* reinit_globals */
3849 false, /* allow_include_registry */
3850 false); /* load_all_shares*/
3854 * most common lp_load wrapper, loading only the globals
3856 bool lp_load_global(const char *file_name
)
3858 return lp_load(file_name
,
3859 true, /* global_only */
3860 false, /* save_defaults */
3861 false, /* add_ipc */
3862 true); /* reinit_globals */
3866 * The typical lp_load wrapper with shares, loads global and
3867 * shares, including IPC, but does not force immediate
3868 * loading of all shares from registry.
3870 bool lp_load_with_shares(const char *file_name
)
3872 return lp_load(file_name
,
3873 false, /* global_only */
3874 false, /* save_defaults */
3876 true); /* reinit_globals */
3880 * lp_load wrapper, especially for clients
3882 bool lp_load_client(const char *file_name
)
3884 lp_set_in_client(true);
3886 return lp_load_global(file_name
);
3890 * lp_load wrapper, loading only globals, but intended
3891 * for subsequent calls, not reinitializing the globals
3894 bool lp_load_global_no_reinit(const char *file_name
)
3896 return lp_load(file_name
,
3897 true, /* global_only */
3898 false, /* save_defaults */
3899 false, /* add_ipc */
3900 false); /* reinit_globals */
3904 * lp_load wrapper, loading globals and shares,
3905 * intended for subsequent calls, i.e. not reinitializing
3906 * the globals to default values.
3908 bool lp_load_no_reinit(const char *file_name
)
3910 return lp_load(file_name
,
3911 false, /* global_only */
3912 false, /* save_defaults */
3913 false, /* add_ipc */
3914 false); /* reinit_globals */
3919 * lp_load wrapper, especially for clients, no reinitialization
3921 bool lp_load_client_no_reinit(const char *file_name
)
3923 lp_set_in_client(true);
3925 return lp_load_global_no_reinit(file_name
);
3928 bool lp_load_with_registry_shares(const char *pszFname
)
3930 return lp_load_ex(pszFname
,
3931 false, /* global_only */
3932 true, /* save_defaults */
3933 false, /* add_ipc */
3934 false, /* reinit_globals */
3935 true, /* allow_include_registry */
3936 true); /* load_all_shares*/
3939 /***************************************************************************
3940 Return the max number of services.
3941 ***************************************************************************/
3943 int lp_numservices(void)
3945 return (iNumServices
);
3948 /***************************************************************************
3949 Display the contents of the services array in human-readable form.
3950 ***************************************************************************/
3952 void lp_dump(FILE *f
, bool show_defaults
, int maxtoprint
)
3955 struct loadparm_context
*lp_ctx
;
3958 defaults_saved
= false;
3960 lp_ctx
= setup_lp_context(talloc_tos());
3961 if (lp_ctx
== NULL
) {
3965 lpcfg_dump_globals(lp_ctx
, f
, !defaults_saved
);
3967 lpcfg_dump_a_service(&sDefault
, &sDefault
, f
, flags_list
, show_defaults
);
3969 for (iService
= 0; iService
< maxtoprint
; iService
++) {
3971 lp_dump_one(f
, show_defaults
, iService
);
3975 /***************************************************************************
3976 Display the contents of one service in human-readable form.
3977 ***************************************************************************/
3979 void lp_dump_one(FILE * f
, bool show_defaults
, int snum
)
3982 if (ServicePtrs
[snum
]->szService
[0] == '\0')
3984 lpcfg_dump_a_service(ServicePtrs
[snum
], &sDefault
, f
,
3985 flags_list
, show_defaults
);
3989 /***************************************************************************
3990 Return the number of the service with the given name, or -1 if it doesn't
3991 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3992 getservicebyname()! This works ONLY if all services have been loaded, and
3993 does not copy the found service.
3994 ***************************************************************************/
3996 int lp_servicenumber(const char *pszServiceName
)
3999 fstring serviceName
;
4001 if (!pszServiceName
) {
4002 return GLOBAL_SECTION_SNUM
;
4005 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4006 if (VALID(iService
) && ServicePtrs
[iService
]->szService
) {
4008 * The substitution here is used to support %U in
4011 fstrcpy(serviceName
, ServicePtrs
[iService
]->szService
);
4012 standard_sub_basic(get_current_username(),
4013 current_user_info
.domain
,
4014 serviceName
,sizeof(serviceName
));
4015 if (strequal(serviceName
, pszServiceName
)) {
4021 if (iService
>= 0 && ServicePtrs
[iService
]->usershare
== USERSHARE_VALID
) {
4022 struct timespec last_mod
;
4024 if (!usershare_exists(iService
, &last_mod
)) {
4025 /* Remove the share security tdb entry for it. */
4026 delete_share_security(lp_servicename(talloc_tos(), iService
));
4027 /* Remove it from the array. */
4028 free_service_byindex(iService
);
4029 /* Doesn't exist anymore. */
4030 return GLOBAL_SECTION_SNUM
;
4033 /* Has it been modified ? If so delete and reload. */
4034 if (timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
4036 /* Remove it from the array. */
4037 free_service_byindex(iService
);
4038 /* and now reload it. */
4039 iService
= load_usershare_service(pszServiceName
);
4044 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName
));
4045 return GLOBAL_SECTION_SNUM
;
4051 /*******************************************************************
4052 A useful volume label function.
4053 ********************************************************************/
4055 const char *volume_label(TALLOC_CTX
*ctx
, int snum
)
4058 const char *label
= lp_volume(ctx
, snum
);
4060 label
= lp_servicename(ctx
, snum
);
4063 /* This returns a 33 byte guarenteed null terminated string. */
4064 ret
= talloc_strndup(ctx
, label
, 32);
4071 /*******************************************************************
4072 Get the default server type we will announce as via nmbd.
4073 ********************************************************************/
4075 int lp_default_server_announce(void)
4077 int default_server_announce
= 0;
4078 default_server_announce
|= SV_TYPE_WORKSTATION
;
4079 default_server_announce
|= SV_TYPE_SERVER
;
4080 default_server_announce
|= SV_TYPE_SERVER_UNIX
;
4082 /* note that the flag should be set only if we have a
4083 printer service but nmbd doesn't actually load the
4084 services so we can't tell --jerry */
4086 default_server_announce
|= SV_TYPE_PRINTQ_SERVER
;
4088 default_server_announce
|= SV_TYPE_SERVER_NT
;
4089 default_server_announce
|= SV_TYPE_NT
;
4091 switch (lp_server_role()) {
4092 case ROLE_DOMAIN_MEMBER
:
4093 default_server_announce
|= SV_TYPE_DOMAIN_MEMBER
;
4095 case ROLE_DOMAIN_PDC
:
4096 default_server_announce
|= SV_TYPE_DOMAIN_CTRL
;
4098 case ROLE_DOMAIN_BDC
:
4099 default_server_announce
|= SV_TYPE_DOMAIN_BAKCTRL
;
4101 case ROLE_STANDALONE
:
4105 if (lp_time_server())
4106 default_server_announce
|= SV_TYPE_TIME_SOURCE
;
4108 if (lp_host_msdfs())
4109 default_server_announce
|= SV_TYPE_DFS_SERVER
;
4111 return default_server_announce
;
4114 /***********************************************************
4115 If we are PDC then prefer us as DMB
4116 ************************************************************/
4118 bool lp_domain_master(void)
4120 if (Globals
._domain_master
== Auto
)
4121 return (lp_server_role() == ROLE_DOMAIN_PDC
);
4123 return (bool)Globals
._domain_master
;
4126 /***********************************************************
4127 If we are PDC then prefer us as DMB
4128 ************************************************************/
4130 static bool lp_domain_master_true_or_auto(void)
4132 if (Globals
._domain_master
) /* auto or yes */
4138 /***********************************************************
4139 If we are DMB then prefer us as LMB
4140 ************************************************************/
4142 bool lp_preferred_master(void)
4144 int preferred_master
= lp__preferred_master();
4146 if (preferred_master
== Auto
)
4147 return (lp_local_master() && lp_domain_master());
4149 return (bool)preferred_master
;
4152 /*******************************************************************
4154 ********************************************************************/
4156 void lp_remove_service(int snum
)
4158 ServicePtrs
[snum
]->valid
= false;
4161 const char *lp_printername(TALLOC_CTX
*ctx
, int snum
)
4163 const char *ret
= lp__printername(ctx
, snum
);
4164 if (ret
== NULL
|| *ret
== '\0') {
4165 ret
= lp_const_servicename(snum
);
4172 /***********************************************************
4173 Allow daemons such as winbindd to fix their logfile name.
4174 ************************************************************/
4176 void lp_set_logfile(const char *name
)
4178 string_set(Globals
.ctx
, &Globals
.logfile
, name
);
4179 debug_set_logfile(name
);
4182 /*******************************************************************
4183 Return the max print jobs per queue.
4184 ********************************************************************/
4186 int lp_maxprintjobs(int snum
)
4188 int maxjobs
= lp_max_print_jobs(snum
);
4190 if (maxjobs
<= 0 || maxjobs
>= PRINT_MAX_JOBID
)
4191 maxjobs
= PRINT_MAX_JOBID
- 1;
4196 const char *lp_printcapname(void)
4198 const char *printcap_name
= lp_printcap_name();
4200 if ((printcap_name
!= NULL
) &&
4201 (printcap_name
[0] != '\0'))
4202 return printcap_name
;
4204 if (sDefault
.printing
== PRINT_CUPS
) {
4208 if (sDefault
.printing
== PRINT_BSD
)
4209 return "/etc/printcap";
4211 return PRINTCAP_NAME
;
4214 static uint32_t spoolss_state
;
4216 bool lp_disable_spoolss( void )
4218 if ( spoolss_state
== SVCCTL_STATE_UNKNOWN
)
4219 spoolss_state
= lp__disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
4221 return spoolss_state
== SVCCTL_STOPPED
? true : false;
4224 void lp_set_spoolss_state( uint32_t state
)
4226 SMB_ASSERT( (state
== SVCCTL_STOPPED
) || (state
== SVCCTL_RUNNING
) );
4228 spoolss_state
= state
;
4231 uint32_t lp_get_spoolss_state( void )
4233 return lp_disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
4236 /*******************************************************************
4237 Ensure we don't use sendfile if server smb signing is active.
4238 ********************************************************************/
4240 bool lp_use_sendfile(int snum
, struct smb_signing_state
*signing_state
)
4242 bool sign_active
= false;
4244 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4245 if (get_Protocol() < PROTOCOL_NT1
) {
4248 if (signing_state
) {
4249 sign_active
= smb_signing_is_active(signing_state
);
4251 return (lp__use_sendfile(snum
) &&
4252 (get_remote_arch() != RA_WIN95
) &&
4256 /*******************************************************************
4257 Turn off sendfile if we find the underlying OS doesn't support it.
4258 ********************************************************************/
4260 void set_use_sendfile(int snum
, bool val
)
4262 if (LP_SNUM_OK(snum
))
4263 ServicePtrs
[snum
]->_use_sendfile
= val
;
4265 sDefault
._use_sendfile
= val
;
4268 /*******************************************************************
4269 Turn off storing DOS attributes if this share doesn't support it.
4270 ********************************************************************/
4272 void set_store_dos_attributes(int snum
, bool val
)
4274 if (!LP_SNUM_OK(snum
))
4276 ServicePtrs
[(snum
)]->store_dos_attributes
= val
;
4279 void lp_set_mangling_method(const char *new_method
)
4281 string_set(Globals
.ctx
, &Globals
.mangling_method
, new_method
);
4284 /*******************************************************************
4285 Global state for POSIX pathname processing.
4286 ********************************************************************/
4288 static bool posix_pathnames
;
4290 bool lp_posix_pathnames(void)
4292 return posix_pathnames
;
4295 /*******************************************************************
4296 Change everything needed to ensure POSIX pathname processing (currently
4298 ********************************************************************/
4300 void lp_set_posix_pathnames(void)
4302 posix_pathnames
= true;
4305 /*******************************************************************
4306 Global state for POSIX lock processing - CIFS unix extensions.
4307 ********************************************************************/
4309 bool posix_default_lock_was_set
;
4310 static enum brl_flavour posix_cifsx_locktype
; /* By default 0 == WINDOWS_LOCK */
4312 enum brl_flavour
lp_posix_cifsu_locktype(files_struct
*fsp
)
4314 if (posix_default_lock_was_set
) {
4315 return posix_cifsx_locktype
;
4317 return fsp
->posix_open
? POSIX_LOCK
: WINDOWS_LOCK
;
4321 /*******************************************************************
4322 ********************************************************************/
4324 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val
)
4326 posix_default_lock_was_set
= true;
4327 posix_cifsx_locktype
= val
;
4330 int lp_min_receive_file_size(void)
4332 int min_receivefile_size
= lp_min_receivefile_size();
4334 if (min_receivefile_size
< 0) {
4337 return min_receivefile_size
;
4340 /*******************************************************************
4341 Safe wide links checks.
4342 This helper function always verify the validity of wide links,
4343 even after a configuration file reload.
4344 ********************************************************************/
4346 void widelinks_warning(int snum
)
4348 if (lp_allow_insecure_wide_links()) {
4352 if (lp_unix_extensions() && lp_wide_links(snum
)) {
4353 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4354 "These parameters are incompatible. "
4355 "Wide links will be disabled for this share.\n",
4356 lp_servicename(talloc_tos(), snum
) ));
4360 bool lp_widelinks(int snum
)
4362 /* wide links is always incompatible with unix extensions */
4363 if (lp_unix_extensions()) {
4365 * Unless we have "allow insecure widelinks"
4368 if (!lp_allow_insecure_wide_links()) {
4373 return lp_wide_links(snum
);
4376 int lp_server_role(void)
4378 return lp_find_server_role(lp__server_role(),
4380 lp__domain_logons(),
4381 lp_domain_master_true_or_auto());
4384 int lp_security(void)
4386 return lp_find_security(lp__server_role(),
4390 int lp_client_max_protocol(void)
4392 int client_max_protocol
= lp__client_max_protocol();
4393 if (client_max_protocol
== PROTOCOL_DEFAULT
) {
4394 return PROTOCOL_NT1
;
4396 return client_max_protocol
;
4399 int lp_winbindd_max_protocol(void)
4401 int client_max_protocol
= lp__client_max_protocol();
4402 if (client_max_protocol
== PROTOCOL_DEFAULT
) {
4403 return PROTOCOL_LATEST
;
4405 return client_max_protocol
;
4408 struct loadparm_global
* get_globals(void)
4413 unsigned int * get_flags(void)
4415 if (flags_list
== NULL
) {
4416 flags_list
= talloc_zero_array(NULL
, unsigned int, num_parameters());