2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12 Copyright (C) Michael Adam 2008
13 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14 Copyright (C) Andrew Bartlett 2011
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 3 of the License, or
19 (at your option) any later version.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program. If not, see <http://www.gnu.org/licenses/>.
33 * This module provides suitable callback functions for the params
34 * module. It builds the internal table of service details which is
35 * then used by the rest of the server.
39 * 1) add it to the global or service structure definition
40 * 2) add it to the parm_table
41 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42 * 4) If it's a global then initialise it in init_globals. If a local
43 * (ie. service) parameter then initialise it in the sDefault structure
47 * The configuration file is processed sequentially for speed. It is NOT
48 * accessed randomly as happens in 'real' Windows. For this reason, there
49 * is a fair bit of sequence-dependent code here - ie., code which assumes
50 * that certain things happen before others. In particular, the code which
51 * happens at the boundary between sections is delicately poised, so be
57 #include "system/filesys.h"
59 #include "lib/param/loadparm.h"
60 #include "lib/param/param.h"
62 #include "lib/smbconf/smbconf.h"
63 #include "lib/smbconf/smbconf_init.h"
66 #include "../librpc/gen_ndr/svcctl.h"
68 #include "../libcli/smb/smb_signing.h"
69 #include "dbwrap/dbwrap.h"
70 #include "dbwrap/dbwrap_rbt.h"
71 #include "../lib/util/bitmap.h"
73 #ifdef HAVE_SYS_SYSCTL_H
74 #include <sys/sysctl.h>
77 #ifdef HAVE_HTTPCONNECTENCRYPT
78 #include <cups/http.h>
81 #ifdef CLUSTER_SUPPORT
82 #include "ctdb_private.h"
87 extern userdom_struct current_user_info
;
89 /* the special value for the include parameter
90 * to be interpreted not as a file name but to
91 * trigger loading of the global smb.conf options
93 #ifndef INCLUDE_REGISTRY_NAME
94 #define INCLUDE_REGISTRY_NAME "registry"
97 static bool in_client
= false; /* Not in the client by default */
98 static struct smbconf_csn conf_last_csn
;
100 static int config_backend
= CONFIG_BACKEND_FILE
;
102 /* some helpful bits */
103 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
104 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
106 #define USERSHARE_VALID 1
107 #define USERSHARE_PENDING_DELETE 2
109 static bool defaults_saved
= false;
111 #define LOADPARM_EXTRA_GLOBALS \
112 struct parmlist_entry *param_opt; \
113 char *realm_original; \
115 int iminreceivefile; \
116 char *szPrintcapname; \
118 int iPreferredMaster; \
119 char *szLdapMachineSuffix; \
120 char *szLdapUserSuffix; \
121 char *szLdapIdmapSuffix; \
122 char *szLdapGroupSuffix; \
125 char *szUsershareTemplateShare; \
128 char *szIdmapBackend; \
129 int winbindMaxDomainConnections; \
130 int ismb2_max_credits; \
132 char *tls_certfile; \
137 #include "param/param_global.h"
139 static struct loadparm_global Globals
;
141 /* This is a default service used to prime a services structure */
142 static struct loadparm_service sDefault
=
147 .usershare_last_mod
= {0, 0},
151 .invalid_users
= NULL
,
158 .root_preexec
= NULL
,
159 .root_postexec
= NULL
,
160 .cups_options
= NULL
,
161 .print_command
= NULL
,
163 .lprm_command
= NULL
,
164 .lppause_command
= NULL
,
165 .lpresume_command
= NULL
,
166 .queuepause_command
= NULL
,
167 .queueresume_command
= NULL
,
168 ._printername
= NULL
,
169 .printjob_username
= NULL
,
170 .dont_descend
= NULL
,
173 .magic_script
= NULL
,
174 .magic_output
= NULL
,
177 .veto_oplock_files
= NULL
,
187 .aio_write_behind
= NULL
,
188 .dfree_command
= NULL
,
190 .iMaxPrintJobs
= 1000,
191 .max_reported_print_jobs
= 0,
192 .write_cache_size
= 0,
194 .force_create_mode
= 0,
195 .directory_mask
= 0755,
196 .force_directory_mode
= 0,
197 .max_connections
= 0,
198 .default_case
= CASE_LOWER
,
199 .printing
= DEFAULT_PRINTING
,
200 .oplock_contention_limit
= 2,
203 .dfree_cache_time
= 0,
204 .preexec_close
= false,
205 .root_preexec_close
= false,
206 .case_sensitive
= Auto
,
207 .preserve_case
= true,
208 .short_preserve_case
= true,
209 .hide_dot_files
= true,
210 .hide_special_files
= false,
211 .hide_unreadable
= false,
212 .hide_unwriteable_files
= false,
214 .access_based_share_enum
= false,
218 .administrative_share
= false,
221 .print_notify_backchannel
= false,
225 .store_dos_attributes
= false,
226 .dmapi_support
= false,
228 .strict_locking
= Auto
,
229 .posix_locking
= true,
231 .kernel_oplocks
= false,
232 .level2_oplocks
= true,
234 .mangled_names
= true,
236 .follow_symlinks
= true,
238 .strict_allocate
= false,
239 .strict_sync
= false,
240 .mangling_char
= '~',
242 .delete_readonly
= false,
243 .fake_oplocks
= false,
244 .delete_veto_files
= false,
245 .dos_filemode
= false,
246 .dos_filetimes
= true,
247 .dos_filetime_resolution
= false,
248 .fake_directory_create_times
= false,
249 .blocking_locks
= true,
250 .inherit_perms
= false,
251 .inherit_acls
= false,
252 .inherit_owner
= false,
254 .use_client_driver
= false,
255 .default_devmode
= true,
256 .force_printername
= false,
257 .nt_acl_support
= true,
258 .force_unknown_acl_user
= false,
259 ._use_sendfile
= false,
260 .profile_acls
= false,
261 .map_acl_inherit
= false,
264 .acl_check_permissions
= true,
265 .acl_map_full_control
= true,
266 .acl_group_control
= false,
267 .acl_allow_execute_always
= false,
268 .change_notify
= true,
269 .kernel_change_notify
= true,
270 .allocation_roundup_size
= SMB_ROUNDUP_ALLOCATION_SIZE
,
273 .map_readonly
= MAP_READONLY_YES
,
274 .directory_name_cache_size
= 100,
275 .smb_encrypt
= SMB_SIGNING_DEFAULT
,
276 .kernel_share_modes
= true,
277 .durable_handles
= true,
282 /* local variables */
283 static struct loadparm_service
**ServicePtrs
= NULL
;
284 static int iNumServices
= 0;
285 static int iServiceIndex
= 0;
286 static struct db_context
*ServiceHash
;
287 static bool bInGlobalSection
= true;
288 static bool bGlobalOnly
= false;
290 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
292 /* prototypes for the special type handlers */
293 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
294 static bool handle_copy(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
295 static bool handle_idmap_backend(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
296 static bool handle_idmap_uid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
297 static bool handle_idmap_gid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
298 static bool handle_debug_list(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
299 static bool handle_realm(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
300 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
301 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
302 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
303 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
304 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
306 /* these are parameter handlers which are not needed in the
310 #define handle_logfile NULL
312 static void set_allowed_client_auth(void);
314 static void add_to_file_list(const char *fname
, const char *subfname
);
315 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
);
316 static void free_param_opts(struct parmlist_entry
**popts
);
318 #include "lib/param/param_table.c"
320 /* this is used to prevent lots of mallocs of size 1 */
321 static const char null_string
[] = "";
324 Set a string value, allocing the space for the string
327 static bool string_init(char **dest
,const char *src
)
337 *dest
= discard_const_p(char, null_string
);
339 (*dest
) = SMB_STRDUP(src
);
340 if ((*dest
) == NULL
) {
341 DEBUG(0,("Out of memory in string_init\n"));
352 static void string_free(char **s
)
356 if (*s
== null_string
)
362 Set a string value, deallocating any existing space, and allocing the space
366 static bool string_set(char **dest
,const char *src
)
369 return(string_init(dest
,src
));
372 /***************************************************************************
373 Initialise the sDefault parameter structure for the printer values.
374 ***************************************************************************/
376 static void init_printer_values(struct loadparm_service
*pService
)
378 /* choose defaults depending on the type of printing */
379 switch (pService
->printing
) {
384 string_set(&pService
->lpq_command
, "lpq -P'%p'");
385 string_set(&pService
->lprm_command
, "lprm -P'%p' %j");
386 string_set(&pService
->print_command
, "lpr -r -P'%p' %s");
391 string_set(&pService
->lpq_command
, "lpq -P'%p'");
392 string_set(&pService
->lprm_command
, "lprm -P'%p' %j");
393 string_set(&pService
->print_command
, "lpr -r -P'%p' %s");
394 string_set(&pService
->queuepause_command
, "lpc stop '%p'");
395 string_set(&pService
->queueresume_command
, "lpc start '%p'");
396 string_set(&pService
->lppause_command
, "lpc hold '%p' %j");
397 string_set(&pService
->lpresume_command
, "lpc release '%p' %j");
402 /* set the lpq command to contain the destination printer
403 name only. This is used by cups_queue_get() */
404 string_set(&pService
->lpq_command
, "%p");
405 string_set(&pService
->lprm_command
, "");
406 string_set(&pService
->print_command
, "");
407 string_set(&pService
->lppause_command
, "");
408 string_set(&pService
->lpresume_command
, "");
409 string_set(&pService
->queuepause_command
, "");
410 string_set(&pService
->queueresume_command
, "");
415 string_set(&pService
->lpq_command
, "lpstat -o%p");
416 string_set(&pService
->lprm_command
, "cancel %p-%j");
417 string_set(&pService
->print_command
, "lp -c -d%p %s; rm %s");
418 string_set(&pService
->queuepause_command
, "disable %p");
419 string_set(&pService
->queueresume_command
, "enable %p");
421 string_set(&pService
->lppause_command
, "lp -i %p-%j -H hold");
422 string_set(&pService
->lpresume_command
, "lp -i %p-%j -H resume");
427 string_set(&pService
->lpq_command
, "lpq -P%p");
428 string_set(&pService
->lprm_command
, "lprm -P%p %j");
429 string_set(&pService
->print_command
, "lp -r -P%p %s");
432 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
437 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
440 tdbfile
= talloc_asprintf(
441 tmp_ctx
, "tdbfile=%s",
442 lp_parm_const_string(-1, "vlp", "tdbfile",
444 if (tdbfile
== NULL
) {
445 tdbfile
="tdbfile=/tmp/vlp.tdb";
448 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s print %%p %%s",
450 string_set(&pService
->print_command
,
451 tmp
? tmp
: "vlp print %p %s");
453 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpq %%p",
455 string_set(&pService
->lpq_command
,
456 tmp
? tmp
: "vlp lpq %p");
458 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lprm %%p %%j",
460 string_set(&pService
->lprm_command
,
461 tmp
? tmp
: "vlp lprm %p %j");
463 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lppause %%p %%j",
465 string_set(&pService
->lppause_command
,
466 tmp
? tmp
: "vlp lppause %p %j");
468 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpresume %%p %%j",
470 string_set(&pService
->lpresume_command
,
471 tmp
? tmp
: "vlp lpresume %p %j");
473 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queuepause %%p",
475 string_set(&pService
->queuepause_command
,
476 tmp
? tmp
: "vlp queuepause %p");
478 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queueresume %%p",
480 string_set(&pService
->queueresume_command
,
481 tmp
? tmp
: "vlp queueresume %p");
482 TALLOC_FREE(tmp_ctx
);
486 #endif /* DEVELOPER */
491 * Function to return the default value for the maximum number of open
492 * file descriptors permitted. This function tries to consult the
493 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
494 * the smaller of those.
496 static int max_open_files(void)
498 int sysctl_max
= MAX_OPEN_FILES
;
499 int rlimit_max
= MAX_OPEN_FILES
;
501 #ifdef HAVE_SYSCTLBYNAME
503 size_t size
= sizeof(sysctl_max
);
504 sysctlbyname("kern.maxfilesperproc", &sysctl_max
, &size
, NULL
,
509 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
515 if (getrlimit(RLIMIT_NOFILE
, &rl
) == 0)
516 rlimit_max
= rl
.rlim_cur
;
518 #if defined(RLIM_INFINITY)
519 if(rl
.rlim_cur
== RLIM_INFINITY
)
520 rlimit_max
= MAX_OPEN_FILES
;
525 if (sysctl_max
< MIN_OPEN_FILES_WINDOWS
) {
526 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
527 "minimum Windows limit (%d)\n",
529 MIN_OPEN_FILES_WINDOWS
));
530 sysctl_max
= MIN_OPEN_FILES_WINDOWS
;
533 if (rlimit_max
< MIN_OPEN_FILES_WINDOWS
) {
534 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
535 "minimum Windows limit (%d)\n",
537 MIN_OPEN_FILES_WINDOWS
));
538 rlimit_max
= MIN_OPEN_FILES_WINDOWS
;
541 return MIN(sysctl_max
, rlimit_max
);
545 * Common part of freeing allocated data for one parameter.
547 static void free_one_parameter_common(void *parm_ptr
,
548 struct parm_struct parm
)
550 if ((parm
.type
== P_STRING
) ||
551 (parm
.type
== P_USTRING
))
553 string_free((char**)parm_ptr
);
554 } else if (parm
.type
== P_LIST
) {
555 TALLOC_FREE(*((char***)parm_ptr
));
560 * Free the allocated data for one parameter for a share
561 * given as a service struct.
563 static void free_one_parameter(struct loadparm_service
*service
,
564 struct parm_struct parm
)
568 if (parm
.p_class
!= P_LOCAL
) {
572 parm_ptr
= lp_parm_ptr(service
, &parm
);
574 free_one_parameter_common(parm_ptr
, parm
);
578 * Free the allocated parameter data of a share given
579 * as a service struct.
581 static void free_parameters(struct loadparm_service
*service
)
585 for (i
=0; parm_table
[i
].label
; i
++) {
586 free_one_parameter(service
, parm_table
[i
]);
591 * Free the allocated data for one parameter for a given share
592 * specified by an snum.
594 static void free_one_parameter_by_snum(int snum
, struct parm_struct parm
)
599 parm_ptr
= lp_parm_ptr(NULL
, &parm
);
600 } else if (parm
.p_class
!= P_LOCAL
) {
603 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm
);
606 free_one_parameter_common(parm_ptr
, parm
);
610 * Free the allocated parameter data for a share specified
613 static void free_parameters_by_snum(int snum
)
617 for (i
=0; parm_table
[i
].label
; i
++) {
618 free_one_parameter_by_snum(snum
, parm_table
[i
]);
623 * Free the allocated global parameters.
625 static void free_global_parameters(void)
627 free_param_opts(&Globals
.param_opt
);
628 free_parameters_by_snum(GLOBAL_SECTION_SNUM
);
629 TALLOC_FREE(Globals
.ctx
);
632 struct lp_stored_option
{
633 struct lp_stored_option
*prev
, *next
;
638 static struct lp_stored_option
*stored_options
;
641 save options set by lp_set_cmdline() into a list. This list is
642 re-applied when we do a globals reset, so that cmdline set options
643 are sticky across reloads of smb.conf
645 static bool store_lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
647 struct lp_stored_option
*entry
, *entry_next
;
648 for (entry
= stored_options
; entry
!= NULL
; entry
= entry_next
) {
649 entry_next
= entry
->next
;
650 if (strcmp(pszParmName
, entry
->label
) == 0) {
651 DLIST_REMOVE(stored_options
, entry
);
657 entry
= talloc(NULL
, struct lp_stored_option
);
662 entry
->label
= talloc_strdup(entry
, pszParmName
);
668 entry
->value
= talloc_strdup(entry
, pszParmValue
);
674 DLIST_ADD_END(stored_options
, entry
, struct lp_stored_option
);
679 static bool apply_lp_set_cmdline(void)
681 struct lp_stored_option
*entry
= NULL
;
682 for (entry
= stored_options
; entry
!= NULL
; entry
= entry
->next
) {
683 if (!lp_set_cmdline_helper(entry
->label
, entry
->value
, false)) {
684 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
685 entry
->label
, entry
->value
));
692 /***************************************************************************
693 Initialise the global parameter structure.
694 ***************************************************************************/
696 static void init_globals(bool reinit_globals
)
698 static bool done_init
= false;
702 /* If requested to initialize only once and we've already done it... */
703 if (!reinit_globals
&& done_init
) {
704 /* ... then we have nothing more to do */
709 /* The logfile can be set before this is invoked. Free it if so. */
710 if (Globals
.logfile
!= NULL
) {
711 string_free(&Globals
.logfile
);
712 Globals
.logfile
= NULL
;
716 free_global_parameters();
719 /* This memset and the free_global_parameters() above will
720 * wipe out smb.conf options set with lp_set_cmdline(). The
721 * apply_lp_set_cmdline() call puts these values back in the
722 * table once the defaults are set */
723 ZERO_STRUCT(Globals
);
725 Globals
.ctx
= talloc_new(NULL
);
727 for (i
= 0; parm_table
[i
].label
; i
++) {
728 if ((parm_table
[i
].type
== P_STRING
||
729 parm_table
[i
].type
== P_USTRING
))
731 string_set((char **)lp_parm_ptr(NULL
, &parm_table
[i
]), "");
736 string_set(&sDefault
.fstype
, FSTYPE_STRING
);
737 string_set(&sDefault
.printjob_username
, "%U");
739 init_printer_values(&sDefault
);
741 sDefault
.ntvfs_handler
= (const char **)str_list_make_v3(NULL
, "unixuid default", NULL
);
743 DEBUG(3, ("Initialising global parameters\n"));
745 /* Must manually force to upper case here, as this does not go via the handler */
746 string_set(&Globals
.netbios_name
, myhostname_upper());
748 string_set(&Globals
.smb_passwd_file
, get_dyn_SMB_PASSWD_FILE());
749 string_set(&Globals
.private_dir
, get_dyn_PRIVATE_DIR());
751 /* use the new 'hash2' method by default, with a prefix of 1 */
752 string_set(&Globals
.mangling_method
, "hash2");
753 Globals
.mangle_prefix
= 1;
755 string_set(&Globals
.guest_account
, GUEST_ACCOUNT
);
757 /* using UTF8 by default allows us to support all chars */
758 string_set(&Globals
.unix_charset
, DEFAULT_UNIX_CHARSET
);
760 /* Use codepage 850 as a default for the dos character set */
761 string_set(&Globals
.dos_charset
, DEFAULT_DOS_CHARSET
);
764 * Allow the default PASSWD_CHAT to be overridden in local.h.
766 string_set(&Globals
.passwd_chat
, DEFAULT_PASSWD_CHAT
);
768 string_set(&Globals
.workgroup
, DEFAULT_WORKGROUP
);
770 string_set(&Globals
.passwd_program
, "");
771 string_set(&Globals
.lock_directory
, get_dyn_LOCKDIR());
772 string_set(&Globals
.szStateDir
, get_dyn_STATEDIR());
773 string_set(&Globals
.szCacheDir
, get_dyn_CACHEDIR());
774 string_set(&Globals
.pid_directory
, get_dyn_PIDDIR());
775 string_set(&Globals
.nbt_client_socket_address
, "0.0.0.0");
777 * By default support explicit binding to broadcast
780 Globals
.nmbd_bind_explicit_broadcast
= true;
782 if (asprintf(&s
, "Samba %s", samba_version_string()) < 0) {
783 smb_panic("init_globals: ENOMEM");
785 string_set(&Globals
.server_string
, s
);
788 string_set(&Globals
.panic_action
, "/bin/sleep 999999999");
791 string_set(&Globals
.socket_options
, DEFAULT_SOCKET_OPTIONS
);
793 string_set(&Globals
.logon_drive
, "");
794 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
795 string_set(&Globals
.logon_home
, "\\\\%N\\%U");
796 string_set(&Globals
.logon_path
, "\\\\%N\\%U\\profile");
798 Globals
.name_resolve_order
= (const char **)str_list_make_v3(NULL
, "lmhosts wins host bcast", NULL
);
799 string_set(&Globals
.password_server
, "*");
801 Globals
.algorithmic_rid_base
= BASE_RID
;
803 Globals
.load_printers
= true;
804 Globals
.printcap_cache_time
= 750; /* 12.5 minutes */
806 Globals
.config_backend
= config_backend
;
807 Globals
._server_role
= ROLE_AUTO
;
809 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
810 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
811 Globals
.max_xmit
= 0x4104;
812 Globals
.max_mux
= 50; /* This is *needed* for profile support. */
813 Globals
.lpq_cache_time
= 30; /* changed to handle large print servers better -- jerry */
814 Globals
._disable_spoolss
= false;
815 Globals
.max_smbd_processes
= 0;/* no limit specified */
816 Globals
.usernamelevel
= 0;
817 Globals
.deadtime
= 0;
818 Globals
.getwd_cache
= true;
819 Globals
.large_readwrite
= true;
820 Globals
.max_log_size
= 5000;
821 Globals
.max_open_files
= max_open_files();
822 Globals
.server_max_protocol
= PROTOCOL_SMB3_00
;
823 Globals
.server_min_protocol
= PROTOCOL_LANMAN1
;
824 Globals
.client_max_protocol
= PROTOCOL_NT1
;
825 Globals
.client_min_protocol
= PROTOCOL_CORE
;
826 Globals
._security
= SEC_AUTO
;
827 Globals
.encrypt_passwords
= true;
828 Globals
.client_schannel
= Auto
;
829 Globals
.winbind_sealed_pipes
= true;
830 Globals
.require_strong_key
= true;
831 Globals
.server_schannel
= Auto
;
832 Globals
.bReadRaw
= true;
833 Globals
.bWriteRaw
= true;
834 Globals
.null_passwords
= false;
835 Globals
.obey_pam_restrictions
= false;
837 Globals
.syslog_only
= false;
838 Globals
.timestamp_logs
= true;
839 string_set(&Globals
.loglevel
, "0");
840 Globals
.debug_prefix_timestamp
= false;
841 Globals
.debug_hires_timestamp
= true;
842 Globals
.debug_pid
= false;
843 Globals
.debug_uid
= false;
844 Globals
.debug_class
= false;
845 Globals
.enable_core_files
= true;
846 Globals
.max_ttl
= 60 * 60 * 24 * 3; /* 3 days default. */
847 Globals
.max_wins_ttl
= 60 * 60 * 24 * 6; /* 6 days default. */
848 Globals
.min_wins_ttl
= 60 * 60 * 6; /* 6 hours default. */
849 Globals
.machine_password_timeout
= 60 * 60 * 24 * 7; /* 7 days default. */
850 Globals
.lm_announce
= Auto
; /* = Auto: send only if LM clients found */
851 Globals
.lm_interval
= 60;
852 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
853 Globals
.nis_home_map
= false;
854 #ifdef WITH_NISPLUS_HOME
855 string_set(&Globals
.homedir_map
, "auto_home.org_dir");
857 string_set(&Globals
.homedir_map
, "auto.home");
860 Globals
.time_server
= false;
861 Globals
.bind_interfaces_only
= false;
862 Globals
.unix_password_sync
= false;
863 Globals
.pam_password_change
= false;
864 Globals
.passwd_chat_debug
= false;
865 Globals
.passwd_chat_timeout
= 2; /* 2 second default. */
866 Globals
.nt_pipe_support
= true; /* Do NT pipes by default. */
867 Globals
.nt_status_support
= true; /* Use NT status by default. */
868 Globals
.stat_cache
= true; /* use stat cache by default */
869 Globals
.max_stat_cache_size
= 256; /* 256k by default */
870 Globals
.restrict_anonymous
= 0;
871 Globals
.client_lanman_auth
= false; /* Do NOT use the LanMan hash if it is available */
872 Globals
.client_plaintext_auth
= false; /* Do NOT use a plaintext password even if is requested by the server */
873 Globals
.lanman_auth
= false; /* Do NOT use the LanMan hash, even if it is supplied */
874 Globals
.ntlm_auth
= true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
875 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 */
876 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
878 Globals
.map_to_guest
= 0; /* By Default, "Never" */
879 Globals
.oplock_break_wait_time
= 0; /* By Default, 0 msecs. */
880 Globals
.enhanced_browsing
= true;
881 Globals
.lock_spin_time
= WINDOWS_MINIMUM_LOCK_TIMEOUT_MS
; /* msec. */
882 #ifdef MMAP_BLACKLIST
883 Globals
.use_mmap
= false;
885 Globals
.use_mmap
= true;
887 Globals
.unicode
= true;
888 Globals
.unix_extensions
= true;
889 Globals
.reset_on_zero_vc
= false;
890 Globals
.log_writeable_files_on_exit
= false;
891 Globals
.create_krb5_conf
= true;
892 Globals
.winbindMaxDomainConnections
= 1;
894 /* hostname lookups can be very expensive and are broken on
895 a large number of sites (tridge) */
896 Globals
.hostname_lookups
= false;
898 string_set(&Globals
.passdb_backend
, "tdbsam");
899 string_set(&Globals
.ldap_suffix
, "");
900 string_set(&Globals
.szLdapMachineSuffix
, "");
901 string_set(&Globals
.szLdapUserSuffix
, "");
902 string_set(&Globals
.szLdapGroupSuffix
, "");
903 string_set(&Globals
.szLdapIdmapSuffix
, "");
905 string_set(&Globals
.ldap_admin_dn
, "");
906 Globals
.ldap_ssl
= LDAP_SSL_START_TLS
;
907 Globals
.ldap_ssl_ads
= false;
908 Globals
.ldap_deref
= -1;
909 Globals
.ldap_passwd_sync
= LDAP_PASSWD_SYNC_OFF
;
910 Globals
.ldap_delete_dn
= false;
911 Globals
.ldap_replication_sleep
= 1000; /* wait 1 sec for replication */
912 Globals
.ldap_follow_referral
= Auto
;
913 Globals
.ldap_timeout
= LDAP_DEFAULT_TIMEOUT
;
914 Globals
.ldap_connection_timeout
= LDAP_CONNECTION_DEFAULT_TIMEOUT
;
915 Globals
.ldap_page_size
= LDAP_PAGE_SIZE
;
917 Globals
.ldap_debug_level
= 0;
918 Globals
.ldap_debug_threshold
= 10;
920 /* This is what we tell the afs client. in reality we set the token
921 * to never expire, though, when this runs out the afs client will
922 * forget the token. Set to 0 to get NEVERDATE.*/
923 Globals
.afs_token_lifetime
= 604800;
924 Globals
.cups_connection_timeout
= CUPS_DEFAULT_CONNECTION_TIMEOUT
;
926 /* these parameters are set to defaults that are more appropriate
927 for the increasing samba install base:
929 as a member of the workgroup, that will possibly become a
930 _local_ master browser (lm = true). this is opposed to a forced
931 local master browser startup (pm = true).
933 doesn't provide WINS server service by default (wsupp = false),
934 and doesn't provide domain master browser services by default, either.
938 Globals
.show_add_printer_wizard
= true;
939 Globals
.os_level
= 20;
940 Globals
.local_master
= true;
941 Globals
._domain_master
= Auto
; /* depending on _domain_logons */
942 Globals
._domain_logons
= false;
943 Globals
.browse_list
= true;
944 Globals
.we_are_a_wins_server
= false;
945 Globals
.wins_proxy
= false;
947 TALLOC_FREE(Globals
.init_logon_delayed_hosts
);
948 Globals
.init_logon_delay
= 100; /* 100 ms default delay */
950 Globals
.wins_dns_proxy
= true;
952 Globals
.allow_trusted_domains
= true;
953 string_set(&Globals
.szIdmapBackend
, "tdb");
955 string_set(&Globals
.template_shell
, "/bin/false");
956 string_set(&Globals
.template_homedir
, "/home/%D/%U");
957 string_set(&Globals
.winbind_separator
, "\\");
958 string_set(&Globals
.winbindd_socket_directory
, dyn_WINBINDD_SOCKET_DIR
);
960 string_set(&Globals
.cups_server
, "");
961 string_set(&Globals
.iprint_server
, "");
963 #ifdef CLUSTER_SUPPORT
964 string_set(&Globals
.ctdbd_socket
, CTDB_PATH
);
966 string_set(&Globals
.ctdbd_socket
, "");
969 Globals
.cluster_addresses
= NULL
;
970 Globals
.clustering
= false;
971 Globals
.ctdb_timeout
= 0;
972 Globals
.ctdb_locktime_warn_threshold
= 0;
974 Globals
.winbind_cache_time
= 300; /* 5 minutes */
975 Globals
.winbind_reconnect_delay
= 30; /* 30 seconds */
976 Globals
.winbind_max_clients
= 200;
977 Globals
.winbind_enum_users
= false;
978 Globals
.winbind_enum_groups
= false;
979 Globals
.winbind_use_default_domain
= false;
980 Globals
.winbind_trusted_domains_only
= false;
981 Globals
.winbind_nested_groups
= true;
982 Globals
.winbind_expand_groups
= 1;
983 Globals
.winbind_nss_info
= (const char **)str_list_make_v3(NULL
, "template", NULL
);
984 Globals
.winbind_refresh_tickets
= false;
985 Globals
.winbind_offline_logon
= false;
987 Globals
.idmap_cache_time
= 86400 * 7; /* a week by default */
988 Globals
.idmap_negative_cache_time
= 120; /* 2 minutes by default */
990 Globals
.passdb_expand_explicit
= false;
992 Globals
.name_cache_timeout
= 660; /* In seconds */
994 Globals
.use_spnego
= true;
995 Globals
.client_use_spnego
= true;
997 Globals
.client_signing
= SMB_SIGNING_DEFAULT
;
998 Globals
.server_signing
= SMB_SIGNING_DEFAULT
;
1000 Globals
.defer_sharing_violations
= true;
1001 Globals
.smb_ports
= (const char **)str_list_make_v3(NULL
, SMB_PORTS
, NULL
);
1003 Globals
.enable_privileges
= true;
1004 Globals
.host_msdfs
= true;
1005 Globals
.enable_asu_support
= false;
1007 /* User defined shares. */
1008 if (asprintf(&s
, "%s/usershares", get_dyn_STATEDIR()) < 0) {
1009 smb_panic("init_globals: ENOMEM");
1011 string_set(&Globals
.usershare_path
, s
);
1013 string_set(&Globals
.szUsershareTemplateShare
, "");
1014 Globals
.usershare_max_shares
= 0;
1015 /* By default disallow sharing of directories not owned by the sharer. */
1016 Globals
.usershare_owner_only
= true;
1017 /* By default disallow guest access to usershares. */
1018 Globals
.usershare_allow_guests
= false;
1020 Globals
.keepalive
= DEFAULT_KEEPALIVE
;
1022 /* By default no shares out of the registry */
1023 Globals
.registry_shares
= false;
1025 Globals
.iminreceivefile
= 0;
1027 Globals
.map_untrusted_to_domain
= false;
1028 Globals
.multicast_dns_register
= true;
1030 Globals
.smb2_max_read
= DEFAULT_SMB2_MAX_READ
;
1031 Globals
.smb2_max_write
= DEFAULT_SMB2_MAX_WRITE
;
1032 Globals
.smb2_max_trans
= DEFAULT_SMB2_MAX_TRANSACT
;
1033 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
1035 string_set(&Globals
.ncalrpc_dir
, get_dyn_NCALRPCDIR());
1037 Globals
.server_services
= (const char **)str_list_make_v3(NULL
, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbind ntp_signd kcc dnsupdate dns", NULL
);
1039 Globals
.dcerpc_endpoint_servers
= (const char **)str_list_make_v3(NULL
, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL
);
1041 Globals
.tls_enabled
= true;
1043 string_set(&Globals
.tls_keyfile
, "tls/key.pem");
1044 string_set(&Globals
.tls_certfile
, "tls/cert.pem");
1045 string_set(&Globals
.tls_cafile
, "tls/ca.pem");
1047 string_set(&Globals
.share_backend
, "classic");
1049 Globals
.iPreferredMaster
= Auto
;
1051 Globals
.allow_dns_updates
= DNS_UPDATE_SIGNED
;
1053 string_set(&Globals
.ntp_signd_socket_directory
, get_dyn_NTP_SIGND_SOCKET_DIR());
1055 string_set(&Globals
.winbindd_privileged_socket_directory
, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
1057 if (asprintf(&s
, "%s/samba_kcc", get_dyn_SCRIPTSBINDIR()) < 0) {
1058 smb_panic("init_globals: ENOMEM");
1060 Globals
.samba_kcc_command
= (const char **)str_list_make_v3(NULL
, s
, NULL
);
1063 if (asprintf(&s
, "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
1064 smb_panic("init_globals: ENOMEM");
1066 Globals
.dns_update_command
= (const char **)str_list_make_v3(NULL
, s
, NULL
);
1069 if (asprintf(&s
, "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
1070 smb_panic("init_globals: ENOMEM");
1072 Globals
.spn_update_command
= (const char **)str_list_make_v3(NULL
, s
, NULL
);
1075 Globals
.nsupdate_command
= (const char **)str_list_make_v3(NULL
, "/usr/bin/nsupdate -g", NULL
);
1077 Globals
.rndc_command
= (const char **)str_list_make_v3(NULL
, "/usr/sbin/rndc", NULL
);
1079 Globals
.cldap_port
= 389;
1081 Globals
.dgram_port
= 138;
1083 Globals
.nbt_port
= 137;
1085 Globals
.krb5_port
= 88;
1087 Globals
.kpasswd_port
= 464;
1089 Globals
.web_port
= 901;
1091 /* Now put back the settings that were set with lp_set_cmdline() */
1092 apply_lp_set_cmdline();
1095 /*******************************************************************
1096 Convenience routine to grab string parameters into talloced memory
1097 and run standard_sub_basic on them. The buffers can be written to by
1098 callers without affecting the source string.
1099 ********************************************************************/
1101 static char *lp_string(TALLOC_CTX
*ctx
, const char *s
)
1105 /* The follow debug is useful for tracking down memory problems
1106 especially if you have an inner loop that is calling a lp_*()
1107 function that returns a string. Perhaps this debug should be
1108 present all the time? */
1111 DEBUG(10, ("lp_string(%s)\n", s
));
1117 ret
= talloc_sub_basic(ctx
,
1118 get_current_username(),
1119 current_user_info
.domain
,
1121 if (trim_char(ret
, '\"', '\"')) {
1122 if (strchr(ret
,'\"') != NULL
) {
1124 ret
= talloc_sub_basic(ctx
,
1125 get_current_username(),
1126 current_user_info
.domain
,
1134 In this section all the functions that are used to access the
1135 parameters from the rest of the program are defined
1138 #define FN_GLOBAL_STRING(fn_name,ptr) \
1139 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1140 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1141 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1142 #define FN_GLOBAL_LIST(fn_name,ptr) \
1143 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1144 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1145 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1146 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1147 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1148 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1149 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1151 #define FN_LOCAL_STRING(fn_name,val) \
1152 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));}
1153 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1154 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1155 #define FN_LOCAL_LIST(fn_name,val) \
1156 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1157 #define FN_LOCAL_BOOL(fn_name,val) \
1158 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1159 #define FN_LOCAL_INTEGER(fn_name,val) \
1160 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1162 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1163 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1164 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1165 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1166 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1167 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1170 static FN_GLOBAL_BOOL(_readraw
, bReadRaw
)
1171 static FN_GLOBAL_BOOL(_writeraw
, bWriteRaw
)
1173 /* If lp_statedir() and lp_cachedir() are explicitely set during the
1174 * build process or in smb.conf, we use that value. Otherwise they
1175 * default to the value of lp_lock_directory(). */
1176 const char *lp_statedir(void) {
1177 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
1178 (strcmp(get_dyn_STATEDIR(), Globals
.szStateDir
) != 0))
1179 return(*(char **)(&Globals
.szStateDir
) ?
1180 *(char **)(&Globals
.szStateDir
) : "");
1182 return(*(char **)(&Globals
.lock_directory
) ?
1183 *(char **)(&Globals
.lock_directory
) : "");
1185 const char *lp_cachedir(void) {
1186 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
1187 (strcmp(get_dyn_CACHEDIR(), Globals
.szCacheDir
) != 0))
1188 return(*(char **)(&Globals
.szCacheDir
) ?
1189 *(char **)(&Globals
.szCacheDir
) : "");
1191 return(*(char **)(&Globals
.lock_directory
) ?
1192 *(char **)(&Globals
.lock_directory
) : "");
1194 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int
,
1195 winbindMaxDomainConnections
)
1197 int lp_winbind_max_domain_connections(void)
1199 if (lp_winbind_offline_logon() &&
1200 lp_winbind_max_domain_connections_int() > 1) {
1201 DEBUG(1, ("offline logons active, restricting max domain "
1202 "connections to 1\n"));
1205 return MAX(1, lp_winbind_max_domain_connections_int());
1208 int lp_smb2_max_credits(void)
1210 if (Globals
.ismb2_max_credits
== 0) {
1211 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
1213 return Globals
.ismb2_max_credits
;
1215 int lp_cups_encrypt(void)
1218 #ifdef HAVE_HTTPCONNECTENCRYPT
1219 switch (Globals
.CupsEncrypt
) {
1221 result
= HTTP_ENCRYPT_REQUIRED
;
1224 result
= HTTP_ENCRYPT_ALWAYS
;
1227 result
= HTTP_ENCRYPT_NEVER
;
1234 /* These functions remain in source3/param for now */
1236 FN_GLOBAL_STRING(configfile
, szConfigFile
)
1238 #include "lib/param/param_functions.c"
1240 FN_LOCAL_STRING(servicename
, szService
)
1241 FN_LOCAL_CONST_STRING(const_servicename
, szService
)
1243 /* local prototypes */
1245 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
);
1246 static const char *get_boolean(bool bool_value
);
1247 static int getservicebyname(const char *pszServiceName
,
1248 struct loadparm_service
*pserviceDest
);
1249 static void copy_service(struct loadparm_service
*pserviceDest
,
1250 struct loadparm_service
*pserviceSource
,
1251 struct bitmap
*pcopymapDest
);
1252 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
1254 static bool do_section(const char *pszSectionName
, void *userdata
);
1255 static void init_copymap(struct loadparm_service
*pservice
);
1256 static bool hash_a_service(const char *name
, int number
);
1257 static void free_service_byindex(int iService
);
1258 static void show_parameter(int parmIndex
);
1259 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
);
1262 * This is a helper function for parametrical options support. It returns a
1263 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1264 * parametrical functions are quite simple
1266 static struct parmlist_entry
*get_parametrics_by_service(struct loadparm_service
*service
, const char *type
,
1269 bool global_section
= false;
1271 struct parmlist_entry
*data
;
1273 if (service
== NULL
) {
1274 data
= Globals
.param_opt
;
1275 global_section
= true;
1277 data
= service
->param_opt
;
1280 if (asprintf(¶m_key
, "%s:%s", type
, option
) == -1) {
1281 DEBUG(0,("asprintf failed!\n"));
1286 if (strwicmp(data
->key
, param_key
) == 0) {
1287 string_free(¶m_key
);
1293 if (!global_section
) {
1294 /* Try to fetch the same option but from globals */
1295 /* but only if we are not already working with Globals */
1296 data
= Globals
.param_opt
;
1298 if (strwicmp(data
->key
, param_key
) == 0) {
1299 string_free(¶m_key
);
1306 string_free(¶m_key
);
1312 * This is a helper function for parametrical options support. It returns a
1313 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1314 * parametrical functions are quite simple
1316 static struct parmlist_entry
*get_parametrics(int snum
, const char *type
,
1319 if (snum
>= iNumServices
) return NULL
;
1322 return get_parametrics_by_service(NULL
, type
, option
);
1324 return get_parametrics_by_service(ServicePtrs
[snum
], type
, option
);
1329 #define MISSING_PARAMETER(name) \
1330 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1332 /*******************************************************************
1333 convenience routine to return int parameters.
1334 ********************************************************************/
1335 static int lp_int(const char *s
)
1339 MISSING_PARAMETER(lp_int
);
1343 return (int)strtol(s
, NULL
, 0);
1346 /*******************************************************************
1347 convenience routine to return unsigned long parameters.
1348 ********************************************************************/
1349 static unsigned long lp_ulong(const char *s
)
1353 MISSING_PARAMETER(lp_ulong
);
1357 return strtoul(s
, NULL
, 0);
1360 /*******************************************************************
1361 convenience routine to return boolean parameters.
1362 ********************************************************************/
1363 static bool lp_bool(const char *s
)
1368 MISSING_PARAMETER(lp_bool
);
1372 if (!set_boolean(s
, &ret
)) {
1373 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s
));
1380 /*******************************************************************
1381 convenience routine to return enum parameters.
1382 ********************************************************************/
1383 static int lp_enum(const char *s
,const struct enum_list
*_enum
)
1387 if (!s
|| !*s
|| !_enum
) {
1388 MISSING_PARAMETER(lp_enum
);
1392 for (i
=0; _enum
[i
].name
; i
++) {
1393 if (strequal(_enum
[i
].name
,s
))
1394 return _enum
[i
].value
;
1397 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s
));
1401 #undef MISSING_PARAMETER
1403 /* Return parametric option from a given service. Type is a part of option before ':' */
1404 /* Parametric option has following syntax: 'Type: option = value' */
1405 char *lp_parm_talloc_string(TALLOC_CTX
*ctx
, int snum
, const char *type
, const char *option
, const char *def
)
1407 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1409 if (data
== NULL
||data
->value
==NULL
) {
1411 return lp_string(ctx
, def
);
1417 return lp_string(ctx
, data
->value
);
1420 /* Return parametric option from a given service. Type is a part of option before ':' */
1421 /* Parametric option has following syntax: 'Type: option = value' */
1422 const char *lp_parm_const_string(int snum
, const char *type
, const char *option
, const char *def
)
1424 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1426 if (data
== NULL
||data
->value
==NULL
)
1432 const char *lp_parm_const_string_service(struct loadparm_service
*service
, const char *type
, const char *option
)
1434 struct parmlist_entry
*data
= get_parametrics_by_service(service
, type
, option
);
1436 if (data
== NULL
||data
->value
==NULL
)
1443 /* Return parametric option from a given service. Type is a part of option before ':' */
1444 /* Parametric option has following syntax: 'Type: option = value' */
1446 const char **lp_parm_string_list(int snum
, const char *type
, const char *option
, const char **def
)
1448 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1450 if (data
== NULL
||data
->value
==NULL
)
1451 return (const char **)def
;
1453 if (data
->list
==NULL
) {
1454 data
->list
= str_list_make_v3(NULL
, data
->value
, NULL
);
1457 return (const char **)data
->list
;
1460 /* Return parametric option from a given service. Type is a part of option before ':' */
1461 /* Parametric option has following syntax: 'Type: option = value' */
1463 int lp_parm_int(int snum
, const char *type
, const char *option
, int def
)
1465 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1467 if (data
&& data
->value
&& *data
->value
)
1468 return lp_int(data
->value
);
1473 /* Return parametric option from a given service. Type is a part of option before ':' */
1474 /* Parametric option has following syntax: 'Type: option = value' */
1476 unsigned long lp_parm_ulong(int snum
, const char *type
, const char *option
, unsigned long def
)
1478 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1480 if (data
&& data
->value
&& *data
->value
)
1481 return lp_ulong(data
->value
);
1486 /* Return parametric option from a given service. Type is a part of option before ':' */
1487 /* Parametric option has following syntax: 'Type: option = value' */
1489 bool lp_parm_bool(int snum
, const char *type
, const char *option
, bool def
)
1491 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1493 if (data
&& data
->value
&& *data
->value
)
1494 return lp_bool(data
->value
);
1499 /* Return parametric option from a given service. Type is a part of option before ':' */
1500 /* Parametric option has following syntax: 'Type: option = value' */
1502 int lp_parm_enum(int snum
, const char *type
, const char *option
,
1503 const struct enum_list
*_enum
, int def
)
1505 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1507 if (data
&& data
->value
&& *data
->value
&& _enum
)
1508 return lp_enum(data
->value
, _enum
);
1514 /***************************************************************************
1515 Initialise a service to the defaults.
1516 ***************************************************************************/
1518 static void init_service(struct loadparm_service
*pservice
)
1520 memset((char *)pservice
, '\0', sizeof(struct loadparm_service
));
1521 copy_service(pservice
, &sDefault
, NULL
);
1526 * free a param_opts structure.
1527 * param_opts handling should be moved to talloc;
1528 * then this whole functions reduces to a TALLOC_FREE().
1531 static void free_param_opts(struct parmlist_entry
**popts
)
1533 struct parmlist_entry
*opt
, *next_opt
;
1535 if (*popts
!= NULL
) {
1536 DEBUG(5, ("Freeing parametrics:\n"));
1539 while (opt
!= NULL
) {
1540 string_free(&opt
->key
);
1541 string_free(&opt
->value
);
1542 TALLOC_FREE(opt
->list
);
1543 next_opt
= opt
->next
;
1550 /***************************************************************************
1551 Free the dynamically allocated parts of a service struct.
1552 ***************************************************************************/
1554 static void free_service(struct loadparm_service
*pservice
)
1559 if (pservice
->szService
)
1560 DEBUG(5, ("free_service: Freeing service %s\n",
1561 pservice
->szService
));
1563 free_parameters(pservice
);
1565 string_free(&pservice
->szService
);
1566 TALLOC_FREE(pservice
->copymap
);
1568 free_param_opts(&pservice
->param_opt
);
1570 ZERO_STRUCTP(pservice
);
1574 /***************************************************************************
1575 remove a service indexed in the ServicePtrs array from the ServiceHash
1576 and free the dynamically allocated parts
1577 ***************************************************************************/
1579 static void free_service_byindex(int idx
)
1581 if ( !LP_SNUM_OK(idx
) )
1584 ServicePtrs
[idx
]->valid
= false;
1586 /* we have to cleanup the hash record */
1588 if (ServicePtrs
[idx
]->szService
) {
1589 char *canon_name
= canonicalize_servicename(
1591 ServicePtrs
[idx
]->szService
);
1593 dbwrap_delete_bystring(ServiceHash
, canon_name
);
1594 TALLOC_FREE(canon_name
);
1597 free_service(ServicePtrs
[idx
]);
1598 talloc_free_children(ServicePtrs
[idx
]);
1601 /***************************************************************************
1602 Add a new service to the services array initialising it with the given
1604 ***************************************************************************/
1606 static int add_a_service(const struct loadparm_service
*pservice
, const char *name
)
1609 struct loadparm_service tservice
;
1610 int num_to_alloc
= iNumServices
+ 1;
1611 struct loadparm_service
**tsp
= NULL
;
1613 tservice
= *pservice
;
1615 /* it might already exist */
1617 i
= getservicebyname(name
, NULL
);
1623 /* if not, then create one */
1625 tsp
= SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs
, struct loadparm_service
*, num_to_alloc
);
1627 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1631 ServicePtrs
[iNumServices
] = talloc(NULL
, struct loadparm_service
);
1632 if (!ServicePtrs
[iNumServices
]) {
1633 DEBUG(0,("add_a_service: out of memory!\n"));
1638 ServicePtrs
[i
]->valid
= true;
1640 init_service(ServicePtrs
[i
]);
1641 copy_service(ServicePtrs
[i
], &tservice
, NULL
);
1643 string_set(&ServicePtrs
[i
]->szService
, name
);
1645 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1646 i
, ServicePtrs
[i
]->szService
));
1648 if (!hash_a_service(ServicePtrs
[i
]->szService
, i
)) {
1655 /***************************************************************************
1656 Convert a string to uppercase and remove whitespaces.
1657 ***************************************************************************/
1659 char *canonicalize_servicename(TALLOC_CTX
*ctx
, const char *src
)
1664 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1668 result
= talloc_strdup(ctx
, src
);
1669 SMB_ASSERT(result
!= NULL
);
1671 if (!strlower_m(result
)) {
1672 TALLOC_FREE(result
);
1678 /***************************************************************************
1679 Add a name/index pair for the services array to the hash table.
1680 ***************************************************************************/
1682 static bool hash_a_service(const char *name
, int idx
)
1686 if ( !ServiceHash
) {
1687 DEBUG(10,("hash_a_service: creating servicehash\n"));
1688 ServiceHash
= db_open_rbt(NULL
);
1689 if ( !ServiceHash
) {
1690 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1695 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1698 canon_name
= canonicalize_servicename(talloc_tos(), name
);
1700 dbwrap_store_bystring(ServiceHash
, canon_name
,
1701 make_tdb_data((uint8
*)&idx
, sizeof(idx
)),
1704 TALLOC_FREE(canon_name
);
1709 /***************************************************************************
1710 Add a new home service, with the specified home directory, defaults coming
1712 ***************************************************************************/
1714 bool lp_add_home(const char *pszHomename
, int iDefaultService
,
1715 const char *user
, const char *pszHomedir
)
1719 if (pszHomename
== NULL
|| user
== NULL
|| pszHomedir
== NULL
||
1720 pszHomedir
[0] == '\0') {
1724 i
= add_a_service(ServicePtrs
[iDefaultService
], pszHomename
);
1729 if (!(*(ServicePtrs
[iDefaultService
]->path
))
1730 || strequal(ServicePtrs
[iDefaultService
]->path
,
1731 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM
))) {
1732 string_set(&ServicePtrs
[i
]->path
, pszHomedir
);
1735 if (!(*(ServicePtrs
[i
]->comment
))) {
1736 char *comment
= NULL
;
1737 if (asprintf(&comment
, "Home directory of %s", user
) < 0) {
1740 string_set(&ServicePtrs
[i
]->comment
, comment
);
1744 /* set the browseable flag from the global default */
1746 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1747 ServicePtrs
[i
]->access_based_share_enum
= sDefault
.access_based_share_enum
;
1749 ServicePtrs
[i
]->autoloaded
= true;
1751 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename
,
1752 user
, ServicePtrs
[i
]->path
));
1757 /***************************************************************************
1758 Add a new service, based on an old one.
1759 ***************************************************************************/
1761 int lp_add_service(const char *pszService
, int iDefaultService
)
1763 if (iDefaultService
< 0) {
1764 return add_a_service(&sDefault
, pszService
);
1767 return (add_a_service(ServicePtrs
[iDefaultService
], pszService
));
1770 /***************************************************************************
1771 Add the IPC service.
1772 ***************************************************************************/
1774 static bool lp_add_ipc(const char *ipc_name
, bool guest_ok
)
1776 char *comment
= NULL
;
1777 int i
= add_a_service(&sDefault
, ipc_name
);
1782 if (asprintf(&comment
, "IPC Service (%s)",
1783 Globals
.server_string
) < 0) {
1787 string_set(&ServicePtrs
[i
]->path
, tmpdir());
1788 string_set(&ServicePtrs
[i
]->username
, "");
1789 string_set(&ServicePtrs
[i
]->comment
, comment
);
1790 string_set(&ServicePtrs
[i
]->fstype
, "IPC");
1791 ServicePtrs
[i
]->max_connections
= 0;
1792 ServicePtrs
[i
]->bAvailable
= true;
1793 ServicePtrs
[i
]->read_only
= true;
1794 ServicePtrs
[i
]->guest_only
= false;
1795 ServicePtrs
[i
]->administrative_share
= true;
1796 ServicePtrs
[i
]->guest_ok
= guest_ok
;
1797 ServicePtrs
[i
]->printable
= false;
1798 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1800 DEBUG(3, ("adding IPC service\n"));
1806 /***************************************************************************
1807 Add a new printer service, with defaults coming from service iFrom.
1808 ***************************************************************************/
1810 bool lp_add_printer(const char *pszPrintername
, int iDefaultService
)
1812 const char *comment
= "From Printcap";
1813 int i
= add_a_service(ServicePtrs
[iDefaultService
], pszPrintername
);
1818 /* note that we do NOT default the availability flag to true - */
1819 /* we take it from the default service passed. This allows all */
1820 /* dynamic printers to be disabled by disabling the [printers] */
1821 /* entry (if/when the 'available' keyword is implemented!). */
1823 /* the printer name is set to the service name. */
1824 string_set(&ServicePtrs
[i
]->_printername
, pszPrintername
);
1825 string_set(&ServicePtrs
[i
]->comment
, comment
);
1827 /* set the browseable flag from the gloabl default */
1828 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1830 /* Printers cannot be read_only. */
1831 ServicePtrs
[i
]->read_only
= false;
1832 /* No oplocks on printer services. */
1833 ServicePtrs
[i
]->oplocks
= false;
1834 /* Printer services must be printable. */
1835 ServicePtrs
[i
]->printable
= true;
1837 DEBUG(3, ("adding printer service %s\n", pszPrintername
));
1843 /***************************************************************************
1844 Check whether the given parameter name is valid.
1845 Parametric options (names containing a colon) are considered valid.
1846 ***************************************************************************/
1848 bool lp_parameter_is_valid(const char *pszParmName
)
1850 return ((lpcfg_map_parameter(pszParmName
) != -1) ||
1851 (strchr(pszParmName
, ':') != NULL
));
1854 /***************************************************************************
1855 Check whether the given name is the name of a global parameter.
1856 Returns true for strings belonging to parameters of class
1857 P_GLOBAL, false for all other strings, also for parametric options
1858 and strings not belonging to any option.
1859 ***************************************************************************/
1861 bool lp_parameter_is_global(const char *pszParmName
)
1863 int num
= lpcfg_map_parameter(pszParmName
);
1866 return (parm_table
[num
].p_class
== P_GLOBAL
);
1872 /**************************************************************************
1873 Check whether the given name is the canonical name of a parameter.
1874 Returns false if it is not a valid parameter Name.
1875 For parametric options, true is returned.
1876 **************************************************************************/
1878 bool lp_parameter_is_canonical(const char *parm_name
)
1880 if (!lp_parameter_is_valid(parm_name
)) {
1884 return (lpcfg_map_parameter(parm_name
) ==
1885 map_parameter_canonical(parm_name
, NULL
));
1888 /**************************************************************************
1889 Determine the canonical name for a parameter.
1890 Indicate when it is an inverse (boolean) synonym instead of a
1892 **************************************************************************/
1894 bool lp_canonicalize_parameter(const char *parm_name
, const char **canon_parm
,
1899 if (!lp_parameter_is_valid(parm_name
)) {
1904 num
= map_parameter_canonical(parm_name
, inverse
);
1906 /* parametric option */
1907 *canon_parm
= parm_name
;
1909 *canon_parm
= parm_table
[num
].label
;
1916 /**************************************************************************
1917 Determine the canonical name for a parameter.
1918 Turn the value given into the inverse boolean expression when
1919 the synonym is an invers boolean synonym.
1921 Return true if parm_name is a valid parameter name and
1922 in case it is an invers boolean synonym, if the val string could
1923 successfully be converted to the reverse bool.
1924 Return false in all other cases.
1925 **************************************************************************/
1927 bool lp_canonicalize_parameter_with_value(const char *parm_name
,
1929 const char **canon_parm
,
1930 const char **canon_val
)
1935 if (!lp_parameter_is_valid(parm_name
)) {
1941 num
= map_parameter_canonical(parm_name
, &inverse
);
1943 /* parametric option */
1944 *canon_parm
= parm_name
;
1947 *canon_parm
= parm_table
[num
].label
;
1949 if (!lp_invert_boolean(val
, canon_val
)) {
1961 /***************************************************************************
1962 Map a parameter's string representation to the index of the canonical
1963 form of the parameter (it might be a synonym).
1964 Returns -1 if the parameter string is not recognised.
1965 ***************************************************************************/
1967 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
)
1969 int parm_num
, canon_num
;
1970 bool loc_inverse
= false;
1972 parm_num
= lpcfg_map_parameter(pszParmName
);
1973 if ((parm_num
< 0) || !(parm_table
[parm_num
].flags
& FLAG_HIDE
)) {
1974 /* invalid, parametric or no canidate for synonyms ... */
1978 for (canon_num
= 0; parm_table
[canon_num
].label
; canon_num
++) {
1979 if (is_synonym_of(parm_num
, canon_num
, &loc_inverse
)) {
1980 parm_num
= canon_num
;
1986 if (inverse
!= NULL
) {
1987 *inverse
= loc_inverse
;
1992 /***************************************************************************
1993 return true if parameter number parm1 is a synonym of parameter
1994 number parm2 (parm2 being the principal name).
1995 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1997 ***************************************************************************/
1999 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
)
2001 if ((parm_table
[parm1
].offset
== parm_table
[parm2
].offset
) &&
2002 (parm_table
[parm1
].p_class
== parm_table
[parm2
].p_class
) &&
2003 (parm_table
[parm1
].flags
& FLAG_HIDE
) &&
2004 !(parm_table
[parm2
].flags
& FLAG_HIDE
))
2006 if (inverse
!= NULL
) {
2007 if ((parm_table
[parm1
].type
== P_BOOLREV
) &&
2008 (parm_table
[parm2
].type
== P_BOOL
))
2020 /***************************************************************************
2021 Show one parameter's name, type, [values,] and flags.
2022 (helper functions for show_parameter_list)
2023 ***************************************************************************/
2025 static void show_parameter(int parmIndex
)
2027 int enumIndex
, flagIndex
;
2032 const char *type
[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2033 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
2035 unsigned flags
[] = { FLAG_BASIC
, FLAG_SHARE
, FLAG_PRINT
, FLAG_GLOBAL
,
2036 FLAG_WIZARD
, FLAG_ADVANCED
, FLAG_DEVELOPER
, FLAG_DEPRECATED
,
2038 const char *flag_names
[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2039 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2040 "FLAG_DEPRECATED", "FLAG_HIDE", NULL
};
2042 printf("%s=%s", parm_table
[parmIndex
].label
,
2043 type
[parm_table
[parmIndex
].type
]);
2044 if (parm_table
[parmIndex
].type
== P_ENUM
) {
2047 parm_table
[parmIndex
].enum_list
[enumIndex
].name
;
2051 enumIndex
? "|" : "",
2052 parm_table
[parmIndex
].enum_list
[enumIndex
].name
);
2057 for (flagIndex
=0; flag_names
[flagIndex
]; flagIndex
++) {
2058 if (parm_table
[parmIndex
].flags
& flags
[flagIndex
]) {
2061 flag_names
[flagIndex
]);
2066 /* output synonyms */
2068 for (parmIndex2
=0; parm_table
[parmIndex2
].label
; parmIndex2
++) {
2069 if (is_synonym_of(parmIndex
, parmIndex2
, &inverse
)) {
2070 printf(" (%ssynonym of %s)", inverse
? "inverse " : "",
2071 parm_table
[parmIndex2
].label
);
2072 } else if (is_synonym_of(parmIndex2
, parmIndex
, &inverse
)) {
2074 printf(" (synonyms: ");
2079 printf("%s%s", parm_table
[parmIndex2
].label
,
2080 inverse
? "[i]" : "");
2090 /***************************************************************************
2091 Show all parameter's name, type, [values,] and flags.
2092 ***************************************************************************/
2094 void show_parameter_list(void)
2096 int classIndex
, parmIndex
;
2097 const char *section_names
[] = { "local", "global", NULL
};
2099 for (classIndex
=0; section_names
[classIndex
]; classIndex
++) {
2100 printf("[%s]\n", section_names
[classIndex
]);
2101 for (parmIndex
= 0; parm_table
[parmIndex
].label
; parmIndex
++) {
2102 if (parm_table
[parmIndex
].p_class
== classIndex
) {
2103 show_parameter(parmIndex
);
2109 /***************************************************************************
2110 Check if a given string correctly represents a boolean value.
2111 ***************************************************************************/
2113 bool lp_string_is_valid_boolean(const char *parm_value
)
2115 return set_boolean(parm_value
, NULL
);
2118 /***************************************************************************
2119 Get the standard string representation of a boolean value ("yes" or "no")
2120 ***************************************************************************/
2122 static const char *get_boolean(bool bool_value
)
2124 static const char *yes_str
= "yes";
2125 static const char *no_str
= "no";
2127 return (bool_value
? yes_str
: no_str
);
2130 /***************************************************************************
2131 Provide the string of the negated boolean value associated to the boolean
2132 given as a string. Returns false if the passed string does not correctly
2133 represent a boolean.
2134 ***************************************************************************/
2136 bool lp_invert_boolean(const char *str
, const char **inverse_str
)
2140 if (!set_boolean(str
, &val
)) {
2144 *inverse_str
= get_boolean(!val
);
2148 /***************************************************************************
2149 Provide the canonical string representation of a boolean value given
2150 as a string. Return true on success, false if the string given does
2151 not correctly represent a boolean.
2152 ***************************************************************************/
2154 bool lp_canonicalize_boolean(const char *str
, const char**canon_str
)
2158 if (!set_boolean(str
, &val
)) {
2162 *canon_str
= get_boolean(val
);
2166 /***************************************************************************
2167 Find a service by name. Otherwise works like get_service.
2168 ***************************************************************************/
2170 static int getservicebyname(const char *pszServiceName
, struct loadparm_service
*pserviceDest
)
2177 if (ServiceHash
== NULL
) {
2181 canon_name
= canonicalize_servicename(talloc_tos(), pszServiceName
);
2183 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
, canon_name
,
2186 if (NT_STATUS_IS_OK(status
) &&
2187 (data
.dptr
!= NULL
) &&
2188 (data
.dsize
== sizeof(iService
)))
2190 iService
= *(int *)data
.dptr
;
2193 TALLOC_FREE(canon_name
);
2195 if ((iService
!= -1) && (LP_SNUM_OK(iService
))
2196 && (pserviceDest
!= NULL
)) {
2197 copy_service(pserviceDest
, ServicePtrs
[iService
], NULL
);
2203 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2204 struct loadparm_service
*lp_service(const char *pszServiceName
)
2206 int iService
= getservicebyname(pszServiceName
, NULL
);
2207 if (iService
== -1 || !LP_SNUM_OK(iService
)) {
2210 return ServicePtrs
[iService
];
2213 struct loadparm_service
*lp_servicebynum(int snum
)
2215 if ((snum
== -1) || !LP_SNUM_OK(snum
)) {
2218 return ServicePtrs
[snum
];
2221 struct loadparm_service
*lp_default_loadparm_service()
2227 /***************************************************************************
2228 Copy a service structure to another.
2229 If pcopymapDest is NULL then copy all fields
2230 ***************************************************************************/
2233 * Add a parametric option to a parmlist_entry,
2234 * replacing old value, if already present.
2236 static void set_param_opt(struct parmlist_entry
**opt_list
,
2237 const char *opt_name
,
2238 const char *opt_value
,
2241 struct parmlist_entry
*new_opt
, *opt
;
2247 /* Traverse destination */
2249 /* If we already have same option, override it */
2250 if (strwicmp(opt
->key
, opt_name
) == 0) {
2251 if ((opt
->priority
& FLAG_CMDLINE
) &&
2252 !(priority
& FLAG_CMDLINE
)) {
2253 /* it's been marked as not to be
2257 string_free(&opt
->value
);
2258 TALLOC_FREE(opt
->list
);
2259 opt
->value
= SMB_STRDUP(opt_value
);
2260 opt
->priority
= priority
;
2267 new_opt
= SMB_XMALLOC_P(struct parmlist_entry
);
2268 new_opt
->key
= SMB_STRDUP(opt_name
);
2269 new_opt
->value
= SMB_STRDUP(opt_value
);
2270 new_opt
->list
= NULL
;
2271 new_opt
->priority
= priority
;
2272 DLIST_ADD(*opt_list
, new_opt
);
2276 static void copy_service(struct loadparm_service
*pserviceDest
, struct loadparm_service
*pserviceSource
,
2277 struct bitmap
*pcopymapDest
)
2280 bool bcopyall
= (pcopymapDest
== NULL
);
2281 struct parmlist_entry
*data
;
2283 for (i
= 0; parm_table
[i
].label
; i
++)
2284 if (parm_table
[i
].p_class
== P_LOCAL
&&
2285 (bcopyall
|| bitmap_query(pcopymapDest
,i
))) {
2286 void *src_ptr
= lp_parm_ptr(pserviceSource
, &parm_table
[i
]);
2287 void *dest_ptr
= lp_parm_ptr(pserviceDest
, &parm_table
[i
]);
2289 switch (parm_table
[i
].type
) {
2292 *(bool *)dest_ptr
= *(bool *)src_ptr
;
2299 *(int *)dest_ptr
= *(int *)src_ptr
;
2303 *(char *)dest_ptr
= *(char *)src_ptr
;
2307 string_set((char **)dest_ptr
,
2313 char *upper_string
= strupper_talloc(talloc_tos(),
2315 string_set((char **)dest_ptr
,
2317 TALLOC_FREE(upper_string
);
2321 TALLOC_FREE(*((char ***)dest_ptr
));
2322 *((char ***)dest_ptr
) = str_list_copy(NULL
,
2323 *(const char ***)src_ptr
);
2331 init_copymap(pserviceDest
);
2332 if (pserviceSource
->copymap
)
2333 bitmap_copy(pserviceDest
->copymap
,
2334 pserviceSource
->copymap
);
2337 data
= pserviceSource
->param_opt
;
2339 set_param_opt(&pserviceDest
->param_opt
, data
->key
, data
->value
, data
->priority
);
2344 /***************************************************************************
2345 Check a service for consistency. Return false if the service is in any way
2346 incomplete or faulty, else true.
2347 ***************************************************************************/
2349 bool service_ok(int iService
)
2354 if (ServicePtrs
[iService
]->szService
[0] == '\0') {
2355 DEBUG(0, ("The following message indicates an internal error:\n"));
2356 DEBUG(0, ("No service name in service entry.\n"));
2360 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2361 /* I can't see why you'd want a non-printable printer service... */
2362 if (strwicmp(ServicePtrs
[iService
]->szService
, PRINTERS_NAME
) == 0) {
2363 if (!ServicePtrs
[iService
]->printable
) {
2364 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2365 ServicePtrs
[iService
]->szService
));
2366 ServicePtrs
[iService
]->printable
= true;
2368 /* [printers] service must also be non-browsable. */
2369 if (ServicePtrs
[iService
]->browseable
)
2370 ServicePtrs
[iService
]->browseable
= false;
2373 if (ServicePtrs
[iService
]->path
[0] == '\0' &&
2374 strwicmp(ServicePtrs
[iService
]->szService
, HOMES_NAME
) != 0 &&
2375 ServicePtrs
[iService
]->msdfs_proxy
[0] == '\0'
2377 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2378 ServicePtrs
[iService
]->szService
));
2379 ServicePtrs
[iService
]->bAvailable
= false;
2382 /* If a service is flagged unavailable, log the fact at level 1. */
2383 if (!ServicePtrs
[iService
]->bAvailable
)
2384 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2385 ServicePtrs
[iService
]->szService
));
2390 static struct smbconf_ctx
*lp_smbconf_ctx(void)
2393 static struct smbconf_ctx
*conf_ctx
= NULL
;
2395 if (conf_ctx
== NULL
) {
2396 err
= smbconf_init(NULL
, &conf_ctx
, "registry:");
2397 if (!SBC_ERROR_IS_OK(err
)) {
2398 DEBUG(1, ("error initializing registry configuration: "
2399 "%s\n", sbcErrorString(err
)));
2407 static bool process_smbconf_service(struct smbconf_service
*service
)
2412 if (service
== NULL
) {
2416 ret
= do_section(service
->name
, NULL
);
2420 for (count
= 0; count
< service
->num_params
; count
++) {
2421 ret
= do_parameter(service
->param_names
[count
],
2422 service
->param_values
[count
],
2428 if (iServiceIndex
>= 0) {
2429 return service_ok(iServiceIndex
);
2435 * load a service from registry and activate it
2437 bool process_registry_service(const char *service_name
)
2440 struct smbconf_service
*service
= NULL
;
2441 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
2442 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2445 if (conf_ctx
== NULL
) {
2449 DEBUG(5, ("process_registry_service: service name %s\n", service_name
));
2451 if (!smbconf_share_exists(conf_ctx
, service_name
)) {
2453 * Registry does not contain data for this service (yet),
2454 * but make sure lp_load doesn't return false.
2460 err
= smbconf_get_share(conf_ctx
, mem_ctx
, service_name
, &service
);
2461 if (!SBC_ERROR_IS_OK(err
)) {
2465 ret
= process_smbconf_service(service
);
2471 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
2474 TALLOC_FREE(mem_ctx
);
2479 * process_registry_globals
2481 static bool process_registry_globals(void)
2485 add_to_file_list(INCLUDE_REGISTRY_NAME
, INCLUDE_REGISTRY_NAME
);
2487 ret
= do_parameter("registry shares", "yes", NULL
);
2492 return process_registry_service(GLOBAL_NAME
);
2495 bool process_registry_shares(void)
2499 struct smbconf_service
**service
= NULL
;
2500 uint32_t num_shares
= 0;
2501 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
2502 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2505 if (conf_ctx
== NULL
) {
2509 err
= smbconf_get_config(conf_ctx
, mem_ctx
, &num_shares
, &service
);
2510 if (!SBC_ERROR_IS_OK(err
)) {
2516 for (count
= 0; count
< num_shares
; count
++) {
2517 if (strequal(service
[count
]->name
, GLOBAL_NAME
)) {
2520 ret
= process_smbconf_service(service
[count
]);
2527 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
2530 TALLOC_FREE(mem_ctx
);
2535 * reload those shares from registry that are already
2536 * activated in the services array.
2538 static bool reload_registry_shares(void)
2543 for (i
= 0; i
< iNumServices
; i
++) {
2548 if (ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
2552 ret
= process_registry_service(ServicePtrs
[i
]->szService
);
2563 #define MAX_INCLUDE_DEPTH 100
2565 static uint8_t include_depth
;
2567 static struct file_lists
{
2568 struct file_lists
*next
;
2572 } *file_lists
= NULL
;
2574 /*******************************************************************
2575 Keep a linked list of all config files so we know when one has changed
2576 it's date and needs to be reloaded.
2577 ********************************************************************/
2579 static void add_to_file_list(const char *fname
, const char *subfname
)
2581 struct file_lists
*f
= file_lists
;
2584 if (f
->name
&& !strcmp(f
->name
, fname
))
2590 f
= SMB_MALLOC_P(struct file_lists
);
2593 f
->next
= file_lists
;
2594 f
->name
= SMB_STRDUP(fname
);
2599 f
->subfname
= SMB_STRDUP(subfname
);
2606 f
->modtime
= file_modtime(subfname
);
2608 time_t t
= file_modtime(subfname
);
2616 * Free the file lists
2618 static void free_file_list(void)
2620 struct file_lists
*f
;
2621 struct file_lists
*next
;
2626 SAFE_FREE( f
->name
);
2627 SAFE_FREE( f
->subfname
);
2636 * Utility function for outsiders to check if we're running on registry.
2638 bool lp_config_backend_is_registry(void)
2640 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY
);
2644 * Utility function to check if the config backend is FILE.
2646 bool lp_config_backend_is_file(void)
2648 return (lp_config_backend() == CONFIG_BACKEND_FILE
);
2651 /*******************************************************************
2652 Check if a config file has changed date.
2653 ********************************************************************/
2655 bool lp_file_list_changed(void)
2657 struct file_lists
*f
= file_lists
;
2659 DEBUG(6, ("lp_file_list_changed()\n"));
2664 if (strequal(f
->name
, INCLUDE_REGISTRY_NAME
)) {
2665 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2667 if (conf_ctx
== NULL
) {
2670 if (smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
,
2673 DEBUGADD(6, ("registry config changed\n"));
2678 n2
= talloc_sub_basic(talloc_tos(),
2679 get_current_username(),
2680 current_user_info
.domain
,
2685 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2686 f
->name
, n2
, ctime(&f
->modtime
)));
2688 mod_time
= file_modtime(n2
);
2691 ((f
->modtime
!= mod_time
) ||
2692 (f
->subfname
== NULL
) ||
2693 (strcmp(n2
, f
->subfname
) != 0)))
2696 ("file %s modified: %s\n", n2
,
2698 f
->modtime
= mod_time
;
2699 SAFE_FREE(f
->subfname
);
2700 f
->subfname
= SMB_STRDUP(n2
);
2713 * Initialize iconv conversion descriptors.
2715 * This is called the first time it is needed, and also called again
2716 * every time the configuration is reloaded, because the charset or
2717 * codepage might have changed.
2719 static void init_iconv(void)
2721 global_iconv_handle
= smb_iconv_handle_reinit(NULL
, lp_dos_charset(),
2723 true, global_iconv_handle
);
2726 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2728 if (strcmp(*ptr
, pszParmValue
) != 0) {
2729 string_set(ptr
, pszParmValue
);
2735 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2737 bool is_utf8
= false;
2738 size_t len
= strlen(pszParmValue
);
2740 if (len
== 4 || len
== 5) {
2741 /* Don't use StrCaseCmp here as we don't want to
2742 initialize iconv. */
2743 if ((toupper_m(pszParmValue
[0]) == 'U') &&
2744 (toupper_m(pszParmValue
[1]) == 'T') &&
2745 (toupper_m(pszParmValue
[2]) == 'F')) {
2747 if (pszParmValue
[3] == '8') {
2751 if (pszParmValue
[3] == '-' &&
2752 pszParmValue
[4] == '8') {
2759 if (strcmp(*ptr
, pszParmValue
) != 0) {
2761 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
2762 "be UTF8, using (default value) %s instead.\n",
2763 DEFAULT_DOS_CHARSET
));
2764 pszParmValue
= DEFAULT_DOS_CHARSET
;
2766 string_set(ptr
, pszParmValue
);
2772 static bool handle_realm(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2775 TALLOC_CTX
*frame
= talloc_stackframe();
2776 char *realm
= strupper_talloc(frame
, pszParmValue
);
2777 char *dnsdomain
= strlower_talloc(realm
, pszParmValue
);
2779 ret
&= string_set(&Globals
.realm_original
, pszParmValue
);
2780 ret
&= string_set(&Globals
.realm
, realm
);
2781 ret
&= string_set(&Globals
.dnsdomain
, dnsdomain
);
2787 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2789 TALLOC_FREE(Globals
.netbios_aliases
);
2790 Globals
.netbios_aliases
= (const char **)str_list_make_v3(NULL
, pszParmValue
, NULL
);
2791 return set_netbios_aliases(Globals
.netbios_aliases
);
2794 /***************************************************************************
2795 Handle the include operation.
2796 ***************************************************************************/
2797 static bool bAllowIncludeRegistry
= true;
2799 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2803 if (include_depth
>= MAX_INCLUDE_DEPTH
) {
2804 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2809 if (strequal(pszParmValue
, INCLUDE_REGISTRY_NAME
)) {
2810 if (!bAllowIncludeRegistry
) {
2813 if (bInGlobalSection
) {
2816 ret
= process_registry_globals();
2820 DEBUG(1, ("\"include = registry\" only effective "
2821 "in %s section\n", GLOBAL_NAME
));
2826 fname
= talloc_sub_basic(talloc_tos(), get_current_username(),
2827 current_user_info
.domain
,
2830 add_to_file_list(pszParmValue
, fname
);
2832 string_set(ptr
, fname
);
2834 if (file_exist(fname
)) {
2837 ret
= pm_process(fname
, do_section
, do_parameter
, NULL
);
2843 DEBUG(2, ("Can't find include file %s\n", fname
));
2848 /***************************************************************************
2849 Handle the interpretation of the copy parameter.
2850 ***************************************************************************/
2852 static bool handle_copy(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2856 struct loadparm_service serviceTemp
;
2858 string_set(ptr
, pszParmValue
);
2860 init_service(&serviceTemp
);
2864 DEBUG(3, ("Copying service from service %s\n", pszParmValue
));
2866 if ((iTemp
= getservicebyname(pszParmValue
, &serviceTemp
)) >= 0) {
2867 if (iTemp
== iServiceIndex
) {
2868 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue
));
2870 copy_service(ServicePtrs
[iServiceIndex
],
2872 ServicePtrs
[iServiceIndex
]->copymap
);
2876 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue
));
2880 free_service(&serviceTemp
);
2884 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2886 Globals
.ldap_debug_level
= lp_int(pszParmValue
);
2887 init_ldap_debugging();
2892 * idmap related parameters
2895 static bool handle_idmap_backend(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2897 lp_do_parameter(snum
, "idmap config * : backend", pszParmValue
);
2902 static bool handle_idmap_uid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2904 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
2909 static bool handle_idmap_gid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2911 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
2916 bool lp_idmap_range(const char *domain_name
, uint32_t *low
, uint32_t *high
)
2918 char *config_option
= NULL
;
2919 const char *range
= NULL
;
2922 SMB_ASSERT(low
!= NULL
);
2923 SMB_ASSERT(high
!= NULL
);
2925 if ((domain_name
== NULL
) || (domain_name
[0] == '\0')) {
2929 config_option
= talloc_asprintf(talloc_tos(), "idmap config %s",
2931 if (config_option
== NULL
) {
2932 DEBUG(0, ("out of memory\n"));
2936 range
= lp_parm_const_string(-1, config_option
, "range", NULL
);
2937 if (range
== NULL
) {
2938 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name
));
2942 if (sscanf(range
, "%u - %u", low
, high
) != 2) {
2943 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2944 range
, domain_name
));
2951 talloc_free(config_option
);
2956 bool lp_idmap_default_range(uint32_t *low
, uint32_t *high
)
2958 return lp_idmap_range("*", low
, high
);
2961 const char *lp_idmap_backend(const char *domain_name
)
2963 char *config_option
= NULL
;
2964 const char *backend
= NULL
;
2966 if ((domain_name
== NULL
) || (domain_name
[0] == '\0')) {
2970 config_option
= talloc_asprintf(talloc_tos(), "idmap config %s",
2972 if (config_option
== NULL
) {
2973 DEBUG(0, ("out of memory\n"));
2977 backend
= lp_parm_const_string(-1, config_option
, "backend", NULL
);
2978 if (backend
== NULL
) {
2979 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name
));
2984 talloc_free(config_option
);
2988 const char *lp_idmap_default_backend(void)
2990 return lp_idmap_backend("*");
2993 /***************************************************************************
2994 Handle the DEBUG level list.
2995 ***************************************************************************/
2997 static bool handle_debug_list(struct loadparm_context
*unused
, int snum
, const char *pszParmValueIn
, char **ptr
)
2999 string_set(ptr
, pszParmValueIn
);
3000 return debug_parse_levels(pszParmValueIn
);
3003 /***************************************************************************
3004 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3005 ***************************************************************************/
3007 static const char *append_ldap_suffix(TALLOC_CTX
*ctx
, const char *str
)
3009 const char *suffix_string
;
3011 suffix_string
= talloc_asprintf(ctx
, "%s,%s", str
,
3012 Globals
.ldap_suffix
);
3013 if ( !suffix_string
) {
3014 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3018 return suffix_string
;
3021 const char *lp_ldap_machine_suffix(TALLOC_CTX
*ctx
)
3023 if (Globals
.szLdapMachineSuffix
[0])
3024 return append_ldap_suffix(ctx
, Globals
.szLdapMachineSuffix
);
3026 return lp_string(ctx
, Globals
.ldap_suffix
);
3029 const char *lp_ldap_user_suffix(TALLOC_CTX
*ctx
)
3031 if (Globals
.szLdapUserSuffix
[0])
3032 return append_ldap_suffix(ctx
, Globals
.szLdapUserSuffix
);
3034 return lp_string(ctx
, Globals
.ldap_suffix
);
3037 const char *lp_ldap_group_suffix(TALLOC_CTX
*ctx
)
3039 if (Globals
.szLdapGroupSuffix
[0])
3040 return append_ldap_suffix(ctx
, Globals
.szLdapGroupSuffix
);
3042 return lp_string(ctx
, Globals
.ldap_suffix
);
3045 const char *lp_ldap_idmap_suffix(TALLOC_CTX
*ctx
)
3047 if (Globals
.szLdapIdmapSuffix
[0])
3048 return append_ldap_suffix(ctx
, Globals
.szLdapIdmapSuffix
);
3050 return lp_string(ctx
, Globals
.ldap_suffix
);
3053 /****************************************************************************
3054 set the value for a P_ENUM
3055 ***************************************************************************/
3057 static void lp_set_enum_parm( struct parm_struct
*parm
, const char *pszParmValue
,
3062 for (i
= 0; parm
->enum_list
[i
].name
; i
++) {
3063 if ( strequal(pszParmValue
, parm
->enum_list
[i
].name
)) {
3064 *ptr
= parm
->enum_list
[i
].value
;
3068 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
3069 pszParmValue
, parm
->label
));
3072 /***************************************************************************
3073 ***************************************************************************/
3075 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
3077 static int parm_num
= -1;
3078 struct loadparm_service
*s
;
3080 if ( parm_num
== -1 )
3081 parm_num
= lpcfg_map_parameter( "printing" );
3083 lp_set_enum_parm( &parm_table
[parm_num
], pszParmValue
, (int*)ptr
);
3088 s
= ServicePtrs
[snum
];
3090 init_printer_values( s
);
3096 /***************************************************************************
3097 Initialise a copymap.
3098 ***************************************************************************/
3100 static void init_copymap(struct loadparm_service
*pservice
)
3104 TALLOC_FREE(pservice
->copymap
);
3106 pservice
->copymap
= bitmap_talloc(NULL
, NUMPARAMETERS
);
3107 if (!pservice
->copymap
)
3109 ("Couldn't allocate copymap!! (size %d)\n",
3110 (int)NUMPARAMETERS
));
3112 for (i
= 0; i
< NUMPARAMETERS
; i
++)
3113 bitmap_set(pservice
->copymap
, i
);
3117 return the parameter pointer for a parameter
3119 void *lp_parm_ptr(struct loadparm_service
*service
, struct parm_struct
*parm
)
3121 if (service
== NULL
) {
3122 if (parm
->p_class
== P_LOCAL
)
3123 return (void *)(((char *)&sDefault
)+parm
->offset
);
3124 else if (parm
->p_class
== P_GLOBAL
)
3125 return (void *)(((char *)&Globals
)+parm
->offset
);
3128 return (void *)(((char *)service
) + parm
->offset
);
3132 /***************************************************************************
3133 Return the local pointer to a parameter given the service number and parameter
3134 ***************************************************************************/
3136 void *lp_local_ptr_by_snum(int snum
, struct parm_struct
*parm
)
3138 return lp_parm_ptr(ServicePtrs
[snum
], parm
);
3141 /***************************************************************************
3142 Process a parameter for a particular service number. If snum < 0
3143 then assume we are in the globals.
3144 ***************************************************************************/
3146 bool lp_do_parameter(int snum
, const char *pszParmName
, const char *pszParmValue
)
3149 void *parm_ptr
= NULL
; /* where we are going to store the result */
3150 struct parmlist_entry
**opt_list
;
3152 parmnum
= lpcfg_map_parameter(pszParmName
);
3155 if (strchr(pszParmName
, ':') == NULL
) {
3156 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
3162 * We've got a parametric option
3165 opt_list
= (snum
< 0)
3166 ? &Globals
.param_opt
: &ServicePtrs
[snum
]->param_opt
;
3167 set_param_opt(opt_list
, pszParmName
, pszParmValue
, 0);
3172 /* if it's already been set by the command line, then we don't
3174 if (parm_table
[parmnum
].flags
& FLAG_CMDLINE
) {
3178 if (parm_table
[parmnum
].flags
& FLAG_DEPRECATED
) {
3179 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3183 /* we might point at a service, the default service or a global */
3185 parm_ptr
= lp_parm_ptr(NULL
, &parm_table
[parmnum
]);
3187 if (parm_table
[parmnum
].p_class
== P_GLOBAL
) {
3189 ("Global parameter %s found in service section!\n",
3193 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm_table
[parmnum
]);
3197 if (!ServicePtrs
[snum
]->copymap
)
3198 init_copymap(ServicePtrs
[snum
]);
3200 /* this handles the aliases - set the copymap for other entries with
3201 the same data pointer */
3202 for (i
= 0; parm_table
[i
].label
; i
++) {
3203 if ((parm_table
[i
].offset
== parm_table
[parmnum
].offset
)
3204 && (parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
)) {
3205 bitmap_clear(ServicePtrs
[snum
]->copymap
, i
);
3210 /* if it is a special case then go ahead */
3211 if (parm_table
[parmnum
].special
) {
3212 return parm_table
[parmnum
].special(NULL
, snum
, pszParmValue
,
3216 /* now switch on the type of variable it is */
3217 switch (parm_table
[parmnum
].type
)
3220 *(bool *)parm_ptr
= lp_bool(pszParmValue
);
3224 *(bool *)parm_ptr
= !lp_bool(pszParmValue
);
3228 *(int *)parm_ptr
= lp_int(pszParmValue
);
3232 *(char *)parm_ptr
= *pszParmValue
;
3236 i
= sscanf(pszParmValue
, "%o", (int *)parm_ptr
);
3238 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName
));
3245 if (conv_str_size_error(pszParmValue
, &val
)) {
3246 if (val
<= INT_MAX
) {
3247 *(int *)parm_ptr
= (int)val
;
3252 DEBUG(0,("lp_do_parameter(%s): value is not "
3253 "a valid size specifier!\n", pszParmValue
));
3259 TALLOC_FREE(*((char ***)parm_ptr
));
3260 *(char ***)parm_ptr
= str_list_make_v3(
3261 NULL
, pszParmValue
, NULL
);
3265 string_set((char **)parm_ptr
, pszParmValue
);
3270 char *upper_string
= strupper_talloc(talloc_tos(),
3272 string_set((char **)parm_ptr
, upper_string
);
3273 TALLOC_FREE(upper_string
);
3277 lp_set_enum_parm( &parm_table
[parmnum
], pszParmValue
, (int*)parm_ptr
);
3286 /***************************************************************************
3287 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
3288 FLAG_CMDLINE won't be overridden by loads from smb.conf.
3289 ***************************************************************************/
3291 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
)
3294 parmnum
= lpcfg_map_parameter(pszParmName
);
3296 parm_table
[parmnum
].flags
&= ~FLAG_CMDLINE
;
3297 if (!lp_do_parameter(-1, pszParmName
, pszParmValue
)) {
3300 parm_table
[parmnum
].flags
|= FLAG_CMDLINE
;
3302 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
3303 * be grouped in the table, so we don't have to search the
3306 i
>=0 && parm_table
[i
].offset
== parm_table
[parmnum
].offset
3307 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;
3309 parm_table
[i
].flags
|= FLAG_CMDLINE
;
3311 for (i
=parmnum
+1;i
<NUMPARAMETERS
&& parm_table
[i
].offset
== parm_table
[parmnum
].offset
3312 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;i
++) {
3313 parm_table
[i
].flags
|= FLAG_CMDLINE
;
3317 store_lp_set_cmdline(pszParmName
, pszParmValue
);
3322 /* it might be parametric */
3323 if (strchr(pszParmName
, ':') != NULL
) {
3324 set_param_opt(&Globals
.param_opt
, pszParmName
, pszParmValue
, FLAG_CMDLINE
);
3326 store_lp_set_cmdline(pszParmName
, pszParmValue
);
3331 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName
));
3335 bool lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
3337 return lp_set_cmdline_helper(pszParmName
, pszParmValue
, true);
3340 /***************************************************************************
3341 Process a parameter.
3342 ***************************************************************************/
3344 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
3347 if (!bInGlobalSection
&& bGlobalOnly
)
3350 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName
, pszParmValue
));
3352 return (lp_do_parameter(bInGlobalSection
? -2 : iServiceIndex
,
3353 pszParmName
, pszParmValue
));
3357 set a option from the commandline in 'a=b' format. Use to support --option
3359 bool lp_set_option(const char *option
)
3364 s
= talloc_strdup(NULL
, option
);
3377 /* skip white spaces after the = sign */
3380 } while (*p
== ' ');
3382 ret
= lp_set_cmdline(s
, p
);
3387 /***************************************************************************
3388 Initialize any local variables in the sDefault table, after parsing a
3390 ***************************************************************************/
3392 static void init_locals(void)
3395 * We run this check once the [globals] is parsed, to force
3396 * the VFS objects and other per-share settings we need for
3397 * the standard way a AD DC is operated. We may change these
3398 * as our code evolves, which is why we force these settings.
3400 * We can't do this at the end of lp_load_ex(), as by that
3401 * point the services have been loaded and they will already
3402 * have "" as their vfs objects.
3404 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
3405 const char **vfs_objects
= lp_vfs_objects(-1);
3406 if (!vfs_objects
|| !vfs_objects
[0]) {
3407 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL
)) {
3408 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
3409 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL
)) {
3410 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
3412 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
3416 lp_do_parameter(-1, "map hidden", "no");
3417 lp_do_parameter(-1, "map system", "no");
3418 lp_do_parameter(-1, "map readonly", "no");
3419 lp_do_parameter(-1, "map archive", "no");
3420 lp_do_parameter(-1, "store dos attributes", "yes");
3424 /***************************************************************************
3425 Process a new section (service). At this stage all sections are services.
3426 Later we'll have special sections that permit server parameters to be set.
3427 Returns true on success, false on failure.
3428 ***************************************************************************/
3430 static bool do_section(const char *pszSectionName
, void *userdata
)
3433 bool isglobal
= ((strwicmp(pszSectionName
, GLOBAL_NAME
) == 0) ||
3434 (strwicmp(pszSectionName
, GLOBAL_NAME2
) == 0));
3437 /* if we were in a global section then do the local inits */
3438 if (bInGlobalSection
&& !isglobal
)
3441 /* if we've just struck a global section, note the fact. */
3442 bInGlobalSection
= isglobal
;
3444 /* check for multiple global sections */
3445 if (bInGlobalSection
) {
3446 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName
));
3450 if (!bInGlobalSection
&& bGlobalOnly
)
3453 /* if we have a current service, tidy it up before moving on */
3456 if (iServiceIndex
>= 0)
3457 bRetval
= service_ok(iServiceIndex
);
3459 /* if all is still well, move to the next record in the services array */
3461 /* We put this here to avoid an odd message order if messages are */
3462 /* issued by the post-processing of a previous section. */
3463 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName
));
3465 iServiceIndex
= add_a_service(&sDefault
, pszSectionName
);
3466 if (iServiceIndex
< 0) {
3467 DEBUG(0, ("Failed to add a new service\n"));
3470 /* Clean all parametric options for service */
3471 /* They will be added during parsing again */
3472 free_param_opts(&ServicePtrs
[iServiceIndex
]->param_opt
);
3479 /***************************************************************************
3480 Determine if a partcular base parameter is currentl set to the default value.
3481 ***************************************************************************/
3483 static bool is_default(int i
)
3485 switch (parm_table
[i
].type
) {
3488 return str_list_equal((const char **)parm_table
[i
].def
.lvalue
,
3489 *(const char ***)lp_parm_ptr(NULL
,
3493 return strequal(parm_table
[i
].def
.svalue
,
3494 *(char **)lp_parm_ptr(NULL
,
3498 return parm_table
[i
].def
.bvalue
==
3499 *(bool *)lp_parm_ptr(NULL
,
3502 return parm_table
[i
].def
.cvalue
==
3503 *(char *)lp_parm_ptr(NULL
,
3509 return parm_table
[i
].def
.ivalue
==
3510 *(int *)lp_parm_ptr(NULL
,
3518 /***************************************************************************
3519 Display the contents of the global structure.
3520 ***************************************************************************/
3522 static void dump_globals(FILE *f
)
3525 struct parmlist_entry
*data
;
3527 fprintf(f
, "[global]\n");
3529 for (i
= 0; parm_table
[i
].label
; i
++)
3530 if (parm_table
[i
].p_class
== P_GLOBAL
&&
3531 !(parm_table
[i
].flags
& FLAG_META
) &&
3532 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
))) {
3533 if (defaults_saved
&& is_default(i
))
3535 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
3536 lpcfg_print_parameter(&parm_table
[i
], lp_parm_ptr(NULL
,
3541 if (Globals
.param_opt
!= NULL
) {
3542 data
= Globals
.param_opt
;
3544 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
3551 /***************************************************************************
3552 Display the contents of a single services record.
3553 ***************************************************************************/
3555 static void dump_a_service(struct loadparm_service
*pService
, FILE * f
)
3558 struct parmlist_entry
*data
;
3560 if (pService
!= &sDefault
)
3561 fprintf(f
, "[%s]\n", pService
->szService
);
3563 for (i
= 0; parm_table
[i
].label
; i
++) {
3565 if (parm_table
[i
].p_class
== P_LOCAL
&&
3566 !(parm_table
[i
].flags
& FLAG_META
) &&
3567 (*parm_table
[i
].label
!= '-') &&
3568 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
)))
3570 if (pService
== &sDefault
) {
3571 if (defaults_saved
&& is_default(i
))
3574 if (lpcfg_equal_parameter(parm_table
[i
].type
,
3575 lp_parm_ptr(pService
, &parm_table
[i
]),
3576 lp_parm_ptr(NULL
, &parm_table
[i
])))
3580 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
3581 lpcfg_print_parameter(&parm_table
[i
],
3582 lp_parm_ptr(pService
, &parm_table
[i
]),
3588 if (pService
->param_opt
!= NULL
) {
3589 data
= pService
->param_opt
;
3591 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
3597 /***************************************************************************
3598 Display the contents of a parameter of a single services record.
3599 ***************************************************************************/
3601 bool dump_a_parameter(int snum
, char *parm_name
, FILE * f
, bool isGlobal
)
3603 bool result
= false;
3604 fstring local_parm_name
;
3606 const char *parm_opt_value
;
3608 struct loadparm_context
*lp_ctx
;
3610 /* check for parametrical option */
3611 fstrcpy( local_parm_name
, parm_name
);
3612 parm_opt
= strchr( local_parm_name
, ':');
3617 if (strlen(parm_opt
)) {
3618 parm_opt_value
= lp_parm_const_string( snum
,
3619 local_parm_name
, parm_opt
, NULL
);
3620 if (parm_opt_value
) {
3621 printf( "%s\n", parm_opt_value
);
3628 lp_ctx
= loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
3629 if (lp_ctx
== NULL
) {
3634 result
= lpcfg_dump_a_parameter(lp_ctx
, NULL
, parm_name
, f
);
3636 result
= lpcfg_dump_a_parameter(lp_ctx
, ServicePtrs
[snum
], parm_name
, f
);
3638 TALLOC_FREE(lp_ctx
);
3642 /***************************************************************************
3643 Return info about the requested parameter (given as a string).
3644 Return NULL when the string is not a valid parameter name.
3645 ***************************************************************************/
3647 struct parm_struct
*lp_get_parameter(const char *param_name
)
3649 int num
= lpcfg_map_parameter(param_name
);
3655 return &parm_table
[num
];
3659 /***************************************************************************
3660 Display the contents of a single copy structure.
3661 ***************************************************************************/
3662 static void dump_copy_map(bool *pcopymap
)
3668 printf("\n\tNon-Copied parameters:\n");
3670 for (i
= 0; parm_table
[i
].label
; i
++)
3671 if (parm_table
[i
].p_class
== P_LOCAL
&&
3672 parm_table
[i
].ptr
&& !pcopymap
[i
] &&
3673 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
- 1].ptr
)))
3675 printf("\t\t%s\n", parm_table
[i
].label
);
3680 /***************************************************************************
3681 Return TRUE if the passed service number is within range.
3682 ***************************************************************************/
3684 bool lp_snum_ok(int iService
)
3686 return (LP_SNUM_OK(iService
) && ServicePtrs
[iService
]->bAvailable
);
3689 /***************************************************************************
3690 Auto-load some home services.
3691 ***************************************************************************/
3693 static void lp_add_auto_services(char *str
)
3703 s
= SMB_STRDUP(str
);
3707 homes
= lp_servicenumber(HOMES_NAME
);
3709 for (p
= strtok_r(s
, LIST_SEP
, &saveptr
); p
;
3710 p
= strtok_r(NULL
, LIST_SEP
, &saveptr
)) {
3713 if (lp_servicenumber(p
) >= 0)
3716 home
= get_user_home_dir(talloc_tos(), p
);
3718 if (home
&& home
[0] && homes
>= 0)
3719 lp_add_home(p
, homes
, p
, home
);
3726 /***************************************************************************
3727 Auto-load one printer.
3728 ***************************************************************************/
3730 void lp_add_one_printer(const char *name
, const char *comment
,
3731 const char *location
, void *pdata
)
3733 int printers
= lp_servicenumber(PRINTERS_NAME
);
3736 if (lp_servicenumber(name
) < 0) {
3737 lp_add_printer(name
, printers
);
3738 if ((i
= lp_servicenumber(name
)) >= 0) {
3739 string_set(&ServicePtrs
[i
]->comment
, comment
);
3740 ServicePtrs
[i
]->autoloaded
= true;
3745 /***************************************************************************
3746 Have we loaded a services file yet?
3747 ***************************************************************************/
3749 bool lp_loaded(void)
3754 /***************************************************************************
3755 Unload unused services.
3756 ***************************************************************************/
3758 void lp_killunused(struct smbd_server_connection
*sconn
,
3759 bool (*snumused
) (struct smbd_server_connection
*, int))
3762 for (i
= 0; i
< iNumServices
; i
++) {
3766 /* don't kill autoloaded or usershare services */
3767 if ( ServicePtrs
[i
]->autoloaded
||
3768 ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
3772 if (!snumused
|| !snumused(sconn
, i
)) {
3773 free_service_byindex(i
);
3779 * Kill all except autoloaded and usershare services - convenience wrapper
3781 void lp_kill_all_services(void)
3783 lp_killunused(NULL
, NULL
);
3786 /***************************************************************************
3788 ***************************************************************************/
3790 void lp_killservice(int iServiceIn
)
3792 if (VALID(iServiceIn
)) {
3793 free_service_byindex(iServiceIn
);
3797 /***************************************************************************
3798 Save the curent values of all global and sDefault parameters into the
3799 defaults union. This allows testparm to show only the
3800 changed (ie. non-default) parameters.
3801 ***************************************************************************/
3803 static void lp_save_defaults(void)
3806 for (i
= 0; parm_table
[i
].label
; i
++) {
3807 if (i
> 0 && parm_table
[i
].offset
== parm_table
[i
- 1].offset
3808 && parm_table
[i
].p_class
== parm_table
[i
- 1].p_class
)
3810 switch (parm_table
[i
].type
) {
3813 parm_table
[i
].def
.lvalue
= str_list_copy(
3814 NULL
, *(const char ***)lp_parm_ptr(NULL
, &parm_table
[i
]));
3818 parm_table
[i
].def
.svalue
= SMB_STRDUP(*(char **)lp_parm_ptr(NULL
, &parm_table
[i
]));
3822 parm_table
[i
].def
.bvalue
=
3823 *(bool *)lp_parm_ptr(NULL
, &parm_table
[i
]);
3826 parm_table
[i
].def
.cvalue
=
3827 *(char *)lp_parm_ptr(NULL
, &parm_table
[i
]);
3833 parm_table
[i
].def
.ivalue
=
3834 *(int *)lp_parm_ptr(NULL
, &parm_table
[i
]);
3840 defaults_saved
= true;
3843 /***********************************************************
3844 If we should send plaintext/LANMAN passwords in the clinet
3845 ************************************************************/
3847 static void set_allowed_client_auth(void)
3849 if (Globals
.client_ntlmv2_auth
) {
3850 Globals
.client_lanman_auth
= false;
3852 if (!Globals
.client_lanman_auth
) {
3853 Globals
.client_plaintext_auth
= false;
3857 /***************************************************************************
3859 The following code allows smbd to read a user defined share file.
3860 Yes, this is my intent. Yes, I'm comfortable with that...
3862 THE FOLLOWING IS SECURITY CRITICAL CODE.
3864 It washes your clothes, it cleans your house, it guards you while you sleep...
3865 Do not f%^k with it....
3866 ***************************************************************************/
3868 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3870 /***************************************************************************
3871 Check allowed stat state of a usershare file.
3872 Ensure we print out who is dicking with us so the admin can
3873 get their sorry ass fired.
3874 ***************************************************************************/
3876 static bool check_usershare_stat(const char *fname
,
3877 const SMB_STRUCT_STAT
*psbuf
)
3879 if (!S_ISREG(psbuf
->st_ex_mode
)) {
3880 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3881 "not a regular file\n",
3882 fname
, (unsigned int)psbuf
->st_ex_uid
));
3886 /* Ensure this doesn't have the other write bit set. */
3887 if (psbuf
->st_ex_mode
& S_IWOTH
) {
3888 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3889 "public write. Refusing to allow as a usershare file.\n",
3890 fname
, (unsigned int)psbuf
->st_ex_uid
));
3894 /* Should be 10k or less. */
3895 if (psbuf
->st_ex_size
> MAX_USERSHARE_FILE_SIZE
) {
3896 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3897 "too large (%u) to be a user share file.\n",
3898 fname
, (unsigned int)psbuf
->st_ex_uid
,
3899 (unsigned int)psbuf
->st_ex_size
));
3906 /***************************************************************************
3907 Parse the contents of a usershare file.
3908 ***************************************************************************/
3910 enum usershare_err
parse_usershare_file(TALLOC_CTX
*ctx
,
3911 SMB_STRUCT_STAT
*psbuf
,
3912 const char *servicename
,
3916 char **pp_sharepath
,
3918 char **pp_cp_servicename
,
3919 struct security_descriptor
**ppsd
,
3922 const char **prefixallowlist
= lp_usershare_prefix_allow_list();
3923 const char **prefixdenylist
= lp_usershare_prefix_deny_list();
3926 SMB_STRUCT_STAT sbuf
;
3927 char *sharepath
= NULL
;
3928 char *comment
= NULL
;
3930 *pp_sharepath
= NULL
;
3933 *pallow_guest
= false;
3936 return USERSHARE_MALFORMED_FILE
;
3939 if (strcmp(lines
[0], "#VERSION 1") == 0) {
3941 } else if (strcmp(lines
[0], "#VERSION 2") == 0) {
3944 return USERSHARE_MALFORMED_FILE
;
3947 return USERSHARE_BAD_VERSION
;
3950 if (strncmp(lines
[1], "path=", 5) != 0) {
3951 return USERSHARE_MALFORMED_PATH
;
3954 sharepath
= talloc_strdup(ctx
, &lines
[1][5]);
3956 return USERSHARE_POSIX_ERR
;
3958 trim_string(sharepath
, " ", " ");
3960 if (strncmp(lines
[2], "comment=", 8) != 0) {
3961 return USERSHARE_MALFORMED_COMMENT_DEF
;
3964 comment
= talloc_strdup(ctx
, &lines
[2][8]);
3966 return USERSHARE_POSIX_ERR
;
3968 trim_string(comment
, " ", " ");
3969 trim_char(comment
, '"', '"');
3971 if (strncmp(lines
[3], "usershare_acl=", 14) != 0) {
3972 return USERSHARE_MALFORMED_ACL_DEF
;
3975 if (!parse_usershare_acl(ctx
, &lines
[3][14], ppsd
)) {
3976 return USERSHARE_ACL_ERR
;
3980 if (strncmp(lines
[4], "guest_ok=", 9) != 0) {
3981 return USERSHARE_MALFORMED_ACL_DEF
;
3983 if (lines
[4][9] == 'y') {
3984 *pallow_guest
= true;
3987 /* Backwards compatible extension to file version #2. */
3989 if (strncmp(lines
[5], "sharename=", 10) != 0) {
3990 return USERSHARE_MALFORMED_SHARENAME_DEF
;
3992 if (!strequal(&lines
[5][10], servicename
)) {
3993 return USERSHARE_BAD_SHARENAME
;
3995 *pp_cp_servicename
= talloc_strdup(ctx
, &lines
[5][10]);
3996 if (!*pp_cp_servicename
) {
3997 return USERSHARE_POSIX_ERR
;
4002 if (*pp_cp_servicename
== NULL
) {
4003 *pp_cp_servicename
= talloc_strdup(ctx
, servicename
);
4004 if (!*pp_cp_servicename
) {
4005 return USERSHARE_POSIX_ERR
;
4009 if (snum
!= -1 && (strcmp(sharepath
, ServicePtrs
[snum
]->path
) == 0)) {
4010 /* Path didn't change, no checks needed. */
4011 *pp_sharepath
= sharepath
;
4012 *pp_comment
= comment
;
4013 return USERSHARE_OK
;
4016 /* The path *must* be absolute. */
4017 if (sharepath
[0] != '/') {
4018 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4019 servicename
, sharepath
));
4020 return USERSHARE_PATH_NOT_ABSOLUTE
;
4023 /* If there is a usershare prefix deny list ensure one of these paths
4024 doesn't match the start of the user given path. */
4025 if (prefixdenylist
) {
4027 for ( i
=0; prefixdenylist
[i
]; i
++ ) {
4028 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4029 servicename
, i
, prefixdenylist
[i
], sharepath
));
4030 if (memcmp( sharepath
, prefixdenylist
[i
], strlen(prefixdenylist
[i
])) == 0) {
4031 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4032 "usershare prefix deny list entries.\n",
4033 servicename
, sharepath
));
4034 return USERSHARE_PATH_IS_DENIED
;
4039 /* If there is a usershare prefix allow list ensure one of these paths
4040 does match the start of the user given path. */
4042 if (prefixallowlist
) {
4044 for ( i
=0; prefixallowlist
[i
]; i
++ ) {
4045 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4046 servicename
, i
, prefixallowlist
[i
], sharepath
));
4047 if (memcmp( sharepath
, prefixallowlist
[i
], strlen(prefixallowlist
[i
])) == 0) {
4051 if (prefixallowlist
[i
] == NULL
) {
4052 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4053 "usershare prefix allow list entries.\n",
4054 servicename
, sharepath
));
4055 return USERSHARE_PATH_NOT_ALLOWED
;
4059 /* Ensure this is pointing to a directory. */
4060 dp
= opendir(sharepath
);
4063 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4064 servicename
, sharepath
));
4065 return USERSHARE_PATH_NOT_DIRECTORY
;
4068 /* Ensure the owner of the usershare file has permission to share
4071 if (sys_stat(sharepath
, &sbuf
, false) == -1) {
4072 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4073 servicename
, sharepath
, strerror(errno
) ));
4075 return USERSHARE_POSIX_ERR
;
4080 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
4081 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4082 servicename
, sharepath
));
4083 return USERSHARE_PATH_NOT_DIRECTORY
;
4086 /* Check if sharing is restricted to owner-only. */
4087 /* psbuf is the stat of the usershare definition file,
4088 sbuf is the stat of the target directory to be shared. */
4090 if (lp_usershare_owner_only()) {
4091 /* root can share anything. */
4092 if ((psbuf
->st_ex_uid
!= 0) && (sbuf
.st_ex_uid
!= psbuf
->st_ex_uid
)) {
4093 return USERSHARE_PATH_NOT_ALLOWED
;
4097 *pp_sharepath
= sharepath
;
4098 *pp_comment
= comment
;
4099 return USERSHARE_OK
;
4102 /***************************************************************************
4103 Deal with a usershare file.
4106 -1 - Bad name, invalid contents.
4107 - service name already existed and not a usershare, problem
4108 with permissions to share directory etc.
4109 ***************************************************************************/
4111 static int process_usershare_file(const char *dir_name
, const char *file_name
, int snum_template
)
4113 SMB_STRUCT_STAT sbuf
;
4114 SMB_STRUCT_STAT lsbuf
;
4116 char *sharepath
= NULL
;
4117 char *comment
= NULL
;
4118 char *cp_service_name
= NULL
;
4119 char **lines
= NULL
;
4123 TALLOC_CTX
*ctx
= talloc_stackframe();
4124 struct security_descriptor
*psd
= NULL
;
4125 bool guest_ok
= false;
4126 char *canon_name
= NULL
;
4127 bool added_service
= false;
4130 /* Ensure share name doesn't contain invalid characters. */
4131 if (!validate_net_name(file_name
, INVALID_SHARENAME_CHARS
, strlen(file_name
))) {
4132 DEBUG(0,("process_usershare_file: share name %s contains "
4133 "invalid characters (any of %s)\n",
4134 file_name
, INVALID_SHARENAME_CHARS
));
4138 canon_name
= canonicalize_servicename(ctx
, file_name
);
4143 fname
= talloc_asprintf(ctx
, "%s/%s", dir_name
, file_name
);
4148 /* Minimize the race condition by doing an lstat before we
4149 open and fstat. Ensure this isn't a symlink link. */
4151 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
4152 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4153 fname
, strerror(errno
) ));
4157 /* This must be a regular file, not a symlink, directory or
4158 other strange filetype. */
4159 if (!check_usershare_stat(fname
, &lsbuf
)) {
4167 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
,
4172 if (NT_STATUS_IS_OK(status
) &&
4173 (data
.dptr
!= NULL
) &&
4174 (data
.dsize
== sizeof(iService
))) {
4175 memcpy(&iService
, data
.dptr
, sizeof(iService
));
4179 if (iService
!= -1 &&
4180 timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
4181 &lsbuf
.st_ex_mtime
) == 0) {
4182 /* Nothing changed - Mark valid and return. */
4183 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4185 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
4190 /* Try and open the file read only - no symlinks allowed. */
4192 fd
= open(fname
, O_RDONLY
|O_NOFOLLOW
, 0);
4194 fd
= open(fname
, O_RDONLY
, 0);
4198 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4199 fname
, strerror(errno
) ));
4203 /* Now fstat to be *SURE* it's a regular file. */
4204 if (sys_fstat(fd
, &sbuf
, false) != 0) {
4206 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4207 fname
, strerror(errno
) ));
4211 /* Is it the same dev/inode as was lstated ? */
4212 if (!check_same_stat(&lsbuf
, &sbuf
)) {
4214 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4215 "Symlink spoofing going on ?\n", fname
));
4219 /* This must be a regular file, not a symlink, directory or
4220 other strange filetype. */
4221 if (!check_usershare_stat(fname
, &sbuf
)) {
4226 lines
= fd_lines_load(fd
, &numlines
, MAX_USERSHARE_FILE_SIZE
, NULL
);
4229 if (lines
== NULL
) {
4230 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4231 fname
, (unsigned int)sbuf
.st_ex_uid
));
4235 if (parse_usershare_file(ctx
, &sbuf
, file_name
,
4236 iService
, lines
, numlines
, &sharepath
,
4237 &comment
, &cp_service_name
,
4238 &psd
, &guest_ok
) != USERSHARE_OK
) {
4242 /* Everything ok - add the service possibly using a template. */
4244 const struct loadparm_service
*sp
= &sDefault
;
4245 if (snum_template
!= -1) {
4246 sp
= ServicePtrs
[snum_template
];
4249 if ((iService
= add_a_service(sp
, cp_service_name
)) < 0) {
4250 DEBUG(0, ("process_usershare_file: Failed to add "
4251 "new service %s\n", cp_service_name
));
4255 added_service
= true;
4257 /* Read only is controlled by usershare ACL below. */
4258 ServicePtrs
[iService
]->read_only
= false;
4261 /* Write the ACL of the new/modified share. */
4262 if (!set_share_security(canon_name
, psd
)) {
4263 DEBUG(0, ("process_usershare_file: Failed to set share "
4264 "security for user share %s\n",
4269 /* If from a template it may be marked invalid. */
4270 ServicePtrs
[iService
]->valid
= true;
4272 /* Set the service as a valid usershare. */
4273 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
4275 /* Set guest access. */
4276 if (lp_usershare_allow_guests()) {
4277 ServicePtrs
[iService
]->guest_ok
= guest_ok
;
4280 /* And note when it was loaded. */
4281 ServicePtrs
[iService
]->usershare_last_mod
= sbuf
.st_ex_mtime
;
4282 string_set(&ServicePtrs
[iService
]->path
, sharepath
);
4283 string_set(&ServicePtrs
[iService
]->comment
, comment
);
4289 if (ret
== -1 && iService
!= -1 && added_service
) {
4290 lp_remove_service(iService
);
4298 /***************************************************************************
4299 Checks if a usershare entry has been modified since last load.
4300 ***************************************************************************/
4302 static bool usershare_exists(int iService
, struct timespec
*last_mod
)
4304 SMB_STRUCT_STAT lsbuf
;
4305 const char *usersharepath
= Globals
.usershare_path
;
4308 if (asprintf(&fname
, "%s/%s",
4310 ServicePtrs
[iService
]->szService
) < 0) {
4314 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
4319 if (!S_ISREG(lsbuf
.st_ex_mode
)) {
4325 *last_mod
= lsbuf
.st_ex_mtime
;
4329 /***************************************************************************
4330 Load a usershare service by name. Returns a valid servicenumber or -1.
4331 ***************************************************************************/
4333 int load_usershare_service(const char *servicename
)
4335 SMB_STRUCT_STAT sbuf
;
4336 const char *usersharepath
= Globals
.usershare_path
;
4337 int max_user_shares
= Globals
.usershare_max_shares
;
4338 int snum_template
= -1;
4340 if (*usersharepath
== 0 || max_user_shares
== 0) {
4344 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
4345 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4346 usersharepath
, strerror(errno
) ));
4350 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
4351 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4357 * This directory must be owned by root, and have the 't' bit set.
4358 * It also must not be writable by "other".
4362 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4364 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4366 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4367 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4372 /* Ensure the template share exists if it's set. */
4373 if (Globals
.szUsershareTemplateShare
[0]) {
4374 /* We can't use lp_servicenumber here as we are recommending that
4375 template shares have -valid=false set. */
4376 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
4377 if (ServicePtrs
[snum_template
]->szService
&&
4378 strequal(ServicePtrs
[snum_template
]->szService
,
4379 Globals
.szUsershareTemplateShare
)) {
4384 if (snum_template
== -1) {
4385 DEBUG(0,("load_usershare_service: usershare template share %s "
4386 "does not exist.\n",
4387 Globals
.szUsershareTemplateShare
));
4392 return process_usershare_file(usersharepath
, servicename
, snum_template
);
4395 /***************************************************************************
4396 Load all user defined shares from the user share directory.
4397 We only do this if we're enumerating the share list.
4398 This is the function that can delete usershares that have
4400 ***************************************************************************/
4402 int load_usershare_shares(struct smbd_server_connection
*sconn
,
4403 bool (*snumused
) (struct smbd_server_connection
*, int))
4406 SMB_STRUCT_STAT sbuf
;
4408 int num_usershares
= 0;
4409 int max_user_shares
= Globals
.usershare_max_shares
;
4410 unsigned int num_dir_entries
, num_bad_dir_entries
, num_tmp_dir_entries
;
4411 unsigned int allowed_bad_entries
= ((2*max_user_shares
)/10);
4412 unsigned int allowed_tmp_entries
= ((2*max_user_shares
)/10);
4414 int snum_template
= -1;
4415 const char *usersharepath
= Globals
.usershare_path
;
4416 int ret
= lp_numservices();
4417 TALLOC_CTX
*tmp_ctx
;
4419 if (max_user_shares
== 0 || *usersharepath
== '\0') {
4420 return lp_numservices();
4423 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
4424 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4425 usersharepath
, strerror(errno
) ));
4430 * This directory must be owned by root, and have the 't' bit set.
4431 * It also must not be writable by "other".
4435 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4437 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4439 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4440 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4445 /* Ensure the template share exists if it's set. */
4446 if (Globals
.szUsershareTemplateShare
[0]) {
4447 /* We can't use lp_servicenumber here as we are recommending that
4448 template shares have -valid=false set. */
4449 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
4450 if (ServicePtrs
[snum_template
]->szService
&&
4451 strequal(ServicePtrs
[snum_template
]->szService
,
4452 Globals
.szUsershareTemplateShare
)) {
4457 if (snum_template
== -1) {
4458 DEBUG(0,("load_usershare_shares: usershare template share %s "
4459 "does not exist.\n",
4460 Globals
.szUsershareTemplateShare
));
4465 /* Mark all existing usershares as pending delete. */
4466 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4467 if (VALID(iService
) && ServicePtrs
[iService
]->usershare
) {
4468 ServicePtrs
[iService
]->usershare
= USERSHARE_PENDING_DELETE
;
4472 dp
= opendir(usersharepath
);
4474 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4475 usersharepath
, strerror(errno
) ));
4479 for (num_dir_entries
= 0, num_bad_dir_entries
= 0, num_tmp_dir_entries
= 0;
4481 num_dir_entries
++ ) {
4483 const char *n
= de
->d_name
;
4485 /* Ignore . and .. */
4487 if ((n
[1] == '\0') || (n
[1] == '.' && n
[2] == '\0')) {
4493 /* Temporary file used when creating a share. */
4494 num_tmp_dir_entries
++;
4497 /* Allow 20% tmp entries. */
4498 if (num_tmp_dir_entries
> allowed_tmp_entries
) {
4499 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4500 "in directory %s\n",
4501 num_tmp_dir_entries
, usersharepath
));
4505 r
= process_usershare_file(usersharepath
, n
, snum_template
);
4507 /* Update the services count. */
4509 if (num_usershares
>= max_user_shares
) {
4510 DEBUG(0,("load_usershare_shares: max user shares reached "
4511 "on file %s in directory %s\n",
4512 n
, usersharepath
));
4515 } else if (r
== -1) {
4516 num_bad_dir_entries
++;
4519 /* Allow 20% bad entries. */
4520 if (num_bad_dir_entries
> allowed_bad_entries
) {
4521 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4522 "in directory %s\n",
4523 num_bad_dir_entries
, usersharepath
));
4527 /* Allow 20% bad entries. */
4528 if (num_dir_entries
> max_user_shares
+ allowed_bad_entries
) {
4529 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4530 "in directory %s\n",
4531 num_dir_entries
, usersharepath
));
4538 /* Sweep through and delete any non-refreshed usershares that are
4539 not currently in use. */
4540 tmp_ctx
= talloc_stackframe();
4541 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4542 if (VALID(iService
) && (ServicePtrs
[iService
]->usershare
== USERSHARE_PENDING_DELETE
)) {
4545 if (snumused
&& snumused(sconn
, iService
)) {
4549 servname
= lp_servicename(tmp_ctx
, iService
);
4551 /* Remove from the share ACL db. */
4552 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4554 delete_share_security(servname
);
4555 free_service_byindex(iService
);
4558 talloc_free(tmp_ctx
);
4560 return lp_numservices();
4563 /********************************************************
4564 Destroy global resources allocated in this file
4565 ********************************************************/
4567 void gfree_loadparm(void)
4573 /* Free resources allocated to services */
4575 for ( i
= 0; i
< iNumServices
; i
++ ) {
4577 free_service_byindex(i
);
4581 SAFE_FREE( ServicePtrs
);
4584 /* Now release all resources allocated to global
4585 parameters and the default service */
4587 free_global_parameters();
4591 /***************************************************************************
4592 Allow client apps to specify that they are a client
4593 ***************************************************************************/
4594 static void lp_set_in_client(bool b
)
4600 /***************************************************************************
4601 Determine if we're running in a client app
4602 ***************************************************************************/
4603 static bool lp_is_in_client(void)
4608 /***************************************************************************
4609 Load the services array from the services file. Return true on success,
4611 ***************************************************************************/
4613 static bool lp_load_ex(const char *pszFname
,
4617 bool initialize_globals
,
4618 bool allow_include_registry
,
4619 bool load_all_shares
)
4626 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4628 bInGlobalSection
= true;
4629 bGlobalOnly
= global_only
;
4630 bAllowIncludeRegistry
= allow_include_registry
;
4632 init_globals(initialize_globals
);
4636 if (save_defaults
) {
4641 if (!initialize_globals
) {
4642 free_param_opts(&Globals
.param_opt
);
4643 apply_lp_set_cmdline();
4646 lp_do_parameter(-1, "idmap config * : backend", Globals
.szIdmapBackend
);
4648 /* We get sections first, so have to start 'behind' to make up */
4651 if (lp_config_backend_is_file()) {
4652 n2
= talloc_sub_basic(talloc_tos(), get_current_username(),
4653 current_user_info
.domain
,
4656 smb_panic("lp_load_ex: out of memory");
4659 add_to_file_list(pszFname
, n2
);
4661 bRetval
= pm_process(n2
, do_section
, do_parameter
, NULL
);
4664 /* finish up the last section */
4665 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval
)));
4667 if (iServiceIndex
>= 0) {
4668 bRetval
= service_ok(iServiceIndex
);
4672 if (lp_config_backend_is_registry()) {
4673 /* config backend changed to registry in config file */
4675 * We need to use this extra global variable here to
4676 * survive restart: init_globals uses this as a default
4677 * for config_backend. Otherwise, init_globals would
4678 * send us into an endless loop here.
4680 config_backend
= CONFIG_BACKEND_REGISTRY
;
4682 DEBUG(1, ("lp_load_ex: changing to config backend "
4685 lp_kill_all_services();
4686 return lp_load_ex(pszFname
, global_only
, save_defaults
,
4687 add_ipc
, initialize_globals
,
4688 allow_include_registry
,
4691 } else if (lp_config_backend_is_registry()) {
4692 bRetval
= process_registry_globals();
4694 DEBUG(0, ("Illegal config backend given: %d\n",
4695 lp_config_backend()));
4699 if (bRetval
&& lp_registry_shares()) {
4700 if (load_all_shares
) {
4701 bRetval
= process_registry_shares();
4703 bRetval
= reload_registry_shares();
4708 char *serv
= lp_auto_services(talloc_tos());
4709 lp_add_auto_services(serv
);
4714 /* When 'restrict anonymous = 2' guest connections to ipc$
4716 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4717 if ( lp_enable_asu_support() ) {
4718 lp_add_ipc("ADMIN$", false);
4722 set_allowed_client_auth();
4724 if (lp_security() == SEC_ADS
&& strchr(lp_password_server(), ':')) {
4725 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4726 lp_password_server()));
4731 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4732 /* if we_are_a_wins_server is true and we are in the client */
4733 if (lp_is_in_client() && Globals
.we_are_a_wins_server
) {
4734 lp_do_parameter(GLOBAL_SECTION_SNUM
, "wins server", "127.0.0.1");
4739 fault_configure(smb_panic_s3
);
4742 * We run this check once the whole smb.conf is parsed, to
4743 * force some settings for the standard way a AD DC is
4744 * operated. We may changed these as our code evolves, which
4745 * is why we force these settings.
4747 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
4748 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4750 lp_do_parameter(-1, "rpc_server:default", "external");
4751 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4752 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4753 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4754 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4755 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4756 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4757 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4758 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4761 bAllowIncludeRegistry
= true;
4766 bool lp_load(const char *pszFname
,
4770 bool initialize_globals
)
4772 return lp_load_ex(pszFname
,
4777 true, /* allow_include_registry */
4778 false); /* load_all_shares*/
4781 bool lp_load_initial_only(const char *pszFname
)
4783 return lp_load_ex(pszFname
,
4784 true, /* global only */
4785 false, /* save_defaults */
4786 false, /* add_ipc */
4787 true, /* initialize_globals */
4788 false, /* allow_include_registry */
4789 false); /* load_all_shares*/
4793 * most common lp_load wrapper, loading only the globals
4795 bool lp_load_global(const char *file_name
)
4797 return lp_load_ex(file_name
,
4798 true, /* global_only */
4799 false, /* save_defaults */
4800 false, /* add_ipc */
4801 true, /* initialize_globals */
4802 true, /* allow_include_registry */
4803 false); /* load_all_shares*/
4807 * lp_load wrapper, especially for clients
4809 bool lp_load_client(const char *file_name
)
4811 lp_set_in_client(true);
4813 return lp_load_global(file_name
);
4817 * lp_load wrapper, loading only globals, but intended
4818 * for subsequent calls, not reinitializing the globals
4821 bool lp_load_global_no_reinit(const char *file_name
)
4823 return lp_load_ex(file_name
,
4824 true, /* global_only */
4825 false, /* save_defaults */
4826 false, /* add_ipc */
4827 false, /* initialize_globals */
4828 true, /* allow_include_registry */
4829 false); /* load_all_shares*/
4833 * lp_load wrapper, especially for clients, no reinitialization
4835 bool lp_load_client_no_reinit(const char *file_name
)
4837 lp_set_in_client(true);
4839 return lp_load_global_no_reinit(file_name
);
4842 bool lp_load_with_registry_shares(const char *pszFname
,
4846 bool initialize_globals
)
4848 return lp_load_ex(pszFname
,
4853 true, /* allow_include_registry */
4854 true); /* load_all_shares*/
4857 /***************************************************************************
4858 Return the max number of services.
4859 ***************************************************************************/
4861 int lp_numservices(void)
4863 return (iNumServices
);
4866 /***************************************************************************
4867 Display the contents of the services array in human-readable form.
4868 ***************************************************************************/
4870 void lp_dump(FILE *f
, bool show_defaults
, int maxtoprint
)
4875 defaults_saved
= false;
4879 dump_a_service(&sDefault
, f
);
4881 for (iService
= 0; iService
< maxtoprint
; iService
++) {
4883 lp_dump_one(f
, show_defaults
, iService
);
4887 /***************************************************************************
4888 Display the contents of one service in human-readable form.
4889 ***************************************************************************/
4891 void lp_dump_one(FILE * f
, bool show_defaults
, int snum
)
4894 if (ServicePtrs
[snum
]->szService
[0] == '\0')
4896 dump_a_service(ServicePtrs
[snum
], f
);
4900 /***************************************************************************
4901 Return the number of the service with the given name, or -1 if it doesn't
4902 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4903 getservicebyname()! This works ONLY if all services have been loaded, and
4904 does not copy the found service.
4905 ***************************************************************************/
4907 int lp_servicenumber(const char *pszServiceName
)
4910 fstring serviceName
;
4912 if (!pszServiceName
) {
4913 return GLOBAL_SECTION_SNUM
;
4916 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4917 if (VALID(iService
) && ServicePtrs
[iService
]->szService
) {
4919 * The substitution here is used to support %U is
4922 fstrcpy(serviceName
, ServicePtrs
[iService
]->szService
);
4923 standard_sub_basic(get_current_username(),
4924 current_user_info
.domain
,
4925 serviceName
,sizeof(serviceName
));
4926 if (strequal(serviceName
, pszServiceName
)) {
4932 if (iService
>= 0 && ServicePtrs
[iService
]->usershare
== USERSHARE_VALID
) {
4933 struct timespec last_mod
;
4935 if (!usershare_exists(iService
, &last_mod
)) {
4936 /* Remove the share security tdb entry for it. */
4937 delete_share_security(lp_servicename(talloc_tos(), iService
));
4938 /* Remove it from the array. */
4939 free_service_byindex(iService
);
4940 /* Doesn't exist anymore. */
4941 return GLOBAL_SECTION_SNUM
;
4944 /* Has it been modified ? If so delete and reload. */
4945 if (timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
4947 /* Remove it from the array. */
4948 free_service_byindex(iService
);
4949 /* and now reload it. */
4950 iService
= load_usershare_service(pszServiceName
);
4955 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName
));
4956 return GLOBAL_SECTION_SNUM
;
4962 /*******************************************************************
4963 A useful volume label function.
4964 ********************************************************************/
4966 const char *volume_label(TALLOC_CTX
*ctx
, int snum
)
4969 const char *label
= lp_volume(ctx
, snum
);
4971 label
= lp_servicename(ctx
, snum
);
4974 /* This returns a 33 byte guarenteed null terminated string. */
4975 ret
= talloc_strndup(ctx
, label
, 32);
4982 /*******************************************************************
4983 Get the default server type we will announce as via nmbd.
4984 ********************************************************************/
4986 int lp_default_server_announce(void)
4988 int default_server_announce
= 0;
4989 default_server_announce
|= SV_TYPE_WORKSTATION
;
4990 default_server_announce
|= SV_TYPE_SERVER
;
4991 default_server_announce
|= SV_TYPE_SERVER_UNIX
;
4993 /* note that the flag should be set only if we have a
4994 printer service but nmbd doesn't actually load the
4995 services so we can't tell --jerry */
4997 default_server_announce
|= SV_TYPE_PRINTQ_SERVER
;
4999 default_server_announce
|= SV_TYPE_SERVER_NT
;
5000 default_server_announce
|= SV_TYPE_NT
;
5002 switch (lp_server_role()) {
5003 case ROLE_DOMAIN_MEMBER
:
5004 default_server_announce
|= SV_TYPE_DOMAIN_MEMBER
;
5006 case ROLE_DOMAIN_PDC
:
5007 default_server_announce
|= SV_TYPE_DOMAIN_CTRL
;
5009 case ROLE_DOMAIN_BDC
:
5010 default_server_announce
|= SV_TYPE_DOMAIN_BAKCTRL
;
5012 case ROLE_STANDALONE
:
5016 if (lp_time_server())
5017 default_server_announce
|= SV_TYPE_TIME_SOURCE
;
5019 if (lp_host_msdfs())
5020 default_server_announce
|= SV_TYPE_DFS_SERVER
;
5022 return default_server_announce
;
5025 /***********************************************************
5026 If we are PDC then prefer us as DMB
5027 ************************************************************/
5029 bool lp_domain_master(void)
5031 if (Globals
._domain_master
== Auto
)
5032 return (lp_server_role() == ROLE_DOMAIN_PDC
);
5034 return (bool)Globals
._domain_master
;
5037 /***********************************************************
5038 If we are PDC then prefer us as DMB
5039 ************************************************************/
5041 static bool lp_domain_master_true_or_auto(void)
5043 if (Globals
._domain_master
) /* auto or yes */
5049 /***********************************************************
5050 If we are DMB then prefer us as LMB
5051 ************************************************************/
5053 bool lp_preferred_master(void)
5055 if (Globals
.iPreferredMaster
== Auto
)
5056 return (lp_local_master() && lp_domain_master());
5058 return (bool)Globals
.iPreferredMaster
;
5061 /*******************************************************************
5063 ********************************************************************/
5065 void lp_remove_service(int snum
)
5067 ServicePtrs
[snum
]->valid
= false;
5070 /*******************************************************************
5072 ********************************************************************/
5074 void lp_copy_service(int snum
, const char *new_name
)
5076 do_section(new_name
, NULL
);
5078 snum
= lp_servicenumber(new_name
);
5080 char *name
= lp_servicename(talloc_tos(), snum
);
5081 lp_do_parameter(snum
, "copy", name
);
5086 const char *lp_printername(TALLOC_CTX
*ctx
, int snum
)
5088 const char *ret
= lp__printername(ctx
, snum
);
5089 if (ret
== NULL
|| *ret
== '\0') {
5090 ret
= lp_const_servicename(snum
);
5097 /***********************************************************
5098 Allow daemons such as winbindd to fix their logfile name.
5099 ************************************************************/
5101 void lp_set_logfile(const char *name
)
5103 string_set(&Globals
.logfile
, name
);
5104 debug_set_logfile(name
);
5107 /*******************************************************************
5108 Return the max print jobs per queue.
5109 ********************************************************************/
5111 int lp_maxprintjobs(int snum
)
5113 int maxjobs
= LP_SNUM_OK(snum
) ? ServicePtrs
[snum
]->iMaxPrintJobs
: sDefault
.iMaxPrintJobs
;
5114 if (maxjobs
<= 0 || maxjobs
>= PRINT_MAX_JOBID
)
5115 maxjobs
= PRINT_MAX_JOBID
- 1;
5120 const char *lp_printcapname(void)
5122 if ((Globals
.szPrintcapname
!= NULL
) &&
5123 (Globals
.szPrintcapname
[0] != '\0'))
5124 return Globals
.szPrintcapname
;
5126 if (sDefault
.printing
== PRINT_CUPS
) {
5130 if (sDefault
.printing
== PRINT_BSD
)
5131 return "/etc/printcap";
5133 return PRINTCAP_NAME
;
5136 static uint32 spoolss_state
;
5138 bool lp_disable_spoolss( void )
5140 if ( spoolss_state
== SVCCTL_STATE_UNKNOWN
)
5141 spoolss_state
= lp__disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
5143 return spoolss_state
== SVCCTL_STOPPED
? true : false;
5146 void lp_set_spoolss_state( uint32 state
)
5148 SMB_ASSERT( (state
== SVCCTL_STOPPED
) || (state
== SVCCTL_RUNNING
) );
5150 spoolss_state
= state
;
5153 uint32
lp_get_spoolss_state( void )
5155 return lp_disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
5158 /*******************************************************************
5159 Ensure we don't use sendfile if server smb signing is active.
5160 ********************************************************************/
5162 bool lp_use_sendfile(int snum
, struct smb_signing_state
*signing_state
)
5164 bool sign_active
= false;
5166 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5167 if (get_Protocol() < PROTOCOL_NT1
) {
5170 if (signing_state
) {
5171 sign_active
= smb_signing_is_active(signing_state
);
5173 return (lp__use_sendfile(snum
) &&
5174 (get_remote_arch() != RA_WIN95
) &&
5178 /*******************************************************************
5179 Turn off sendfile if we find the underlying OS doesn't support it.
5180 ********************************************************************/
5182 void set_use_sendfile(int snum
, bool val
)
5184 if (LP_SNUM_OK(snum
))
5185 ServicePtrs
[snum
]->_use_sendfile
= val
;
5187 sDefault
._use_sendfile
= val
;
5190 /*******************************************************************
5191 Turn off storing DOS attributes if this share doesn't support it.
5192 ********************************************************************/
5194 void set_store_dos_attributes(int snum
, bool val
)
5196 if (!LP_SNUM_OK(snum
))
5198 ServicePtrs
[(snum
)]->store_dos_attributes
= val
;
5201 void lp_set_mangling_method(const char *new_method
)
5203 string_set(&Globals
.mangling_method
, new_method
);
5206 /*******************************************************************
5207 Global state for POSIX pathname processing.
5208 ********************************************************************/
5210 static bool posix_pathnames
;
5212 bool lp_posix_pathnames(void)
5214 return posix_pathnames
;
5217 /*******************************************************************
5218 Change everything needed to ensure POSIX pathname processing (currently
5220 ********************************************************************/
5222 void lp_set_posix_pathnames(void)
5224 posix_pathnames
= true;
5227 /*******************************************************************
5228 Global state for POSIX lock processing - CIFS unix extensions.
5229 ********************************************************************/
5231 bool posix_default_lock_was_set
;
5232 static enum brl_flavour posix_cifsx_locktype
; /* By default 0 == WINDOWS_LOCK */
5234 enum brl_flavour
lp_posix_cifsu_locktype(files_struct
*fsp
)
5236 if (posix_default_lock_was_set
) {
5237 return posix_cifsx_locktype
;
5239 return fsp
->posix_open
? POSIX_LOCK
: WINDOWS_LOCK
;
5243 /*******************************************************************
5244 ********************************************************************/
5246 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val
)
5248 posix_default_lock_was_set
= true;
5249 posix_cifsx_locktype
= val
;
5252 int lp_min_receive_file_size(void)
5254 if (Globals
.iminreceivefile
< 0) {
5257 return MIN(Globals
.iminreceivefile
, BUFFER_SIZE
);
5260 /*******************************************************************
5261 Safe wide links checks.
5262 This helper function always verify the validity of wide links,
5263 even after a configuration file reload.
5264 ********************************************************************/
5266 static bool lp_widelinks_internal(int snum
)
5268 return (bool)(LP_SNUM_OK(snum
)? ServicePtrs
[(snum
)]->bWidelinks
:
5269 sDefault
.bWidelinks
);
5272 void widelinks_warning(int snum
)
5274 if (lp_allow_insecure_wide_links()) {
5278 if (lp_unix_extensions() && lp_widelinks_internal(snum
)) {
5279 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
5280 "These parameters are incompatible. "
5281 "Wide links will be disabled for this share.\n",
5282 lp_servicename(talloc_tos(), snum
) ));
5286 bool lp_widelinks(int snum
)
5288 /* wide links is always incompatible with unix extensions */
5289 if (lp_unix_extensions()) {
5291 * Unless we have "allow insecure widelinks"
5294 if (!lp_allow_insecure_wide_links()) {
5299 return lp_widelinks_internal(snum
);
5302 bool lp_writeraw(void)
5304 if (lp_async_smb_echo_handler()) {
5307 return lp__writeraw();
5310 bool lp_readraw(void)
5312 if (lp_async_smb_echo_handler()) {
5315 return lp__readraw();
5318 int lp_server_role(void)
5320 return lp_find_server_role(lp__server_role(),
5322 lp__domain_logons(),
5323 lp_domain_master_true_or_auto());
5326 int lp_security(void)
5328 return lp_find_security(lp__server_role(),