source: branches/samba-3.2.x/source/param/loadparm.c@ 238

Last change on this file since 238 was 238, checked in by Herwig Bauernfeind, 16 years ago

Fix for Ticket #85 (by diver) in 3.2 branch (typo)

File size: 251.8 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
5
6 Largely re-written by Andrew Tridgell, September 1994
7
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12 Copyright (C) Michael Adam 2008
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 3 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
26*/
27
28/*
29 * Load parameters.
30 *
31 * This module provides suitable callback functions for the params
32 * module. It builds the internal table of service details which is
33 * then used by the rest of the server.
34 *
35 * To add a parameter:
36 *
37 * 1) add it to the global or service structure definition
38 * 2) add it to the parm_table
39 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40 * 4) If it's a global then initialise it in init_globals. If a local
41 * (ie. service) parameter then initialise it in the sDefault structure
42 *
43 *
44 * Notes:
45 * The configuration file is processed sequentially for speed. It is NOT
46 * accessed randomly as happens in 'real' Windows. For this reason, there
47 * is a fair bit of sequence-dependent code here - ie., code which assumes
48 * that certain things happen before others. In particular, the code which
49 * happens at the boundary between sections is delicately poised, so be
50 * careful!
51 *
52 */
53
54#include "includes.h"
55
56bool bLoaded = False;
57
58extern enum protocol_types Protocol;
59extern userdom_struct current_user_info;
60
61#ifndef GLOBAL_NAME
62#define GLOBAL_NAME "global"
63#endif
64
65#ifndef PRINTERS_NAME
66#define PRINTERS_NAME "printers"
67#endif
68
69#ifndef HOMES_NAME
70#define HOMES_NAME "homes"
71#endif
72
73/* the special value for the include parameter
74 * to be interpreted not as a file name but to
75 * trigger loading of the global smb.conf options
76 * from registry. */
77#ifndef INCLUDE_REGISTRY_NAME
78#define INCLUDE_REGISTRY_NAME "registry"
79#endif
80
81static bool in_client = False; /* Not in the client by default */
82static struct smbconf_csn conf_last_csn;
83
84#define CONFIG_BACKEND_FILE 0
85#define CONFIG_BACKEND_REGISTRY 1
86
87static int config_backend = CONFIG_BACKEND_FILE;
88
89/* some helpful bits */
90#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
91#define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
92
93#define USERSHARE_VALID 1
94#define USERSHARE_PENDING_DELETE 2
95
96extern int extra_time_offset;
97
98static bool defaults_saved = False;
99
100typedef struct _param_opt_struct param_opt_struct;
101struct _param_opt_struct {
102 param_opt_struct *prev, *next;
103 char *key;
104 char *value;
105 char **list;
106};
107
108/*
109 * This structure describes global (ie., server-wide) parameters.
110 */
111struct global {
112 int ConfigBackend;
113 char *smb_ports;
114 char *dos_charset;
115 char *unix_charset;
116 char *display_charset;
117 char *szPrintcapname;
118 char *szAddPortCommand;
119 char *szEnumPortsCommand;
120 char *szAddPrinterCommand;
121 char *szDeletePrinterCommand;
122 char *szOs2DriverMap;
123 char *szLockDir;
124 char *szPidDir;
125 char *szRootdir;
126 char *szDefaultService;
127 char *szGetQuota;
128 char *szSetQuota;
129 char *szMsgCommand;
130 char *szServerString;
131 char *szAutoServices;
132 char *szPasswdProgram;
133 char *szPasswdChat;
134 char *szLogFile;
135 char *szConfigFile;
136 char *szSMBPasswdFile;
137 char *szPrivateDir;
138 char *szPassdbBackend;
139 char **szPreloadModules;
140 char *szPasswordServer;
141 char *szSocketOptions;
142 char *szRealm;
143 char *szAfsUsernameMap;
144 int iAfsTokenLifetime;
145 char *szLogNtTokenCommand;
146 char *szUsernameMap;
147 char *szLogonScript;
148 char *szLogonPath;
149 char *szLogonDrive;
150 char *szLogonHome;
151 char **szWINSservers;
152 char **szInterfaces;
153 char *szRemoteAnnounce;
154 char *szRemoteBrowseSync;
155 char *szSocketAddress;
156 char *szNISHomeMapName;
157 char *szAnnounceVersion; /* This is initialised in init_globals */
158 char *szWorkgroup;
159 char *szNetbiosName;
160 char **szNetbiosAliases;
161 char *szNetbiosScope;
162 char *szNameResolveOrder;
163 char *szPanicAction;
164 char *szAddUserScript;
165 char *szRenameUserScript;
166 char *szDelUserScript;
167 char *szAddGroupScript;
168 char *szDelGroupScript;
169 char *szAddUserToGroupScript;
170 char *szDelUserFromGroupScript;
171 char *szSetPrimaryGroupScript;
172 char *szAddMachineScript;
173 char *szShutdownScript;
174 char *szAbortShutdownScript;
175 char *szUsernameMapScript;
176 char *szCheckPasswordScript;
177 char *szWINSHook;
178 char *szUtmpDir;
179 char *szWtmpDir;
180 bool bUtmp;
181 char *szIdmapUID;
182 char *szIdmapGID;
183 bool bPassdbExpandExplicit;
184 int AlgorithmicRidBase;
185 char *szTemplateHomedir;
186 char *szTemplateShell;
187 char *szWinbindSeparator;
188 bool bWinbindEnumUsers;
189 bool bWinbindEnumGroups;
190 bool bWinbindUseDefaultDomain;
191 bool bWinbindTrustedDomainsOnly;
192 bool bWinbindNestedGroups;
193 int winbind_expand_groups;
194 bool bWinbindRefreshTickets;
195 bool bWinbindOfflineLogon;
196 bool bWinbindNormalizeNames;
197 bool bWinbindRpcOnly;
198 char **szIdmapDomains;
199 char **szIdmapBackend; /* deprecated */
200 char *szIdmapAllocBackend;
201 char *szAddShareCommand;
202 char *szChangeShareCommand;
203 char *szDeleteShareCommand;
204 char **szEventLogs;
205 char *szGuestaccount;
206 char *szManglingMethod;
207 char **szServicesList;
208 char *szUsersharePath;
209 char *szUsershareTemplateShare;
210 char **szUsersharePrefixAllowList;
211 char **szUsersharePrefixDenyList;
212 int mangle_prefix;
213 int max_log_size;
214 char *szLogLevel;
215 int max_xmit;
216 int max_mux;
217 int max_open_files;
218 int open_files_db_hash_size;
219 int pwordlevel;
220 int unamelevel;
221 int deadtime;
222 bool getwd_cache;
223 int maxprotocol;
224 int minprotocol;
225 int security;
226 char **AuthMethods;
227 bool paranoid_server_security;
228 int maxdisksize;
229 int lpqcachetime;
230 int iMaxSmbdProcesses;
231 bool bDisableSpoolss;
232 int syslog;
233 int os_level;
234 bool enhanced_browsing;
235 int max_ttl;
236 int max_wins_ttl;
237 int min_wins_ttl;
238 int lm_announce;
239 int lm_interval;
240 int announce_as; /* This is initialised in init_globals */
241 int machine_password_timeout;
242 int map_to_guest;
243 int oplock_break_wait_time;
244 int winbind_cache_time;
245 int winbind_max_idle_children;
246 char **szWinbindNssInfo;
247 int iLockSpinTime;
248 char *szLdapMachineSuffix;
249 char *szLdapUserSuffix;
250 char *szLdapIdmapSuffix;
251 char *szLdapGroupSuffix;
252 int ldap_ssl;
253 char *szLdapSuffix;
254 char *szLdapAdminDn;
255 int ldap_debug_level;
256 int ldap_debug_threshold;
257 int iAclCompat;
258 char *szCupsServer;
259 char *szIPrintServer;
260 char *ctdbdSocket;
261 char **szClusterAddresses;
262 bool clustering;
263 int ldap_passwd_sync;
264 int ldap_replication_sleep;
265 int ldap_timeout; /* This is initialised in init_globals */
266 int ldap_connection_timeout;
267 int ldap_page_size;
268 bool ldap_delete_dn;
269 bool bMsAddPrinterWizard;
270 bool bDNSproxy;
271 bool bWINSsupport;
272 bool bWINSproxy;
273 bool bLocalMaster;
274 int iPreferredMaster;
275 int iDomainMaster;
276 bool bDomainLogons;
277 bool bEncryptPasswords;
278 bool bUpdateEncrypt;
279 int clientSchannel;
280 int serverSchannel;
281 bool bNullPasswords;
282 bool bObeyPamRestrictions;
283 bool bLoadPrinters;
284 int PrintcapCacheTime;
285 bool bLargeReadwrite;
286 bool bReadRaw;
287 bool bWriteRaw;
288 bool bSyslogOnly;
289 bool bBrowseList;
290 bool bNISHomeMap;
291 bool bTimeServer;
292 bool bBindInterfacesOnly;
293 bool bPamPasswordChange;
294 bool bUnixPasswdSync;
295 bool bPasswdChatDebug;
296 int iPasswdChatTimeout;
297 bool bTimestampLogs;
298 bool bNTSmbSupport;
299 bool bNTPipeSupport;
300 bool bNTStatusSupport;
301 bool bStatCache;
302 int iMaxStatCacheSize;
303 bool bKernelOplocks;
304 bool bAllowTrustedDomains;
305 bool bLanmanAuth;
306 bool bNTLMAuth;
307 bool bUseSpnego;
308 bool bClientLanManAuth;
309 bool bClientNTLMv2Auth;
310 bool bClientPlaintextAuth;
311 bool bClientUseSpnego;
312 bool bDebugPrefixTimestamp;
313 bool bDebugHiresTimestamp;
314 bool bDebugPid;
315 bool bDebugUid;
316 bool bDebugClass;
317 bool bEnableCoreFiles;
318 bool bHostMSDfs;
319 bool bUseMmap;
320 bool bHostnameLookups;
321 bool bUnixExtensions;
322 bool bDisableNetbios;
323 bool bUseKerberosKeytab;
324 bool bDeferSharingViolations;
325 bool bEnablePrivileges;
326 bool bASUSupport;
327 bool bUsershareOwnerOnly;
328 bool bUsershareAllowGuests;
329 bool bRegistryShares;
330 int restrict_anonymous;
331 int name_cache_timeout;
332 int client_signing;
333 int server_signing;
334 int client_ldap_sasl_wrapping;
335 int iUsershareMaxShares;
336 int iIdmapCacheTime;
337 int iIdmapNegativeCacheTime;
338 bool bResetOnZeroVC;
339 int iKeepalive;
340 int iminreceivefile;
341 param_opt_struct *param_opt;
342};
343
344static struct global Globals;
345
346/*
347 * This structure describes a single service.
348 */
349struct service {
350 bool valid;
351 bool autoloaded;
352 int usershare;
353 time_t usershare_last_mod;
354 char *szService;
355 char *szPath;
356 char *szUsername;
357 char **szInvalidUsers;
358 char **szValidUsers;
359 char **szAdminUsers;
360 char *szCopy;
361 char *szInclude;
362 char *szPreExec;
363 char *szPostExec;
364 char *szRootPreExec;
365 char *szRootPostExec;
366 char *szCupsOptions;
367 char *szPrintcommand;
368 char *szLpqcommand;
369 char *szLprmcommand;
370 char *szLppausecommand;
371 char *szLpresumecommand;
372 char *szQueuepausecommand;
373 char *szQueueresumecommand;
374 char *szPrintername;
375 char *szPrintjobUsername;
376 char *szDontdescend;
377 char **szHostsallow;
378 char **szHostsdeny;
379 char *szMagicScript;
380 char *szMagicOutput;
381 char *szVetoFiles;
382 char *szHideFiles;
383 char *szVetoOplockFiles;
384 char *comment;
385 char *force_user;
386 char *force_group;
387 char **readlist;
388 char **writelist;
389 char **printer_admin;
390 char *volume;
391 char *fstype;
392 char **szVfsObjects;
393 char *szMSDfsProxy;
394 char *szAioWriteBehind;
395 char *szDfree;
396 int iMinPrintSpace;
397 int iMaxPrintJobs;
398 int iMaxReportedPrintJobs;
399 int iWriteCacheSize;
400 int iCreate_mask;
401 int iCreate_force_mode;
402 int iSecurity_mask;
403 int iSecurity_force_mode;
404 int iDir_mask;
405 int iDir_force_mode;
406 int iDir_Security_mask;
407 int iDir_Security_force_mode;
408 int iMaxConnections;
409 int iDefaultCase;
410 int iPrinting;
411 int iOplockContentionLimit;
412 int iCSCPolicy;
413 int iBlock_size;
414 int iDfreeCacheTime;
415 bool bPreexecClose;
416 bool bRootpreexecClose;
417 int iCaseSensitive;
418 bool bCasePreserve;
419 bool bShortCasePreserve;
420 bool bHideDotFiles;
421 bool bHideSpecialFiles;
422 bool bHideUnReadable;
423 bool bHideUnWriteableFiles;
424 bool bBrowseable;
425 bool bAvailable;
426 bool bRead_only;
427 bool bNo_set_dir;
428 bool bGuest_only;
429 bool bAdministrative_share;
430 bool bGuest_ok;
431 bool bPrint_ok;
432 bool bMap_system;
433 bool bMap_hidden;
434 bool bMap_archive;
435 bool bStoreDosAttributes;
436 bool bDmapiSupport;
437 bool bLocking;
438 int iStrictLocking;
439 bool bPosixLocking;
440 bool bShareModes;
441 bool bOpLocks;
442 bool bLevel2OpLocks;
443 bool bOnlyUser;
444 bool bMangledNames;
445 bool bWidelinks;
446 bool bSymlinks;
447 bool bSyncAlways;
448 bool bStrictAllocate;
449 bool bStrictSync;
450 char magic_char;
451 struct bitmap *copymap;
452 bool bDeleteReadonly;
453 bool bFakeOplocks;
454 bool bDeleteVetoFiles;
455 bool bDosFilemode;
456 bool bDosFiletimes;
457 bool bDosFiletimeResolution;
458 bool bFakeDirCreateTimes;
459 bool bBlockingLocks;
460 bool bInheritPerms;
461 bool bInheritACLS;
462 bool bInheritOwner;
463 bool bMSDfsRoot;
464 bool bUseClientDriver;
465 bool bDefaultDevmode;
466 bool bForcePrintername;
467 bool bNTAclSupport;
468 bool bForceUnknownAclUser;
469 bool bUseSendfile;
470 bool bProfileAcls;
471 bool bMap_acl_inherit;
472 bool bAfs_Share;
473 bool bEASupport;
474 bool bAclCheckPermissions;
475 bool bAclMapFullControl;
476 bool bAclGroupControl;
477 bool bChangeNotify;
478 bool bKernelChangeNotify;
479 int iallocation_roundup_size;
480 int iAioReadSize;
481 int iAioWriteSize;
482 int iMap_readonly;
483 int iDirectoryNameCacheSize;
484 int ismb_encrypt;
485 param_opt_struct *param_opt;
486
487 char dummy[3]; /* for alignment */
488};
489
490
491/* This is a default service used to prime a services structure */
492static struct service sDefault = {
493 True, /* valid */
494 False, /* not autoloaded */
495 0, /* not a usershare */
496 (time_t)0, /* No last mod time */
497 NULL, /* szService */
498 NULL, /* szPath */
499 NULL, /* szUsername */
500 NULL, /* szInvalidUsers */
501 NULL, /* szValidUsers */
502 NULL, /* szAdminUsers */
503 NULL, /* szCopy */
504 NULL, /* szInclude */
505 NULL, /* szPreExec */
506 NULL, /* szPostExec */
507 NULL, /* szRootPreExec */
508 NULL, /* szRootPostExec */
509 NULL, /* szCupsOptions */
510 NULL, /* szPrintcommand */
511 NULL, /* szLpqcommand */
512 NULL, /* szLprmcommand */
513 NULL, /* szLppausecommand */
514 NULL, /* szLpresumecommand */
515 NULL, /* szQueuepausecommand */
516 NULL, /* szQueueresumecommand */
517 NULL, /* szPrintername */
518 NULL, /* szPrintjobUsername */
519 NULL, /* szDontdescend */
520 NULL, /* szHostsallow */
521 NULL, /* szHostsdeny */
522 NULL, /* szMagicScript */
523 NULL, /* szMagicOutput */
524 NULL, /* szVetoFiles */
525 NULL, /* szHideFiles */
526 NULL, /* szVetoOplockFiles */
527 NULL, /* comment */
528 NULL, /* force user */
529 NULL, /* force group */
530 NULL, /* readlist */
531 NULL, /* writelist */
532 NULL, /* printer admin */
533 NULL, /* volume */
534 NULL, /* fstype */
535 NULL, /* vfs objects */
536 NULL, /* szMSDfsProxy */
537 NULL, /* szAioWriteBehind */
538 NULL, /* szDfree */
539 0, /* iMinPrintSpace */
540 1000, /* iMaxPrintJobs */
541 0, /* iMaxReportedPrintJobs */
542 0, /* iWriteCacheSize */
543 0744, /* iCreate_mask */
544 0000, /* iCreate_force_mode */
545 0777, /* iSecurity_mask */
546 0, /* iSecurity_force_mode */
547 0755, /* iDir_mask */
548 0000, /* iDir_force_mode */
549 0777, /* iDir_Security_mask */
550 0, /* iDir_Security_force_mode */
551 0, /* iMaxConnections */
552 CASE_LOWER, /* iDefaultCase */
553 DEFAULT_PRINTING, /* iPrinting */
554 2, /* iOplockContentionLimit */
555 0, /* iCSCPolicy */
556 1024, /* iBlock_size */
557 0, /* iDfreeCacheTime */
558 False, /* bPreexecClose */
559 False, /* bRootpreexecClose */
560 Auto, /* case sensitive */
561 True, /* case preserve */
562 True, /* short case preserve */
563 True, /* bHideDotFiles */
564 False, /* bHideSpecialFiles */
565 False, /* bHideUnReadable */
566 False, /* bHideUnWriteableFiles */
567 True, /* bBrowseable */
568 True, /* bAvailable */
569 True, /* bRead_only */
570 True, /* bNo_set_dir */
571 False, /* bGuest_only */
572 False, /* bAdministrative_share */
573 False, /* bGuest_ok */
574 False, /* bPrint_ok */
575 False, /* bMap_system */
576 False, /* bMap_hidden */
577 True, /* bMap_archive */
578 False, /* bStoreDosAttributes */
579 False, /* bDmapiSupport */
580 True, /* bLocking */
581 Auto, /* iStrictLocking */
582 True, /* bPosixLocking */
583 True, /* bShareModes */
584 True, /* bOpLocks */
585 True, /* bLevel2OpLocks */
586 False, /* bOnlyUser */
587 True, /* bMangledNames */
588 True, /* bWidelinks */
589 True, /* bSymlinks */
590 False, /* bSyncAlways */
591 False, /* bStrictAllocate */
592 False, /* bStrictSync */
593 '~', /* magic char */
594 NULL, /* copymap */
595 False, /* bDeleteReadonly */
596 False, /* bFakeOplocks */
597 False, /* bDeleteVetoFiles */
598 False, /* bDosFilemode */
599 True, /* bDosFiletimes */
600 False, /* bDosFiletimeResolution */
601 False, /* bFakeDirCreateTimes */
602 True, /* bBlockingLocks */
603 False, /* bInheritPerms */
604 False, /* bInheritACLS */
605 False, /* bInheritOwner */
606 False, /* bMSDfsRoot */
607 False, /* bUseClientDriver */
608 True, /* bDefaultDevmode */
609 False, /* bForcePrintername */
610 True, /* bNTAclSupport */
611 False, /* bForceUnknownAclUser */
612 False, /* bUseSendfile */
613 False, /* bProfileAcls */
614 False, /* bMap_acl_inherit */
615 False, /* bAfs_Share */
616 False, /* bEASupport */
617 True, /* bAclCheckPermissions */
618 True, /* bAclMapFullControl */
619 False, /* bAclGroupControl */
620 True, /* bChangeNotify */
621 True, /* bKernelChangeNotify */
622 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
623 0, /* iAioReadSize */
624 0, /* iAioWriteSize */
625 MAP_READONLY_YES, /* iMap_readonly */
626#ifdef BROKEN_DIRECTORY_HANDLING
627 0, /* iDirectoryNameCacheSize */
628#else
629 100, /* iDirectoryNameCacheSize */
630#endif
631 Auto, /* ismb_encrypt */
632 NULL, /* Parametric options */
633
634 "" /* dummy */
635};
636
637/* local variables */
638static struct service **ServicePtrs = NULL;
639static int iNumServices = 0;
640static int iServiceIndex = 0;
641static struct db_context *ServiceHash;
642static int *invalid_services = NULL;
643static int num_invalid_services = 0;
644static bool bInGlobalSection = True;
645static bool bGlobalOnly = False;
646static int server_role;
647static int default_server_announce;
648
649#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
650
651/* prototypes for the special type handlers */
652static bool handle_include( int snum, const char *pszParmValue, char **ptr);
653static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
654static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
655static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
656static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
657static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
658static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
659static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
660static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
661static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
662static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
663static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
664
665static void set_server_role(void);
666static void set_default_server_announce_type(void);
667static void set_allowed_client_auth(void);
668
669static const struct enum_list enum_protocol[] = {
670 {PROTOCOL_NT1, "NT1"},
671 {PROTOCOL_LANMAN2, "LANMAN2"},
672 {PROTOCOL_LANMAN1, "LANMAN1"},
673 {PROTOCOL_CORE, "CORE"},
674 {PROTOCOL_COREPLUS, "COREPLUS"},
675 {PROTOCOL_COREPLUS, "CORE+"},
676 {-1, NULL}
677};
678
679static const struct enum_list enum_security[] = {
680 {SEC_SHARE, "SHARE"},
681 {SEC_USER, "USER"},
682 {SEC_SERVER, "SERVER"},
683 {SEC_DOMAIN, "DOMAIN"},
684#ifdef HAVE_ADS
685 {SEC_ADS, "ADS"},
686#endif
687 {-1, NULL}
688};
689
690static const struct enum_list enum_printing[] = {
691 {PRINT_SYSV, "sysv"},
692 {PRINT_AIX, "aix"},
693 {PRINT_HPUX, "hpux"},
694 {PRINT_BSD, "bsd"},
695 {PRINT_QNX, "qnx"},
696 {PRINT_PLP, "plp"},
697 {PRINT_LPRNG, "lprng"},
698 {PRINT_CUPS, "cups"},
699 {PRINT_IPRINT, "iprint"},
700 {PRINT_LPRNT, "nt"},
701 {PRINT_LPROS2, "os2"},
702#ifdef DEVELOPER
703 {PRINT_TEST, "test"},
704 {PRINT_VLP, "vlp"},
705#endif /* DEVELOPER */
706 {-1, NULL}
707};
708
709static const struct enum_list enum_ldap_sasl_wrapping[] = {
710 {0, "plain"},
711 {ADS_AUTH_SASL_SIGN, "sign"},
712 {ADS_AUTH_SASL_SEAL, "seal"},
713 {-1, NULL}
714};
715
716static const struct enum_list enum_ldap_ssl[] = {
717 {LDAP_SSL_OFF, "no"},
718 {LDAP_SSL_OFF, "No"},
719 {LDAP_SSL_OFF, "off"},
720 {LDAP_SSL_OFF, "Off"},
721 {LDAP_SSL_START_TLS, "start tls"},
722 {LDAP_SSL_START_TLS, "Start_tls"},
723 {-1, NULL}
724};
725
726static const struct enum_list enum_ldap_passwd_sync[] = {
727 {LDAP_PASSWD_SYNC_OFF, "no"},
728 {LDAP_PASSWD_SYNC_OFF, "No"},
729 {LDAP_PASSWD_SYNC_OFF, "off"},
730 {LDAP_PASSWD_SYNC_OFF, "Off"},
731 {LDAP_PASSWD_SYNC_ON, "Yes"},
732 {LDAP_PASSWD_SYNC_ON, "yes"},
733 {LDAP_PASSWD_SYNC_ON, "on"},
734 {LDAP_PASSWD_SYNC_ON, "On"},
735 {LDAP_PASSWD_SYNC_ONLY, "Only"},
736 {LDAP_PASSWD_SYNC_ONLY, "only"},
737 {-1, NULL}
738};
739
740/* Types of machine we can announce as. */
741#define ANNOUNCE_AS_NT_SERVER 1
742#define ANNOUNCE_AS_WIN95 2
743#define ANNOUNCE_AS_WFW 3
744#define ANNOUNCE_AS_NT_WORKSTATION 4
745
746static const struct enum_list enum_announce_as[] = {
747 {ANNOUNCE_AS_NT_SERVER, "NT"},
748 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
749 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
750 {ANNOUNCE_AS_WIN95, "win95"},
751 {ANNOUNCE_AS_WFW, "WfW"},
752 {-1, NULL}
753};
754
755static const struct enum_list enum_map_readonly[] = {
756 {MAP_READONLY_NO, "no"},
757 {MAP_READONLY_NO, "false"},
758 {MAP_READONLY_NO, "0"},
759 {MAP_READONLY_YES, "yes"},
760 {MAP_READONLY_YES, "true"},
761 {MAP_READONLY_YES, "1"},
762 {MAP_READONLY_PERMISSIONS, "permissions"},
763 {MAP_READONLY_PERMISSIONS, "perms"},
764 {-1, NULL}
765};
766
767static const struct enum_list enum_case[] = {
768 {CASE_LOWER, "lower"},
769 {CASE_UPPER, "upper"},
770 {-1, NULL}
771};
772
773static const struct enum_list enum_bool_auto[] = {
774 {False, "No"},
775 {False, "False"},
776 {False, "0"},
777 {True, "Yes"},
778 {True, "True"},
779 {True, "1"},
780 {Auto, "Auto"},
781 {-1, NULL}
782};
783
784/* Client-side offline caching policy types */
785#define CSC_POLICY_MANUAL 0
786#define CSC_POLICY_DOCUMENTS 1
787#define CSC_POLICY_PROGRAMS 2
788#define CSC_POLICY_DISABLE 3
789
790static const struct enum_list enum_csc_policy[] = {
791 {CSC_POLICY_MANUAL, "manual"},
792 {CSC_POLICY_DOCUMENTS, "documents"},
793 {CSC_POLICY_PROGRAMS, "programs"},
794 {CSC_POLICY_DISABLE, "disable"},
795 {-1, NULL}
796};
797
798/* SMB signing types. */
799static const struct enum_list enum_smb_signing_vals[] = {
800 {False, "No"},
801 {False, "False"},
802 {False, "0"},
803 {False, "Off"},
804 {False, "disabled"},
805 {True, "Yes"},
806 {True, "True"},
807 {True, "1"},
808 {True, "On"},
809 {True, "enabled"},
810 {Auto, "auto"},
811 {Required, "required"},
812 {Required, "mandatory"},
813 {Required, "force"},
814 {Required, "forced"},
815 {Required, "enforced"},
816 {-1, NULL}
817};
818
819/* ACL compatibility options. */
820static const struct enum_list enum_acl_compat_vals[] = {
821 { ACL_COMPAT_AUTO, "auto" },
822 { ACL_COMPAT_WINNT, "winnt" },
823 { ACL_COMPAT_WIN2K, "win2k" },
824 { -1, NULL}
825};
826
827/*
828 Do you want session setups at user level security with a invalid
829 password to be rejected or allowed in as guest? WinNT rejects them
830 but it can be a pain as it means "net view" needs to use a password
831
832 You have 3 choices in the setting of map_to_guest:
833
834 "Never" means session setups with an invalid password
835 are rejected. This is the default.
836
837 "Bad User" means session setups with an invalid password
838 are rejected, unless the username does not exist, in which case it
839 is treated as a guest login
840
841 "Bad Password" means session setups with an invalid password
842 are treated as a guest login
843
844 Note that map_to_guest only has an effect in user or server
845 level security.
846*/
847
848static const struct enum_list enum_map_to_guest[] = {
849 {NEVER_MAP_TO_GUEST, "Never"},
850 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
851 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
852 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
853 {-1, NULL}
854};
855
856/* Config backend options */
857
858static const struct enum_list enum_config_backend[] = {
859 {CONFIG_BACKEND_FILE, "file"},
860 {CONFIG_BACKEND_REGISTRY, "registry"},
861 {-1, NULL}
862};
863
864/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
865 *
866 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
867 * screen in SWAT. This is used to exclude parameters as well as to squash all
868 * parameters that have been duplicated by pseudonyms.
869 *
870 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
871 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
872 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
873 * respective views.
874 *
875 * NOTE2: Handling of duplicated (synonym) parameters:
876 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
877 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
878 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
879 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
880 */
881
882static struct parm_struct parm_table[] = {
883 {N_("Base Options"), P_SEP, P_SEPARATOR},
884
885 {
886 .label = "dos charset",
887 .type = P_STRING,
888 .p_class = P_GLOBAL,
889 .ptr = &Globals.dos_charset,
890 .special = handle_charset,
891 .enum_list = NULL,
892 .flags = FLAG_ADVANCED
893 },
894 {
895 .label = "unix charset",
896 .type = P_STRING,
897 .p_class = P_GLOBAL,
898 .ptr = &Globals.unix_charset,
899 .special = handle_charset,
900 .enum_list = NULL,
901 .flags = FLAG_ADVANCED
902 },
903 {
904 .label = "display charset",
905 .type = P_STRING,
906 .p_class = P_GLOBAL,
907 .ptr = &Globals.display_charset,
908 .special = handle_charset,
909 .enum_list = NULL,
910 .flags = FLAG_ADVANCED
911 },
912 {
913 .label = "comment",
914 .type = P_STRING,
915 .p_class = P_LOCAL,
916 .ptr = &sDefault.comment,
917 .special = NULL,
918 .enum_list = NULL,
919 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
920 },
921 {
922 .label = "path",
923 .type = P_STRING,
924 .p_class = P_LOCAL,
925 .ptr = &sDefault.szPath,
926 .special = NULL,
927 .enum_list = NULL,
928 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
929 },
930 {
931 .label = "directory",
932 .type = P_STRING,
933 .p_class = P_LOCAL,
934 .ptr = &sDefault.szPath,
935 .special = NULL,
936 .enum_list = NULL,
937 .flags = FLAG_HIDE,
938 },
939 {
940 .label = "workgroup",
941 .type = P_USTRING,
942 .p_class = P_GLOBAL,
943 .ptr = &Globals.szWorkgroup,
944 .special = handle_workgroup,
945 .enum_list = NULL,
946 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
947 },
948#ifdef WITH_ADS
949 {
950 .label = "realm",
951 .type = P_USTRING,
952 .p_class = P_GLOBAL,
953 .ptr = &Globals.szRealm,
954 .special = NULL,
955 .enum_list = NULL,
956 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
957 },
958#endif
959 {
960 .label = "netbios name",
961 .type = P_USTRING,
962 .p_class = P_GLOBAL,
963 .ptr = &Globals.szNetbiosName,
964 .special = handle_netbios_name,
965 .enum_list = NULL,
966 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
967 },
968 {
969 .label = "netbios aliases",
970 .type = P_LIST,
971 .p_class = P_GLOBAL,
972 .ptr = &Globals.szNetbiosAliases,
973 .special = handle_netbios_aliases,
974 .enum_list = NULL,
975 .flags = FLAG_ADVANCED,
976 },
977 {
978 .label = "netbios scope",
979 .type = P_USTRING,
980 .p_class = P_GLOBAL,
981 .ptr = &Globals.szNetbiosScope,
982 .special = handle_netbios_scope,
983 .enum_list = NULL,
984 .flags = FLAG_ADVANCED,
985 },
986 {
987 .label = "server string",
988 .type = P_STRING,
989 .p_class = P_GLOBAL,
990 .ptr = &Globals.szServerString,
991 .special = NULL,
992 .enum_list = NULL,
993 .flags = FLAG_BASIC | FLAG_ADVANCED,
994 },
995 {
996 .label = "interfaces",
997 .type = P_LIST,
998 .p_class = P_GLOBAL,
999 .ptr = &Globals.szInterfaces,
1000 .special = NULL,
1001 .enum_list = NULL,
1002 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1003 },
1004 {
1005 .label = "bind interfaces only",
1006 .type = P_BOOL,
1007 .p_class = P_GLOBAL,
1008 .ptr = &Globals.bBindInterfacesOnly,
1009 .special = NULL,
1010 .enum_list = NULL,
1011 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1012 },
1013 {
1014 .label = "config backend",
1015 .type = P_ENUM,
1016 .p_class = P_GLOBAL,
1017 .ptr = &Globals.ConfigBackend,
1018 .special = NULL,
1019 .enum_list = enum_config_backend,
1020 .flags = FLAG_ADVANCED,
1021 },
1022
1023 {N_("Security Options"), P_SEP, P_SEPARATOR},
1024
1025 {
1026 .label = "security",
1027 .type = P_ENUM,
1028 .p_class = P_GLOBAL,
1029 .ptr = &Globals.security,
1030 .special = NULL,
1031 .enum_list = enum_security,
1032 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1033 },
1034 {
1035 .label = "auth methods",
1036 .type = P_LIST,
1037 .p_class = P_GLOBAL,
1038 .ptr = &Globals.AuthMethods,
1039 .special = NULL,
1040 .enum_list = NULL,
1041 .flags = FLAG_ADVANCED,
1042 },
1043 {
1044 .label = "encrypt passwords",
1045 .type = P_BOOL,
1046 .p_class = P_GLOBAL,
1047 .ptr = &Globals.bEncryptPasswords,
1048 .special = NULL,
1049 .enum_list = NULL,
1050 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1051 },
1052 {
1053 .label = "update encrypted",
1054 .type = P_BOOL,
1055 .p_class = P_GLOBAL,
1056 .ptr = &Globals.bUpdateEncrypt,
1057 .special = NULL,
1058 .enum_list = NULL,
1059 .flags = FLAG_ADVANCED,
1060 },
1061 {
1062 .label = "client schannel",
1063 .type = P_ENUM,
1064 .p_class = P_GLOBAL,
1065 .ptr = &Globals.clientSchannel,
1066 .special = NULL,
1067 .enum_list = enum_bool_auto,
1068 .flags = FLAG_BASIC | FLAG_ADVANCED,
1069 },
1070 {
1071 .label = "server schannel",
1072 .type = P_ENUM,
1073 .p_class = P_GLOBAL,
1074 .ptr = &Globals.serverSchannel,
1075 .special = NULL,
1076 .enum_list = enum_bool_auto,
1077 .flags = FLAG_BASIC | FLAG_ADVANCED,
1078 },
1079 {
1080 .label = "allow trusted domains",
1081 .type = P_BOOL,
1082 .p_class = P_GLOBAL,
1083 .ptr = &Globals.bAllowTrustedDomains,
1084 .special = NULL,
1085 .enum_list = NULL,
1086 .flags = FLAG_ADVANCED,
1087 },
1088 {
1089 .label = "map to guest",
1090 .type = P_ENUM,
1091 .p_class = P_GLOBAL,
1092 .ptr = &Globals.map_to_guest,
1093 .special = NULL,
1094 .enum_list = enum_map_to_guest,
1095 .flags = FLAG_ADVANCED,
1096 },
1097 {
1098 .label = "null passwords",
1099 .type = P_BOOL,
1100 .p_class = P_GLOBAL,
1101 .ptr = &Globals.bNullPasswords,
1102 .special = NULL,
1103 .enum_list = NULL,
1104 .flags = FLAG_ADVANCED,
1105 },
1106 {
1107 .label = "obey pam restrictions",
1108 .type = P_BOOL,
1109 .p_class = P_GLOBAL,
1110 .ptr = &Globals.bObeyPamRestrictions,
1111 .special = NULL,
1112 .enum_list = NULL,
1113 .flags = FLAG_ADVANCED,
1114 },
1115 {
1116 .label = "password server",
1117 .type = P_STRING,
1118 .p_class = P_GLOBAL,
1119 .ptr = &Globals.szPasswordServer,
1120 .special = NULL,
1121 .enum_list = NULL,
1122 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1123 },
1124 {
1125 .label = "smb passwd file",
1126 .type = P_STRING,
1127 .p_class = P_GLOBAL,
1128 .ptr = &Globals.szSMBPasswdFile,
1129 .special = NULL,
1130 .enum_list = NULL,
1131 .flags = FLAG_ADVANCED,
1132 },
1133 {
1134 .label = "private dir",
1135 .type = P_STRING,
1136 .p_class = P_GLOBAL,
1137 .ptr = &Globals.szPrivateDir,
1138 .special = NULL,
1139 .enum_list = NULL,
1140 .flags = FLAG_ADVANCED,
1141 },
1142 {
1143 .label = "passdb backend",
1144 .type = P_STRING,
1145 .p_class = P_GLOBAL,
1146 .ptr = &Globals.szPassdbBackend,
1147 .special = NULL,
1148 .enum_list = NULL,
1149 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1150 },
1151 {
1152 .label = "algorithmic rid base",
1153 .type = P_INTEGER,
1154 .p_class = P_GLOBAL,
1155 .ptr = &Globals.AlgorithmicRidBase,
1156 .special = NULL,
1157 .enum_list = NULL,
1158 .flags = FLAG_ADVANCED,
1159 },
1160 {
1161 .label = "root directory",
1162 .type = P_STRING,
1163 .p_class = P_GLOBAL,
1164 .ptr = &Globals.szRootdir,
1165 .special = NULL,
1166 .enum_list = NULL,
1167 .flags = FLAG_ADVANCED,
1168 },
1169 {
1170 .label = "root dir",
1171 .type = P_STRING,
1172 .p_class = P_GLOBAL,
1173 .ptr = &Globals.szRootdir,
1174 .special = NULL,
1175 .enum_list = NULL,
1176 .flags = FLAG_HIDE,
1177 },
1178 {
1179 .label = "root",
1180 .type = P_STRING,
1181 .p_class = P_GLOBAL,
1182 .ptr = &Globals.szRootdir,
1183 .special = NULL,
1184 .enum_list = NULL,
1185 .flags = FLAG_HIDE,
1186 },
1187 {
1188 .label = "guest account",
1189 .type = P_STRING,
1190 .p_class = P_GLOBAL,
1191 .ptr = &Globals.szGuestaccount,
1192 .special = NULL,
1193 .enum_list = NULL,
1194 .flags = FLAG_BASIC | FLAG_ADVANCED,
1195 },
1196 {
1197 .label = "enable privileges",
1198 .type = P_BOOL,
1199 .p_class = P_GLOBAL,
1200 .ptr = &Globals.bEnablePrivileges,
1201 .special = NULL,
1202 .enum_list = NULL,
1203 .flags = FLAG_ADVANCED,
1204 },
1205
1206 {
1207 .label = "pam password change",
1208 .type = P_BOOL,
1209 .p_class = P_GLOBAL,
1210 .ptr = &Globals.bPamPasswordChange,
1211 .special = NULL,
1212 .enum_list = NULL,
1213 .flags = FLAG_ADVANCED,
1214 },
1215 {
1216 .label = "passwd program",
1217 .type = P_STRING,
1218 .p_class = P_GLOBAL,
1219 .ptr = &Globals.szPasswdProgram,
1220 .special = NULL,
1221 .enum_list = NULL,
1222 .flags = FLAG_ADVANCED,
1223 },
1224 {
1225 .label = "passwd chat",
1226 .type = P_STRING,
1227 .p_class = P_GLOBAL,
1228 .ptr = &Globals.szPasswdChat,
1229 .special = NULL,
1230 .enum_list = NULL,
1231 .flags = FLAG_ADVANCED,
1232 },
1233 {
1234 .label = "passwd chat debug",
1235 .type = P_BOOL,
1236 .p_class = P_GLOBAL,
1237 .ptr = &Globals.bPasswdChatDebug,
1238 .special = NULL,
1239 .enum_list = NULL,
1240 .flags = FLAG_ADVANCED,
1241 },
1242 {
1243 .label = "passwd chat timeout",
1244 .type = P_INTEGER,
1245 .p_class = P_GLOBAL,
1246 .ptr = &Globals.iPasswdChatTimeout,
1247 .special = NULL,
1248 .enum_list = NULL,
1249 .flags = FLAG_ADVANCED,
1250 },
1251 {
1252 .label = "check password script",
1253 .type = P_STRING,
1254 .p_class = P_GLOBAL,
1255 .ptr = &Globals.szCheckPasswordScript,
1256 .special = NULL,
1257 .enum_list = NULL,
1258 .flags = FLAG_ADVANCED,
1259 },
1260 {
1261 .label = "username map",
1262 .type = P_STRING,
1263 .p_class = P_GLOBAL,
1264 .ptr = &Globals.szUsernameMap,
1265 .special = NULL,
1266 .enum_list = NULL,
1267 .flags = FLAG_ADVANCED,
1268 },
1269 {
1270 .label = "password level",
1271 .type = P_INTEGER,
1272 .p_class = P_GLOBAL,
1273 .ptr = &Globals.pwordlevel,
1274 .special = NULL,
1275 .enum_list = NULL,
1276 .flags = FLAG_ADVANCED,
1277 },
1278 {
1279 .label = "username level",
1280 .type = P_INTEGER,
1281 .p_class = P_GLOBAL,
1282 .ptr = &Globals.unamelevel,
1283 .special = NULL,
1284 .enum_list = NULL,
1285 .flags = FLAG_ADVANCED,
1286 },
1287 {
1288 .label = "unix password sync",
1289 .type = P_BOOL,
1290 .p_class = P_GLOBAL,
1291 .ptr = &Globals.bUnixPasswdSync,
1292 .special = NULL,
1293 .enum_list = NULL,
1294 .flags = FLAG_ADVANCED,
1295 },
1296 {
1297 .label = "restrict anonymous",
1298 .type = P_INTEGER,
1299 .p_class = P_GLOBAL,
1300 .ptr = &Globals.restrict_anonymous,
1301 .special = NULL,
1302 .enum_list = NULL,
1303 .flags = FLAG_ADVANCED,
1304 },
1305 {
1306 .label = "lanman auth",
1307 .type = P_BOOL,
1308 .p_class = P_GLOBAL,
1309 .ptr = &Globals.bLanmanAuth,
1310 .special = NULL,
1311 .enum_list = NULL,
1312 .flags = FLAG_ADVANCED,
1313 },
1314 {
1315 .label = "ntlm auth",
1316 .type = P_BOOL,
1317 .p_class = P_GLOBAL,
1318 .ptr = &Globals.bNTLMAuth,
1319 .special = NULL,
1320 .enum_list = NULL,
1321 .flags = FLAG_ADVANCED,
1322 },
1323 {
1324 .label = "client NTLMv2 auth",
1325 .type = P_BOOL,
1326 .p_class = P_GLOBAL,
1327 .ptr = &Globals.bClientNTLMv2Auth,
1328 .special = NULL,
1329 .enum_list = NULL,
1330 .flags = FLAG_ADVANCED,
1331 },
1332 {
1333 .label = "client lanman auth",
1334 .type = P_BOOL,
1335 .p_class = P_GLOBAL,
1336 .ptr = &Globals.bClientLanManAuth,
1337 .special = NULL,
1338 .enum_list = NULL,
1339 .flags = FLAG_ADVANCED,
1340 },
1341 {
1342 .label = "client plaintext auth",
1343 .type = P_BOOL,
1344 .p_class = P_GLOBAL,
1345 .ptr = &Globals.bClientPlaintextAuth,
1346 .special = NULL,
1347 .enum_list = NULL,
1348 .flags = FLAG_ADVANCED,
1349 },
1350 {
1351 .label = "username",
1352 .type = P_STRING,
1353 .p_class = P_LOCAL,
1354 .ptr = &sDefault.szUsername,
1355 .special = NULL,
1356 .enum_list = NULL,
1357 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1358 },
1359 {
1360 .label = "user",
1361 .type = P_STRING,
1362 .p_class = P_LOCAL,
1363 .ptr = &sDefault.szUsername,
1364 .special = NULL,
1365 .enum_list = NULL,
1366 .flags = FLAG_HIDE,
1367 },
1368 {
1369 .label = "users",
1370 .type = P_STRING,
1371 .p_class = P_LOCAL,
1372 .ptr = &sDefault.szUsername,
1373 .special = NULL,
1374 .enum_list = NULL,
1375 .flags = FLAG_HIDE,
1376 },
1377 {
1378 .label = "invalid users",
1379 .type = P_LIST,
1380 .p_class = P_LOCAL,
1381 .ptr = &sDefault.szInvalidUsers,
1382 .special = NULL,
1383 .enum_list = NULL,
1384 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1385 },
1386 {
1387 .label = "valid users",
1388 .type = P_LIST,
1389 .p_class = P_LOCAL,
1390 .ptr = &sDefault.szValidUsers,
1391 .special = NULL,
1392 .enum_list = NULL,
1393 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1394 },
1395 {
1396 .label = "admin users",
1397 .type = P_LIST,
1398 .p_class = P_LOCAL,
1399 .ptr = &sDefault.szAdminUsers,
1400 .special = NULL,
1401 .enum_list = NULL,
1402 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1403 },
1404 {
1405 .label = "read list",
1406 .type = P_LIST,
1407 .p_class = P_LOCAL,
1408 .ptr = &sDefault.readlist,
1409 .special = NULL,
1410 .enum_list = NULL,
1411 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1412 },
1413 {
1414 .label = "write list",
1415 .type = P_LIST,
1416 .p_class = P_LOCAL,
1417 .ptr = &sDefault.writelist,
1418 .special = NULL,
1419 .enum_list = NULL,
1420 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1421 },
1422 {
1423 .label = "printer admin",
1424 .type = P_LIST,
1425 .p_class = P_LOCAL,
1426 .ptr = &sDefault.printer_admin,
1427 .special = NULL,
1428 .enum_list = NULL,
1429 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1430 },
1431 {
1432 .label = "force user",
1433 .type = P_STRING,
1434 .p_class = P_LOCAL,
1435 .ptr = &sDefault.force_user,
1436 .special = NULL,
1437 .enum_list = NULL,
1438 .flags = FLAG_ADVANCED | FLAG_SHARE,
1439 },
1440 {
1441 .label = "force group",
1442 .type = P_STRING,
1443 .p_class = P_LOCAL,
1444 .ptr = &sDefault.force_group,
1445 .special = NULL,
1446 .enum_list = NULL,
1447 .flags = FLAG_ADVANCED | FLAG_SHARE,
1448 },
1449 {
1450 .label = "group",
1451 .type = P_STRING,
1452 .p_class = P_LOCAL,
1453 .ptr = &sDefault.force_group,
1454 .special = NULL,
1455 .enum_list = NULL,
1456 .flags = FLAG_ADVANCED,
1457 },
1458 {
1459 .label = "read only",
1460 .type = P_BOOL,
1461 .p_class = P_LOCAL,
1462 .ptr = &sDefault.bRead_only,
1463 .special = NULL,
1464 .enum_list = NULL,
1465 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1466 },
1467 {
1468 .label = "write ok",
1469 .type = P_BOOLREV,
1470 .p_class = P_LOCAL,
1471 .ptr = &sDefault.bRead_only,
1472 .special = NULL,
1473 .enum_list = NULL,
1474 .flags = FLAG_HIDE,
1475 },
1476 {
1477 .label = "writeable",
1478 .type = P_BOOLREV,
1479 .p_class = P_LOCAL,
1480 .ptr = &sDefault.bRead_only,
1481 .special = NULL,
1482 .enum_list = NULL,
1483 .flags = FLAG_HIDE,
1484 },
1485 {
1486 .label = "writable",
1487 .type = P_BOOLREV,
1488 .p_class = P_LOCAL,
1489 .ptr = &sDefault.bRead_only,
1490 .special = NULL,
1491 .enum_list = NULL,
1492 .flags = FLAG_HIDE,
1493 },
1494 {
1495 .label = "acl check permissions",
1496 .type = P_BOOL,
1497 .p_class = P_LOCAL,
1498 .ptr = &sDefault.bAclCheckPermissions,
1499 .special = NULL,
1500 .enum_list = NULL,
1501 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1502 },
1503 {
1504 .label = "acl group control",
1505 .type = P_BOOL,
1506 .p_class = P_LOCAL,
1507 .ptr = &sDefault.bAclGroupControl,
1508 .special = NULL,
1509 .enum_list = NULL,
1510 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1511 },
1512 {
1513 .label = "acl map full control",
1514 .type = P_BOOL,
1515 .p_class = P_LOCAL,
1516 .ptr = &sDefault.bAclMapFullControl,
1517 .special = NULL,
1518 .enum_list = NULL,
1519 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1520 },
1521 {
1522 .label = "create mask",
1523 .type = P_OCTAL,
1524 .p_class = P_LOCAL,
1525 .ptr = &sDefault.iCreate_mask,
1526 .special = NULL,
1527 .enum_list = NULL,
1528 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1529 },
1530 {
1531 .label = "create mode",
1532 .type = P_OCTAL,
1533 .p_class = P_LOCAL,
1534 .ptr = &sDefault.iCreate_mask,
1535 .special = NULL,
1536 .enum_list = NULL,
1537 .flags = FLAG_HIDE,
1538 },
1539 {
1540 .label = "force create mode",
1541 .type = P_OCTAL,
1542 .p_class = P_LOCAL,
1543 .ptr = &sDefault.iCreate_force_mode,
1544 .special = NULL,
1545 .enum_list = NULL,
1546 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1547 },
1548 {
1549 .label = "security mask",
1550 .type = P_OCTAL,
1551 .p_class = P_LOCAL,
1552 .ptr = &sDefault.iSecurity_mask,
1553 .special = NULL,
1554 .enum_list = NULL,
1555 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1556 },
1557 {
1558 .label = "force security mode",
1559 .type = P_OCTAL,
1560 .p_class = P_LOCAL,
1561 .ptr = &sDefault.iSecurity_force_mode,
1562 .special = NULL,
1563 .enum_list = NULL,
1564 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1565 },
1566 {
1567 .label = "directory mask",
1568 .type = P_OCTAL,
1569 .p_class = P_LOCAL,
1570 .ptr = &sDefault.iDir_mask,
1571 .special = NULL,
1572 .enum_list = NULL,
1573 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1574 },
1575 {
1576 .label = "directory mode",
1577 .type = P_OCTAL,
1578 .p_class = P_LOCAL,
1579 .ptr = &sDefault.iDir_mask,
1580 .special = NULL,
1581 .enum_list = NULL,
1582 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1583 },
1584 {
1585 .label = "force directory mode",
1586 .type = P_OCTAL,
1587 .p_class = P_LOCAL,
1588 .ptr = &sDefault.iDir_force_mode,
1589 .special = NULL,
1590 .enum_list = NULL,
1591 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1592 },
1593 {
1594 .label = "directory security mask",
1595 .type = P_OCTAL,
1596 .p_class = P_LOCAL,
1597 .ptr = &sDefault.iDir_Security_mask,
1598 .special = NULL,
1599 .enum_list = NULL,
1600 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1601 },
1602 {
1603 .label = "force directory security mode",
1604 .type = P_OCTAL,
1605 .p_class = P_LOCAL,
1606 .ptr = &sDefault.iDir_Security_force_mode,
1607 .special = NULL,
1608 .enum_list = NULL,
1609 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1610 },
1611 {
1612 .label = "force unknown acl user",
1613 .type = P_BOOL,
1614 .p_class = P_LOCAL,
1615 .ptr = &sDefault.bForceUnknownAclUser,
1616 .special = NULL,
1617 .enum_list = NULL,
1618 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1619 },
1620 {
1621 .label = "inherit permissions",
1622 .type = P_BOOL,
1623 .p_class = P_LOCAL,
1624 .ptr = &sDefault.bInheritPerms,
1625 .special = NULL,
1626 .enum_list = NULL,
1627 .flags = FLAG_ADVANCED | FLAG_SHARE,
1628 },
1629 {
1630 .label = "inherit acls",
1631 .type = P_BOOL,
1632 .p_class = P_LOCAL,
1633 .ptr = &sDefault.bInheritACLS,
1634 .special = NULL,
1635 .enum_list = NULL,
1636 .flags = FLAG_ADVANCED | FLAG_SHARE,
1637 },
1638 {
1639 .label = "inherit owner",
1640 .type = P_BOOL,
1641 .p_class = P_LOCAL,
1642 .ptr = &sDefault.bInheritOwner,
1643 .special = NULL,
1644 .enum_list = NULL,
1645 .flags = FLAG_ADVANCED | FLAG_SHARE,
1646 },
1647 {
1648 .label = "guest only",
1649 .type = P_BOOL,
1650 .p_class = P_LOCAL,
1651 .ptr = &sDefault.bGuest_only,
1652 .special = NULL,
1653 .enum_list = NULL,
1654 .flags = FLAG_ADVANCED | FLAG_SHARE,
1655 },
1656 {
1657 .label = "only guest",
1658 .type = P_BOOL,
1659 .p_class = P_LOCAL,
1660 .ptr = &sDefault.bGuest_only,
1661 .special = NULL,
1662 .enum_list = NULL,
1663 .flags = FLAG_HIDE,
1664 },
1665 {
1666 .label = "administrative share",
1667 .type = P_BOOL,
1668 .p_class = P_LOCAL,
1669 .ptr = &sDefault.bAdministrative_share,
1670 .special = NULL,
1671 .enum_list = NULL,
1672 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1673 },
1674
1675 {
1676 .label = "guest ok",
1677 .type = P_BOOL,
1678 .p_class = P_LOCAL,
1679 .ptr = &sDefault.bGuest_ok,
1680 .special = NULL,
1681 .enum_list = NULL,
1682 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1683 },
1684 {
1685 .label = "public",
1686 .type = P_BOOL,
1687 .p_class = P_LOCAL,
1688 .ptr = &sDefault.bGuest_ok,
1689 .special = NULL,
1690 .enum_list = NULL,
1691 .flags = FLAG_HIDE,
1692 },
1693 {
1694 .label = "only user",
1695 .type = P_BOOL,
1696 .p_class = P_LOCAL,
1697 .ptr = &sDefault.bOnlyUser,
1698 .special = NULL,
1699 .enum_list = NULL,
1700 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1701 },
1702 {
1703 .label = "hosts allow",
1704 .type = P_LIST,
1705 .p_class = P_LOCAL,
1706 .ptr = &sDefault.szHostsallow,
1707 .special = NULL,
1708 .enum_list = NULL,
1709 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1710 },
1711 {
1712 .label = "allow hosts",
1713 .type = P_LIST,
1714 .p_class = P_LOCAL,
1715 .ptr = &sDefault.szHostsallow,
1716 .special = NULL,
1717 .enum_list = NULL,
1718 .flags = FLAG_HIDE,
1719 },
1720 {
1721 .label = "hosts deny",
1722 .type = P_LIST,
1723 .p_class = P_LOCAL,
1724 .ptr = &sDefault.szHostsdeny,
1725 .special = NULL,
1726 .enum_list = NULL,
1727 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1728 },
1729 {
1730 .label = "deny hosts",
1731 .type = P_LIST,
1732 .p_class = P_LOCAL,
1733 .ptr = &sDefault.szHostsdeny,
1734 .special = NULL,
1735 .enum_list = NULL,
1736 .flags = FLAG_HIDE,
1737 },
1738 {
1739 .label = "preload modules",
1740 .type = P_LIST,
1741 .p_class = P_GLOBAL,
1742 .ptr = &Globals.szPreloadModules,
1743 .special = NULL,
1744 .enum_list = NULL,
1745 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1746 },
1747 {
1748 .label = "use kerberos keytab",
1749 .type = P_BOOL,
1750 .p_class = P_GLOBAL,
1751 .ptr = &Globals.bUseKerberosKeytab,
1752 .special = NULL,
1753 .enum_list = NULL,
1754 .flags = FLAG_ADVANCED,
1755 },
1756
1757 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1758
1759 {
1760 .label = "log level",
1761 .type = P_STRING,
1762 .p_class = P_GLOBAL,
1763 .ptr = &Globals.szLogLevel,
1764 .special = handle_debug_list,
1765 .enum_list = NULL,
1766 .flags = FLAG_ADVANCED,
1767 },
1768 {
1769 .label = "debuglevel",
1770 .type = P_STRING,
1771 .p_class = P_GLOBAL,
1772 .ptr = &Globals.szLogLevel,
1773 .special = handle_debug_list,
1774 .enum_list = NULL,
1775 .flags = FLAG_HIDE,
1776 },
1777 {
1778 .label = "syslog",
1779 .type = P_INTEGER,
1780 .p_class = P_GLOBAL,
1781 .ptr = &Globals.syslog,
1782 .special = NULL,
1783 .enum_list = NULL,
1784 .flags = FLAG_ADVANCED,
1785 },
1786 {
1787 .label = "syslog only",
1788 .type = P_BOOL,
1789 .p_class = P_GLOBAL,
1790 .ptr = &Globals.bSyslogOnly,
1791 .special = NULL,
1792 .enum_list = NULL,
1793 .flags = FLAG_ADVANCED,
1794 },
1795 {
1796 .label = "log file",
1797 .type = P_STRING,
1798 .p_class = P_GLOBAL,
1799 .ptr = &Globals.szLogFile,
1800 .special = NULL,
1801 .enum_list = NULL,
1802 .flags = FLAG_ADVANCED,
1803 },
1804 {
1805 .label = "max log size",
1806 .type = P_INTEGER,
1807 .p_class = P_GLOBAL,
1808 .ptr = &Globals.max_log_size,
1809 .special = NULL,
1810 .enum_list = NULL,
1811 .flags = FLAG_ADVANCED,
1812 },
1813 {
1814 .label = "debug timestamp",
1815 .type = P_BOOL,
1816 .p_class = P_GLOBAL,
1817 .ptr = &Globals.bTimestampLogs,
1818 .special = NULL,
1819 .enum_list = NULL,
1820 .flags = FLAG_ADVANCED,
1821 },
1822 {
1823 .label = "timestamp logs",
1824 .type = P_BOOL,
1825 .p_class = P_GLOBAL,
1826 .ptr = &Globals.bTimestampLogs,
1827 .special = NULL,
1828 .enum_list = NULL,
1829 .flags = FLAG_ADVANCED,
1830 },
1831 {
1832 .label = "debug prefix timestamp",
1833 .type = P_BOOL,
1834 .p_class = P_GLOBAL,
1835 .ptr = &Globals.bDebugPrefixTimestamp,
1836 .special = NULL,
1837 .enum_list = NULL,
1838 .flags = FLAG_ADVANCED,
1839 },
1840 {
1841 .label = "debug hires timestamp",
1842 .type = P_BOOL,
1843 .p_class = P_GLOBAL,
1844 .ptr = &Globals.bDebugHiresTimestamp,
1845 .special = NULL,
1846 .enum_list = NULL,
1847 .flags = FLAG_ADVANCED,
1848 },
1849 {
1850 .label = "debug pid",
1851 .type = P_BOOL,
1852 .p_class = P_GLOBAL,
1853 .ptr = &Globals.bDebugPid,
1854 .special = NULL,
1855 .enum_list = NULL,
1856 .flags = FLAG_ADVANCED,
1857 },
1858 {
1859 .label = "debug uid",
1860 .type = P_BOOL,
1861 .p_class = P_GLOBAL,
1862 .ptr = &Globals.bDebugUid,
1863 .special = NULL,
1864 .enum_list = NULL,
1865 .flags = FLAG_ADVANCED,
1866 },
1867 {
1868 .label = "debug class",
1869 .type = P_BOOL,
1870 .p_class = P_GLOBAL,
1871 .ptr = &Globals.bDebugClass,
1872 .special = NULL,
1873 .enum_list = NULL,
1874 .flags = FLAG_ADVANCED,
1875 },
1876 {
1877 .label = "enable core files",
1878 .type = P_BOOL,
1879 .p_class = P_GLOBAL,
1880 .ptr = &Globals.bEnableCoreFiles,
1881 .special = NULL,
1882 .enum_list = NULL,
1883 .flags = FLAG_ADVANCED,
1884 },
1885
1886 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1887
1888 {
1889 .label = "allocation roundup size",
1890 .type = P_INTEGER,
1891 .p_class = P_LOCAL,
1892 .ptr = &sDefault.iallocation_roundup_size,
1893 .special = NULL,
1894 .enum_list = NULL,
1895 .flags = FLAG_ADVANCED,
1896 },
1897 {
1898 .label = "aio read size",
1899 .type = P_INTEGER,
1900 .p_class = P_LOCAL,
1901 .ptr = &sDefault.iAioReadSize,
1902 .special = NULL,
1903 .enum_list = NULL,
1904 .flags = FLAG_ADVANCED,
1905 },
1906 {
1907 .label = "aio write size",
1908 .type = P_INTEGER,
1909 .p_class = P_LOCAL,
1910 .ptr = &sDefault.iAioWriteSize,
1911 .special = NULL,
1912 .enum_list = NULL,
1913 .flags = FLAG_ADVANCED,
1914 },
1915 {
1916 .label = "aio write behind",
1917 .type = P_STRING,
1918 .p_class = P_LOCAL,
1919 .ptr = &sDefault.szAioWriteBehind,
1920 .special = NULL,
1921 .enum_list = NULL,
1922 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1923 },
1924 {
1925 .label = "smb ports",
1926 .type = P_STRING,
1927 .p_class = P_GLOBAL,
1928 .ptr = &Globals.smb_ports,
1929 .special = NULL,
1930 .enum_list = NULL,
1931 .flags = FLAG_ADVANCED,
1932 },
1933 {
1934 .label = "large readwrite",
1935 .type = P_BOOL,
1936 .p_class = P_GLOBAL,
1937 .ptr = &Globals.bLargeReadwrite,
1938 .special = NULL,
1939 .enum_list = NULL,
1940 .flags = FLAG_ADVANCED,
1941 },
1942 {
1943 .label = "max protocol",
1944 .type = P_ENUM,
1945 .p_class = P_GLOBAL,
1946 .ptr = &Globals.maxprotocol,
1947 .special = NULL,
1948 .enum_list = enum_protocol,
1949 .flags = FLAG_ADVANCED,
1950 },
1951 {
1952 .label = "protocol",
1953 .type = P_ENUM,
1954 .p_class = P_GLOBAL,
1955 .ptr = &Globals.maxprotocol,
1956 .special = NULL,
1957 .enum_list = enum_protocol,
1958 .flags = FLAG_ADVANCED,
1959 },
1960 {
1961 .label = "min protocol",
1962 .type = P_ENUM,
1963 .p_class = P_GLOBAL,
1964 .ptr = &Globals.minprotocol,
1965 .special = NULL,
1966 .enum_list = enum_protocol,
1967 .flags = FLAG_ADVANCED,
1968 },
1969 {
1970 .label = "min receivefile size",
1971 .type = P_INTEGER,
1972 .p_class = P_GLOBAL,
1973 .ptr = &Globals.iminreceivefile,
1974 .special = NULL,
1975 .enum_list = NULL,
1976 .flags = FLAG_ADVANCED,
1977 },
1978 {
1979 .label = "read raw",
1980 .type = P_BOOL,
1981 .p_class = P_GLOBAL,
1982 .ptr = &Globals.bReadRaw,
1983 .special = NULL,
1984 .enum_list = NULL,
1985 .flags = FLAG_ADVANCED,
1986 },
1987 {
1988 .label = "write raw",
1989 .type = P_BOOL,
1990 .p_class = P_GLOBAL,
1991 .ptr = &Globals.bWriteRaw,
1992 .special = NULL,
1993 .enum_list = NULL,
1994 .flags = FLAG_ADVANCED,
1995 },
1996 {
1997 .label = "disable netbios",
1998 .type = P_BOOL,
1999 .p_class = P_GLOBAL,
2000 .ptr = &Globals.bDisableNetbios,
2001 .special = NULL,
2002 .enum_list = NULL,
2003 .flags = FLAG_ADVANCED,
2004 },
2005 {
2006 .label = "reset on zero vc",
2007 .type = P_BOOL,
2008 .p_class = P_GLOBAL,
2009 .ptr = &Globals.bResetOnZeroVC,
2010 .special = NULL,
2011 .enum_list = NULL,
2012 .flags = FLAG_ADVANCED,
2013 },
2014 {
2015 .label = "acl compatibility",
2016 .type = P_ENUM,
2017 .p_class = P_GLOBAL,
2018 .ptr = &Globals.iAclCompat,
2019 .special = NULL,
2020 .enum_list = enum_acl_compat_vals,
2021 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2022 },
2023 {
2024 .label = "defer sharing violations",
2025 .type = P_BOOL,
2026 .p_class = P_GLOBAL,
2027 .ptr = &Globals.bDeferSharingViolations,
2028 .special = NULL,
2029 .enum_list = NULL,
2030 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2031 },
2032 {
2033 .label = "ea support",
2034 .type = P_BOOL,
2035 .p_class = P_LOCAL,
2036 .ptr = &sDefault.bEASupport,
2037 .special = NULL,
2038 .enum_list = NULL,
2039 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2040 },
2041 {
2042 .label = "nt acl support",
2043 .type = P_BOOL,
2044 .p_class = P_LOCAL,
2045 .ptr = &sDefault.bNTAclSupport,
2046 .special = NULL,
2047 .enum_list = NULL,
2048 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2049 },
2050 {
2051 .label = "nt pipe support",
2052 .type = P_BOOL,
2053 .p_class = P_GLOBAL,
2054 .ptr = &Globals.bNTPipeSupport,
2055 .special = NULL,
2056 .enum_list = NULL,
2057 .flags = FLAG_ADVANCED,
2058 },
2059 {
2060 .label = "nt status support",
2061 .type = P_BOOL,
2062 .p_class = P_GLOBAL,
2063 .ptr = &Globals.bNTStatusSupport,
2064 .special = NULL,
2065 .enum_list = NULL,
2066 .flags = FLAG_ADVANCED,
2067 },
2068 {
2069 .label = "profile acls",
2070 .type = P_BOOL,
2071 .p_class = P_LOCAL,
2072 .ptr = &sDefault.bProfileAcls,
2073 .special = NULL,
2074 .enum_list = NULL,
2075 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2076 },
2077 {
2078 .label = "announce version",
2079 .type = P_STRING,
2080 .p_class = P_GLOBAL,
2081 .ptr = &Globals.szAnnounceVersion,
2082 .special = NULL,
2083 .enum_list = NULL,
2084 .flags = FLAG_ADVANCED,
2085 },
2086 {
2087 .label = "announce as",
2088 .type = P_ENUM,
2089 .p_class = P_GLOBAL,
2090 .ptr = &Globals.announce_as,
2091 .special = NULL,
2092 .enum_list = enum_announce_as,
2093 .flags = FLAG_ADVANCED,
2094 },
2095 {
2096 .label = "map acl inherit",
2097 .type = P_BOOL,
2098 .p_class = P_LOCAL,
2099 .ptr = &sDefault.bMap_acl_inherit,
2100 .special = NULL,
2101 .enum_list = NULL,
2102 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2103 },
2104 {
2105 .label = "afs share",
2106 .type = P_BOOL,
2107 .p_class = P_LOCAL,
2108 .ptr = &sDefault.bAfs_Share,
2109 .special = NULL,
2110 .enum_list = NULL,
2111 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2112 },
2113 {
2114 .label = "max mux",
2115 .type = P_INTEGER,
2116 .p_class = P_GLOBAL,
2117 .ptr = &Globals.max_mux,
2118 .special = NULL,
2119 .enum_list = NULL,
2120 .flags = FLAG_ADVANCED,
2121 },
2122 {
2123 .label = "max xmit",
2124 .type = P_INTEGER,
2125 .p_class = P_GLOBAL,
2126 .ptr = &Globals.max_xmit,
2127 .special = NULL,
2128 .enum_list = NULL,
2129 .flags = FLAG_ADVANCED,
2130 },
2131 {
2132 .label = "name resolve order",
2133 .type = P_STRING,
2134 .p_class = P_GLOBAL,
2135 .ptr = &Globals.szNameResolveOrder,
2136 .special = NULL,
2137 .enum_list = NULL,
2138 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2139 },
2140 {
2141 .label = "max ttl",
2142 .type = P_INTEGER,
2143 .p_class = P_GLOBAL,
2144 .ptr = &Globals.max_ttl,
2145 .special = NULL,
2146 .enum_list = NULL,
2147 .flags = FLAG_ADVANCED,
2148 },
2149 {
2150 .label = "max wins ttl",
2151 .type = P_INTEGER,
2152 .p_class = P_GLOBAL,
2153 .ptr = &Globals.max_wins_ttl,
2154 .special = NULL,
2155 .enum_list = NULL,
2156 .flags = FLAG_ADVANCED,
2157 },
2158 {
2159 .label = "min wins ttl",
2160 .type = P_INTEGER,
2161 .p_class = P_GLOBAL,
2162 .ptr = &Globals.min_wins_ttl,
2163 .special = NULL,
2164 .enum_list = NULL,
2165 .flags = FLAG_ADVANCED,
2166 },
2167 {
2168 .label = "time server",
2169 .type = P_BOOL,
2170 .p_class = P_GLOBAL,
2171 .ptr = &Globals.bTimeServer,
2172 .special = NULL,
2173 .enum_list = NULL,
2174 .flags = FLAG_ADVANCED,
2175 },
2176 {
2177 .label = "unix extensions",
2178 .type = P_BOOL,
2179 .p_class = P_GLOBAL,
2180 .ptr = &Globals.bUnixExtensions,
2181 .special = NULL,
2182 .enum_list = NULL,
2183 .flags = FLAG_ADVANCED,
2184 },
2185 {
2186 .label = "use spnego",
2187 .type = P_BOOL,
2188 .p_class = P_GLOBAL,
2189 .ptr = &Globals.bUseSpnego,
2190 .special = NULL,
2191 .enum_list = NULL,
2192 .flags = FLAG_ADVANCED,
2193 },
2194 {
2195 .label = "client signing",
2196 .type = P_ENUM,
2197 .p_class = P_GLOBAL,
2198 .ptr = &Globals.client_signing,
2199 .special = NULL,
2200 .enum_list = enum_smb_signing_vals,
2201 .flags = FLAG_ADVANCED,
2202 },
2203 {
2204 .label = "server signing",
2205 .type = P_ENUM,
2206 .p_class = P_GLOBAL,
2207 .ptr = &Globals.server_signing,
2208 .special = NULL,
2209 .enum_list = enum_smb_signing_vals,
2210 .flags = FLAG_ADVANCED,
2211 },
2212 {
2213 .label = "smb encrypt",
2214 .type = P_ENUM,
2215 .p_class = P_LOCAL,
2216 .ptr = &sDefault.ismb_encrypt,
2217 .special = NULL,
2218 .enum_list = enum_smb_signing_vals,
2219 .flags = FLAG_ADVANCED,
2220 },
2221 {
2222 .label = "client use spnego",
2223 .type = P_BOOL,
2224 .p_class = P_GLOBAL,
2225 .ptr = &Globals.bClientUseSpnego,
2226 .special = NULL,
2227 .enum_list = NULL,
2228 .flags = FLAG_ADVANCED,
2229 },
2230 {
2231 .label = "client ldap sasl wrapping",
2232 .type = P_ENUM,
2233 .p_class = P_GLOBAL,
2234 .ptr = &Globals.client_ldap_sasl_wrapping,
2235 .special = NULL,
2236 .enum_list = enum_ldap_sasl_wrapping,
2237 .flags = FLAG_ADVANCED,
2238 },
2239 {
2240 .label = "enable asu support",
2241 .type = P_BOOL,
2242 .p_class = P_GLOBAL,
2243 .ptr = &Globals.bASUSupport,
2244 .special = NULL,
2245 .enum_list = NULL,
2246 .flags = FLAG_ADVANCED,
2247 },
2248 {
2249 .label = "svcctl list",
2250 .type = P_LIST,
2251 .p_class = P_GLOBAL,
2252 .ptr = &Globals.szServicesList,
2253 .special = NULL,
2254 .enum_list = NULL,
2255 .flags = FLAG_ADVANCED,
2256 },
2257
2258 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2259
2260 {
2261 .label = "block size",
2262 .type = P_INTEGER,
2263 .p_class = P_LOCAL,
2264 .ptr = &sDefault.iBlock_size,
2265 .special = NULL,
2266 .enum_list = NULL,
2267 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2268 },
2269 {
2270 .label = "deadtime",
2271 .type = P_INTEGER,
2272 .p_class = P_GLOBAL,
2273 .ptr = &Globals.deadtime,
2274 .special = NULL,
2275 .enum_list = NULL,
2276 .flags = FLAG_ADVANCED,
2277 },
2278 {
2279 .label = "getwd cache",
2280 .type = P_BOOL,
2281 .p_class = P_GLOBAL,
2282 .ptr = &Globals.getwd_cache,
2283 .special = NULL,
2284 .enum_list = NULL,
2285 .flags = FLAG_ADVANCED,
2286 },
2287 {
2288 .label = "keepalive",
2289 .type = P_INTEGER,
2290 .p_class = P_GLOBAL,
2291 .ptr = &Globals.iKeepalive,
2292 .special = NULL,
2293 .enum_list = NULL,
2294 .flags = FLAG_ADVANCED,
2295 },
2296 {
2297 .label = "change notify",
2298 .type = P_BOOL,
2299 .p_class = P_LOCAL,
2300 .ptr = &sDefault.bChangeNotify,
2301 .special = NULL,
2302 .enum_list = NULL,
2303 .flags = FLAG_ADVANCED | FLAG_SHARE,
2304 },
2305 {
2306 .label = "directory name cache size",
2307 .type = P_INTEGER,
2308 .p_class = P_LOCAL,
2309 .ptr = &sDefault.iDirectoryNameCacheSize,
2310 .special = NULL,
2311 .enum_list = NULL,
2312 .flags = FLAG_ADVANCED | FLAG_SHARE,
2313 },
2314 {
2315 .label = "kernel change notify",
2316 .type = P_BOOL,
2317 .p_class = P_LOCAL,
2318 .ptr = &sDefault.bKernelChangeNotify,
2319 .special = NULL,
2320 .enum_list = NULL,
2321 .flags = FLAG_ADVANCED | FLAG_SHARE,
2322 },
2323 {
2324 .label = "lpq cache time",
2325 .type = P_INTEGER,
2326 .p_class = P_GLOBAL,
2327 .ptr = &Globals.lpqcachetime,
2328 .special = NULL,
2329 .enum_list = NULL,
2330 .flags = FLAG_ADVANCED,
2331 },
2332 {
2333 .label = "max smbd processes",
2334 .type = P_INTEGER,
2335 .p_class = P_GLOBAL,
2336 .ptr = &Globals.iMaxSmbdProcesses,
2337 .special = NULL,
2338 .enum_list = NULL,
2339 .flags = FLAG_ADVANCED,
2340 },
2341 {
2342 .label = "max connections",
2343 .type = P_INTEGER,
2344 .p_class = P_LOCAL,
2345 .ptr = &sDefault.iMaxConnections,
2346 .special = NULL,
2347 .enum_list = NULL,
2348 .flags = FLAG_ADVANCED | FLAG_SHARE,
2349 },
2350 {
2351 .label = "paranoid server security",
2352 .type = P_BOOL,
2353 .p_class = P_GLOBAL,
2354 .ptr = &Globals.paranoid_server_security,
2355 .special = NULL,
2356 .enum_list = NULL,
2357 .flags = FLAG_ADVANCED,
2358 },
2359 {
2360 .label = "max disk size",
2361 .type = P_INTEGER,
2362 .p_class = P_GLOBAL,
2363 .ptr = &Globals.maxdisksize,
2364 .special = NULL,
2365 .enum_list = NULL,
2366 .flags = FLAG_ADVANCED,
2367 },
2368 {
2369 .label = "max open files",
2370 .type = P_INTEGER,
2371 .p_class = P_GLOBAL,
2372 .ptr = &Globals.max_open_files,
2373 .special = NULL,
2374 .enum_list = NULL,
2375 .flags = FLAG_ADVANCED,
2376 },
2377 {
2378 .label = "min print space",
2379 .type = P_INTEGER,
2380 .p_class = P_LOCAL,
2381 .ptr = &sDefault.iMinPrintSpace,
2382 .special = NULL,
2383 .enum_list = NULL,
2384 .flags = FLAG_ADVANCED | FLAG_PRINT,
2385 },
2386 {
2387 .label = "socket options",
2388 .type = P_STRING,
2389 .p_class = P_GLOBAL,
2390 .ptr = &Globals.szSocketOptions,
2391 .special = NULL,
2392 .enum_list = NULL,
2393 .flags = FLAG_ADVANCED,
2394 },
2395 {
2396 .label = "strict allocate",
2397 .type = P_BOOL,
2398 .p_class = P_LOCAL,
2399 .ptr = &sDefault.bStrictAllocate,
2400 .special = NULL,
2401 .enum_list = NULL,
2402 .flags = FLAG_ADVANCED | FLAG_SHARE,
2403 },
2404 {
2405 .label = "strict sync",
2406 .type = P_BOOL,
2407 .p_class = P_LOCAL,
2408 .ptr = &sDefault.bStrictSync,
2409 .special = NULL,
2410 .enum_list = NULL,
2411 .flags = FLAG_ADVANCED | FLAG_SHARE,
2412 },
2413 {
2414 .label = "sync always",
2415 .type = P_BOOL,
2416 .p_class = P_LOCAL,
2417 .ptr = &sDefault.bSyncAlways,
2418 .special = NULL,
2419 .enum_list = NULL,
2420 .flags = FLAG_ADVANCED | FLAG_SHARE,
2421 },
2422 {
2423 .label = "use mmap",
2424 .type = P_BOOL,
2425 .p_class = P_GLOBAL,
2426 .ptr = &Globals.bUseMmap,
2427 .special = NULL,
2428 .enum_list = NULL,
2429 .flags = FLAG_ADVANCED,
2430 },
2431 {
2432 .label = "use sendfile",
2433 .type = P_BOOL,
2434 .p_class = P_LOCAL,
2435 .ptr = &sDefault.bUseSendfile,
2436 .special = NULL,
2437 .enum_list = NULL,
2438 .flags = FLAG_ADVANCED | FLAG_SHARE,
2439 },
2440 {
2441 .label = "hostname lookups",
2442 .type = P_BOOL,
2443 .p_class = P_GLOBAL,
2444 .ptr = &Globals.bHostnameLookups,
2445 .special = NULL,
2446 .enum_list = NULL,
2447 .flags = FLAG_ADVANCED,
2448 },
2449 {
2450 .label = "write cache size",
2451 .type = P_INTEGER,
2452 .p_class = P_LOCAL,
2453 .ptr = &sDefault.iWriteCacheSize,
2454 .special = NULL,
2455 .enum_list = NULL,
2456 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2457 },
2458 {
2459 .label = "name cache timeout",
2460 .type = P_INTEGER,
2461 .p_class = P_GLOBAL,
2462 .ptr = &Globals.name_cache_timeout,
2463 .special = NULL,
2464 .enum_list = NULL,
2465 .flags = FLAG_ADVANCED,
2466 },
2467 {
2468 .label = "ctdbd socket",
2469 .type = P_STRING,
2470 .p_class = P_GLOBAL,
2471 .ptr = &Globals.ctdbdSocket,
2472 .special = NULL,
2473 .enum_list = NULL,
2474 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2475 },
2476 {
2477 .label = "cluster addresses",
2478 .type = P_LIST,
2479 .p_class = P_GLOBAL,
2480 .ptr = &Globals.szClusterAddresses,
2481 .special = NULL,
2482 .enum_list = NULL,
2483 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2484 },
2485 {
2486 .label = "clustering",
2487 .type = P_BOOL,
2488 .p_class = P_GLOBAL,
2489 .ptr = &Globals.clustering,
2490 .special = NULL,
2491 .enum_list = NULL,
2492 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2493 },
2494
2495 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2496
2497 {
2498 .label = "max reported print jobs",
2499 .type = P_INTEGER,
2500 .p_class = P_LOCAL,
2501 .ptr = &sDefault.iMaxReportedPrintJobs,
2502 .special = NULL,
2503 .enum_list = NULL,
2504 .flags = FLAG_ADVANCED | FLAG_PRINT,
2505 },
2506 {
2507 .label = "max print jobs",
2508 .type = P_INTEGER,
2509 .p_class = P_LOCAL,
2510 .ptr = &sDefault.iMaxPrintJobs,
2511 .special = NULL,
2512 .enum_list = NULL,
2513 .flags = FLAG_ADVANCED | FLAG_PRINT,
2514 },
2515 {
2516 .label = "load printers",
2517 .type = P_BOOL,
2518 .p_class = P_GLOBAL,
2519 .ptr = &Globals.bLoadPrinters,
2520 .special = NULL,
2521 .enum_list = NULL,
2522 .flags = FLAG_ADVANCED | FLAG_PRINT,
2523 },
2524 {
2525 .label = "printcap cache time",
2526 .type = P_INTEGER,
2527 .p_class = P_GLOBAL,
2528 .ptr = &Globals.PrintcapCacheTime,
2529 .special = NULL,
2530 .enum_list = NULL,
2531 .flags = FLAG_ADVANCED | FLAG_PRINT,
2532 },
2533 {
2534 .label = "printcap name",
2535 .type = P_STRING,
2536 .p_class = P_GLOBAL,
2537 .ptr = &Globals.szPrintcapname,
2538 .special = NULL,
2539 .enum_list = NULL,
2540 .flags = FLAG_ADVANCED | FLAG_PRINT,
2541 },
2542 {
2543 .label = "printcap",
2544 .type = P_STRING,
2545 .p_class = P_GLOBAL,
2546 .ptr = &Globals.szPrintcapname,
2547 .special = NULL,
2548 .enum_list = NULL,
2549 .flags = FLAG_HIDE,
2550 },
2551 {
2552 .label = "printable",
2553 .type = P_BOOL,
2554 .p_class = P_LOCAL,
2555 .ptr = &sDefault.bPrint_ok,
2556 .special = NULL,
2557 .enum_list = NULL,
2558 .flags = FLAG_ADVANCED | FLAG_PRINT,
2559 },
2560 {
2561 .label = "print ok",
2562 .type = P_BOOL,
2563 .p_class = P_LOCAL,
2564 .ptr = &sDefault.bPrint_ok,
2565 .special = NULL,
2566 .enum_list = NULL,
2567 .flags = FLAG_HIDE,
2568 },
2569 {
2570 .label = "printing",
2571 .type = P_ENUM,
2572 .p_class = P_LOCAL,
2573 .ptr = &sDefault.iPrinting,
2574 .special = handle_printing,
2575 .enum_list = enum_printing,
2576 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2577 },
2578 {
2579 .label = "cups options",
2580 .type = P_STRING,
2581 .p_class = P_LOCAL,
2582 .ptr = &sDefault.szCupsOptions,
2583 .special = NULL,
2584 .enum_list = NULL,
2585 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2586 },
2587 {
2588 .label = "cups server",
2589 .type = P_STRING,
2590 .p_class = P_GLOBAL,
2591 .ptr = &Globals.szCupsServer,
2592 .special = NULL,
2593 .enum_list = NULL,
2594 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2595 },
2596 {
2597 .label = "iprint server",
2598 .type = P_STRING,
2599 .p_class = P_GLOBAL,
2600 .ptr = &Globals.szIPrintServer,
2601 .special = NULL,
2602 .enum_list = NULL,
2603 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2604 },
2605 {
2606 .label = "print command",
2607 .type = P_STRING,
2608 .p_class = P_LOCAL,
2609 .ptr = &sDefault.szPrintcommand,
2610 .special = NULL,
2611 .enum_list = NULL,
2612 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2613 },
2614 {
2615 .label = "disable spoolss",
2616 .type = P_BOOL,
2617 .p_class = P_GLOBAL,
2618 .ptr = &Globals.bDisableSpoolss,
2619 .special = NULL,
2620 .enum_list = NULL,
2621 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2622 },
2623 {
2624 .label = "enable spoolss",
2625 .type = P_BOOLREV,
2626 .p_class = P_GLOBAL,
2627 .ptr = &Globals.bDisableSpoolss,
2628 .special = NULL,
2629 .enum_list = NULL,
2630 .flags = FLAG_HIDE,
2631 },
2632 {
2633 .label = "lpq command",
2634 .type = P_STRING,
2635 .p_class = P_LOCAL,
2636 .ptr = &sDefault.szLpqcommand,
2637 .special = NULL,
2638 .enum_list = NULL,
2639 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2640 },
2641 {
2642 .label = "lprm command",
2643 .type = P_STRING,
2644 .p_class = P_LOCAL,
2645 .ptr = &sDefault.szLprmcommand,
2646 .special = NULL,
2647 .enum_list = NULL,
2648 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2649 },
2650 {
2651 .label = "lppause command",
2652 .type = P_STRING,
2653 .p_class = P_LOCAL,
2654 .ptr = &sDefault.szLppausecommand,
2655 .special = NULL,
2656 .enum_list = NULL,
2657 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2658 },
2659 {
2660 .label = "lpresume command",
2661 .type = P_STRING,
2662 .p_class = P_LOCAL,
2663 .ptr = &sDefault.szLpresumecommand,
2664 .special = NULL,
2665 .enum_list = NULL,
2666 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2667 },
2668 {
2669 .label = "queuepause command",
2670 .type = P_STRING,
2671 .p_class = P_LOCAL,
2672 .ptr = &sDefault.szQueuepausecommand,
2673 .special = NULL,
2674 .enum_list = NULL,
2675 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2676 },
2677 {
2678 .label = "queueresume command",
2679 .type = P_STRING,
2680 .p_class = P_LOCAL,
2681 .ptr = &sDefault.szQueueresumecommand,
2682 .special = NULL,
2683 .enum_list = NULL,
2684 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2685 },
2686 {
2687 .label = "addport command",
2688 .type = P_STRING,
2689 .p_class = P_GLOBAL,
2690 .ptr = &Globals.szAddPortCommand,
2691 .special = NULL,
2692 .enum_list = NULL,
2693 .flags = FLAG_ADVANCED,
2694 },
2695 {
2696 .label = "enumports command",
2697 .type = P_STRING,
2698 .p_class = P_GLOBAL,
2699 .ptr = &Globals.szEnumPortsCommand,
2700 .special = NULL,
2701 .enum_list = NULL,
2702 .flags = FLAG_ADVANCED,
2703 },
2704 {
2705 .label = "addprinter command",
2706 .type = P_STRING,
2707 .p_class = P_GLOBAL,
2708 .ptr = &Globals.szAddPrinterCommand,
2709 .special = NULL,
2710 .enum_list = NULL,
2711 .flags = FLAG_ADVANCED,
2712 },
2713 {
2714 .label = "deleteprinter command",
2715 .type = P_STRING,
2716 .p_class = P_GLOBAL,
2717 .ptr = &Globals.szDeletePrinterCommand,
2718 .special = NULL,
2719 .enum_list = NULL,
2720 .flags = FLAG_ADVANCED,
2721 },
2722 {
2723 .label = "show add printer wizard",
2724 .type = P_BOOL,
2725 .p_class = P_GLOBAL,
2726 .ptr = &Globals.bMsAddPrinterWizard,
2727 .special = NULL,
2728 .enum_list = NULL,
2729 .flags = FLAG_ADVANCED,
2730 },
2731 {
2732 .label = "os2 driver map",
2733 .type = P_STRING,
2734 .p_class = P_GLOBAL,
2735 .ptr = &Globals.szOs2DriverMap,
2736 .special = NULL,
2737 .enum_list = NULL,
2738 .flags = FLAG_ADVANCED,
2739 },
2740
2741 {
2742 .label = "printer name",
2743 .type = P_STRING,
2744 .p_class = P_LOCAL,
2745 .ptr = &sDefault.szPrintername,
2746 .special = NULL,
2747 .enum_list = NULL,
2748 .flags = FLAG_ADVANCED | FLAG_PRINT,
2749 },
2750 {
2751 .label = "printer",
2752 .type = P_STRING,
2753 .p_class = P_LOCAL,
2754 .ptr = &sDefault.szPrintername,
2755 .special = NULL,
2756 .enum_list = NULL,
2757 .flags = FLAG_HIDE,
2758 },
2759 {
2760 .label = "use client driver",
2761 .type = P_BOOL,
2762 .p_class = P_LOCAL,
2763 .ptr = &sDefault.bUseClientDriver,
2764 .special = NULL,
2765 .enum_list = NULL,
2766 .flags = FLAG_ADVANCED | FLAG_PRINT,
2767 },
2768 {
2769 .label = "default devmode",
2770 .type = P_BOOL,
2771 .p_class = P_LOCAL,
2772 .ptr = &sDefault.bDefaultDevmode,
2773 .special = NULL,
2774 .enum_list = NULL,
2775 .flags = FLAG_ADVANCED | FLAG_PRINT,
2776 },
2777 {
2778 .label = "force printername",
2779 .type = P_BOOL,
2780 .p_class = P_LOCAL,
2781 .ptr = &sDefault.bForcePrintername,
2782 .special = NULL,
2783 .enum_list = NULL,
2784 .flags = FLAG_ADVANCED | FLAG_PRINT,
2785 },
2786 {
2787 .label = "printjob username",
2788 .type = P_STRING,
2789 .p_class = P_LOCAL,
2790 .ptr = &sDefault.szPrintjobUsername,
2791 .special = NULL,
2792 .enum_list = NULL,
2793 .flags = FLAG_ADVANCED | FLAG_PRINT,
2794 },
2795
2796 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2797
2798 {
2799 .label = "mangling method",
2800 .type = P_STRING,
2801 .p_class = P_GLOBAL,
2802 .ptr = &Globals.szManglingMethod,
2803 .special = NULL,
2804 .enum_list = NULL,
2805 .flags = FLAG_ADVANCED,
2806 },
2807 {
2808 .label = "mangle prefix",
2809 .type = P_INTEGER,
2810 .p_class = P_GLOBAL,
2811 .ptr = &Globals.mangle_prefix,
2812 .special = NULL,
2813 .enum_list = NULL,
2814 .flags = FLAG_ADVANCED,
2815 },
2816
2817 {
2818 .label = "default case",
2819 .type = P_ENUM,
2820 .p_class = P_LOCAL,
2821 .ptr = &sDefault.iDefaultCase,
2822 .special = NULL,
2823 .enum_list = enum_case,
2824 .flags = FLAG_ADVANCED | FLAG_SHARE,
2825 },
2826 {
2827 .label = "case sensitive",
2828 .type = P_ENUM,
2829 .p_class = P_LOCAL,
2830 .ptr = &sDefault.iCaseSensitive,
2831 .special = NULL,
2832 .enum_list = enum_bool_auto,
2833 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2834 },
2835 {
2836 .label = "casesignames",
2837 .type = P_ENUM,
2838 .p_class = P_LOCAL,
2839 .ptr = &sDefault.iCaseSensitive,
2840 .special = NULL,
2841 .enum_list = enum_bool_auto,
2842 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2843 },
2844 {
2845 .label = "preserve case",
2846 .type = P_BOOL,
2847 .p_class = P_LOCAL,
2848 .ptr = &sDefault.bCasePreserve,
2849 .special = NULL,
2850 .enum_list = NULL,
2851 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2852 },
2853 {
2854 .label = "short preserve case",
2855 .type = P_BOOL,
2856 .p_class = P_LOCAL,
2857 .ptr = &sDefault.bShortCasePreserve,
2858 .special = NULL,
2859 .enum_list = NULL,
2860 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2861 },
2862 {
2863 .label = "mangling char",
2864 .type = P_CHAR,
2865 .p_class = P_LOCAL,
2866 .ptr = &sDefault.magic_char,
2867 .special = NULL,
2868 .enum_list = NULL,
2869 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2870 },
2871 {
2872 .label = "hide dot files",
2873 .type = P_BOOL,
2874 .p_class = P_LOCAL,
2875 .ptr = &sDefault.bHideDotFiles,
2876 .special = NULL,
2877 .enum_list = NULL,
2878 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2879 },
2880 {
2881 .label = "hide special files",
2882 .type = P_BOOL,
2883 .p_class = P_LOCAL,
2884 .ptr = &sDefault.bHideSpecialFiles,
2885 .special = NULL,
2886 .enum_list = NULL,
2887 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2888 },
2889 {
2890 .label = "hide unreadable",
2891 .type = P_BOOL,
2892 .p_class = P_LOCAL,
2893 .ptr = &sDefault.bHideUnReadable,
2894 .special = NULL,
2895 .enum_list = NULL,
2896 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2897 },
2898 {
2899 .label = "hide unwriteable files",
2900 .type = P_BOOL,
2901 .p_class = P_LOCAL,
2902 .ptr = &sDefault.bHideUnWriteableFiles,
2903 .special = NULL,
2904 .enum_list = NULL,
2905 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2906 },
2907 {
2908 .label = "delete veto files",
2909 .type = P_BOOL,
2910 .p_class = P_LOCAL,
2911 .ptr = &sDefault.bDeleteVetoFiles,
2912 .special = NULL,
2913 .enum_list = NULL,
2914 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2915 },
2916 {
2917 .label = "veto files",
2918 .type = P_STRING,
2919 .p_class = P_LOCAL,
2920 .ptr = &sDefault.szVetoFiles,
2921 .special = NULL,
2922 .enum_list = NULL,
2923 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2924 },
2925 {
2926 .label = "hide files",
2927 .type = P_STRING,
2928 .p_class = P_LOCAL,
2929 .ptr = &sDefault.szHideFiles,
2930 .special = NULL,
2931 .enum_list = NULL,
2932 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2933 },
2934 {
2935 .label = "veto oplock files",
2936 .type = P_STRING,
2937 .p_class = P_LOCAL,
2938 .ptr = &sDefault.szVetoOplockFiles,
2939 .special = NULL,
2940 .enum_list = NULL,
2941 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2942 },
2943 {
2944 .label = "map archive",
2945 .type = P_BOOL,
2946 .p_class = P_LOCAL,
2947 .ptr = &sDefault.bMap_archive,
2948 .special = NULL,
2949 .enum_list = NULL,
2950 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2951 },
2952 {
2953 .label = "map hidden",
2954 .type = P_BOOL,
2955 .p_class = P_LOCAL,
2956 .ptr = &sDefault.bMap_hidden,
2957 .special = NULL,
2958 .enum_list = NULL,
2959 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2960 },
2961 {
2962 .label = "map system",
2963 .type = P_BOOL,
2964 .p_class = P_LOCAL,
2965 .ptr = &sDefault.bMap_system,
2966 .special = NULL,
2967 .enum_list = NULL,
2968 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2969 },
2970 {
2971 .label = "map readonly",
2972 .type = P_ENUM,
2973 .p_class = P_LOCAL,
2974 .ptr = &sDefault.iMap_readonly,
2975 .special = NULL,
2976 .enum_list = enum_map_readonly,
2977 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2978 },
2979 {
2980 .label = "mangled names",
2981 .type = P_BOOL,
2982 .p_class = P_LOCAL,
2983 .ptr = &sDefault.bMangledNames,
2984 .special = NULL,
2985 .enum_list = NULL,
2986 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2987 },
2988 {
2989 .label = "max stat cache size",
2990 .type = P_INTEGER,
2991 .p_class = P_GLOBAL,
2992 .ptr = &Globals.iMaxStatCacheSize,
2993 .special = NULL,
2994 .enum_list = NULL,
2995 .flags = FLAG_ADVANCED,
2996 },
2997 {
2998 .label = "stat cache",
2999 .type = P_BOOL,
3000 .p_class = P_GLOBAL,
3001 .ptr = &Globals.bStatCache,
3002 .special = NULL,
3003 .enum_list = NULL,
3004 .flags = FLAG_ADVANCED,
3005 },
3006 {
3007 .label = "store dos attributes",
3008 .type = P_BOOL,
3009 .p_class = P_LOCAL,
3010 .ptr = &sDefault.bStoreDosAttributes,
3011 .special = NULL,
3012 .enum_list = NULL,
3013 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3014 },
3015 {
3016 .label = "dmapi support",
3017 .type = P_BOOL,
3018 .p_class = P_LOCAL,
3019 .ptr = &sDefault.bDmapiSupport,
3020 .special = NULL,
3021 .enum_list = NULL,
3022 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3023 },
3024
3025
3026 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3027
3028 {
3029 .label = "machine password timeout",
3030 .type = P_INTEGER,
3031 .p_class = P_GLOBAL,
3032 .ptr = &Globals.machine_password_timeout,
3033 .special = NULL,
3034 .enum_list = NULL,
3035 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3036 },
3037
3038 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3039
3040 {
3041 .label = "add user script",
3042 .type = P_STRING,
3043 .p_class = P_GLOBAL,
3044 .ptr = &Globals.szAddUserScript,
3045 .special = NULL,
3046 .enum_list = NULL,
3047 .flags = FLAG_ADVANCED,
3048 },
3049 {
3050 .label = "rename user script",
3051 .type = P_STRING,
3052 .p_class = P_GLOBAL,
3053 .ptr = &Globals.szRenameUserScript,
3054 .special = NULL,
3055 .enum_list = NULL,
3056 .flags = FLAG_ADVANCED,
3057 },
3058 {
3059 .label = "delete user script",
3060 .type = P_STRING,
3061 .p_class = P_GLOBAL,
3062 .ptr = &Globals.szDelUserScript,
3063 .special = NULL,
3064 .enum_list = NULL,
3065 .flags = FLAG_ADVANCED,
3066 },
3067 {
3068 .label = "add group script",
3069 .type = P_STRING,
3070 .p_class = P_GLOBAL,
3071 .ptr = &Globals.szAddGroupScript,
3072 .special = NULL,
3073 .enum_list = NULL,
3074 .flags = FLAG_ADVANCED,
3075 },
3076 {
3077 .label = "delete group script",
3078 .type = P_STRING,
3079 .p_class = P_GLOBAL,
3080 .ptr = &Globals.szDelGroupScript,
3081 .special = NULL,
3082 .enum_list = NULL,
3083 .flags = FLAG_ADVANCED,
3084 },
3085 {
3086 .label = "add user to group script",
3087 .type = P_STRING,
3088 .p_class = P_GLOBAL,
3089 .ptr = &Globals.szAddUserToGroupScript,
3090 .special = NULL,
3091 .enum_list = NULL,
3092 .flags = FLAG_ADVANCED,
3093 },
3094 {
3095 .label = "delete user from group script",
3096 .type = P_STRING,
3097 .p_class = P_GLOBAL,
3098 .ptr = &Globals.szDelUserFromGroupScript,
3099 .special = NULL,
3100 .enum_list = NULL,
3101 .flags = FLAG_ADVANCED,
3102 },
3103 {
3104 .label = "set primary group script",
3105 .type = P_STRING,
3106 .p_class = P_GLOBAL,
3107 .ptr = &Globals.szSetPrimaryGroupScript,
3108 .special = NULL,
3109 .enum_list = NULL,
3110 .flags = FLAG_ADVANCED,
3111 },
3112 {
3113 .label = "add machine script",
3114 .type = P_STRING,
3115 .p_class = P_GLOBAL,
3116 .ptr = &Globals.szAddMachineScript,
3117 .special = NULL,
3118 .enum_list = NULL,
3119 .flags = FLAG_ADVANCED,
3120 },
3121 {
3122 .label = "shutdown script",
3123 .type = P_STRING,
3124 .p_class = P_GLOBAL,
3125 .ptr = &Globals.szShutdownScript,
3126 .special = NULL,
3127 .enum_list = NULL,
3128 .flags = FLAG_ADVANCED,
3129 },
3130 {
3131 .label = "abort shutdown script",
3132 .type = P_STRING,
3133 .p_class = P_GLOBAL,
3134 .ptr = &Globals.szAbortShutdownScript,
3135 .special = NULL,
3136 .enum_list = NULL,
3137 .flags = FLAG_ADVANCED,
3138 },
3139 {
3140 .label = "username map script",
3141 .type = P_STRING,
3142 .p_class = P_GLOBAL,
3143 .ptr = &Globals.szUsernameMapScript,
3144 .special = NULL,
3145 .enum_list = NULL,
3146 .flags = FLAG_ADVANCED,
3147 },
3148 {
3149 .label = "logon script",
3150 .type = P_STRING,
3151 .p_class = P_GLOBAL,
3152 .ptr = &Globals.szLogonScript,
3153 .special = NULL,
3154 .enum_list = NULL,
3155 .flags = FLAG_ADVANCED,
3156 },
3157 {
3158 .label = "logon path",
3159 .type = P_STRING,
3160 .p_class = P_GLOBAL,
3161 .ptr = &Globals.szLogonPath,
3162 .special = NULL,
3163 .enum_list = NULL,
3164 .flags = FLAG_ADVANCED,
3165 },
3166 {
3167 .label = "logon drive",
3168 .type = P_STRING,
3169 .p_class = P_GLOBAL,
3170 .ptr = &Globals.szLogonDrive,
3171 .special = NULL,
3172 .enum_list = NULL,
3173 .flags = FLAG_ADVANCED,
3174 },
3175 {
3176 .label = "logon home",
3177 .type = P_STRING,
3178 .p_class = P_GLOBAL,
3179 .ptr = &Globals.szLogonHome,
3180 .special = NULL,
3181 .enum_list = NULL,
3182 .flags = FLAG_ADVANCED,
3183 },
3184 {
3185 .label = "domain logons",
3186 .type = P_BOOL,
3187 .p_class = P_GLOBAL,
3188 .ptr = &Globals.bDomainLogons,
3189 .special = NULL,
3190 .enum_list = NULL,
3191 .flags = FLAG_ADVANCED,
3192 },
3193
3194 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3195
3196 {
3197 .label = "os level",
3198 .type = P_INTEGER,
3199 .p_class = P_GLOBAL,
3200 .ptr = &Globals.os_level,
3201 .special = NULL,
3202 .enum_list = NULL,
3203 .flags = FLAG_BASIC | FLAG_ADVANCED,
3204 },
3205 {
3206 .label = "lm announce",
3207 .type = P_ENUM,
3208 .p_class = P_GLOBAL,
3209 .ptr = &Globals.lm_announce,
3210 .special = NULL,
3211 .enum_list = enum_bool_auto,
3212 .flags = FLAG_ADVANCED,
3213 },
3214 {
3215 .label = "lm interval",
3216 .type = P_INTEGER,
3217 .p_class = P_GLOBAL,
3218 .ptr = &Globals.lm_interval,
3219 .special = NULL,
3220 .enum_list = NULL,
3221 .flags = FLAG_ADVANCED,
3222 },
3223 {
3224 .label = "preferred master",
3225 .type = P_ENUM,
3226 .p_class = P_GLOBAL,
3227 .ptr = &Globals.iPreferredMaster,
3228 .special = NULL,
3229 .enum_list = enum_bool_auto,
3230 .flags = FLAG_BASIC | FLAG_ADVANCED,
3231 },
3232 {
3233 .label = "prefered master",
3234 .type = P_ENUM,
3235 .p_class = P_GLOBAL,
3236 .ptr = &Globals.iPreferredMaster,
3237 .special = NULL,
3238 .enum_list = enum_bool_auto,
3239 .flags = FLAG_HIDE,
3240 },
3241 {
3242 .label = "local master",
3243 .type = P_BOOL,
3244 .p_class = P_GLOBAL,
3245 .ptr = &Globals.bLocalMaster,
3246 .special = NULL,
3247 .enum_list = NULL,
3248 .flags = FLAG_BASIC | FLAG_ADVANCED,
3249 },
3250 {
3251 .label = "domain master",
3252 .type = P_ENUM,
3253 .p_class = P_GLOBAL,
3254 .ptr = &Globals.iDomainMaster,
3255 .special = NULL,
3256 .enum_list = enum_bool_auto,
3257 .flags = FLAG_BASIC | FLAG_ADVANCED,
3258 },
3259 {
3260 .label = "browse list",
3261 .type = P_BOOL,
3262 .p_class = P_GLOBAL,
3263 .ptr = &Globals.bBrowseList,
3264 .special = NULL,
3265 .enum_list = NULL,
3266 .flags = FLAG_ADVANCED,
3267 },
3268 {
3269 .label = "browseable",
3270 .type = P_BOOL,
3271 .p_class = P_LOCAL,
3272 .ptr = &sDefault.bBrowseable,
3273 .special = NULL,
3274 .enum_list = NULL,
3275 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3276 },
3277 {
3278 .label = "browsable",
3279 .type = P_BOOL,
3280 .p_class = P_LOCAL,
3281 .ptr = &sDefault.bBrowseable,
3282 .special = NULL,
3283 .enum_list = NULL,
3284 .flags = FLAG_HIDE,
3285 },
3286 {
3287 .label = "enhanced browsing",
3288 .type = P_BOOL,
3289 .p_class = P_GLOBAL,
3290 .ptr = &Globals.enhanced_browsing,
3291 .special = NULL,
3292 .enum_list = NULL,
3293 .flags = FLAG_ADVANCED,
3294 },
3295
3296 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3297
3298 {
3299 .label = "dns proxy",
3300 .type = P_BOOL,
3301 .p_class = P_GLOBAL,
3302 .ptr = &Globals.bDNSproxy,
3303 .special = NULL,
3304 .enum_list = NULL,
3305 .flags = FLAG_ADVANCED,
3306 },
3307 {
3308 .label = "wins proxy",
3309 .type = P_BOOL,
3310 .p_class = P_GLOBAL,
3311 .ptr = &Globals.bWINSproxy,
3312 .special = NULL,
3313 .enum_list = NULL,
3314 .flags = FLAG_ADVANCED,
3315 },
3316 {
3317 .label = "wins server",
3318 .type = P_LIST,
3319 .p_class = P_GLOBAL,
3320 .ptr = &Globals.szWINSservers,
3321 .special = NULL,
3322 .enum_list = NULL,
3323 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3324 },
3325 {
3326 .label = "wins support",
3327 .type = P_BOOL,
3328 .p_class = P_GLOBAL,
3329 .ptr = &Globals.bWINSsupport,
3330 .special = NULL,
3331 .enum_list = NULL,
3332 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3333 },
3334 {
3335 .label = "wins hook",
3336 .type = P_STRING,
3337 .p_class = P_GLOBAL,
3338 .ptr = &Globals.szWINSHook,
3339 .special = NULL,
3340 .enum_list = NULL,
3341 .flags = FLAG_ADVANCED,
3342 },
3343
3344 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3345
3346 {
3347 .label = "blocking locks",
3348 .type = P_BOOL,
3349 .p_class = P_LOCAL,
3350 .ptr = &sDefault.bBlockingLocks,
3351 .special = NULL,
3352 .enum_list = NULL,
3353 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3354 },
3355 {
3356 .label = "csc policy",
3357 .type = P_ENUM,
3358 .p_class = P_LOCAL,
3359 .ptr = &sDefault.iCSCPolicy,
3360 .special = NULL,
3361 .enum_list = enum_csc_policy,
3362 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3363 },
3364 {
3365 .label = "fake oplocks",
3366 .type = P_BOOL,
3367 .p_class = P_LOCAL,
3368 .ptr = &sDefault.bFakeOplocks,
3369 .special = NULL,
3370 .enum_list = NULL,
3371 .flags = FLAG_ADVANCED | FLAG_SHARE,
3372 },
3373 {
3374 .label = "kernel oplocks",
3375 .type = P_BOOL,
3376 .p_class = P_GLOBAL,
3377 .ptr = &Globals.bKernelOplocks,
3378 .special = NULL,
3379 .enum_list = NULL,
3380 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3381 },
3382 {
3383 .label = "locking",
3384 .type = P_BOOL,
3385 .p_class = P_LOCAL,
3386 .ptr = &sDefault.bLocking,
3387 .special = NULL,
3388 .enum_list = NULL,
3389 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3390 },
3391 {
3392 .label = "lock spin time",
3393 .type = P_INTEGER,
3394 .p_class = P_GLOBAL,
3395 .ptr = &Globals.iLockSpinTime,
3396 .special = NULL,
3397 .enum_list = NULL,
3398 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3399 },
3400 {
3401 .label = "oplocks",
3402 .type = P_BOOL,
3403 .p_class = P_LOCAL,
3404 .ptr = &sDefault.bOpLocks,
3405 .special = NULL,
3406 .enum_list = NULL,
3407 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3408 },
3409 {
3410 .label = "level2 oplocks",
3411 .type = P_BOOL,
3412 .p_class = P_LOCAL,
3413 .ptr = &sDefault.bLevel2OpLocks,
3414 .special = NULL,
3415 .enum_list = NULL,
3416 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3417 },
3418 {
3419 .label = "oplock break wait time",
3420 .type = P_INTEGER,
3421 .p_class = P_GLOBAL,
3422 .ptr = &Globals.oplock_break_wait_time,
3423 .special = NULL,
3424 .enum_list = NULL,
3425 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3426 },
3427 {
3428 .label = "oplock contention limit",
3429 .type = P_INTEGER,
3430 .p_class = P_LOCAL,
3431 .ptr = &sDefault.iOplockContentionLimit,
3432 .special = NULL,
3433 .enum_list = NULL,
3434 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3435 },
3436 {
3437 .label = "posix locking",
3438 .type = P_BOOL,
3439 .p_class = P_LOCAL,
3440 .ptr = &sDefault.bPosixLocking,
3441 .special = NULL,
3442 .enum_list = NULL,
3443 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3444 },
3445 {
3446 .label = "strict locking",
3447 .type = P_ENUM,
3448 .p_class = P_LOCAL,
3449 .ptr = &sDefault.iStrictLocking,
3450 .special = NULL,
3451 .enum_list = enum_bool_auto,
3452 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3453 },
3454 {
3455 .label = "share modes",
3456 .type = P_BOOL,
3457 .p_class = P_LOCAL,
3458 .ptr = &sDefault.bShareModes,
3459 .special = NULL,
3460 .enum_list = NULL,
3461 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3462 },
3463
3464 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3465
3466 {
3467 .label = "ldap admin dn",
3468 .type = P_STRING,
3469 .p_class = P_GLOBAL,
3470 .ptr = &Globals.szLdapAdminDn,
3471 .special = NULL,
3472 .enum_list = NULL,
3473 .flags = FLAG_ADVANCED,
3474 },
3475 {
3476 .label = "ldap delete dn",
3477 .type = P_BOOL,
3478 .p_class = P_GLOBAL,
3479 .ptr = &Globals.ldap_delete_dn,
3480 .special = NULL,
3481 .enum_list = NULL,
3482 .flags = FLAG_ADVANCED,
3483 },
3484 {
3485 .label = "ldap group suffix",
3486 .type = P_STRING,
3487 .p_class = P_GLOBAL,
3488 .ptr = &Globals.szLdapGroupSuffix,
3489 .special = NULL,
3490 .enum_list = NULL,
3491 .flags = FLAG_ADVANCED,
3492 },
3493 {
3494 .label = "ldap idmap suffix",
3495 .type = P_STRING,
3496 .p_class = P_GLOBAL,
3497 .ptr = &Globals.szLdapIdmapSuffix,
3498 .special = NULL,
3499 .enum_list = NULL,
3500 .flags = FLAG_ADVANCED,
3501 },
3502 {
3503 .label = "ldap machine suffix",
3504 .type = P_STRING,
3505 .p_class = P_GLOBAL,
3506 .ptr = &Globals.szLdapMachineSuffix,
3507 .special = NULL,
3508 .enum_list = NULL,
3509 .flags = FLAG_ADVANCED,
3510 },
3511 {
3512 .label = "ldap passwd sync",
3513 .type = P_ENUM,
3514 .p_class = P_GLOBAL,
3515 .ptr = &Globals.ldap_passwd_sync,
3516 .special = NULL,
3517 .enum_list = enum_ldap_passwd_sync,
3518 .flags = FLAG_ADVANCED,
3519 },
3520 {
3521 .label = "ldap password sync",
3522 .type = P_ENUM,
3523 .p_class = P_GLOBAL,
3524 .ptr = &Globals.ldap_passwd_sync,
3525 .special = NULL,
3526 .enum_list = enum_ldap_passwd_sync,
3527 .flags = FLAG_HIDE,
3528 },
3529 {
3530 .label = "ldap replication sleep",
3531 .type = P_INTEGER,
3532 .p_class = P_GLOBAL,
3533 .ptr = &Globals.ldap_replication_sleep,
3534 .special = NULL,
3535 .enum_list = NULL,
3536 .flags = FLAG_ADVANCED,
3537 },
3538 {
3539 .label = "ldap suffix",
3540 .type = P_STRING,
3541 .p_class = P_GLOBAL,
3542 .ptr = &Globals.szLdapSuffix,
3543 .special = NULL,
3544 .enum_list = NULL,
3545 .flags = FLAG_ADVANCED,
3546 },
3547 {
3548 .label = "ldap ssl",
3549 .type = P_ENUM,
3550 .p_class = P_GLOBAL,
3551 .ptr = &Globals.ldap_ssl,
3552 .special = NULL,
3553 .enum_list = enum_ldap_ssl,
3554 .flags = FLAG_ADVANCED,
3555 },
3556 {
3557 .label = "ldap timeout",
3558 .type = P_INTEGER,
3559 .p_class = P_GLOBAL,
3560 .ptr = &Globals.ldap_timeout,
3561 .special = NULL,
3562 .enum_list = NULL,
3563 .flags = FLAG_ADVANCED,
3564 },
3565 {
3566 .label = "ldap connection timeout",
3567 .type = P_INTEGER,
3568 .p_class = P_GLOBAL,
3569 .ptr = &Globals.ldap_connection_timeout,
3570 .special = NULL,
3571 .enum_list = NULL,
3572 .flags = FLAG_ADVANCED,
3573 },
3574 {
3575 .label = "ldap page size",
3576 .type = P_INTEGER,
3577 .p_class = P_GLOBAL,
3578 .ptr = &Globals.ldap_page_size,
3579 .special = NULL,
3580 .enum_list = NULL,
3581 .flags = FLAG_ADVANCED,
3582 },
3583 {
3584 .label = "ldap user suffix",
3585 .type = P_STRING,
3586 .p_class = P_GLOBAL,
3587 .ptr = &Globals.szLdapUserSuffix,
3588 .special = NULL,
3589 .enum_list = NULL,
3590 .flags = FLAG_ADVANCED,
3591 },
3592 {
3593 .label = "ldap debug level",
3594 .type = P_INTEGER,
3595 .p_class = P_GLOBAL,
3596 .ptr = &Globals.ldap_debug_level,
3597 .special = handle_ldap_debug_level,
3598 .enum_list = NULL,
3599 .flags = FLAG_ADVANCED,
3600 },
3601 {
3602 .label = "ldap debug threshold",
3603 .type = P_INTEGER,
3604 .p_class = P_GLOBAL,
3605 .ptr = &Globals.ldap_debug_threshold,
3606 .special = NULL,
3607 .enum_list = NULL,
3608 .flags = FLAG_ADVANCED,
3609 },
3610
3611 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3612
3613 {
3614 .label = "eventlog list",
3615 .type = P_LIST,
3616 .p_class = P_GLOBAL,
3617 .ptr = &Globals.szEventLogs,
3618 .special = NULL,
3619 .enum_list = NULL,
3620 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3621 },
3622
3623 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3624
3625 {
3626 .label = "add share command",
3627 .type = P_STRING,
3628 .p_class = P_GLOBAL,
3629 .ptr = &Globals.szAddShareCommand,
3630 .special = NULL,
3631 .enum_list = NULL,
3632 .flags = FLAG_ADVANCED,
3633 },
3634 {
3635 .label = "change share command",
3636 .type = P_STRING,
3637 .p_class = P_GLOBAL,
3638 .ptr = &Globals.szChangeShareCommand,
3639 .special = NULL,
3640 .enum_list = NULL,
3641 .flags = FLAG_ADVANCED,
3642 },
3643 {
3644 .label = "delete share command",
3645 .type = P_STRING,
3646 .p_class = P_GLOBAL,
3647 .ptr = &Globals.szDeleteShareCommand,
3648 .special = NULL,
3649 .enum_list = NULL,
3650 .flags = FLAG_ADVANCED,
3651 },
3652 {
3653 .label = "config file",
3654 .type = P_STRING,
3655 .p_class = P_GLOBAL,
3656 .ptr = &Globals.szConfigFile,
3657 .special = NULL,
3658 .enum_list = NULL,
3659 .flags = FLAG_HIDE,
3660 },
3661 {
3662 .label = "preload",
3663 .type = P_STRING,
3664 .p_class = P_GLOBAL,
3665 .ptr = &Globals.szAutoServices,
3666 .special = NULL,
3667 .enum_list = NULL,
3668 .flags = FLAG_ADVANCED,
3669 },
3670 {
3671 .label = "auto services",
3672 .type = P_STRING,
3673 .p_class = P_GLOBAL,
3674 .ptr = &Globals.szAutoServices,
3675 .special = NULL,
3676 .enum_list = NULL,
3677 .flags = FLAG_ADVANCED,
3678 },
3679 {
3680 .label = "lock directory",
3681 .type = P_STRING,
3682 .p_class = P_GLOBAL,
3683 .ptr = &Globals.szLockDir,
3684 .special = NULL,
3685 .enum_list = NULL,
3686 .flags = FLAG_ADVANCED,
3687 },
3688 {
3689 .label = "lock dir",
3690 .type = P_STRING,
3691 .p_class = P_GLOBAL,
3692 .ptr = &Globals.szLockDir,
3693 .special = NULL,
3694 .enum_list = NULL,
3695 .flags = FLAG_HIDE,
3696 },
3697 {
3698 .label = "pid directory",
3699 .type = P_STRING,
3700 .p_class = P_GLOBAL,
3701 .ptr = &Globals.szPidDir,
3702 .special = NULL,
3703 .enum_list = NULL,
3704 .flags = FLAG_ADVANCED,
3705 },
3706#ifdef WITH_UTMP
3707 {
3708 .label = "utmp directory",
3709 .type = P_STRING,
3710 .p_class = P_GLOBAL,
3711 .ptr = &Globals.szUtmpDir,
3712 .special = NULL,
3713 .enum_list = NULL,
3714 .flags = FLAG_ADVANCED,
3715 },
3716 {
3717 .label = "wtmp directory",
3718 .type = P_STRING,
3719 .p_class = P_GLOBAL,
3720 .ptr = &Globals.szWtmpDir,
3721 .special = NULL,
3722 .enum_list = NULL,
3723 .flags = FLAG_ADVANCED,
3724 },
3725 {
3726 .label = "utmp",
3727 .type = P_BOOL,
3728 .p_class = P_GLOBAL,
3729 .ptr = &Globals.bUtmp,
3730 .special = NULL,
3731 .enum_list = NULL,
3732 .flags = FLAG_ADVANCED,
3733 },
3734#endif
3735 {
3736 .label = "default service",
3737 .type = P_STRING,
3738 .p_class = P_GLOBAL,
3739 .ptr = &Globals.szDefaultService,
3740 .special = NULL,
3741 .enum_list = NULL,
3742 .flags = FLAG_ADVANCED,
3743 },
3744 {
3745 .label = "default",
3746 .type = P_STRING,
3747 .p_class = P_GLOBAL,
3748 .ptr = &Globals.szDefaultService,
3749 .special = NULL,
3750 .enum_list = NULL,
3751 .flags = FLAG_ADVANCED,
3752 },
3753 {
3754 .label = "message command",
3755 .type = P_STRING,
3756 .p_class = P_GLOBAL,
3757 .ptr = &Globals.szMsgCommand,
3758 .special = NULL,
3759 .enum_list = NULL,
3760 .flags = FLAG_ADVANCED,
3761 },
3762 {
3763 .label = "dfree cache time",
3764 .type = P_INTEGER,
3765 .p_class = P_LOCAL,
3766 .ptr = &sDefault.iDfreeCacheTime,
3767 .special = NULL,
3768 .enum_list = NULL,
3769 .flags = FLAG_ADVANCED,
3770 },
3771 {
3772 .label = "dfree command",
3773 .type = P_STRING,
3774 .p_class = P_LOCAL,
3775 .ptr = &sDefault.szDfree,
3776 .special = NULL,
3777 .enum_list = NULL,
3778 .flags = FLAG_ADVANCED,
3779 },
3780 {
3781 .label = "get quota command",
3782 .type = P_STRING,
3783 .p_class = P_GLOBAL,
3784 .ptr = &Globals.szGetQuota,
3785 .special = NULL,
3786 .enum_list = NULL,
3787 .flags = FLAG_ADVANCED,
3788 },
3789 {
3790 .label = "set quota command",
3791 .type = P_STRING,
3792 .p_class = P_GLOBAL,
3793 .ptr = &Globals.szSetQuota,
3794 .special = NULL,
3795 .enum_list = NULL,
3796 .flags = FLAG_ADVANCED,
3797 },
3798 {
3799 .label = "remote announce",
3800 .type = P_STRING,
3801 .p_class = P_GLOBAL,
3802 .ptr = &Globals.szRemoteAnnounce,
3803 .special = NULL,
3804 .enum_list = NULL,
3805 .flags = FLAG_ADVANCED,
3806 },
3807 {
3808 .label = "remote browse sync",
3809 .type = P_STRING,
3810 .p_class = P_GLOBAL,
3811 .ptr = &Globals.szRemoteBrowseSync,
3812 .special = NULL,
3813 .enum_list = NULL,
3814 .flags = FLAG_ADVANCED,
3815 },
3816 {
3817 .label = "socket address",
3818 .type = P_STRING,
3819 .p_class = P_GLOBAL,
3820 .ptr = &Globals.szSocketAddress,
3821 .special = NULL,
3822 .enum_list = NULL,
3823 .flags = FLAG_ADVANCED,
3824 },
3825 {
3826 .label = "homedir map",
3827 .type = P_STRING,
3828 .p_class = P_GLOBAL,
3829 .ptr = &Globals.szNISHomeMapName,
3830 .special = NULL,
3831 .enum_list = NULL,
3832 .flags = FLAG_ADVANCED,
3833 },
3834 {
3835 .label = "afs username map",
3836 .type = P_STRING,
3837 .p_class = P_GLOBAL,
3838 .ptr = &Globals.szAfsUsernameMap,
3839 .special = NULL,
3840 .enum_list = NULL,
3841 .flags = FLAG_ADVANCED,
3842 },
3843 {
3844 .label = "afs token lifetime",
3845 .type = P_INTEGER,
3846 .p_class = P_GLOBAL,
3847 .ptr = &Globals.iAfsTokenLifetime,
3848 .special = NULL,
3849 .enum_list = NULL,
3850 .flags = FLAG_ADVANCED,
3851 },
3852 {
3853 .label = "log nt token command",
3854 .type = P_STRING,
3855 .p_class = P_GLOBAL,
3856 .ptr = &Globals.szLogNtTokenCommand,
3857 .special = NULL,
3858 .enum_list = NULL,
3859 .flags = FLAG_ADVANCED,
3860 },
3861 {
3862 .label = "time offset",
3863 .type = P_INTEGER,
3864 .p_class = P_GLOBAL,
3865 .ptr = &extra_time_offset,
3866 .special = NULL,
3867 .enum_list = NULL,
3868 .flags = FLAG_ADVANCED,
3869 },
3870 {
3871 .label = "NIS homedir",
3872 .type = P_BOOL,
3873 .p_class = P_GLOBAL,
3874 .ptr = &Globals.bNISHomeMap,
3875 .special = NULL,
3876 .enum_list = NULL,
3877 .flags = FLAG_ADVANCED,
3878 },
3879 {
3880 .label = "-valid",
3881 .type = P_BOOL,
3882 .p_class = P_LOCAL,
3883 .ptr = &sDefault.valid,
3884 .special = NULL,
3885 .enum_list = NULL,
3886 .flags = FLAG_HIDE,
3887 },
3888 {
3889 .label = "copy",
3890 .type = P_STRING,
3891 .p_class = P_LOCAL,
3892 .ptr = &sDefault.szCopy,
3893 .special = handle_copy,
3894 .enum_list = NULL,
3895 .flags = FLAG_HIDE,
3896 },
3897 {
3898 .label = "include",
3899 .type = P_STRING,
3900 .p_class = P_LOCAL,
3901 .ptr = &sDefault.szInclude,
3902 .special = handle_include,
3903 .enum_list = NULL,
3904 .flags = FLAG_HIDE,
3905 },
3906 {
3907 .label = "preexec",
3908 .type = P_STRING,
3909 .p_class = P_LOCAL,
3910 .ptr = &sDefault.szPreExec,
3911 .special = NULL,
3912 .enum_list = NULL,
3913 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3914 },
3915 {
3916 .label = "exec",
3917 .type = P_STRING,
3918 .p_class = P_LOCAL,
3919 .ptr = &sDefault.szPreExec,
3920 .special = NULL,
3921 .enum_list = NULL,
3922 .flags = FLAG_ADVANCED,
3923 },
3924 {
3925 .label = "preexec close",
3926 .type = P_BOOL,
3927 .p_class = P_LOCAL,
3928 .ptr = &sDefault.bPreexecClose,
3929 .special = NULL,
3930 .enum_list = NULL,
3931 .flags = FLAG_ADVANCED | FLAG_SHARE,
3932 },
3933 {
3934 .label = "postexec",
3935 .type = P_STRING,
3936 .p_class = P_LOCAL,
3937 .ptr = &sDefault.szPostExec,
3938 .special = NULL,
3939 .enum_list = NULL,
3940 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3941 },
3942 {
3943 .label = "root preexec",
3944 .type = P_STRING,
3945 .p_class = P_LOCAL,
3946 .ptr = &sDefault.szRootPreExec,
3947 .special = NULL,
3948 .enum_list = NULL,
3949 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3950 },
3951 {
3952 .label = "root preexec close",
3953 .type = P_BOOL,
3954 .p_class = P_LOCAL,
3955 .ptr = &sDefault.bRootpreexecClose,
3956 .special = NULL,
3957 .enum_list = NULL,
3958 .flags = FLAG_ADVANCED | FLAG_SHARE,
3959 },
3960 {
3961 .label = "root postexec",
3962 .type = P_STRING,
3963 .p_class = P_LOCAL,
3964 .ptr = &sDefault.szRootPostExec,
3965 .special = NULL,
3966 .enum_list = NULL,
3967 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3968 },
3969 {
3970 .label = "available",
3971 .type = P_BOOL,
3972 .p_class = P_LOCAL,
3973 .ptr = &sDefault.bAvailable,
3974 .special = NULL,
3975 .enum_list = NULL,
3976 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3977 },
3978 {
3979 .label = "registry shares",
3980 .type = P_BOOL,
3981 .p_class = P_GLOBAL,
3982 .ptr = &Globals.bRegistryShares,
3983 .special = NULL,
3984 .enum_list = NULL,
3985 .flags = FLAG_ADVANCED,
3986 },
3987 {
3988 .label = "usershare allow guests",
3989 .type = P_BOOL,
3990 .p_class = P_GLOBAL,
3991 .ptr = &Globals.bUsershareAllowGuests,
3992 .special = NULL,
3993 .enum_list = NULL,
3994 .flags = FLAG_ADVANCED,
3995 },
3996 {
3997 .label = "usershare max shares",
3998 .type = P_INTEGER,
3999 .p_class = P_GLOBAL,
4000 .ptr = &Globals.iUsershareMaxShares,
4001 .special = NULL,
4002 .enum_list = NULL,
4003 .flags = FLAG_ADVANCED,
4004 },
4005 {
4006 .label = "usershare owner only",
4007 .type = P_BOOL,
4008 .p_class = P_GLOBAL,
4009 .ptr = &Globals.bUsershareOwnerOnly,
4010 .special = NULL,
4011 .enum_list = NULL,
4012 .flags = FLAG_ADVANCED,
4013 },
4014 {
4015 .label = "usershare path",
4016 .type = P_STRING,
4017 .p_class = P_GLOBAL,
4018 .ptr = &Globals.szUsersharePath,
4019 .special = NULL,
4020 .enum_list = NULL,
4021 .flags = FLAG_ADVANCED,
4022 },
4023 {
4024 .label = "usershare prefix allow list",
4025 .type = P_LIST,
4026 .p_class = P_GLOBAL,
4027 .ptr = &Globals.szUsersharePrefixAllowList,
4028 .special = NULL,
4029 .enum_list = NULL,
4030 .flags = FLAG_ADVANCED,
4031 },
4032 {
4033 .label = "usershare prefix deny list",
4034 .type = P_LIST,
4035 .p_class = P_GLOBAL,
4036 .ptr = &Globals.szUsersharePrefixDenyList,
4037 .special = NULL,
4038 .enum_list = NULL,
4039 .flags = FLAG_ADVANCED,
4040 },
4041 {
4042 .label = "usershare template share",
4043 .type = P_STRING,
4044 .p_class = P_GLOBAL,
4045 .ptr = &Globals.szUsershareTemplateShare,
4046 .special = NULL,
4047 .enum_list = NULL,
4048 .flags = FLAG_ADVANCED,
4049 },
4050 {
4051 .label = "volume",
4052 .type = P_STRING,
4053 .p_class = P_LOCAL,
4054 .ptr = &sDefault.volume,
4055 .special = NULL,
4056 .enum_list = NULL,
4057 .flags = FLAG_ADVANCED | FLAG_SHARE,
4058 },
4059 {
4060 .label = "fstype",
4061 .type = P_STRING,
4062 .p_class = P_LOCAL,
4063 .ptr = &sDefault.fstype,
4064 .special = NULL,
4065 .enum_list = NULL,
4066 .flags = FLAG_ADVANCED | FLAG_SHARE,
4067 },
4068 {
4069 .label = "set directory",
4070 .type = P_BOOLREV,
4071 .p_class = P_LOCAL,
4072 .ptr = &sDefault.bNo_set_dir,
4073 .special = NULL,
4074 .enum_list = NULL,
4075 .flags = FLAG_ADVANCED | FLAG_SHARE,
4076 },
4077 {
4078 .label = "wide links",
4079 .type = P_BOOL,
4080 .p_class = P_LOCAL,
4081 .ptr = &sDefault.bWidelinks,
4082 .special = NULL,
4083 .enum_list = NULL,
4084 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4085 },
4086 {
4087 .label = "follow symlinks",
4088 .type = P_BOOL,
4089 .p_class = P_LOCAL,
4090 .ptr = &sDefault.bSymlinks,
4091 .special = NULL,
4092 .enum_list = NULL,
4093 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4094 },
4095 {
4096 .label = "dont descend",
4097 .type = P_STRING,
4098 .p_class = P_LOCAL,
4099 .ptr = &sDefault.szDontdescend,
4100 .special = NULL,
4101 .enum_list = NULL,
4102 .flags = FLAG_ADVANCED | FLAG_SHARE,
4103 },
4104 {
4105 .label = "magic script",
4106 .type = P_STRING,
4107 .p_class = P_LOCAL,
4108 .ptr = &sDefault.szMagicScript,
4109 .special = NULL,
4110 .enum_list = NULL,
4111 .flags = FLAG_ADVANCED | FLAG_SHARE,
4112 },
4113 {
4114 .label = "magic output",
4115 .type = P_STRING,
4116 .p_class = P_LOCAL,
4117 .ptr = &sDefault.szMagicOutput,
4118 .special = NULL,
4119 .enum_list = NULL,
4120 .flags = FLAG_ADVANCED | FLAG_SHARE,
4121 },
4122 {
4123 .label = "delete readonly",
4124 .type = P_BOOL,
4125 .p_class = P_LOCAL,
4126 .ptr = &sDefault.bDeleteReadonly,
4127 .special = NULL,
4128 .enum_list = NULL,
4129 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4130 },
4131 {
4132 .label = "dos filemode",
4133 .type = P_BOOL,
4134 .p_class = P_LOCAL,
4135 .ptr = &sDefault.bDosFilemode,
4136 .special = NULL,
4137 .enum_list = NULL,
4138 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4139 },
4140 {
4141 .label = "dos filetimes",
4142 .type = P_BOOL,
4143 .p_class = P_LOCAL,
4144 .ptr = &sDefault.bDosFiletimes,
4145 .special = NULL,
4146 .enum_list = NULL,
4147 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4148 },
4149 {
4150 .label = "dos filetime resolution",
4151 .type = P_BOOL,
4152 .p_class = P_LOCAL,
4153 .ptr = &sDefault.bDosFiletimeResolution,
4154 .special = NULL,
4155 .enum_list = NULL,
4156 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4157 },
4158 {
4159 .label = "fake directory create times",
4160 .type = P_BOOL,
4161 .p_class = P_LOCAL,
4162 .ptr = &sDefault.bFakeDirCreateTimes,
4163 .special = NULL,
4164 .enum_list = NULL,
4165 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4166 },
4167 {
4168 .label = "panic action",
4169 .type = P_STRING,
4170 .p_class = P_GLOBAL,
4171 .ptr = &Globals.szPanicAction,
4172 .special = NULL,
4173 .enum_list = NULL,
4174 .flags = FLAG_ADVANCED,
4175 },
4176
4177 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4178
4179 {
4180 .label = "vfs objects",
4181 .type = P_LIST,
4182 .p_class = P_LOCAL,
4183 .ptr = &sDefault.szVfsObjects,
4184 .special = NULL,
4185 .enum_list = NULL,
4186 .flags = FLAG_ADVANCED | FLAG_SHARE,
4187 },
4188 {
4189 .label = "vfs object",
4190 .type = P_LIST,
4191 .p_class = P_LOCAL,
4192 .ptr = &sDefault.szVfsObjects,
4193 .special = NULL,
4194 .enum_list = NULL,
4195 .flags = FLAG_HIDE,
4196 },
4197
4198
4199 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4200
4201 {
4202 .label = "msdfs root",
4203 .type = P_BOOL,
4204 .p_class = P_LOCAL,
4205 .ptr = &sDefault.bMSDfsRoot,
4206 .special = NULL,
4207 .enum_list = NULL,
4208 .flags = FLAG_ADVANCED | FLAG_SHARE,
4209 },
4210 {
4211 .label = "msdfs proxy",
4212 .type = P_STRING,
4213 .p_class = P_LOCAL,
4214 .ptr = &sDefault.szMSDfsProxy,
4215 .special = NULL,
4216 .enum_list = NULL,
4217 .flags = FLAG_ADVANCED | FLAG_SHARE,
4218 },
4219 {
4220 .label = "host msdfs",
4221 .type = P_BOOL,
4222 .p_class = P_GLOBAL,
4223 .ptr = &Globals.bHostMSDfs,
4224 .special = NULL,
4225 .enum_list = NULL,
4226 .flags = FLAG_ADVANCED,
4227 },
4228
4229 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4230
4231 {
4232 .label = "passdb expand explicit",
4233 .type = P_BOOL,
4234 .p_class = P_GLOBAL,
4235 .ptr = &Globals.bPassdbExpandExplicit,
4236 .special = NULL,
4237 .enum_list = NULL,
4238 .flags = FLAG_ADVANCED,
4239 },
4240 {
4241 .label = "idmap domains",
4242 .type = P_LIST,
4243 .p_class = P_GLOBAL,
4244 .ptr = &Globals.szIdmapDomains,
4245 .special = NULL,
4246 .enum_list = NULL,
4247 .flags = FLAG_ADVANCED,
4248 },
4249 {
4250 .label = "idmap backend",
4251 .type = P_LIST,
4252 .p_class = P_GLOBAL,
4253 .ptr = &Globals.szIdmapBackend,
4254 .special = NULL,
4255 .enum_list = NULL,
4256 .flags = FLAG_ADVANCED,
4257 },
4258 {
4259 .label = "idmap alloc backend",
4260 .type = P_STRING,
4261 .p_class = P_GLOBAL,
4262 .ptr = &Globals.szIdmapAllocBackend,
4263 .special = NULL,
4264 .enum_list = NULL,
4265 .flags = FLAG_ADVANCED,
4266 },
4267 {
4268 .label = "idmap cache time",
4269 .type = P_INTEGER,
4270 .p_class = P_GLOBAL,
4271 .ptr = &Globals.iIdmapCacheTime,
4272 .special = NULL,
4273 .enum_list = NULL,
4274 .flags = FLAG_ADVANCED,
4275 },
4276 {
4277 .label = "idmap negative cache time",
4278 .type = P_INTEGER,
4279 .p_class = P_GLOBAL,
4280 .ptr = &Globals.iIdmapNegativeCacheTime,
4281 .special = NULL,
4282 .enum_list = NULL,
4283 .flags = FLAG_ADVANCED,
4284 },
4285 {
4286 .label = "idmap uid",
4287 .type = P_STRING,
4288 .p_class = P_GLOBAL,
4289 .ptr = &Globals.szIdmapUID,
4290 .special = handle_idmap_uid,
4291 .enum_list = NULL,
4292 .flags = FLAG_ADVANCED,
4293 },
4294 {
4295 .label = "winbind uid",
4296 .type = P_STRING,
4297 .p_class = P_GLOBAL,
4298 .ptr = &Globals.szIdmapUID,
4299 .special = handle_idmap_uid,
4300 .enum_list = NULL,
4301 .flags = FLAG_HIDE,
4302 },
4303 {
4304 .label = "idmap gid",
4305 .type = P_STRING,
4306 .p_class = P_GLOBAL,
4307 .ptr = &Globals.szIdmapGID,
4308 .special = handle_idmap_gid,
4309 .enum_list = NULL,
4310 .flags = FLAG_ADVANCED,
4311 },
4312 {
4313 .label = "winbind gid",
4314 .type = P_STRING,
4315 .p_class = P_GLOBAL,
4316 .ptr = &Globals.szIdmapGID,
4317 .special = handle_idmap_gid,
4318 .enum_list = NULL,
4319 .flags = FLAG_HIDE,
4320 },
4321 {
4322 .label = "template homedir",
4323 .type = P_STRING,
4324 .p_class = P_GLOBAL,
4325 .ptr = &Globals.szTemplateHomedir,
4326 .special = NULL,
4327 .enum_list = NULL,
4328 .flags = FLAG_ADVANCED,
4329 },
4330 {
4331 .label = "template shell",
4332 .type = P_STRING,
4333 .p_class = P_GLOBAL,
4334 .ptr = &Globals.szTemplateShell,
4335 .special = NULL,
4336 .enum_list = NULL,
4337 .flags = FLAG_ADVANCED,
4338 },
4339 {
4340 .label = "winbind separator",
4341 .type = P_STRING,
4342 .p_class = P_GLOBAL,
4343 .ptr = &Globals.szWinbindSeparator,
4344 .special = NULL,
4345 .enum_list = NULL,
4346 .flags = FLAG_ADVANCED,
4347 },
4348 {
4349 .label = "winbind cache time",
4350 .type = P_INTEGER,
4351 .p_class = P_GLOBAL,
4352 .ptr = &Globals.winbind_cache_time,
4353 .special = NULL,
4354 .enum_list = NULL,
4355 .flags = FLAG_ADVANCED,
4356 },
4357 {
4358 .label = "winbind enum users",
4359 .type = P_BOOL,
4360 .p_class = P_GLOBAL,
4361 .ptr = &Globals.bWinbindEnumUsers,
4362 .special = NULL,
4363 .enum_list = NULL,
4364 .flags = FLAG_ADVANCED,
4365 },
4366 {
4367 .label = "winbind enum groups",
4368 .type = P_BOOL,
4369 .p_class = P_GLOBAL,
4370 .ptr = &Globals.bWinbindEnumGroups,
4371 .special = NULL,
4372 .enum_list = NULL,
4373 .flags = FLAG_ADVANCED,
4374 },
4375 {
4376 .label = "winbind use default domain",
4377 .type = P_BOOL,
4378 .p_class = P_GLOBAL,
4379 .ptr = &Globals.bWinbindUseDefaultDomain,
4380 .special = NULL,
4381 .enum_list = NULL,
4382 .flags = FLAG_ADVANCED,
4383 },
4384 {
4385 .label = "winbind trusted domains only",
4386 .type = P_BOOL,
4387 .p_class = P_GLOBAL,
4388 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4389 .special = NULL,
4390 .enum_list = NULL,
4391 .flags = FLAG_ADVANCED,
4392 },
4393 {
4394 .label = "winbind nested groups",
4395 .type = P_BOOL,
4396 .p_class = P_GLOBAL,
4397 .ptr = &Globals.bWinbindNestedGroups,
4398 .special = NULL,
4399 .enum_list = NULL,
4400 .flags = FLAG_ADVANCED,
4401 },
4402 {
4403 .label = "winbind expand groups",
4404 .type = P_INTEGER,
4405 .p_class = P_GLOBAL,
4406 .ptr = &Globals.winbind_expand_groups,
4407 .special = NULL,
4408 .enum_list = NULL,
4409 .flags = FLAG_ADVANCED,
4410 },
4411 {
4412 .label = "winbind nss info",
4413 .type = P_LIST,
4414 .p_class = P_GLOBAL,
4415 .ptr = &Globals.szWinbindNssInfo,
4416 .special = NULL,
4417 .enum_list = NULL,
4418 .flags = FLAG_ADVANCED,
4419 },
4420 {
4421 .label = "winbind refresh tickets",
4422 .type = P_BOOL,
4423 .p_class = P_GLOBAL,
4424 .ptr = &Globals.bWinbindRefreshTickets,
4425 .special = NULL,
4426 .enum_list = NULL,
4427 .flags = FLAG_ADVANCED,
4428 },
4429 {
4430 .label = "winbind offline logon",
4431 .type = P_BOOL,
4432 .p_class = P_GLOBAL,
4433 .ptr = &Globals.bWinbindOfflineLogon,
4434 .special = NULL,
4435 .enum_list = NULL,
4436 .flags = FLAG_ADVANCED,
4437 },
4438 {
4439 .label = "winbind normalize names",
4440 .type = P_BOOL,
4441 .p_class = P_GLOBAL,
4442 .ptr = &Globals.bWinbindNormalizeNames,
4443 .special = NULL,
4444 .enum_list = NULL,
4445 .flags = FLAG_ADVANCED,
4446 },
4447 {
4448 .label = "winbind rpc only",
4449 .type = P_BOOL,
4450 .p_class = P_GLOBAL,
4451 .ptr = &Globals.bWinbindRpcOnly,
4452 .special = NULL,
4453 .enum_list = NULL,
4454 .flags = FLAG_ADVANCED,
4455 },
4456
4457 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4458};
4459
4460/***************************************************************************
4461 Initialise the sDefault parameter structure for the printer values.
4462***************************************************************************/
4463
4464static void init_printer_values(struct service *pService)
4465{
4466 /* choose defaults depending on the type of printing */
4467 switch (pService->iPrinting) {
4468 case PRINT_BSD:
4469 case PRINT_AIX:
4470 case PRINT_LPRNT:
4471 case PRINT_LPROS2:
4472 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4473 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4474 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4475 break;
4476
4477 case PRINT_LPRNG:
4478 case PRINT_PLP:
4479 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4480 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4481 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4482 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4483 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4484 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4485 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4486 break;
4487
4488 case PRINT_CUPS:
4489 case PRINT_IPRINT:
4490#ifdef HAVE_CUPS
4491 /* set the lpq command to contain the destination printer
4492 name only. This is used by cups_queue_get() */
4493 string_set(&pService->szLpqcommand, "%p");
4494 string_set(&pService->szLprmcommand, "");
4495 string_set(&pService->szPrintcommand, "");
4496 string_set(&pService->szLppausecommand, "");
4497 string_set(&pService->szLpresumecommand, "");
4498 string_set(&pService->szQueuepausecommand, "");
4499 string_set(&pService->szQueueresumecommand, "");
4500#else
4501 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4502 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4503 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4504 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4505 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4506 string_set(&pService->szQueuepausecommand, "disable '%p'");
4507 string_set(&pService->szQueueresumecommand, "enable '%p'");
4508#endif /* HAVE_CUPS */
4509 break;
4510
4511 case PRINT_SYSV:
4512 case PRINT_HPUX:
4513 string_set(&pService->szLpqcommand, "lpstat -o%p");
4514 string_set(&pService->szLprmcommand, "cancel %p-%j");
4515 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4516 string_set(&pService->szQueuepausecommand, "disable %p");
4517 string_set(&pService->szQueueresumecommand, "enable %p");
4518#ifndef HPUX
4519 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4520 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4521#endif /* HPUX */
4522 break;
4523
4524 case PRINT_QNX:
4525 string_set(&pService->szLpqcommand, "lpq -P%p");
4526 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4527 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4528 break;
4529
4530#ifdef DEVELOPER
4531 case PRINT_TEST:
4532 case PRINT_VLP:
4533 string_set(&pService->szPrintcommand, "vlp print %p %s");
4534 string_set(&pService->szLpqcommand, "vlp lpq %p");
4535 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4536 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4537 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4538 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4539 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4540 break;
4541#endif /* DEVELOPER */
4542
4543 }
4544}
4545
4546/***************************************************************************
4547 Initialise the global parameter structure.
4548***************************************************************************/
4549
4550#ifndef __OS2__
4551static
4552#endif
4553void init_globals(bool first_time_only)
4554{
4555 static bool done_init = False;
4556 char *s = NULL;
4557 int i;
4558
4559 /* If requested to initialize only once and we've already done it... */
4560 if (first_time_only && done_init) {
4561 /* ... then we have nothing more to do */
4562 return;
4563 }
4564
4565 if (!done_init) {
4566 /* The logfile can be set before this is invoked. Free it if so. */
4567 if (Globals.szLogFile != NULL) {
4568 string_free(&Globals.szLogFile);
4569 Globals.szLogFile = NULL;
4570 }
4571 done_init = True;
4572 } else {
4573 for (i = 0; parm_table[i].label; i++) {
4574 if ((parm_table[i].type == P_STRING ||
4575 parm_table[i].type == P_USTRING) &&
4576 parm_table[i].ptr)
4577 {
4578 string_free((char **)parm_table[i].ptr);
4579 }
4580 }
4581 }
4582
4583 memset((void *)&Globals, '\0', sizeof(Globals));
4584
4585 for (i = 0; parm_table[i].label; i++) {
4586 if ((parm_table[i].type == P_STRING ||
4587 parm_table[i].type == P_USTRING) &&
4588 parm_table[i].ptr)
4589 {
4590 string_set((char **)parm_table[i].ptr, "");
4591 }
4592 }
4593
4594 string_set(&sDefault.fstype, FSTYPE_STRING);
4595 string_set(&sDefault.szPrintjobUsername, "%U");
4596
4597 init_printer_values(&sDefault);
4598
4599
4600 DEBUG(3, ("Initialising global parameters\n"));
4601
4602 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4603 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4604
4605 /* use the new 'hash2' method by default, with a prefix of 1 */
4606 string_set(&Globals.szManglingMethod, "hash2");
4607 Globals.mangle_prefix = 1;
4608
4609 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4610
4611#ifndef __OS2__
4612 /* using UTF8 by default allows us to support all chars */
4613 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4614#else
4615 /* On OS/2, using UTF8 causes problems with display of foreign
4616 characters - default to IBM-850 codepage */
4617 string_set(&Globals.unix_charset, "IBM-850");
4618#endif
4619
4620#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4621 /* If the system supports nl_langinfo(), try to grab the value
4622 from the user's locale */
4623#ifndef __OS2__
4624 /* this does somehow not work on OS/2 */
4625 string_set(&Globals.display_charset, "LOCALE");
4626#else
4627 /* On OS/2, using UTF8 causes problems with display of foreign
4628 characters - default to IBM-850 codepage */
4629 string_set(&Globals.display_charset, "IBM-850");
4630#endif
4631
4632#else
4633 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4634#endif
4635
4636#ifndef __OS2__
4637 /* Use codepage 850 as a default for the dos character set */
4638 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4639#else
4640 /* On OS/2, using UTF8 causes problems with display of foreign
4641 characters - default to IBM-850 codepage */
4642 string_set(&Globals.dos_charset, "IBM-850");
4643#endif
4644
4645 /*
4646 * Allow the default PASSWD_CHAT to be overridden in local.h.
4647 */
4648 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4649
4650 set_global_myname(myhostname());
4651 string_set(&Globals.szNetbiosName,global_myname());
4652
4653 set_global_myworkgroup(WORKGROUP);
4654 string_set(&Globals.szWorkgroup, lp_workgroup());
4655
4656 string_set(&Globals.szPasswdProgram, "");
4657 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4658 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4659 string_set(&Globals.szSocketAddress, "0.0.0.0");
4660
4661 if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
4662 smb_panic("init_globals: ENOMEM");
4663 }
4664 string_set(&Globals.szServerString, s);
4665 SAFE_FREE(s);
4666 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4667 DEFAULT_MINOR_VERSION) < 0) {
4668 smb_panic("init_globals: ENOMEM");
4669 }
4670 string_set(&Globals.szAnnounceVersion, s);
4671 SAFE_FREE(s);
4672#ifdef DEVELOPER
4673 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4674#endif
4675
4676 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4677
4678 string_set(&Globals.szLogonDrive, "");
4679 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4680 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4681 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4682
4683 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4684 string_set(&Globals.szPasswordServer, "*");
4685
4686 Globals.AlgorithmicRidBase = BASE_RID;
4687
4688 Globals.bLoadPrinters = True;
4689 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4690
4691 Globals.ConfigBackend = config_backend;
4692
4693 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4694 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4695 Globals.max_xmit = 0x4104;
4696 Globals.max_mux = 50; /* This is *needed* for profile support. */
4697 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4698 Globals.bDisableSpoolss = False;
4699 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4700 Globals.pwordlevel = 0;
4701 Globals.unamelevel = 0;
4702 Globals.deadtime = 0;
4703 Globals.getwd_cache = true;
4704 Globals.bLargeReadwrite = True;
4705 Globals.max_log_size = 5000;
4706 Globals.max_open_files = MAX_OPEN_FILES;
4707 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4708 Globals.maxprotocol = PROTOCOL_NT1;
4709 Globals.minprotocol = PROTOCOL_CORE;
4710 Globals.security = SEC_USER;
4711 Globals.paranoid_server_security = True;
4712 Globals.bEncryptPasswords = True;
4713 Globals.bUpdateEncrypt = False;
4714 Globals.clientSchannel = Auto;
4715 Globals.serverSchannel = Auto;
4716 Globals.bReadRaw = True;
4717 Globals.bWriteRaw = True;
4718 Globals.bNullPasswords = False;
4719 Globals.bObeyPamRestrictions = False;
4720 Globals.syslog = 1;
4721 Globals.bSyslogOnly = False;
4722 Globals.bTimestampLogs = True;
4723 string_set(&Globals.szLogLevel, "0");
4724 Globals.bDebugPrefixTimestamp = False;
4725 Globals.bDebugHiresTimestamp = False;
4726 Globals.bDebugPid = False;
4727 Globals.bDebugUid = False;
4728 Globals.bDebugClass = False;
4729 Globals.bEnableCoreFiles = True;
4730 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4731 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4732 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4733 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4734 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4735 Globals.lm_interval = 60;
4736 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4737#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4738 Globals.bNISHomeMap = False;
4739#ifdef WITH_NISPLUS_HOME
4740 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4741#else
4742 string_set(&Globals.szNISHomeMapName, "auto.home");
4743#endif
4744#endif
4745 Globals.bTimeServer = False;
4746 Globals.bBindInterfacesOnly = False;
4747 Globals.bUnixPasswdSync = False;
4748 Globals.bPamPasswordChange = False;
4749 Globals.bPasswdChatDebug = False;
4750 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4751 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4752 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4753 Globals.bStatCache = True; /* use stat cache by default */
4754 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4755 Globals.restrict_anonymous = 0;
4756 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4757 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4758 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4759 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4760 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4761 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4762
4763 Globals.map_to_guest = 0; /* By Default, "Never" */
4764 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4765 Globals.enhanced_browsing = true;
4766 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4767#ifdef MMAP_BLACKLIST
4768 Globals.bUseMmap = False;
4769#else
4770 Globals.bUseMmap = True;
4771#endif
4772 Globals.bUnixExtensions = True;
4773 Globals.bResetOnZeroVC = False;
4774
4775 /* hostname lookups can be very expensive and are broken on
4776 a large number of sites (tridge) */
4777 Globals.bHostnameLookups = False;
4778
4779 string_set(&Globals.szPassdbBackend, "smbpasswd");
4780 string_set(&Globals.szLdapSuffix, "");
4781 string_set(&Globals.szLdapMachineSuffix, "");
4782 string_set(&Globals.szLdapUserSuffix, "");
4783 string_set(&Globals.szLdapGroupSuffix, "");
4784 string_set(&Globals.szLdapIdmapSuffix, "");
4785
4786 string_set(&Globals.szLdapAdminDn, "");
4787 Globals.ldap_ssl = LDAP_SSL_OFF;
4788 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4789 Globals.ldap_delete_dn = False;
4790 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4791 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4792 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4793 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4794
4795 Globals.ldap_debug_level = 0;
4796 Globals.ldap_debug_threshold = 10;
4797
4798 /* This is what we tell the afs client. in reality we set the token
4799 * to never expire, though, when this runs out the afs client will
4800 * forget the token. Set to 0 to get NEVERDATE.*/
4801 Globals.iAfsTokenLifetime = 604800;
4802
4803/* these parameters are set to defaults that are more appropriate
4804 for the increasing samba install base:
4805
4806 as a member of the workgroup, that will possibly become a
4807 _local_ master browser (lm = True). this is opposed to a forced
4808 local master browser startup (pm = True).
4809
4810 doesn't provide WINS server service by default (wsupp = False),
4811 and doesn't provide domain master browser services by default, either.
4812
4813*/
4814
4815 Globals.bMsAddPrinterWizard = True;
4816 Globals.os_level = 20;
4817 Globals.bLocalMaster = True;
4818 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4819 Globals.bDomainLogons = False;
4820 Globals.bBrowseList = True;
4821 Globals.bWINSsupport = False;
4822 Globals.bWINSproxy = False;
4823
4824 Globals.bDNSproxy = True;
4825
4826 /* this just means to use them if they exist */
4827 Globals.bKernelOplocks = True;
4828
4829 Globals.bAllowTrustedDomains = True;
4830
4831 string_set(&Globals.szTemplateShell, "/bin/false");
4832 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4833 string_set(&Globals.szWinbindSeparator, "\\");
4834
4835 string_set(&Globals.szCupsServer, "");
4836 string_set(&Globals.szIPrintServer, "");
4837
4838 string_set(&Globals.ctdbdSocket, "");
4839 Globals.szClusterAddresses = NULL;
4840 Globals.clustering = False;
4841
4842 Globals.winbind_cache_time = 300; /* 5 minutes */
4843 Globals.bWinbindEnumUsers = False;
4844 Globals.bWinbindEnumGroups = False;
4845 Globals.bWinbindUseDefaultDomain = False;
4846 Globals.bWinbindTrustedDomainsOnly = False;
4847 Globals.bWinbindNestedGroups = True;
4848 Globals.winbind_expand_groups = 1;
4849 Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
4850 Globals.bWinbindRefreshTickets = False;
4851 Globals.bWinbindOfflineLogon = False;
4852
4853 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
4854 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4855
4856 Globals.bPassdbExpandExplicit = False;
4857
4858 Globals.name_cache_timeout = 660; /* In seconds */
4859
4860 Globals.bUseSpnego = True;
4861 Globals.bClientUseSpnego = True;
4862
4863 Globals.client_signing = Auto;
4864 Globals.server_signing = False;
4865
4866 Globals.bDeferSharingViolations = True;
4867 string_set(&Globals.smb_ports, SMB_PORTS);
4868
4869 Globals.bEnablePrivileges = True;
4870 Globals.bHostMSDfs = True;
4871 Globals.bASUSupport = False;
4872
4873 /* User defined shares. */
4874 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4875 smb_panic("init_globals: ENOMEM");
4876 }
4877 string_set(&Globals.szUsersharePath, s);
4878 SAFE_FREE(s);
4879 string_set(&Globals.szUsershareTemplateShare, "");
4880 Globals.iUsershareMaxShares = 0;
4881 /* By default disallow sharing of directories not owned by the sharer. */
4882 Globals.bUsershareOwnerOnly = True;
4883 /* By default disallow guest access to usershares. */
4884 Globals.bUsershareAllowGuests = False;
4885
4886 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4887
4888 /* By default no shares out of the registry */
4889 Globals.bRegistryShares = False;
4890
4891 Globals.iminreceivefile = 0;
4892}
4893
4894/*******************************************************************
4895 Convenience routine to grab string parameters into temporary memory
4896 and run standard_sub_basic on them. The buffers can be written to by
4897 callers without affecting the source string.
4898********************************************************************/
4899
4900static char *lp_string(const char *s)
4901{
4902 char *ret;
4903 TALLOC_CTX *ctx = talloc_tos();
4904
4905 /* The follow debug is useful for tracking down memory problems
4906 especially if you have an inner loop that is calling a lp_*()
4907 function that returns a string. Perhaps this debug should be
4908 present all the time? */
4909
4910#if 0
4911 DEBUG(10, ("lp_string(%s)\n", s));
4912#endif
4913
4914 ret = talloc_sub_basic(ctx,
4915 get_current_username(),
4916 current_user_info.domain,
4917 s);
4918 if (trim_char(ret, '\"', '\"')) {
4919 if (strchr(ret,'\"') != NULL) {
4920 TALLOC_FREE(ret);
4921 ret = talloc_sub_basic(ctx,
4922 get_current_username(),
4923 current_user_info.domain,
4924 s);
4925 }
4926 }
4927 return ret;
4928}
4929
4930/*
4931 In this section all the functions that are used to access the
4932 parameters from the rest of the program are defined
4933*/
4934
4935#define FN_GLOBAL_STRING(fn_name,ptr) \
4936 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4937#define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4938 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4939#define FN_GLOBAL_LIST(fn_name,ptr) \
4940 const char **fn_name(void) {return(*(const char ***)(ptr));}
4941#define FN_GLOBAL_BOOL(fn_name,ptr) \
4942 bool fn_name(void) {return(*(bool *)(ptr));}
4943#define FN_GLOBAL_CHAR(fn_name,ptr) \
4944 char fn_name(void) {return(*(char *)(ptr));}
4945#define FN_GLOBAL_INTEGER(fn_name,ptr) \
4946 int fn_name(void) {return(*(int *)(ptr));}
4947
4948#define FN_LOCAL_STRING(fn_name,val) \
4949 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
4950#define FN_LOCAL_CONST_STRING(fn_name,val) \
4951 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
4952#define FN_LOCAL_LIST(fn_name,val) \
4953 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4954#define FN_LOCAL_BOOL(fn_name,val) \
4955 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4956#define FN_LOCAL_INTEGER(fn_name,val) \
4957 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4958
4959#define FN_LOCAL_PARM_BOOL(fn_name,val) \
4960 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4961#define FN_LOCAL_PARM_INTEGER(fn_name,val) \
4962 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4963#define FN_LOCAL_PARM_STRING(fn_name,val) \
4964 char *fn_name(const struct share_params *p) {return(lp_string((LP_SNUM_OK(p->service) && ServicePtrs[(p->service)]->val) ? ServicePtrs[(p->service)]->val : sDefault.val));}
4965#define FN_LOCAL_CHAR(fn_name,val) \
4966 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4967
4968FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
4969FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
4970FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
4971FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
4972FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
4973FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
4974FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
4975FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
4976FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
4977FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
4978FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
4979FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
4980FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
4981FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
4982FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
4983FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
4984FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
4985FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
4986FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
4987FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
4988FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
4989FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
4990FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
4991FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
4992FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
4993FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
4994FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
4995FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
4996FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
4997FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
4998FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
4999FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5000FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5001FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5002FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5003FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5004FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5005FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5006FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5007FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5008FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5009FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5010FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5011FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5012FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5013FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5014static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5015FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5016/* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5017 * lp_passdb_backend() should be replace by the this macro again after
5018 * some releases.
5019 * */
5020const char *lp_passdb_backend(void)
5021{
5022 char *delim, *quote;
5023
5024 delim = strchr( Globals.szPassdbBackend, ' ');
5025 /* no space at all */
5026 if (delim == NULL) {
5027 goto out;
5028 }
5029
5030 quote = strchr(Globals.szPassdbBackend, '"');
5031 /* no quote char or non in the first part */
5032 if (quote == NULL || quote > delim) {
5033 *delim = '\0';
5034 goto warn;
5035 }
5036
5037 quote = strchr(quote+1, '"');
5038 if (quote == NULL) {
5039 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5040 goto out;
5041 } else if (*(quote+1) == '\0') {
5042 /* space, fitting quote char, and one backend only */
5043 goto out;
5044 } else {
5045 /* terminate string after the fitting quote char */
5046 *(quote+1) = '\0';
5047 }
5048
5049warn:
5050 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5051 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5052 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5053 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5054
5055out:
5056 return Globals.szPassdbBackend;
5057}
5058FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5059FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5060FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5061FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5062FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5063
5064FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5065FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5066FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5067FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5068FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5069FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5070
5071FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5072
5073FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5074FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5075FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5076
5077FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5078
5079FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5080FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5081FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5082FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5083FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5084FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5085FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5086FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5087FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5088FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5089FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5090FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5091FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5092FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5093FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5094
5095FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
5096FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
5097FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5098FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5099FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5100FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5101FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5102
5103FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5104FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5105FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5106FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5107FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5108FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5109FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5110FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5111FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5112FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5113FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5114FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5115FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5116FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5117FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5118FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5119FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5120
5121FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5122
5123FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5124FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5125FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5126FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5127FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5128FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5129FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5130FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5131FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5132FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5133FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5134FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5135FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5136FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5137FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5138FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5139FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5140FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5141FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5142FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5143FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5144FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5145FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5146FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5147FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5148FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5149FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5150FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5151FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5152FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5153FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5154FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5155static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5156FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5157FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5158FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5159FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5160FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5161FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5162FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5163FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5164FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5165FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5166FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5167FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5168FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5169FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5170FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5171FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5172FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5173FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5174FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5175FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5176FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5177FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5178FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5179FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5180FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5181FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5182FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5183FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5184FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5185FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5186FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5187FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5188FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5189FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5190FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5191FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5192FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5193FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5194FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5195FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5196FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5197FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5198FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5199FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5200FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5201FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5202FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5203FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5204FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5205FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5206FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5207FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5208FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5209static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5210FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5211FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5212FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5213FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5214FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5215FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5216FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5217FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5218FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5219
5220FN_LOCAL_STRING(lp_preexec, szPreExec)
5221FN_LOCAL_STRING(lp_postexec, szPostExec)
5222FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5223FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5224FN_LOCAL_STRING(lp_servicename, szService)
5225FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5226FN_LOCAL_STRING(lp_pathname, szPath)
5227FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5228FN_LOCAL_STRING(lp_username, szUsername)
5229FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5230FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5231FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5232FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5233FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5234FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5235FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5236FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5237FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5238FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5239FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5240FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5241FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5242FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5243FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5244FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5245FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5246static FN_LOCAL_STRING(_lp_printername, szPrintername)
5247FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5248FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5249FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5250FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5251FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5252FN_LOCAL_STRING(lp_comment, comment)
5253FN_LOCAL_STRING(lp_force_user, force_user)
5254FN_LOCAL_STRING(lp_force_group, force_group)
5255FN_LOCAL_LIST(lp_readlist, readlist)
5256FN_LOCAL_LIST(lp_writelist, writelist)
5257FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5258FN_LOCAL_STRING(lp_fstype, fstype)
5259FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5260FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5261static FN_LOCAL_STRING(lp_volume, volume)
5262FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5263FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5264FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5265FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5266FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5267FN_LOCAL_STRING(lp_dfree_command, szDfree)
5268FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5269FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5270FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5271FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5272FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5273FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5274FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5275FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5276FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5277FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5278FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5279FN_LOCAL_BOOL(lp_readonly, bRead_only)
5280FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5281FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5282FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5283FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5284FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5285FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5286FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5287FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5288FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5289FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5290FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5291FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5292FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5293FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5294FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5295FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5296FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5297FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5298FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5299FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5300FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5301FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5302FN_LOCAL_BOOL(lp_map_system, bMap_system)
5303FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5304FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5305FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5306FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5307FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5308FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5309FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5310FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5311FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5312FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5313FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5314FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5315FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5316FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5317FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5318FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5319FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5320FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5321FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5322FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5323FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5324FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5325FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5326FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5327FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5328FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5329FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5330FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5331FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5332FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5333FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5334FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5335FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5336FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5337FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5338FN_LOCAL_INTEGER(lp_printing, iPrinting)
5339FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5340FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5341FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5342FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5343FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5344FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5345FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5346FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5347FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5348FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5349FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5350FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5351FN_LOCAL_CHAR(lp_magicchar, magic_char)
5352FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5353FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5354FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5355FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5356FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5357FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5358FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5359
5360/* local prototypes */
5361
5362static int map_parameter(const char *pszParmName);
5363static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5364static bool set_boolean(bool *pb, const char *pszParmValue);
5365static const char *get_boolean(bool bool_value);
5366static int getservicebyname(const char *pszServiceName,
5367 struct service *pserviceDest);
5368static void copy_service(struct service *pserviceDest,
5369 struct service *pserviceSource,
5370 struct bitmap *pcopymapDest);
5371static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5372 void *userdata);
5373static bool do_section(const char *pszSectionName, void *userdata);
5374static void init_copymap(struct service *pservice);
5375static bool hash_a_service(const char *name, int number);
5376static void free_service_byindex(int iService);
5377static char * canonicalize_servicename(const char *name);
5378static void show_parameter(int parmIndex);
5379static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5380
5381/* This is a helper function for parametrical options support. */
5382/* It returns a pointer to parametrical option value if it exists or NULL otherwise */
5383/* Actual parametrical functions are quite simple */
5384static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
5385{
5386 bool global_section = False;
5387 char* param_key;
5388 param_opt_struct *data;
5389
5390 if (snum >= iNumServices) return NULL;
5391
5392 if (snum < 0) {
5393 data = Globals.param_opt;
5394 global_section = True;
5395 } else {
5396 data = ServicePtrs[snum]->param_opt;
5397 }
5398
5399 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5400 DEBUG(0,("asprintf failed!\n"));
5401 return NULL;
5402 }
5403
5404 while (data) {
5405 if (strcmp(data->key, param_key) == 0) {
5406 string_free(&param_key);
5407 return data;
5408 }
5409 data = data->next;
5410 }
5411
5412 if (!global_section) {
5413 /* Try to fetch the same option but from globals */
5414 /* but only if we are not already working with Globals */
5415 data = Globals.param_opt;
5416 while (data) {
5417 if (strcmp(data->key, param_key) == 0) {
5418 string_free(&param_key);
5419 return data;
5420 }
5421 data = data->next;
5422 }
5423 }
5424
5425 string_free(&param_key);
5426
5427 return NULL;
5428}
5429
5430
5431#define MISSING_PARAMETER(name) \
5432 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5433
5434/*******************************************************************
5435convenience routine to return int parameters.
5436********************************************************************/
5437static int lp_int(const char *s)
5438{
5439
5440 if (!s || !*s) {
5441 MISSING_PARAMETER(lp_int);
5442 return (-1);
5443 }
5444
5445 return (int)strtol(s, NULL, 0);
5446}
5447
5448/*******************************************************************
5449convenience routine to return unsigned long parameters.
5450********************************************************************/
5451static unsigned long lp_ulong(const char *s)
5452{
5453
5454 if (!s || !*s) {
5455 MISSING_PARAMETER(lp_ulong);
5456 return (0);
5457 }
5458
5459 return strtoul(s, NULL, 0);
5460}
5461
5462/*******************************************************************
5463convenience routine to return boolean parameters.
5464********************************************************************/
5465static bool lp_bool(const char *s)
5466{
5467 bool ret = False;
5468
5469 if (!s || !*s) {
5470 MISSING_PARAMETER(lp_bool);
5471 return False;
5472 }
5473
5474 if (!set_boolean(&ret,s)) {
5475 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5476 return False;
5477 }
5478
5479 return ret;
5480}
5481
5482/*******************************************************************
5483convenience routine to return enum parameters.
5484********************************************************************/
5485static int lp_enum(const char *s,const struct enum_list *_enum)
5486{
5487 int i;
5488
5489 if (!s || !*s || !_enum) {
5490 MISSING_PARAMETER(lp_enum);
5491 return (-1);
5492 }
5493
5494 for (i=0; _enum[i].name; i++) {
5495 if (strequal(_enum[i].name,s))
5496 return _enum[i].value;
5497 }
5498
5499 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5500 return (-1);
5501}
5502
5503#undef MISSING_PARAMETER
5504
5505/* DO NOT USE lp_parm_string ANYMORE!!!!
5506 * use lp_parm_const_string or lp_parm_talloc_string
5507 *
5508 * lp_parm_string is only used to let old modules find this symbol
5509 */
5510#undef lp_parm_string
5511 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5512 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5513{
5514 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5515}
5516
5517/* Return parametric option from a given service. Type is a part of option before ':' */
5518/* Parametric option has following syntax: 'Type: option = value' */
5519/* the returned value is talloced on the talloc_tos() */
5520char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5521{
5522 param_opt_struct *data = get_parametrics(snum, type, option);
5523
5524 if (data == NULL||data->value==NULL) {
5525 if (def) {
5526 return lp_string(def);
5527 } else {
5528 return NULL;
5529 }
5530 }
5531
5532 return lp_string(data->value);
5533}
5534
5535/* Return parametric option from a given service. Type is a part of option before ':' */
5536/* Parametric option has following syntax: 'Type: option = value' */
5537const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5538{
5539 param_opt_struct *data = get_parametrics(snum, type, option);
5540
5541 if (data == NULL||data->value==NULL)
5542 return def;
5543
5544 return data->value;
5545}
5546
5547/* Return parametric option from a given service. Type is a part of option before ':' */
5548/* Parametric option has following syntax: 'Type: option = value' */
5549
5550const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5551{
5552 param_opt_struct *data = get_parametrics(snum, type, option);
5553
5554 if (data == NULL||data->value==NULL)
5555 return (const char **)def;
5556
5557 if (data->list==NULL) {
5558 data->list = str_list_make(NULL, data->value, NULL);
5559 }
5560
5561 return (const char **)data->list;
5562}
5563
5564/* Return parametric option from a given service. Type is a part of option before ':' */
5565/* Parametric option has following syntax: 'Type: option = value' */
5566
5567int lp_parm_int(int snum, const char *type, const char *option, int def)
5568{
5569 param_opt_struct *data = get_parametrics(snum, type, option);
5570
5571 if (data && data->value && *data->value)
5572 return lp_int(data->value);
5573
5574 return def;
5575}
5576
5577/* Return parametric option from a given service. Type is a part of option before ':' */
5578/* Parametric option has following syntax: 'Type: option = value' */
5579
5580unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5581{
5582 param_opt_struct *data = get_parametrics(snum, type, option);
5583
5584 if (data && data->value && *data->value)
5585 return lp_ulong(data->value);
5586
5587 return def;
5588}
5589
5590/* Return parametric option from a given service. Type is a part of option before ':' */
5591/* Parametric option has following syntax: 'Type: option = value' */
5592
5593bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5594{
5595 param_opt_struct *data = get_parametrics(snum, type, option);
5596
5597 if (data && data->value && *data->value)
5598 return lp_bool(data->value);
5599
5600 return def;
5601}
5602
5603/* Return parametric option from a given service. Type is a part of option before ':' */
5604/* Parametric option has following syntax: 'Type: option = value' */
5605
5606int lp_parm_enum(int snum, const char *type, const char *option,
5607 const struct enum_list *_enum, int def)
5608{
5609 param_opt_struct *data = get_parametrics(snum, type, option);
5610
5611 if (data && data->value && *data->value && _enum)
5612 return lp_enum(data->value, _enum);
5613
5614 return def;
5615}
5616
5617
5618/***************************************************************************
5619 Initialise a service to the defaults.
5620***************************************************************************/
5621
5622static void init_service(struct service *pservice)
5623{
5624 memset((char *)pservice, '\0', sizeof(struct service));
5625 copy_service(pservice, &sDefault, NULL);
5626}
5627
5628/***************************************************************************
5629 Free the dynamically allocated parts of a service struct.
5630***************************************************************************/
5631
5632static void free_service(struct service *pservice)
5633{
5634 int i;
5635 param_opt_struct *data, *pdata;
5636 if (!pservice)
5637 return;
5638
5639 if (pservice->szService)
5640 DEBUG(5, ("free_service: Freeing service %s\n",
5641 pservice->szService));
5642
5643 string_free(&pservice->szService);
5644 bitmap_free(pservice->copymap);
5645
5646 for (i = 0; parm_table[i].label; i++) {
5647 if ((parm_table[i].type == P_STRING ||
5648 parm_table[i].type == P_USTRING) &&
5649 parm_table[i].p_class == P_LOCAL)
5650 string_free((char **)
5651 (((char *)pservice) +
5652 PTR_DIFF(parm_table[i].ptr, &sDefault)));
5653 else if (parm_table[i].type == P_LIST &&
5654 parm_table[i].p_class == P_LOCAL)
5655 TALLOC_FREE(*((char ***)
5656 (((char *)pservice) +
5657 PTR_DIFF(parm_table[i].ptr,
5658 &sDefault))));
5659 }
5660
5661 data = pservice->param_opt;
5662 if (data)
5663 DEBUG(5,("Freeing parametrics:\n"));
5664 while (data) {
5665 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5666 string_free(&data->key);
5667 string_free(&data->value);
5668 TALLOC_FREE(data->list);
5669 pdata = data->next;
5670 SAFE_FREE(data);
5671 data = pdata;
5672 }
5673
5674 ZERO_STRUCTP(pservice);
5675}
5676
5677
5678/***************************************************************************
5679 remove a service indexed in the ServicePtrs array from the ServiceHash
5680 and free the dynamically allocated parts
5681***************************************************************************/
5682
5683static void free_service_byindex(int idx)
5684{
5685 if ( !LP_SNUM_OK(idx) )
5686 return;
5687
5688 ServicePtrs[idx]->valid = False;
5689 invalid_services[num_invalid_services++] = idx;
5690
5691 /* we have to cleanup the hash record */
5692
5693 if (ServicePtrs[idx]->szService) {
5694 char *canon_name = canonicalize_servicename(
5695 ServicePtrs[idx]->szService );
5696
5697 dbwrap_delete_bystring(ServiceHash, canon_name );
5698 TALLOC_FREE(canon_name);
5699 }
5700
5701 free_service(ServicePtrs[idx]);
5702}
5703
5704/***************************************************************************
5705 Add a new service to the services array initialising it with the given
5706 service.
5707***************************************************************************/
5708
5709static int add_a_service(const struct service *pservice, const char *name)
5710{
5711 int i;
5712 struct service tservice;
5713 int num_to_alloc = iNumServices + 1;
5714 param_opt_struct *data, *pdata;
5715
5716 tservice = *pservice;
5717
5718 /* it might already exist */
5719 if (name) {
5720 i = getservicebyname(name, NULL);
5721 if (i >= 0) {
5722 /* Clean all parametric options for service */
5723 /* They will be added during parsing again */
5724 data = ServicePtrs[i]->param_opt;
5725 while (data) {
5726 string_free(&data->key);
5727 string_free(&data->value);
5728 TALLOC_FREE(data->list);
5729 pdata = data->next;
5730 SAFE_FREE(data);
5731 data = pdata;
5732 }
5733 ServicePtrs[i]->param_opt = NULL;
5734 return (i);
5735 }
5736 }
5737
5738 /* find an invalid one */
5739 i = iNumServices;
5740 if (num_invalid_services > 0) {
5741 i = invalid_services[--num_invalid_services];
5742 }
5743
5744 /* if not, then create one */
5745 if (i == iNumServices) {
5746 struct service **tsp;
5747 int *tinvalid;
5748
5749 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5750 if (tsp == NULL) {
5751 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5752 return (-1);
5753 }
5754 ServicePtrs = tsp;
5755 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5756 if (!ServicePtrs[iNumServices]) {
5757 DEBUG(0,("add_a_service: out of memory!\n"));
5758 return (-1);
5759 }
5760 iNumServices++;
5761
5762 /* enlarge invalid_services here for now... */
5763 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5764 num_to_alloc);
5765 if (tinvalid == NULL) {
5766 DEBUG(0,("add_a_service: failed to enlarge "
5767 "invalid_services!\n"));
5768 return (-1);
5769 }
5770 invalid_services = tinvalid;
5771 } else {
5772 free_service_byindex(i);
5773 }
5774
5775 ServicePtrs[i]->valid = True;
5776
5777 init_service(ServicePtrs[i]);
5778 copy_service(ServicePtrs[i], &tservice, NULL);
5779 if (name)
5780 string_set(&ServicePtrs[i]->szService, name);
5781
5782 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5783 i, ServicePtrs[i]->szService));
5784
5785 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5786 return (-1);
5787 }
5788
5789 return (i);
5790}
5791
5792/***************************************************************************
5793 Convert a string to uppercase and remove whitespaces.
5794***************************************************************************/
5795
5796static char *canonicalize_servicename(const char *src)
5797{
5798 char *result;
5799
5800 if ( !src ) {
5801 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5802 return NULL;
5803 }
5804
5805 result = talloc_strdup(talloc_tos(), src);
5806 SMB_ASSERT(result != NULL);
5807
5808 strlower_m(result);
5809 return result;
5810}
5811
5812/***************************************************************************
5813 Add a name/index pair for the services array to the hash table.
5814***************************************************************************/
5815
5816static bool hash_a_service(const char *name, int idx)
5817{
5818 char *canon_name;
5819
5820 if ( !ServiceHash ) {
5821 DEBUG(10,("hash_a_service: creating servicehash\n"));
5822 ServiceHash = db_open_rbt(NULL);
5823 if ( !ServiceHash ) {
5824 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5825 return False;
5826 }
5827 }
5828
5829 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5830 idx, name));
5831
5832 canon_name = canonicalize_servicename( name );
5833
5834 dbwrap_store_bystring(ServiceHash, canon_name,
5835 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5836 TDB_REPLACE);
5837
5838 TALLOC_FREE(canon_name);
5839
5840 return True;
5841}
5842
5843/***************************************************************************
5844 Add a new home service, with the specified home directory, defaults coming
5845 from service ifrom.
5846***************************************************************************/
5847
5848bool lp_add_home(const char *pszHomename, int iDefaultService,
5849 const char *user, const char *pszHomedir)
5850{
5851 int i;
5852
5853 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5854
5855 if (i < 0)
5856 return (False);
5857
5858 if (!(*(ServicePtrs[iDefaultService]->szPath))
5859 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5860 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5861 }
5862
5863 if (!(*(ServicePtrs[i]->comment))) {
5864 char *comment = NULL;
5865 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5866 return false;
5867 }
5868 string_set(&ServicePtrs[i]->comment, comment);
5869 SAFE_FREE(comment);
5870 }
5871
5872 /* set the browseable flag from the global default */
5873
5874 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5875
5876 ServicePtrs[i]->autoloaded = True;
5877
5878 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5879 user, ServicePtrs[i]->szPath ));
5880
5881 return (True);
5882}
5883
5884/***************************************************************************
5885 Add a new service, based on an old one.
5886***************************************************************************/
5887
5888int lp_add_service(const char *pszService, int iDefaultService)
5889{
5890 if (iDefaultService < 0) {
5891 return add_a_service(&sDefault, pszService);
5892 }
5893
5894 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5895}
5896
5897/***************************************************************************
5898 Add the IPC service.
5899***************************************************************************/
5900
5901static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5902{
5903 char *comment = NULL;
5904 int i = add_a_service(&sDefault, ipc_name);
5905
5906 if (i < 0)
5907 return (False);
5908
5909 if (asprintf(&comment, "IPC Service (%s)",
5910 Globals.szServerString) < 0) {
5911 return (False);
5912 }
5913
5914 string_set(&ServicePtrs[i]->szPath, tmpdir());
5915 string_set(&ServicePtrs[i]->szUsername, "");
5916 string_set(&ServicePtrs[i]->comment, comment);
5917 string_set(&ServicePtrs[i]->fstype, "IPC");
5918 ServicePtrs[i]->iMaxConnections = 0;
5919 ServicePtrs[i]->bAvailable = True;
5920 ServicePtrs[i]->bRead_only = True;
5921 ServicePtrs[i]->bGuest_only = False;
5922 ServicePtrs[i]->bAdministrative_share = True;
5923 ServicePtrs[i]->bGuest_ok = guest_ok;
5924 ServicePtrs[i]->bPrint_ok = False;
5925 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5926
5927 DEBUG(3, ("adding IPC service\n"));
5928
5929 SAFE_FREE(comment);
5930 return (True);
5931}
5932
5933/***************************************************************************
5934 Add a new printer service, with defaults coming from service iFrom.
5935***************************************************************************/
5936
5937bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5938{
5939 const char *comment = "From Printcap";
5940 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5941
5942 if (i < 0)
5943 return (False);
5944
5945 /* note that we do NOT default the availability flag to True - */
5946 /* we take it from the default service passed. This allows all */
5947 /* dynamic printers to be disabled by disabling the [printers] */
5948 /* entry (if/when the 'available' keyword is implemented!). */
5949
5950 /* the printer name is set to the service name. */
5951 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5952 string_set(&ServicePtrs[i]->comment, comment);
5953
5954 /* set the browseable flag from the gloabl default */
5955 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5956
5957 /* Printers cannot be read_only. */
5958 ServicePtrs[i]->bRead_only = False;
5959 /* No share modes on printer services. */
5960 ServicePtrs[i]->bShareModes = False;
5961 /* No oplocks on printer services. */
5962 ServicePtrs[i]->bOpLocks = False;
5963 /* Printer services must be printable. */
5964 ServicePtrs[i]->bPrint_ok = True;
5965
5966 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5967
5968 return (True);
5969}
5970
5971
5972/***************************************************************************
5973 Check whether the given parameter name is valid.
5974 Parametric options (names containing a colon) are considered valid.
5975***************************************************************************/
5976
5977bool lp_parameter_is_valid(const char *pszParmName)
5978{
5979 return ((map_parameter(pszParmName) != -1) ||
5980 (strchr(pszParmName, ':') != NULL));
5981}
5982
5983/***************************************************************************
5984 Check whether the given name is the name of a global parameter.
5985 Returns True for strings belonging to parameters of class
5986 P_GLOBAL, False for all other strings, also for parametric options
5987 and strings not belonging to any option.
5988***************************************************************************/
5989
5990bool lp_parameter_is_global(const char *pszParmName)
5991{
5992 int num = map_parameter(pszParmName);
5993
5994 if (num >= 0) {
5995 return (parm_table[num].p_class == P_GLOBAL);
5996 }
5997
5998 return False;
5999}
6000
6001/**************************************************************************
6002 Check whether the given name is the canonical name of a parameter.
6003 Returns False if it is not a valid parameter Name.
6004 For parametric options, True is returned.
6005**************************************************************************/
6006
6007bool lp_parameter_is_canonical(const char *parm_name)
6008{
6009 if (!lp_parameter_is_valid(parm_name)) {
6010 return False;
6011 }
6012
6013 return (map_parameter(parm_name) ==
6014 map_parameter_canonical(parm_name, NULL));
6015}
6016
6017/**************************************************************************
6018 Determine the canonical name for a parameter.
6019 Indicate when it is an inverse (boolean) synonym instead of a
6020 "usual" synonym.
6021**************************************************************************/
6022
6023bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6024 bool *inverse)
6025{
6026 int num;
6027
6028 if (!lp_parameter_is_valid(parm_name)) {
6029 *canon_parm = NULL;
6030 return False;
6031 }
6032
6033 num = map_parameter_canonical(parm_name, inverse);
6034 if (num < 0) {
6035 /* parametric option */
6036 *canon_parm = parm_name;
6037 } else {
6038 *canon_parm = parm_table[num].label;
6039 }
6040
6041 return True;
6042
6043}
6044
6045/**************************************************************************
6046 Determine the canonical name for a parameter.
6047 Turn the value given into the inverse boolean expression when
6048 the synonym is an invers boolean synonym.
6049
6050 Return True if parm_name is a valid parameter name and
6051 in case it is an invers boolean synonym, if the val string could
6052 successfully be converted to the reverse bool.
6053 Return false in all other cases.
6054**************************************************************************/
6055
6056bool lp_canonicalize_parameter_with_value(const char *parm_name,
6057 const char *val,
6058 const char **canon_parm,
6059 const char **canon_val)
6060{
6061 int num;
6062 bool inverse;
6063
6064 if (!lp_parameter_is_valid(parm_name)) {
6065 *canon_parm = NULL;
6066 *canon_val = NULL;
6067 return False;
6068 }
6069
6070 num = map_parameter_canonical(parm_name, &inverse);
6071 if (num < 0) {
6072 /* parametric option */
6073 *canon_parm = parm_name;
6074 *canon_val = val;
6075 } else {
6076 *canon_parm = parm_table[num].label;
6077 if (inverse) {
6078 if (!lp_invert_boolean(val, canon_val)) {
6079 *canon_val = NULL;
6080 return False;
6081 }
6082 } else {
6083 *canon_val = val;
6084 }
6085 }
6086
6087 return True;
6088}
6089
6090/***************************************************************************
6091 Map a parameter's string representation to something we can use.
6092 Returns False if the parameter string is not recognised, else TRUE.
6093***************************************************************************/
6094
6095static int map_parameter(const char *pszParmName)
6096{
6097 int iIndex;
6098
6099 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6100 return (-1);
6101
6102 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6103 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6104 return (iIndex);
6105
6106 /* Warn only if it isn't parametric option */
6107 if (strchr(pszParmName, ':') == NULL)
6108 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6109 /* We do return 'fail' for parametric options as well because they are
6110 stored in different storage
6111 */
6112 return (-1);
6113}
6114
6115/***************************************************************************
6116 Map a parameter's string representation to the index of the canonical
6117 form of the parameter (it might be a synonym).
6118 Returns -1 if the parameter string is not recognised.
6119***************************************************************************/
6120
6121static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6122{
6123 int parm_num, canon_num;
6124 bool loc_inverse = False;
6125
6126 parm_num = map_parameter(pszParmName);
6127 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6128 /* invalid, parametric or no canidate for synonyms ... */
6129 goto done;
6130 }
6131
6132 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6133 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6134 parm_num = canon_num;
6135 goto done;
6136 }
6137 }
6138
6139done:
6140 if (inverse != NULL) {
6141 *inverse = loc_inverse;
6142 }
6143 return parm_num;
6144}
6145
6146/***************************************************************************
6147 return true if parameter number parm1 is a synonym of parameter
6148 number parm2 (parm2 being the principal name).
6149 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6150 False otherwise.
6151***************************************************************************/
6152
6153static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6154{
6155 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6156 (parm_table[parm1].flags & FLAG_HIDE) &&
6157 !(parm_table[parm2].flags & FLAG_HIDE))
6158 {
6159 if (inverse != NULL) {
6160 if ((parm_table[parm1].type == P_BOOLREV) &&
6161 (parm_table[parm2].type == P_BOOL))
6162 {
6163 *inverse = True;
6164 } else {
6165 *inverse = False;
6166 }
6167 }
6168 return True;
6169 }
6170 return False;
6171}
6172
6173/***************************************************************************
6174 Show one parameter's name, type, [values,] and flags.
6175 (helper functions for show_parameter_list)
6176***************************************************************************/
6177
6178static void show_parameter(int parmIndex)
6179{
6180 int enumIndex, flagIndex;
6181 int parmIndex2;
6182 bool hadFlag;
6183 bool hadSyn;
6184 bool inverse;
6185 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6186 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6187 "P_ENUM", "P_SEP"};
6188 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6189 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6190 FLAG_HIDE, FLAG_DOS_STRING};
6191 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6192 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6193 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6194
6195 printf("%s=%s", parm_table[parmIndex].label,
6196 type[parm_table[parmIndex].type]);
6197 if (parm_table[parmIndex].type == P_ENUM) {
6198 printf(",");
6199 for (enumIndex=0;
6200 parm_table[parmIndex].enum_list[enumIndex].name;
6201 enumIndex++)
6202 {
6203 printf("%s%s",
6204 enumIndex ? "|" : "",
6205 parm_table[parmIndex].enum_list[enumIndex].name);
6206 }
6207 }
6208 printf(",");
6209 hadFlag = False;
6210 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6211 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6212 printf("%s%s",
6213 hadFlag ? "|" : "",
6214 flag_names[flagIndex]);
6215 hadFlag = True;
6216 }
6217 }
6218
6219 /* output synonyms */
6220 hadSyn = False;
6221 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6222 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6223 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6224 parm_table[parmIndex2].label);
6225 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6226 if (!hadSyn) {
6227 printf(" (synonyms: ");
6228 hadSyn = True;
6229 } else {
6230 printf(", ");
6231 }
6232 printf("%s%s", parm_table[parmIndex2].label,
6233 inverse ? "[i]" : "");
6234 }
6235 }
6236 if (hadSyn) {
6237 printf(")");
6238 }
6239
6240 printf("\n");
6241}
6242
6243/***************************************************************************
6244 Show all parameter's name, type, [values,] and flags.
6245***************************************************************************/
6246
6247void show_parameter_list(void)
6248{
6249 int classIndex, parmIndex;
6250 const char *section_names[] = { "local", "global", NULL};
6251
6252 for (classIndex=0; section_names[classIndex]; classIndex++) {
6253 printf("[%s]\n", section_names[classIndex]);
6254 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6255 if (parm_table[parmIndex].p_class == classIndex) {
6256 show_parameter(parmIndex);
6257 }
6258 }
6259 }
6260}
6261
6262/***************************************************************************
6263 Set a boolean variable from the text value stored in the passed string.
6264 Returns True in success, False if the passed string does not correctly
6265 represent a boolean.
6266***************************************************************************/
6267
6268static bool set_boolean(bool *pb, const char *pszParmValue)
6269{
6270 bool bRetval;
6271 bool value;
6272
6273 bRetval = True;
6274 value = False;
6275 if (strwicmp(pszParmValue, "yes") == 0 ||
6276 strwicmp(pszParmValue, "true") == 0 ||
6277 strwicmp(pszParmValue, "1") == 0)
6278 value = True;
6279 else if (strwicmp(pszParmValue, "no") == 0 ||
6280 strwicmp(pszParmValue, "False") == 0 ||
6281 strwicmp(pszParmValue, "0") == 0)
6282 value = False;
6283 else {
6284 DEBUG(2,
6285 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6286 pszParmValue));
6287 bRetval = False;
6288 }
6289
6290 if ((pb != NULL) && (bRetval != False)) {
6291 *pb = value;
6292 }
6293
6294 return (bRetval);
6295}
6296
6297
6298/***************************************************************************
6299 Check if a given string correctly represents a boolean value.
6300***************************************************************************/
6301
6302bool lp_string_is_valid_boolean(const char *parm_value)
6303{
6304 return set_boolean(NULL, parm_value);
6305}
6306
6307/***************************************************************************
6308 Get the standard string representation of a boolean value ("yes" or "no")
6309***************************************************************************/
6310
6311static const char *get_boolean(bool bool_value)
6312{
6313 static const char *yes_str = "yes";
6314 static const char *no_str = "no";
6315
6316 return (bool_value ? yes_str : no_str);
6317}
6318
6319/***************************************************************************
6320 Provide the string of the negated boolean value associated to the boolean
6321 given as a string. Returns False if the passed string does not correctly
6322 represent a boolean.
6323***************************************************************************/
6324
6325bool lp_invert_boolean(const char *str, const char **inverse_str)
6326{
6327 bool val;
6328
6329 if (!set_boolean(&val, str)) {
6330 return False;
6331 }
6332
6333 *inverse_str = get_boolean(!val);
6334 return True;
6335}
6336
6337/***************************************************************************
6338 Provide the canonical string representation of a boolean value given
6339 as a string. Return True on success, False if the string given does
6340 not correctly represent a boolean.
6341***************************************************************************/
6342
6343bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6344{
6345 bool val;
6346
6347 if (!set_boolean(&val, str)) {
6348 return False;
6349 }
6350
6351 *canon_str = get_boolean(val);
6352 return True;
6353}
6354
6355/***************************************************************************
6356Find a service by name. Otherwise works like get_service.
6357***************************************************************************/
6358
6359static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6360{
6361 int iService = -1;
6362 char *canon_name;
6363 TDB_DATA data;
6364
6365 if (ServiceHash == NULL) {
6366 return -1;
6367 }
6368
6369 canon_name = canonicalize_servicename(pszServiceName);
6370
6371 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6372
6373 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6374 iService = *(int *)data.dptr;
6375 }
6376
6377 TALLOC_FREE(canon_name);
6378
6379 if ((iService != -1) && (LP_SNUM_OK(iService))
6380 && (pserviceDest != NULL)) {
6381 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6382 }
6383
6384 return (iService);
6385}
6386
6387/***************************************************************************
6388 Copy a service structure to another.
6389 If pcopymapDest is NULL then copy all fields
6390***************************************************************************/
6391
6392static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6393 struct bitmap *pcopymapDest)
6394{
6395 int i;
6396 bool bcopyall = (pcopymapDest == NULL);
6397 param_opt_struct *data, *pdata, *paramo;
6398 bool not_added;
6399
6400 for (i = 0; parm_table[i].label; i++)
6401 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6402 (bcopyall || bitmap_query(pcopymapDest,i))) {
6403 void *def_ptr = parm_table[i].ptr;
6404 void *src_ptr =
6405 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6406 &sDefault);
6407 void *dest_ptr =
6408 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6409 &sDefault);
6410
6411 switch (parm_table[i].type) {
6412 case P_BOOL:
6413 case P_BOOLREV:
6414 *(bool *)dest_ptr = *(bool *)src_ptr;
6415 break;
6416
6417 case P_INTEGER:
6418 case P_ENUM:
6419 case P_OCTAL:
6420 *(int *)dest_ptr = *(int *)src_ptr;
6421 break;
6422
6423 case P_CHAR:
6424 *(char *)dest_ptr = *(char *)src_ptr;
6425 break;
6426
6427 case P_STRING:
6428 string_set((char **)dest_ptr,
6429 *(char **)src_ptr);
6430 break;
6431
6432 case P_USTRING:
6433 string_set((char **)dest_ptr,
6434 *(char **)src_ptr);
6435 strupper_m(*(char **)dest_ptr);
6436 break;
6437 case P_LIST:
6438 TALLOC_FREE(*((char ***)dest_ptr));
6439 str_list_copy(NULL, (char ***)dest_ptr,
6440 *(const char ***)src_ptr);
6441 break;
6442 default:
6443 break;
6444 }
6445 }
6446
6447 if (bcopyall) {
6448 init_copymap(pserviceDest);
6449 if (pserviceSource->copymap)
6450 bitmap_copy(pserviceDest->copymap,
6451 pserviceSource->copymap);
6452 }
6453
6454 data = pserviceSource->param_opt;
6455 while (data) {
6456 not_added = True;
6457 pdata = pserviceDest->param_opt;
6458 /* Traverse destination */
6459 while (pdata) {
6460 /* If we already have same option, override it */
6461 if (strcmp(pdata->key, data->key) == 0) {
6462 string_free(&pdata->value);
6463 TALLOC_FREE(data->list);
6464 pdata->value = SMB_STRDUP(data->value);
6465 not_added = False;
6466 break;
6467 }
6468 pdata = pdata->next;
6469 }
6470 if (not_added) {
6471 paramo = SMB_XMALLOC_P(param_opt_struct);
6472 paramo->key = SMB_STRDUP(data->key);
6473 paramo->value = SMB_STRDUP(data->value);
6474 paramo->list = NULL;
6475 DLIST_ADD(pserviceDest->param_opt, paramo);
6476 }
6477 data = data->next;
6478 }
6479}
6480
6481/***************************************************************************
6482Check a service for consistency. Return False if the service is in any way
6483incomplete or faulty, else True.
6484***************************************************************************/
6485
6486bool service_ok(int iService)
6487{
6488 bool bRetval;
6489
6490 bRetval = True;
6491 if (ServicePtrs[iService]->szService[0] == '\0') {
6492 DEBUG(0, ("The following message indicates an internal error:\n"));
6493 DEBUG(0, ("No service name in service entry.\n"));
6494 bRetval = False;
6495 }
6496
6497 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6498 /* I can't see why you'd want a non-printable printer service... */
6499 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6500 if (!ServicePtrs[iService]->bPrint_ok) {
6501 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6502 ServicePtrs[iService]->szService));
6503 ServicePtrs[iService]->bPrint_ok = True;
6504 }
6505 /* [printers] service must also be non-browsable. */
6506 if (ServicePtrs[iService]->bBrowseable)
6507 ServicePtrs[iService]->bBrowseable = False;
6508 }
6509
6510 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6511 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6512 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6513 ) {
6514 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6515 ServicePtrs[iService]->szService));
6516 ServicePtrs[iService]->bAvailable = False;
6517 }
6518
6519 /* If a service is flagged unavailable, log the fact at level 1. */
6520 if (!ServicePtrs[iService]->bAvailable)
6521 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6522 ServicePtrs[iService]->szService));
6523
6524 return (bRetval);
6525}
6526
6527static struct smbconf_ctx *lp_smbconf_ctx(void)
6528{
6529 WERROR werr;
6530 static struct smbconf_ctx *conf_ctx = NULL;
6531
6532 if (conf_ctx == NULL) {
6533 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6534 if (!W_ERROR_IS_OK(werr)) {
6535 DEBUG(1, ("error initializing registry configuration: "
6536 "%s\n", dos_errstr(werr)));
6537 conf_ctx = NULL;
6538 }
6539 }
6540
6541 return conf_ctx;
6542}
6543
6544static bool process_registry_service(struct smbconf_service *service)
6545{
6546 uint32_t count;
6547 bool ret;
6548
6549 if (service == NULL) {
6550 return false;
6551 }
6552
6553 ret = do_section(service->name, NULL);
6554 if (ret != true) {
6555 return false;
6556 }
6557 for (count = 0; count < service->num_params; count++) {
6558 ret = do_parameter(service->param_names[count],
6559 service->param_values[count],
6560 NULL);
6561 if (ret != true) {
6562 return false;
6563 }
6564 }
6565 return true;
6566}
6567
6568/*
6569 * process_registry_globals
6570 */
6571static bool process_registry_globals(void)
6572{
6573 WERROR werr;
6574 struct smbconf_service *service = NULL;
6575 TALLOC_CTX *mem_ctx = talloc_stackframe();
6576 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6577 bool ret = false;
6578
6579 if (conf_ctx == NULL) {
6580 goto done;
6581 }
6582
6583 ret = do_parameter("registry shares", "yes", NULL);
6584 if (!ret) {
6585 goto done;
6586 }
6587
6588 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6589 /* nothing to read from the registry yet but make sure lp_load
6590 * doesn't return false */
6591 ret = true;
6592 goto done;
6593 }
6594
6595 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6596 if (!W_ERROR_IS_OK(werr)) {
6597 goto done;
6598 }
6599
6600 ret = process_registry_service(service);
6601 if (!ret) {
6602 goto done;
6603 }
6604
6605 /* store the csn */
6606 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6607
6608done:
6609 TALLOC_FREE(mem_ctx);
6610 return ret;
6611}
6612
6613static bool process_registry_shares(void)
6614{
6615 WERROR werr;
6616 uint32_t count;
6617 struct smbconf_service **service = NULL;
6618 uint32_t num_shares = 0;
6619 TALLOC_CTX *mem_ctx = talloc_stackframe();
6620 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6621 bool ret = false;
6622
6623 if (conf_ctx == NULL) {
6624 goto done;
6625 }
6626
6627 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6628 if (!W_ERROR_IS_OK(werr)) {
6629 goto done;
6630 }
6631
6632 ret = true;
6633
6634 for (count = 0; count < num_shares; count++) {
6635 if (strequal(service[count]->name, GLOBAL_NAME)) {
6636 continue;
6637 }
6638 ret = process_registry_service(service[count]);
6639 if (!ret) {
6640 goto done;
6641 }
6642 }
6643
6644 /* store the csn */
6645 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6646
6647done:
6648 TALLOC_FREE(mem_ctx);
6649 return ret;
6650}
6651
6652static struct file_lists {
6653 struct file_lists *next;
6654 char *name;
6655 char *subfname;
6656 time_t modtime;
6657} *file_lists = NULL;
6658
6659/*******************************************************************
6660 Keep a linked list of all config files so we know when one has changed
6661 it's date and needs to be reloaded.
6662********************************************************************/
6663
6664static void add_to_file_list(const char *fname, const char *subfname)
6665{
6666 struct file_lists *f = file_lists;
6667
6668 while (f) {
6669 if (f->name && !strcmp(f->name, fname))
6670 break;
6671 f = f->next;
6672 }
6673
6674 if (!f) {
6675 f = SMB_MALLOC_P(struct file_lists);
6676 if (!f)
6677 return;
6678 f->next = file_lists;
6679 f->name = SMB_STRDUP(fname);
6680 if (!f->name) {
6681 SAFE_FREE(f);
6682 return;
6683 }
6684 f->subfname = SMB_STRDUP(subfname);
6685 if (!f->subfname) {
6686 SAFE_FREE(f);
6687 return;
6688 }
6689 file_lists = f;
6690 f->modtime = file_modtime(subfname);
6691 } else {
6692 time_t t = file_modtime(subfname);
6693 if (t)
6694 f->modtime = t;
6695 }
6696}
6697
6698/**
6699 * Utility function for outsiders to check if we're running on registry.
6700 */
6701bool lp_config_backend_is_registry(void)
6702{
6703 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6704}
6705
6706/**
6707 * Utility function to check if the config backend is FILE.
6708 */
6709bool lp_config_backend_is_file(void)
6710{
6711 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6712}
6713
6714/*******************************************************************
6715 Check if a config file has changed date.
6716********************************************************************/
6717
6718bool lp_file_list_changed(void)
6719{
6720 struct file_lists *f = file_lists;
6721
6722 DEBUG(6, ("lp_file_list_changed()\n"));
6723
6724 if (lp_config_backend_is_registry()) {
6725 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6726
6727 if (conf_ctx == NULL) {
6728 return false;
6729 }
6730 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6731 DEBUGADD(6, ("registry config changed\n"));
6732 return true;
6733 }
6734 }
6735
6736 while (f) {
6737 char *n2 = NULL;
6738 time_t mod_time;
6739
6740 n2 = alloc_sub_basic(get_current_username(),
6741 current_user_info.domain,
6742 f->name);
6743 if (!n2) {
6744 return false;
6745 }
6746 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6747 f->name, n2, ctime(&f->modtime)));
6748
6749 mod_time = file_modtime(n2);
6750
6751 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6752 DEBUGADD(6,
6753 ("file %s modified: %s\n", n2,
6754 ctime(&mod_time)));
6755 f->modtime = mod_time;
6756 SAFE_FREE(f->subfname);
6757 f->subfname = n2; /* Passing ownership of
6758 return from alloc_sub_basic
6759 above. */
6760 return true;
6761 }
6762 SAFE_FREE(n2);
6763 f = f->next;
6764 }
6765 return (False);
6766}
6767
6768
6769/***************************************************************************
6770 Run standard_sub_basic on netbios name... needed because global_myname
6771 is not accessed through any lp_ macro.
6772 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6773***************************************************************************/
6774
6775static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6776{
6777 bool ret;
6778 char *netbios_name = alloc_sub_basic(get_current_username(),
6779 current_user_info.domain,
6780 pszParmValue);
6781
6782 ret = set_global_myname(netbios_name);
6783 SAFE_FREE(netbios_name);
6784 string_set(&Globals.szNetbiosName,global_myname());
6785
6786 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6787 global_myname()));
6788
6789 return ret;
6790}
6791
6792static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6793{
6794 if (strcmp(*ptr, pszParmValue) != 0) {
6795 string_set(ptr, pszParmValue);
6796 init_iconv();
6797 }
6798 return True;
6799}
6800
6801
6802
6803static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6804{
6805 bool ret;
6806
6807 ret = set_global_myworkgroup(pszParmValue);
6808 string_set(&Globals.szWorkgroup,lp_workgroup());
6809
6810 return ret;
6811}
6812
6813static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6814{
6815 bool ret;
6816
6817 ret = set_global_scope(pszParmValue);
6818 string_set(&Globals.szNetbiosScope,global_scope());
6819
6820 return ret;
6821}
6822
6823static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6824{
6825 TALLOC_FREE(Globals.szNetbiosAliases);
6826 Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6827 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6828}
6829
6830/***************************************************************************
6831 Handle the include operation.
6832***************************************************************************/
6833static bool bAllowIncludeRegistry = true;
6834
6835static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6836{
6837 char *fname;
6838
6839 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6840 if (!bAllowIncludeRegistry) {
6841 return true;
6842 }
6843 if (bInGlobalSection) {
6844 return process_registry_globals();
6845 } else {
6846 DEBUG(1, ("\"include = registry\" only effective "
6847 "in %s section\n", GLOBAL_NAME));
6848 return false;
6849 }
6850 }
6851
6852 fname = alloc_sub_basic(get_current_username(),
6853 current_user_info.domain,
6854 pszParmValue);
6855
6856 add_to_file_list(pszParmValue, fname);
6857
6858 string_set(ptr, fname);
6859
6860 if (file_exist(fname, NULL)) {
6861 bool ret = pm_process(fname, do_section, do_parameter, NULL);
6862 SAFE_FREE(fname);
6863 return ret;
6864 }
6865
6866 DEBUG(2, ("Can't find include file %s\n", fname));
6867 SAFE_FREE(fname);
6868 return false;
6869}
6870
6871/***************************************************************************
6872 Handle the interpretation of the copy parameter.
6873***************************************************************************/
6874
6875static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6876{
6877 bool bRetval;
6878 int iTemp;
6879 struct service serviceTemp;
6880
6881 string_set(ptr, pszParmValue);
6882
6883 init_service(&serviceTemp);
6884
6885 bRetval = False;
6886
6887 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6888
6889 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6890 if (iTemp == iServiceIndex) {
6891 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6892 } else {
6893 copy_service(ServicePtrs[iServiceIndex],
6894 &serviceTemp,
6895 ServicePtrs[iServiceIndex]->copymap);
6896 bRetval = True;
6897 }
6898 } else {
6899 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6900 bRetval = False;
6901 }
6902
6903 free_service(&serviceTemp);
6904 return (bRetval);
6905}
6906
6907static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6908{
6909 Globals.ldap_debug_level = lp_int(pszParmValue);
6910 init_ldap_debugging();
6911 return true;
6912}
6913
6914/***************************************************************************
6915 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6916 parameters is:
6917
6918 [global]
6919
6920 idmap uid = 1000-1999
6921 idmap gid = 700-899
6922
6923 We only do simple parsing checks here. The strings are parsed into useful
6924 structures in the idmap daemon code.
6925
6926***************************************************************************/
6927
6928/* Some lp_ routines to return idmap [ug]id information */
6929
6930static uid_t idmap_uid_low, idmap_uid_high;
6931static gid_t idmap_gid_low, idmap_gid_high;
6932
6933bool lp_idmap_uid(uid_t *low, uid_t *high)
6934{
6935 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6936 return False;
6937
6938 if (low)
6939 *low = idmap_uid_low;
6940
6941 if (high)
6942 *high = idmap_uid_high;
6943
6944 return True;
6945}
6946
6947bool lp_idmap_gid(gid_t *low, gid_t *high)
6948{
6949 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6950 return False;
6951
6952 if (low)
6953 *low = idmap_gid_low;
6954
6955 if (high)
6956 *high = idmap_gid_high;
6957
6958 return True;
6959}
6960
6961/* Do some simple checks on "idmap [ug]id" parameter values */
6962
6963static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6964{
6965 uint32 low, high;
6966
6967 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6968 return False;
6969
6970 /* Parse OK */
6971
6972 string_set(ptr, pszParmValue);
6973
6974 idmap_uid_low = low;
6975 idmap_uid_high = high;
6976
6977 return True;
6978}
6979
6980static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6981{
6982 uint32 low, high;
6983
6984 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6985 return False;
6986
6987 /* Parse OK */
6988
6989 string_set(ptr, pszParmValue);
6990
6991 idmap_gid_low = low;
6992 idmap_gid_high = high;
6993
6994 return True;
6995}
6996
6997/***************************************************************************
6998 Handle the DEBUG level list.
6999***************************************************************************/
7000
7001static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7002{
7003 string_set(ptr, pszParmValueIn);
7004 return debug_parse_levels(pszParmValueIn);
7005}
7006
7007/***************************************************************************
7008 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7009***************************************************************************/
7010
7011static const char *append_ldap_suffix( const char *str )
7012{
7013 const char *suffix_string;
7014
7015
7016 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7017 Globals.szLdapSuffix );
7018 if ( !suffix_string ) {
7019 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7020 return "";
7021 }
7022
7023 return suffix_string;
7024}
7025
7026const char *lp_ldap_machine_suffix(void)
7027{
7028 if (Globals.szLdapMachineSuffix[0])
7029 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7030
7031 return lp_string(Globals.szLdapSuffix);
7032}
7033
7034const char *lp_ldap_user_suffix(void)
7035{
7036 if (Globals.szLdapUserSuffix[0])
7037 return append_ldap_suffix(Globals.szLdapUserSuffix);
7038
7039 return lp_string(Globals.szLdapSuffix);
7040}
7041
7042const char *lp_ldap_group_suffix(void)
7043{
7044 if (Globals.szLdapGroupSuffix[0])
7045 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7046
7047 return lp_string(Globals.szLdapSuffix);
7048}
7049
7050const char *lp_ldap_idmap_suffix(void)
7051{
7052 if (Globals.szLdapIdmapSuffix[0])
7053 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7054
7055 return lp_string(Globals.szLdapSuffix);
7056}
7057
7058/****************************************************************************
7059 set the value for a P_ENUM
7060 ***************************************************************************/
7061
7062static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7063 int *ptr )
7064{
7065 int i;
7066
7067 for (i = 0; parm->enum_list[i].name; i++) {
7068 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7069 *ptr = parm->enum_list[i].value;
7070 break;
7071 }
7072 }
7073}
7074
7075/***************************************************************************
7076***************************************************************************/
7077
7078static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7079{
7080 static int parm_num = -1;
7081 struct service *s;
7082
7083 if ( parm_num == -1 )
7084 parm_num = map_parameter( "printing" );
7085
7086 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7087
7088 if ( snum < 0 )
7089 s = &sDefault;
7090 else
7091 s = ServicePtrs[snum];
7092
7093 init_printer_values( s );
7094
7095 return True;
7096}
7097
7098
7099/***************************************************************************
7100 Initialise a copymap.
7101***************************************************************************/
7102
7103static void init_copymap(struct service *pservice)
7104{
7105 int i;
7106 if (pservice->copymap) {
7107 bitmap_free(pservice->copymap);
7108 }
7109 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7110 if (!pservice->copymap)
7111 DEBUG(0,
7112 ("Couldn't allocate copymap!! (size %d)\n",
7113 (int)NUMPARAMETERS));
7114 else
7115 for (i = 0; i < NUMPARAMETERS; i++)
7116 bitmap_set(pservice->copymap, i);
7117}
7118
7119/***************************************************************************
7120 Return the local pointer to a parameter given the service number and the
7121 pointer into the default structure.
7122***************************************************************************/
7123
7124void *lp_local_ptr(int snum, void *ptr)
7125{
7126 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7127}
7128
7129/***************************************************************************
7130 Process a parameter for a particular service number. If snum < 0
7131 then assume we are in the globals.
7132***************************************************************************/
7133
7134bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7135{
7136 int parmnum, i, slen;
7137 void *parm_ptr = NULL; /* where we are going to store the result */
7138 void *def_ptr = NULL;
7139 char *param_key = NULL;
7140 char *sep;
7141 param_opt_struct *paramo, *data;
7142 bool not_added;
7143
7144 parmnum = map_parameter(pszParmName);
7145
7146 if (parmnum < 0) {
7147 if ((sep=strchr(pszParmName, ':')) != NULL) {
7148 TALLOC_CTX *frame = talloc_stackframe();
7149
7150 *sep = '\0';
7151 param_key = talloc_asprintf(frame, "%s:", pszParmName);
7152 if (!param_key) {
7153 TALLOC_FREE(frame);
7154 return false;
7155 }
7156 slen = strlen(param_key);
7157 param_key = talloc_asprintf_append(param_key, sep+1);
7158 if (!param_key) {
7159 TALLOC_FREE(frame);
7160 return false;
7161 }
7162 trim_char(param_key+slen, ' ', ' ');
7163 not_added = True;
7164 data = (snum < 0) ? Globals.param_opt :
7165 ServicePtrs[snum]->param_opt;
7166 /* Traverse destination */
7167 while (data) {
7168 /* If we already have same option, override it */
7169 if (strcmp(data->key, param_key) == 0) {
7170 string_free(&data->value);
7171 TALLOC_FREE(data->list);
7172 data->value = SMB_STRDUP(pszParmValue);
7173 not_added = False;
7174 break;
7175 }
7176 data = data->next;
7177 }
7178 if (not_added) {
7179 paramo = SMB_XMALLOC_P(param_opt_struct);
7180 paramo->key = SMB_STRDUP(param_key);
7181 paramo->value = SMB_STRDUP(pszParmValue);
7182 paramo->list = NULL;
7183 if (snum < 0) {
7184 DLIST_ADD(Globals.param_opt, paramo);
7185 } else {
7186 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
7187 }
7188 }
7189
7190 *sep = ':';
7191 TALLOC_FREE(frame);
7192 return (True);
7193 }
7194 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7195 return (True);
7196 }
7197
7198 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7199 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7200 pszParmName));
7201 }
7202
7203 def_ptr = parm_table[parmnum].ptr;
7204
7205 /* we might point at a service, the default service or a global */
7206 if (snum < 0) {
7207 parm_ptr = def_ptr;
7208 } else {
7209 if (parm_table[parmnum].p_class == P_GLOBAL) {
7210 DEBUG(0,
7211 ("Global parameter %s found in service section!\n",
7212 pszParmName));
7213 return (True);
7214 }
7215 parm_ptr =
7216 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7217 &sDefault);
7218 }
7219
7220 if (snum >= 0) {
7221 if (!ServicePtrs[snum]->copymap)
7222 init_copymap(ServicePtrs[snum]);
7223
7224 /* this handles the aliases - set the copymap for other entries with
7225 the same data pointer */
7226 for (i = 0; parm_table[i].label; i++)
7227 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7228 bitmap_clear(ServicePtrs[snum]->copymap, i);
7229 }
7230
7231 /* if it is a special case then go ahead */
7232 if (parm_table[parmnum].special) {
7233 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
7234 return (True);
7235 }
7236
7237 /* now switch on the type of variable it is */
7238 switch (parm_table[parmnum].type)
7239 {
7240 case P_BOOL:
7241 *(bool *)parm_ptr = lp_bool(pszParmValue);
7242 break;
7243
7244 case P_BOOLREV:
7245 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7246 break;
7247
7248 case P_INTEGER:
7249 *(int *)parm_ptr = lp_int(pszParmValue);
7250 break;
7251
7252 case P_CHAR:
7253 *(char *)parm_ptr = *pszParmValue;
7254 break;
7255
7256 case P_OCTAL:
7257 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7258 if ( i != 1 ) {
7259 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7260 }
7261 break;
7262
7263 case P_LIST:
7264 TALLOC_FREE(*((char ***)parm_ptr));
7265 *(char ***)parm_ptr = str_list_make(
7266 NULL, pszParmValue, NULL);
7267 break;
7268
7269 case P_STRING:
7270 string_set((char **)parm_ptr, pszParmValue);
7271 break;
7272
7273 case P_USTRING:
7274 string_set((char **)parm_ptr, pszParmValue);
7275 strupper_m(*(char **)parm_ptr);
7276 break;
7277
7278 case P_ENUM:
7279 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7280 break;
7281 case P_SEP:
7282 break;
7283 }
7284
7285 return (True);
7286}
7287
7288/***************************************************************************
7289 Process a parameter.
7290***************************************************************************/
7291
7292static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7293 void *userdata)
7294{
7295 if (!bInGlobalSection && bGlobalOnly)
7296 return (True);
7297
7298 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7299
7300 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7301 pszParmName, pszParmValue));
7302}
7303
7304/***************************************************************************
7305 Print a parameter of the specified type.
7306***************************************************************************/
7307
7308static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7309{
7310 int i;
7311 switch (p->type)
7312 {
7313 case P_ENUM:
7314 for (i = 0; p->enum_list[i].name; i++) {
7315 if (*(int *)ptr == p->enum_list[i].value) {
7316 fprintf(f, "%s",
7317 p->enum_list[i].name);
7318 break;
7319 }
7320 }
7321 break;
7322
7323 case P_BOOL:
7324 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7325 break;
7326
7327 case P_BOOLREV:
7328 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7329 break;
7330
7331 case P_INTEGER:
7332 fprintf(f, "%d", *(int *)ptr);
7333 break;
7334
7335 case P_CHAR:
7336 fprintf(f, "%c", *(char *)ptr);
7337 break;
7338
7339 case P_OCTAL: {
7340 char *o = octal_string(*(int *)ptr);
7341 fprintf(f, "%s", o);
7342 TALLOC_FREE(o);
7343 break;
7344 }
7345
7346 case P_LIST:
7347 if ((char ***)ptr && *(char ***)ptr) {
7348 char **list = *(char ***)ptr;
7349 for (; *list; list++) {
7350 /* surround strings with whitespace in double quotes */
7351 if ( strchr_m( *list, ' ' ) )
7352 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7353 else
7354 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7355 }
7356 }
7357 break;
7358
7359 case P_STRING:
7360 case P_USTRING:
7361 if (*(char **)ptr) {
7362 fprintf(f, "%s", *(char **)ptr);
7363 }
7364 break;
7365 case P_SEP:
7366 break;
7367 }
7368}
7369
7370/***************************************************************************
7371 Check if two parameters are equal.
7372***************************************************************************/
7373
7374static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7375{
7376 switch (type) {
7377 case P_BOOL:
7378 case P_BOOLREV:
7379 return (*((bool *)ptr1) == *((bool *)ptr2));
7380
7381 case P_INTEGER:
7382 case P_ENUM:
7383 case P_OCTAL:
7384 return (*((int *)ptr1) == *((int *)ptr2));
7385
7386 case P_CHAR:
7387 return (*((char *)ptr1) == *((char *)ptr2));
7388
7389 case P_LIST:
7390 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7391
7392 case P_STRING:
7393 case P_USTRING:
7394 {
7395 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7396 if (p1 && !*p1)
7397 p1 = NULL;
7398 if (p2 && !*p2)
7399 p2 = NULL;
7400 return (p1 == p2 || strequal(p1, p2));
7401 }
7402 case P_SEP:
7403 break;
7404 }
7405 return (False);
7406}
7407
7408/***************************************************************************
7409 Initialize any local varients in the sDefault table.
7410***************************************************************************/
7411
7412void init_locals(void)
7413{
7414 /* None as yet. */
7415}
7416
7417/***************************************************************************
7418 Process a new section (service). At this stage all sections are services.
7419 Later we'll have special sections that permit server parameters to be set.
7420 Returns True on success, False on failure.
7421***************************************************************************/
7422
7423static bool do_section(const char *pszSectionName, void *userdata)
7424{
7425 bool bRetval;
7426 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7427 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7428 bRetval = False;
7429
7430 /* if we were in a global section then do the local inits */
7431 if (bInGlobalSection && !isglobal)
7432 init_locals();
7433
7434 /* if we've just struck a global section, note the fact. */
7435 bInGlobalSection = isglobal;
7436
7437 /* check for multiple global sections */
7438 if (bInGlobalSection) {
7439 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7440 return (True);
7441 }
7442
7443 if (!bInGlobalSection && bGlobalOnly)
7444 return (True);
7445
7446 /* if we have a current service, tidy it up before moving on */
7447 bRetval = True;
7448
7449 if (iServiceIndex >= 0)
7450 bRetval = service_ok(iServiceIndex);
7451
7452 /* if all is still well, move to the next record in the services array */
7453 if (bRetval) {
7454 /* We put this here to avoid an odd message order if messages are */
7455 /* issued by the post-processing of a previous section. */
7456 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7457
7458 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7459 < 0) {
7460 DEBUG(0, ("Failed to add a new service\n"));
7461 return (False);
7462 }
7463 }
7464
7465 return (bRetval);
7466}
7467
7468
7469/***************************************************************************
7470 Determine if a partcular base parameter is currentl set to the default value.
7471***************************************************************************/
7472
7473static bool is_default(int i)
7474{
7475 if (!defaults_saved)
7476 return False;
7477 switch (parm_table[i].type) {
7478 case P_LIST:
7479 return str_list_compare (parm_table[i].def.lvalue,
7480 *(char ***)parm_table[i].ptr);
7481 case P_STRING:
7482 case P_USTRING:
7483 return strequal(parm_table[i].def.svalue,
7484 *(char **)parm_table[i].ptr);
7485 case P_BOOL:
7486 case P_BOOLREV:
7487 return parm_table[i].def.bvalue ==
7488 *(bool *)parm_table[i].ptr;
7489 case P_CHAR:
7490 return parm_table[i].def.cvalue ==
7491 *(char *)parm_table[i].ptr;
7492 case P_INTEGER:
7493 case P_OCTAL:
7494 case P_ENUM:
7495 return parm_table[i].def.ivalue ==
7496 *(int *)parm_table[i].ptr;
7497 case P_SEP:
7498 break;
7499 }
7500 return False;
7501}
7502
7503/***************************************************************************
7504Display the contents of the global structure.
7505***************************************************************************/
7506
7507static void dump_globals(FILE *f)
7508{
7509 int i;
7510 param_opt_struct *data;
7511
7512 fprintf(f, "[global]\n");
7513
7514 for (i = 0; parm_table[i].label; i++)
7515 if (parm_table[i].p_class == P_GLOBAL &&
7516 parm_table[i].ptr &&
7517 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7518 if (defaults_saved && is_default(i))
7519 continue;
7520 fprintf(f, "\t%s = ", parm_table[i].label);
7521 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7522 fprintf(f, "\n");
7523 }
7524 if (Globals.param_opt != NULL) {
7525 data = Globals.param_opt;
7526 while(data) {
7527 fprintf(f, "\t%s = %s\n", data->key, data->value);
7528 data = data->next;
7529 }
7530 }
7531
7532}
7533
7534/***************************************************************************
7535 Return True if a local parameter is currently set to the global default.
7536***************************************************************************/
7537
7538bool lp_is_default(int snum, struct parm_struct *parm)
7539{
7540 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7541
7542 return equal_parameter(parm->type,
7543 ((char *)ServicePtrs[snum]) + pdiff,
7544 ((char *)&sDefault) + pdiff);
7545}
7546
7547/***************************************************************************
7548 Display the contents of a single services record.
7549***************************************************************************/
7550
7551static void dump_a_service(struct service *pService, FILE * f)
7552{
7553 int i;
7554 param_opt_struct *data;
7555
7556 if (pService != &sDefault)
7557 fprintf(f, "[%s]\n", pService->szService);
7558
7559 for (i = 0; parm_table[i].label; i++) {
7560
7561 if (parm_table[i].p_class == P_LOCAL &&
7562 parm_table[i].ptr &&
7563 (*parm_table[i].label != '-') &&
7564 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7565 {
7566
7567 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7568
7569 if (pService == &sDefault) {
7570 if (defaults_saved && is_default(i))
7571 continue;
7572 } else {
7573 if (equal_parameter(parm_table[i].type,
7574 ((char *)pService) +
7575 pdiff,
7576 ((char *)&sDefault) +
7577 pdiff))
7578 continue;
7579 }
7580
7581 fprintf(f, "\t%s = ", parm_table[i].label);
7582 print_parameter(&parm_table[i],
7583 ((char *)pService) + pdiff, f);
7584 fprintf(f, "\n");
7585 }
7586 }
7587
7588 if (pService->param_opt != NULL) {
7589 data = pService->param_opt;
7590 while(data) {
7591 fprintf(f, "\t%s = %s\n", data->key, data->value);
7592 data = data->next;
7593 }
7594 }
7595}
7596
7597/***************************************************************************
7598 Display the contents of a parameter of a single services record.
7599***************************************************************************/
7600
7601bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7602{
7603 int i;
7604 bool result = False;
7605 parm_class p_class;
7606 unsigned flag = 0;
7607 fstring local_parm_name;
7608 char *parm_opt;
7609 const char *parm_opt_value;
7610
7611 /* check for parametrical option */
7612 fstrcpy( local_parm_name, parm_name);
7613 parm_opt = strchr( local_parm_name, ':');
7614
7615 if (parm_opt) {
7616 *parm_opt = '\0';
7617 parm_opt++;
7618 if (strlen(parm_opt)) {
7619 parm_opt_value = lp_parm_const_string( snum,
7620 local_parm_name, parm_opt, NULL);
7621 if (parm_opt_value) {
7622 printf( "%s\n", parm_opt_value);
7623 result = True;
7624 }
7625 }
7626 return result;
7627 }
7628
7629 /* check for a key and print the value */
7630 if (isGlobal) {
7631 p_class = P_GLOBAL;
7632 flag = FLAG_GLOBAL;
7633 } else
7634 p_class = P_LOCAL;
7635
7636 for (i = 0; parm_table[i].label; i++) {
7637 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7638 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7639 parm_table[i].ptr &&
7640 (*parm_table[i].label != '-') &&
7641 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7642 {
7643 void *ptr;
7644
7645 if (isGlobal) {
7646 ptr = parm_table[i].ptr;
7647 } else {
7648 struct service *pService = ServicePtrs[snum];
7649 ptr = ((char *)pService) +
7650 PTR_DIFF(parm_table[i].ptr, &sDefault);
7651 }
7652
7653 print_parameter(&parm_table[i],
7654 ptr, f);
7655 fprintf(f, "\n");
7656 result = True;
7657 break;
7658 }
7659 }
7660
7661 return result;
7662}
7663
7664/***************************************************************************
7665 Return info about the requested parameter (given as a string).
7666 Return NULL when the string is not a valid parameter name.
7667***************************************************************************/
7668
7669struct parm_struct *lp_get_parameter(const char *param_name)
7670{
7671 int num = map_parameter(param_name);
7672
7673 if (num < 0) {
7674 return NULL;
7675 }
7676
7677 return &parm_table[num];
7678}
7679
7680/***************************************************************************
7681 Return info about the next parameter in a service.
7682 snum==GLOBAL_SECTION_SNUM gives the globals.
7683 Return NULL when out of parameters.
7684***************************************************************************/
7685
7686struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7687{
7688 if (snum < 0) {
7689 /* do the globals */
7690 for (; parm_table[*i].label; (*i)++) {
7691 if (parm_table[*i].p_class == P_SEPARATOR)
7692 return &parm_table[(*i)++];
7693
7694 if (!parm_table[*i].ptr
7695 || (*parm_table[*i].label == '-'))
7696 continue;
7697
7698 if ((*i) > 0
7699 && (parm_table[*i].ptr ==
7700 parm_table[(*i) - 1].ptr))
7701 continue;
7702
7703 if (is_default(*i) && !allparameters)
7704 continue;
7705
7706 return &parm_table[(*i)++];
7707 }
7708 } else {
7709 struct service *pService = ServicePtrs[snum];
7710
7711 for (; parm_table[*i].label; (*i)++) {
7712 if (parm_table[*i].p_class == P_SEPARATOR)
7713 return &parm_table[(*i)++];
7714
7715 if (parm_table[*i].p_class == P_LOCAL &&
7716 parm_table[*i].ptr &&
7717 (*parm_table[*i].label != '-') &&
7718 ((*i) == 0 ||
7719 (parm_table[*i].ptr !=
7720 parm_table[(*i) - 1].ptr)))
7721 {
7722 int pdiff =
7723 PTR_DIFF(parm_table[*i].ptr,
7724 &sDefault);
7725
7726 if (allparameters ||
7727 !equal_parameter(parm_table[*i].type,
7728 ((char *)pService) +
7729 pdiff,
7730 ((char *)&sDefault) +
7731 pdiff))
7732 {
7733 return &parm_table[(*i)++];
7734 }
7735 }
7736 }
7737 }
7738
7739 return NULL;
7740}
7741
7742
7743#if 0
7744/***************************************************************************
7745 Display the contents of a single copy structure.
7746***************************************************************************/
7747static void dump_copy_map(bool *pcopymap)
7748{
7749 int i;
7750 if (!pcopymap)
7751 return;
7752
7753 printf("\n\tNon-Copied parameters:\n");
7754
7755 for (i = 0; parm_table[i].label; i++)
7756 if (parm_table[i].p_class == P_LOCAL &&
7757 parm_table[i].ptr && !pcopymap[i] &&
7758 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7759 {
7760 printf("\t\t%s\n", parm_table[i].label);
7761 }
7762}
7763#endif
7764
7765/***************************************************************************
7766 Return TRUE if the passed service number is within range.
7767***************************************************************************/
7768
7769bool lp_snum_ok(int iService)
7770{
7771 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7772}
7773
7774/***************************************************************************
7775 Auto-load some home services.
7776***************************************************************************/
7777
7778static void lp_add_auto_services(char *str)
7779{
7780 char *s;
7781 char *p;
7782 int homes;
7783 char *saveptr;
7784
7785 if (!str)
7786 return;
7787
7788 s = SMB_STRDUP(str);
7789 if (!s)
7790 return;
7791
7792 homes = lp_servicenumber(HOMES_NAME);
7793
7794 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7795 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7796 char *home;
7797
7798 if (lp_servicenumber(p) >= 0)
7799 continue;
7800
7801 home = get_user_home_dir(talloc_tos(), p);
7802
7803 if (home && homes >= 0)
7804 lp_add_home(p, homes, p, home);
7805
7806 TALLOC_FREE(home);
7807 }
7808 SAFE_FREE(s);
7809}
7810
7811/***************************************************************************
7812 Auto-load one printer.
7813***************************************************************************/
7814
7815void lp_add_one_printer(const char *name, const char *comment, void *pdata)
7816{
7817 int printers = lp_servicenumber(PRINTERS_NAME);
7818 int i;
7819
7820 if (lp_servicenumber(name) < 0) {
7821 lp_add_printer(name, printers);
7822 if ((i = lp_servicenumber(name)) >= 0) {
7823 string_set(&ServicePtrs[i]->comment, comment);
7824 ServicePtrs[i]->autoloaded = True;
7825 }
7826 }
7827}
7828
7829/***************************************************************************
7830 Have we loaded a services file yet?
7831***************************************************************************/
7832
7833bool lp_loaded(void)
7834{
7835 return (bLoaded);
7836}
7837
7838/***************************************************************************
7839 Unload unused services.
7840***************************************************************************/
7841
7842void lp_killunused(bool (*snumused) (int))
7843{
7844 int i;
7845 for (i = 0; i < iNumServices; i++) {
7846 if (!VALID(i))
7847 continue;
7848
7849 /* don't kill autoloaded or usershare services */
7850 if ( ServicePtrs[i]->autoloaded ||
7851 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7852 continue;
7853 }
7854
7855 if (!snumused || !snumused(i)) {
7856 free_service_byindex(i);
7857 }
7858 }
7859}
7860
7861/**
7862 * Kill all except autoloaded and usershare services - convenience wrapper
7863 */
7864void lp_kill_all_services(void)
7865{
7866 lp_killunused(NULL);
7867}
7868
7869/***************************************************************************
7870 Unload a service.
7871***************************************************************************/
7872
7873void lp_killservice(int iServiceIn)
7874{
7875 if (VALID(iServiceIn)) {
7876 free_service_byindex(iServiceIn);
7877 }
7878}
7879
7880/***************************************************************************
7881 Save the curent values of all global and sDefault parameters into the
7882 defaults union. This allows swat and testparm to show only the
7883 changed (ie. non-default) parameters.
7884***************************************************************************/
7885
7886static void lp_save_defaults(void)
7887{
7888 int i;
7889 for (i = 0; parm_table[i].label; i++) {
7890 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7891 continue;
7892 switch (parm_table[i].type) {
7893 case P_LIST:
7894 str_list_copy(
7895 NULL, &(parm_table[i].def.lvalue),
7896 *(const char ***)parm_table[i].ptr);
7897 break;
7898 case P_STRING:
7899 case P_USTRING:
7900 if (parm_table[i].ptr) {
7901 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7902 } else {
7903 parm_table[i].def.svalue = NULL;
7904 }
7905 break;
7906 case P_BOOL:
7907 case P_BOOLREV:
7908 parm_table[i].def.bvalue =
7909 *(bool *)parm_table[i].ptr;
7910 break;
7911 case P_CHAR:
7912 parm_table[i].def.cvalue =
7913 *(char *)parm_table[i].ptr;
7914 break;
7915 case P_INTEGER:
7916 case P_OCTAL:
7917 case P_ENUM:
7918 parm_table[i].def.ivalue =
7919 *(int *)parm_table[i].ptr;
7920 break;
7921 case P_SEP:
7922 break;
7923 }
7924 }
7925 defaults_saved = True;
7926}
7927
7928/*******************************************************************
7929 Set the server type we will announce as via nmbd.
7930********************************************************************/
7931
7932static const struct srv_role_tab {
7933 uint32 role;
7934 const char *role_str;
7935} srv_role_tab [] = {
7936 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7937 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7938 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7939 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7940 { 0, NULL }
7941};
7942
7943const char* server_role_str(uint32 role)
7944{
7945 int i = 0;
7946 for (i=0; srv_role_tab[i].role_str; i++) {
7947 if (role == srv_role_tab[i].role) {
7948 return srv_role_tab[i].role_str;
7949 }
7950 }
7951 return NULL;
7952}
7953
7954static void set_server_role(void)
7955{
7956 server_role = ROLE_STANDALONE;
7957
7958 switch (lp_security()) {
7959 case SEC_SHARE:
7960 if (lp_domain_logons())
7961 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7962 break;
7963 case SEC_SERVER:
7964 if (lp_domain_logons())
7965 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7966 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7967 server_role = ROLE_STANDALONE;
7968 break;
7969 case SEC_DOMAIN:
7970 if (lp_domain_logons()) {
7971 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7972 server_role = ROLE_DOMAIN_BDC;
7973 break;
7974 }
7975 server_role = ROLE_DOMAIN_MEMBER;
7976 break;
7977 case SEC_ADS:
7978 if (lp_domain_logons()) {
7979 server_role = ROLE_DOMAIN_PDC;
7980 break;
7981 }
7982 server_role = ROLE_DOMAIN_MEMBER;
7983 break;
7984 case SEC_USER:
7985 if (lp_domain_logons()) {
7986
7987 if (Globals.iDomainMaster) /* auto or yes */
7988 server_role = ROLE_DOMAIN_PDC;
7989 else
7990 server_role = ROLE_DOMAIN_BDC;
7991 }
7992 break;
7993 default:
7994 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7995 break;
7996 }
7997
7998 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
7999}
8000
8001/***********************************************************
8002 If we should send plaintext/LANMAN passwords in the clinet
8003************************************************************/
8004
8005static void set_allowed_client_auth(void)
8006{
8007 if (Globals.bClientNTLMv2Auth) {
8008 Globals.bClientLanManAuth = False;
8009 }
8010 if (!Globals.bClientLanManAuth) {
8011 Globals.bClientPlaintextAuth = False;
8012 }
8013}
8014
8015/***************************************************************************
8016 JRA.
8017 The following code allows smbd to read a user defined share file.
8018 Yes, this is my intent. Yes, I'm comfortable with that...
8019
8020 THE FOLLOWING IS SECURITY CRITICAL CODE.
8021
8022 It washes your clothes, it cleans your house, it guards you while you sleep...
8023 Do not f%^k with it....
8024***************************************************************************/
8025
8026#define MAX_USERSHARE_FILE_SIZE (10*1024)
8027
8028/***************************************************************************
8029 Check allowed stat state of a usershare file.
8030 Ensure we print out who is dicking with us so the admin can
8031 get their sorry ass fired.
8032***************************************************************************/
8033
8034static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8035{
8036 if (!S_ISREG(psbuf->st_mode)) {
8037 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8038 "not a regular file\n",
8039 fname, (unsigned int)psbuf->st_uid ));
8040 return False;
8041 }
8042
8043 /* Ensure this doesn't have the other write bit set. */
8044 if (psbuf->st_mode & S_IWOTH) {
8045 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8046 "public write. Refusing to allow as a usershare file.\n",
8047 fname, (unsigned int)psbuf->st_uid ));
8048 return False;
8049 }
8050
8051 /* Should be 10k or less. */
8052 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8053 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8054 "too large (%u) to be a user share file.\n",
8055 fname, (unsigned int)psbuf->st_uid,
8056 (unsigned int)psbuf->st_size ));
8057 return False;
8058 }
8059
8060 return True;
8061}
8062
8063/***************************************************************************
8064 Parse the contents of a usershare file.
8065***************************************************************************/
8066
8067enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8068 SMB_STRUCT_STAT *psbuf,
8069 const char *servicename,
8070 int snum,
8071 char **lines,
8072 int numlines,
8073 char **pp_sharepath,
8074 char **pp_comment,
8075 SEC_DESC **ppsd,
8076 bool *pallow_guest)
8077{
8078 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8079 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8080 int us_vers;
8081 SMB_STRUCT_DIR *dp;
8082 SMB_STRUCT_STAT sbuf;
8083 char *sharepath = NULL;
8084 char *comment = NULL;
8085
8086 *pp_sharepath = NULL;
8087 *pp_comment = NULL;
8088
8089 *pallow_guest = False;
8090
8091 if (numlines < 4) {
8092 return USERSHARE_MALFORMED_FILE;
8093 }
8094
8095 if (strcmp(lines[0], "#VERSION 1") == 0) {
8096 us_vers = 1;
8097 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8098 us_vers = 2;
8099 if (numlines < 5) {
8100 return USERSHARE_MALFORMED_FILE;
8101 }
8102 } else {
8103 return USERSHARE_BAD_VERSION;
8104 }
8105
8106 if (strncmp(lines[1], "path=", 5) != 0) {
8107 return USERSHARE_MALFORMED_PATH;
8108 }
8109
8110 sharepath = talloc_strdup(ctx, &lines[1][5]);
8111 if (!sharepath) {
8112 return USERSHARE_POSIX_ERR;
8113 }
8114 trim_string(sharepath, " ", " ");
8115
8116 if (strncmp(lines[2], "comment=", 8) != 0) {
8117 return USERSHARE_MALFORMED_COMMENT_DEF;
8118 }
8119
8120 comment = talloc_strdup(ctx, &lines[2][8]);
8121 if (!comment) {
8122 return USERSHARE_POSIX_ERR;
8123 }
8124 trim_string(comment, " ", " ");
8125 trim_char(comment, '"', '"');
8126
8127 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8128 return USERSHARE_MALFORMED_ACL_DEF;
8129 }
8130
8131 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8132 return USERSHARE_ACL_ERR;
8133 }
8134
8135 if (us_vers == 2) {
8136 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8137 return USERSHARE_MALFORMED_ACL_DEF;
8138 }
8139 if (lines[4][9] == 'y') {
8140 *pallow_guest = True;
8141 }
8142 }
8143
8144 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8145 /* Path didn't change, no checks needed. */
8146 *pp_sharepath = sharepath;
8147 *pp_comment = comment;
8148 return USERSHARE_OK;
8149 }
8150
8151 /* The path *must* be absolute. */
8152 if (sharepath[0] != '/') {
8153 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8154 servicename, sharepath));
8155 return USERSHARE_PATH_NOT_ABSOLUTE;
8156 }
8157
8158 /* If there is a usershare prefix deny list ensure one of these paths
8159 doesn't match the start of the user given path. */
8160 if (prefixdenylist) {
8161 int i;
8162 for ( i=0; prefixdenylist[i]; i++ ) {
8163 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8164 servicename, i, prefixdenylist[i], sharepath ));
8165 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8166 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8167 "usershare prefix deny list entries.\n",
8168 servicename, sharepath));
8169 return USERSHARE_PATH_IS_DENIED;
8170 }
8171 }
8172 }
8173
8174 /* If there is a usershare prefix allow list ensure one of these paths
8175 does match the start of the user given path. */
8176
8177 if (prefixallowlist) {
8178 int i;
8179 for ( i=0; prefixallowlist[i]; i++ ) {
8180 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8181 servicename, i, prefixallowlist[i], sharepath ));
8182 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8183 break;
8184 }
8185 }
8186 if (prefixallowlist[i] == NULL) {
8187 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8188 "usershare prefix allow list entries.\n",
8189 servicename, sharepath));
8190 return USERSHARE_PATH_NOT_ALLOWED;
8191 }
8192 }
8193
8194 /* Ensure this is pointing to a directory. */
8195 dp = sys_opendir(sharepath);
8196
8197 if (!dp) {
8198 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8199 servicename, sharepath));
8200 return USERSHARE_PATH_NOT_DIRECTORY;
8201 }
8202
8203 /* Ensure the owner of the usershare file has permission to share
8204 this directory. */
8205
8206 if (sys_stat(sharepath, &sbuf) == -1) {
8207 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8208 servicename, sharepath, strerror(errno) ));
8209 sys_closedir(dp);
8210 return USERSHARE_POSIX_ERR;
8211 }
8212
8213 sys_closedir(dp);
8214
8215 if (!S_ISDIR(sbuf.st_mode)) {
8216 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8217 servicename, sharepath ));
8218 return USERSHARE_PATH_NOT_DIRECTORY;
8219 }
8220
8221 /* Check if sharing is restricted to owner-only. */
8222 /* psbuf is the stat of the usershare definition file,
8223 sbuf is the stat of the target directory to be shared. */
8224
8225 if (lp_usershare_owner_only()) {
8226 /* root can share anything. */
8227 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8228 return USERSHARE_PATH_NOT_ALLOWED;
8229 }
8230 }
8231
8232 *pp_sharepath = sharepath;
8233 *pp_comment = comment;
8234 return USERSHARE_OK;
8235}
8236
8237/***************************************************************************
8238 Deal with a usershare file.
8239 Returns:
8240 >= 0 - snum
8241 -1 - Bad name, invalid contents.
8242 - service name already existed and not a usershare, problem
8243 with permissions to share directory etc.
8244***************************************************************************/
8245
8246static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8247{
8248 SMB_STRUCT_STAT sbuf;
8249 SMB_STRUCT_STAT lsbuf;
8250 char *fname = NULL;
8251 char *sharepath = NULL;
8252 char *comment = NULL;
8253 fstring service_name;
8254 char **lines = NULL;
8255 int numlines = 0;
8256 int fd = -1;
8257 int iService = -1;
8258 TALLOC_CTX *ctx = NULL;
8259 SEC_DESC *psd = NULL;
8260 bool guest_ok = False;
8261
8262 /* Ensure share name doesn't contain invalid characters. */
8263 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8264 DEBUG(0,("process_usershare_file: share name %s contains "
8265 "invalid characters (any of %s)\n",
8266 file_name, INVALID_SHARENAME_CHARS ));
8267 return -1;
8268 }
8269
8270 fstrcpy(service_name, file_name);
8271
8272 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8273 }
8274
8275 /* Minimize the race condition by doing an lstat before we
8276 open and fstat. Ensure this isn't a symlink link. */
8277
8278 if (sys_lstat(fname, &lsbuf) != 0) {
8279 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8280 fname, strerror(errno) ));
8281 SAFE_FREE(fname);
8282 return -1;
8283 }
8284
8285 /* This must be a regular file, not a symlink, directory or
8286 other strange filetype. */
8287 if (!check_usershare_stat(fname, &lsbuf)) {
8288 SAFE_FREE(fname);
8289 return -1;
8290 }
8291
8292 {
8293 char *canon_name = canonicalize_servicename(service_name);
8294 TDB_DATA data = dbwrap_fetch_bystring(
8295 ServiceHash, canon_name, canon_name);
8296
8297 iService = -1;
8298
8299 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8300 iService = *(int *)data.dptr;
8301 }
8302 TALLOC_FREE(canon_name);
8303 }
8304
8305 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8306 /* Nothing changed - Mark valid and return. */
8307 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8308 service_name ));
8309 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8310 SAFE_FREE(fname);
8311 return iService;
8312 }
8313
8314 /* Try and open the file read only - no symlinks allowed. */
8315#ifdef O_NOFOLLOW
8316 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8317#else
8318 fd = sys_open(fname, O_RDONLY, 0);
8319#endif
8320
8321 if (fd == -1) {
8322 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8323 fname, strerror(errno) ));
8324 SAFE_FREE(fname);
8325 return -1;
8326 }
8327
8328 /* Now fstat to be *SURE* it's a regular file. */
8329 if (sys_fstat(fd, &sbuf) != 0) {
8330 close(fd);
8331 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8332 fname, strerror(errno) ));
8333 SAFE_FREE(fname);
8334 return -1;
8335 }
8336
8337 /* Is it the same dev/inode as was lstated ? */
8338 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8339 close(fd);
8340 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8341 "Symlink spoofing going on ?\n", fname ));
8342 SAFE_FREE(fname);
8343 return -1;
8344 }
8345
8346 /* This must be a regular file, not a symlink, directory or
8347 other strange filetype. */
8348 if (!check_usershare_stat(fname, &sbuf)) {
8349 SAFE_FREE(fname);
8350 return -1;
8351 }
8352
8353 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8354
8355 close(fd);
8356 if (lines == NULL) {
8357 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8358 fname, (unsigned int)sbuf.st_uid ));
8359 SAFE_FREE(fname);
8360 return -1;
8361 }
8362
8363 SAFE_FREE(fname);
8364
8365 /* Should we allow printers to be shared... ? */
8366 ctx = talloc_init("usershare_sd_xctx");
8367 if (!ctx) {
8368 file_lines_free(lines);
8369 return 1;
8370 }
8371
8372 if (parse_usershare_file(ctx, &sbuf, service_name,
8373 iService, lines, numlines, &sharepath,
8374 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8375 talloc_destroy(ctx);
8376 file_lines_free(lines);
8377 return -1;
8378 }
8379
8380 file_lines_free(lines);
8381
8382 /* Everything ok - add the service possibly using a template. */
8383 if (iService < 0) {
8384 const struct service *sp = &sDefault;
8385 if (snum_template != -1) {
8386 sp = ServicePtrs[snum_template];
8387 }
8388
8389 if ((iService = add_a_service(sp, service_name)) < 0) {
8390 DEBUG(0, ("process_usershare_file: Failed to add "
8391 "new service %s\n", service_name));
8392 talloc_destroy(ctx);
8393 return -1;
8394 }
8395
8396 /* Read only is controlled by usershare ACL below. */
8397 ServicePtrs[iService]->bRead_only = False;
8398 }
8399
8400 /* Write the ACL of the new/modified share. */
8401 if (!set_share_security(service_name, psd)) {
8402 DEBUG(0, ("process_usershare_file: Failed to set share "
8403 "security for user share %s\n",
8404 service_name ));
8405 lp_remove_service(iService);
8406 talloc_destroy(ctx);
8407 return -1;
8408 }
8409
8410 /* If from a template it may be marked invalid. */
8411 ServicePtrs[iService]->valid = True;
8412
8413 /* Set the service as a valid usershare. */
8414 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8415
8416 /* Set guest access. */
8417 if (lp_usershare_allow_guests()) {
8418 ServicePtrs[iService]->bGuest_ok = guest_ok;
8419 }
8420
8421 /* And note when it was loaded. */
8422 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8423 string_set(&ServicePtrs[iService]->szPath, sharepath);
8424 string_set(&ServicePtrs[iService]->comment, comment);
8425
8426 talloc_destroy(ctx);
8427
8428 return iService;
8429}
8430
8431/***************************************************************************
8432 Checks if a usershare entry has been modified since last load.
8433***************************************************************************/
8434
8435static bool usershare_exists(int iService, time_t *last_mod)
8436{
8437 SMB_STRUCT_STAT lsbuf;
8438 const char *usersharepath = Globals.szUsersharePath;
8439 char *fname;
8440
8441 if (asprintf(&fname, "%s/%s",
8442 usersharepath,
8443 ServicePtrs[iService]->szService) < 0) {
8444 return false;
8445 }
8446
8447 if (sys_lstat(fname, &lsbuf) != 0) {
8448 SAFE_FREE(fname);
8449 return false;
8450 }
8451
8452 if (!S_ISREG(lsbuf.st_mode)) {
8453 SAFE_FREE(fname);
8454 return false;
8455 }
8456
8457 SAFE_FREE(fname);
8458 *last_mod = lsbuf.st_mtime;
8459 return true;
8460}
8461
8462/***************************************************************************
8463 Load a usershare service by name. Returns a valid servicenumber or -1.
8464***************************************************************************/
8465
8466int load_usershare_service(const char *servicename)
8467{
8468 SMB_STRUCT_STAT sbuf;
8469 const char *usersharepath = Globals.szUsersharePath;
8470 int max_user_shares = Globals.iUsershareMaxShares;
8471 int snum_template = -1;
8472
8473 if (*usersharepath == 0 || max_user_shares == 0) {
8474 return -1;
8475 }
8476
8477 if (sys_stat(usersharepath, &sbuf) != 0) {
8478 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8479 usersharepath, strerror(errno) ));
8480 return -1;
8481 }
8482
8483 if (!S_ISDIR(sbuf.st_mode)) {
8484 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8485 usersharepath ));
8486 return -1;
8487 }
8488
8489 /*
8490 * This directory must be owned by root, and have the 't' bit set.
8491 * It also must not be writable by "other".
8492 */
8493
8494#ifdef S_ISVTX
8495 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8496#else
8497 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8498#endif
8499 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8500 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8501 usersharepath ));
8502 return -1;
8503 }
8504
8505 /* Ensure the template share exists if it's set. */
8506 if (Globals.szUsershareTemplateShare[0]) {
8507 /* We can't use lp_servicenumber here as we are recommending that
8508 template shares have -valid=False set. */
8509 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8510 if (ServicePtrs[snum_template]->szService &&
8511 strequal(ServicePtrs[snum_template]->szService,
8512 Globals.szUsershareTemplateShare)) {
8513 break;
8514 }
8515 }
8516
8517 if (snum_template == -1) {
8518 DEBUG(0,("load_usershare_service: usershare template share %s "
8519 "does not exist.\n",
8520 Globals.szUsershareTemplateShare ));
8521 return -1;
8522 }
8523 }
8524
8525 return process_usershare_file(usersharepath, servicename, snum_template);
8526}
8527
8528/***************************************************************************
8529 Load all user defined shares from the user share directory.
8530 We only do this if we're enumerating the share list.
8531 This is the function that can delete usershares that have
8532 been removed.
8533***************************************************************************/
8534
8535int load_usershare_shares(void)
8536{
8537 SMB_STRUCT_DIR *dp;
8538 SMB_STRUCT_STAT sbuf;
8539 SMB_STRUCT_DIRENT *de;
8540 int num_usershares = 0;
8541 int max_user_shares = Globals.iUsershareMaxShares;
8542 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8543 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8544 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8545 int iService;
8546 int snum_template = -1;
8547 const char *usersharepath = Globals.szUsersharePath;
8548 int ret = lp_numservices();
8549
8550 if (max_user_shares == 0 || *usersharepath == '\0') {
8551 return lp_numservices();
8552 }
8553
8554 if (sys_stat(usersharepath, &sbuf) != 0) {
8555 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8556 usersharepath, strerror(errno) ));
8557 return ret;
8558 }
8559
8560 /*
8561 * This directory must be owned by root, and have the 't' bit set.
8562 * It also must not be writable by "other".
8563 */
8564
8565#ifdef S_ISVTX
8566 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8567#else
8568 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8569#endif
8570 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8571 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8572 usersharepath ));
8573 return ret;
8574 }
8575
8576 /* Ensure the template share exists if it's set. */
8577 if (Globals.szUsershareTemplateShare[0]) {
8578 /* We can't use lp_servicenumber here as we are recommending that
8579 template shares have -valid=False set. */
8580 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8581 if (ServicePtrs[snum_template]->szService &&
8582 strequal(ServicePtrs[snum_template]->szService,
8583 Globals.szUsershareTemplateShare)) {
8584 break;
8585 }
8586 }
8587
8588 if (snum_template == -1) {
8589 DEBUG(0,("load_usershare_shares: usershare template share %s "
8590 "does not exist.\n",
8591 Globals.szUsershareTemplateShare ));
8592 return ret;
8593 }
8594 }
8595
8596 /* Mark all existing usershares as pending delete. */
8597 for (iService = iNumServices - 1; iService >= 0; iService--) {
8598 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8599 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8600 }
8601 }
8602
8603 dp = sys_opendir(usersharepath);
8604 if (!dp) {
8605 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8606 usersharepath, strerror(errno) ));
8607 return ret;
8608 }
8609
8610 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8611 (de = sys_readdir(dp));
8612 num_dir_entries++ ) {
8613 int r;
8614 const char *n = de->d_name;
8615
8616 /* Ignore . and .. */
8617 if (*n == '.') {
8618 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8619 continue;
8620 }
8621 }
8622
8623 if (n[0] == ':') {
8624 /* Temporary file used when creating a share. */
8625 num_tmp_dir_entries++;
8626 }
8627
8628 /* Allow 20% tmp entries. */
8629 if (num_tmp_dir_entries > allowed_tmp_entries) {
8630 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8631 "in directory %s\n",
8632 num_tmp_dir_entries, usersharepath));
8633 break;
8634 }
8635
8636 r = process_usershare_file(usersharepath, n, snum_template);
8637 if (r == 0) {
8638 /* Update the services count. */
8639 num_usershares++;
8640 if (num_usershares >= max_user_shares) {
8641 DEBUG(0,("load_usershare_shares: max user shares reached "
8642 "on file %s in directory %s\n",
8643 n, usersharepath ));
8644 break;
8645 }
8646 } else if (r == -1) {
8647 num_bad_dir_entries++;
8648 }
8649
8650 /* Allow 20% bad entries. */
8651 if (num_bad_dir_entries > allowed_bad_entries) {
8652 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8653 "in directory %s\n",
8654 num_bad_dir_entries, usersharepath));
8655 break;
8656 }
8657
8658 /* Allow 20% bad entries. */
8659 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8660 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8661 "in directory %s\n",
8662 num_dir_entries, usersharepath));
8663 break;
8664 }
8665 }
8666
8667 sys_closedir(dp);
8668
8669 /* Sweep through and delete any non-refreshed usershares that are
8670 not currently in use. */
8671 for (iService = iNumServices - 1; iService >= 0; iService--) {
8672 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8673 if (conn_snum_used(iService)) {
8674 continue;
8675 }
8676 /* Remove from the share ACL db. */
8677 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8678 lp_servicename(iService) ));
8679 delete_share_security(lp_servicename(iService));
8680 free_service_byindex(iService);
8681 }
8682 }
8683
8684 return lp_numservices();
8685}
8686
8687/********************************************************
8688 Destroy global resources allocated in this file
8689********************************************************/
8690
8691void gfree_loadparm(void)
8692{
8693 struct file_lists *f;
8694 struct file_lists *next;
8695 int i;
8696
8697 /* Free the file lists */
8698
8699 f = file_lists;
8700 while( f ) {
8701 next = f->next;
8702 SAFE_FREE( f->name );
8703 SAFE_FREE( f->subfname );
8704 SAFE_FREE( f );
8705 f = next;
8706 }
8707 file_lists = NULL;
8708
8709 /* Free resources allocated to services */
8710
8711 for ( i = 0; i < iNumServices; i++ ) {
8712 if ( VALID(i) ) {
8713 free_service_byindex(i);
8714 }
8715 }
8716
8717 SAFE_FREE( ServicePtrs );
8718 iNumServices = 0;
8719
8720 /* Now release all resources allocated to global
8721 parameters and the default service */
8722
8723 for (i = 0; parm_table[i].label; i++)
8724 {
8725 if ( parm_table[i].type == P_STRING
8726 || parm_table[i].type == P_USTRING )
8727 {
8728 string_free( (char**)parm_table[i].ptr );
8729 }
8730 else if (parm_table[i].type == P_LIST) {
8731 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8732 }
8733 }
8734}
8735
8736
8737/***************************************************************************
8738 Allow client apps to specify that they are a client
8739***************************************************************************/
8740void lp_set_in_client(bool b)
8741{
8742 in_client = b;
8743}
8744
8745
8746/***************************************************************************
8747 Determine if we're running in a client app
8748***************************************************************************/
8749bool lp_is_in_client(void)
8750{
8751 return in_client;
8752}
8753
8754
8755
8756
8757/***************************************************************************
8758 Load the services array from the services file. Return True on success,
8759 False on failure.
8760***************************************************************************/
8761
8762bool lp_load_ex(const char *pszFname,
8763 bool global_only,
8764 bool save_defaults,
8765 bool add_ipc,
8766 bool initialize_globals,
8767 bool allow_include_registry,
8768 bool allow_registry_shares)
8769{
8770 char *n2 = NULL;
8771 bool bRetval;
8772 param_opt_struct *data, *pdata;
8773
8774 bRetval = False;
8775
8776 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8777
8778 bInGlobalSection = True;
8779 bGlobalOnly = global_only;
8780 bAllowIncludeRegistry = allow_include_registry;
8781
8782 init_globals(! initialize_globals);
8783 debug_init();
8784
8785 if (save_defaults) {
8786 init_locals();
8787 lp_save_defaults();
8788 }
8789
8790 /* We get sections first, so have to start 'behind' to make up */
8791 iServiceIndex = -1;
8792
8793 if (Globals.param_opt != NULL) {
8794 data = Globals.param_opt;
8795 while (data) {
8796 string_free(&data->key);
8797 string_free(&data->value);
8798 TALLOC_FREE(data->list);
8799 pdata = data->next;
8800 SAFE_FREE(data);
8801 data = pdata;
8802 }
8803 Globals.param_opt = NULL;
8804 }
8805
8806 if (lp_config_backend_is_file()) {
8807 n2 = alloc_sub_basic(get_current_username(),
8808 current_user_info.domain,
8809 pszFname);
8810 if (!n2) {
8811 smb_panic("lp_load_ex: out of memory");
8812 }
8813
8814 add_to_file_list(pszFname, n2);
8815
8816 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8817 SAFE_FREE(n2);
8818
8819 /* finish up the last section */
8820 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8821 if (bRetval) {
8822 if (iServiceIndex >= 0) {
8823 bRetval = service_ok(iServiceIndex);
8824 }
8825 }
8826
8827 if (lp_config_backend_is_registry()) {
8828 /* config backend changed to registry in config file */
8829 /*
8830 * We need to use this extra global variable here to
8831 * survive restart: init_globals uses this as a default
8832 * for ConfigBackend. Otherwise, init_globals would
8833 * send us into an endless loop here.
8834 */
8835 config_backend = CONFIG_BACKEND_REGISTRY;
8836 /* start over */
8837 DEBUG(1, ("lp_load_ex: changing to config backend "
8838 "registry\n"));
8839 init_globals(false);
8840 lp_kill_all_services();
8841 return lp_load_ex(pszFname, global_only, save_defaults,
8842 add_ipc, initialize_globals,
8843 allow_include_registry,
8844 allow_registry_shares);
8845 }
8846 } else if (lp_config_backend_is_registry()) {
8847 bRetval = process_registry_globals();
8848 } else {
8849 DEBUG(0, ("Illegal config backend given: %d\n",
8850 lp_config_backend()));
8851 bRetval = false;
8852 }
8853
8854 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8855 bRetval = process_registry_shares();
8856 }
8857
8858 lp_add_auto_services(lp_auto_services());
8859
8860 if (add_ipc) {
8861 /* When 'restrict anonymous = 2' guest connections to ipc$
8862 are denied */
8863 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8864 if ( lp_enable_asu_support() ) {
8865 lp_add_ipc("ADMIN$", false);
8866 }
8867 }
8868
8869 set_server_role();
8870 set_default_server_announce_type();
8871 set_allowed_client_auth();
8872
8873 bLoaded = True;
8874
8875 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8876 /* if bWINSsupport is true and we are in the client */
8877 if (lp_is_in_client() && Globals.bWINSsupport) {
8878 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8879 }
8880
8881 init_iconv();
8882
8883 bAllowIncludeRegistry = true;
8884
8885 return (bRetval);
8886}
8887
8888bool lp_load(const char *pszFname,
8889 bool global_only,
8890 bool save_defaults,
8891 bool add_ipc,
8892 bool initialize_globals)
8893{
8894 return lp_load_ex(pszFname,
8895 global_only,
8896 save_defaults,
8897 add_ipc,
8898 initialize_globals,
8899 true, false);
8900}
8901
8902bool lp_load_initial_only(const char *pszFname)
8903{
8904 return lp_load_ex(pszFname,
8905 true,
8906 false,
8907 false,
8908 true,
8909 false,
8910 false);
8911}
8912
8913bool lp_load_with_registry_shares(const char *pszFname,
8914 bool global_only,
8915 bool save_defaults,
8916 bool add_ipc,
8917 bool initialize_globals)
8918{
8919 return lp_load_ex(pszFname,
8920 global_only,
8921 save_defaults,
8922 add_ipc,
8923 initialize_globals,
8924 true,
8925 true);
8926}
8927
8928/***************************************************************************
8929 Return the max number of services.
8930***************************************************************************/
8931
8932int lp_numservices(void)
8933{
8934 return (iNumServices);
8935}
8936
8937/***************************************************************************
8938Display the contents of the services array in human-readable form.
8939***************************************************************************/
8940
8941void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8942{
8943 int iService;
8944
8945 if (show_defaults)
8946 defaults_saved = False;
8947
8948 dump_globals(f);
8949
8950 dump_a_service(&sDefault, f);
8951
8952 for (iService = 0; iService < maxtoprint; iService++) {
8953 fprintf(f,"\n");
8954 lp_dump_one(f, show_defaults, iService);
8955 }
8956}
8957
8958/***************************************************************************
8959Display the contents of one service in human-readable form.
8960***************************************************************************/
8961
8962void lp_dump_one(FILE * f, bool show_defaults, int snum)
8963{
8964 if (VALID(snum)) {
8965 if (ServicePtrs[snum]->szService[0] == '\0')
8966 return;
8967 dump_a_service(ServicePtrs[snum], f);
8968 }
8969}
8970
8971/***************************************************************************
8972Return the number of the service with the given name, or -1 if it doesn't
8973exist. Note that this is a DIFFERENT ANIMAL from the internal function
8974getservicebyname()! This works ONLY if all services have been loaded, and
8975does not copy the found service.
8976***************************************************************************/
8977
8978int lp_servicenumber(const char *pszServiceName)
8979{
8980 int iService;
8981 fstring serviceName;
8982
8983 if (!pszServiceName) {
8984 return GLOBAL_SECTION_SNUM;
8985 }
8986
8987 for (iService = iNumServices - 1; iService >= 0; iService--) {
8988 if (VALID(iService) && ServicePtrs[iService]->szService) {
8989 /*
8990 * The substitution here is used to support %U is
8991 * service names
8992 */
8993 fstrcpy(serviceName, ServicePtrs[iService]->szService);
8994 standard_sub_basic(get_current_username(),
8995 current_user_info.domain,
8996 serviceName,sizeof(serviceName));
8997 if (strequal(serviceName, pszServiceName)) {
8998 break;
8999 }
9000 }
9001 }
9002
9003 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9004 time_t last_mod;
9005
9006 if (!usershare_exists(iService, &last_mod)) {
9007 /* Remove the share security tdb entry for it. */
9008 delete_share_security(lp_servicename(iService));
9009 /* Remove it from the array. */
9010 free_service_byindex(iService);
9011 /* Doesn't exist anymore. */
9012 return GLOBAL_SECTION_SNUM;
9013 }
9014
9015 /* Has it been modified ? If so delete and reload. */
9016 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9017 /* Remove it from the array. */
9018 free_service_byindex(iService);
9019 /* and now reload it. */
9020 iService = load_usershare_service(pszServiceName);
9021 }
9022 }
9023
9024 if (iService < 0) {
9025 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9026 return GLOBAL_SECTION_SNUM;
9027 }
9028
9029 return (iService);
9030}
9031
9032bool share_defined(const char *service_name)
9033{
9034 return (lp_servicenumber(service_name) != -1);
9035}
9036
9037struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9038 const char *sharename)
9039{
9040 struct share_params *result;
9041 char *sname;
9042 int snum;
9043
9044 if (!(sname = SMB_STRDUP(sharename))) {
9045 return NULL;
9046 }
9047
9048 snum = find_service(sname);
9049 SAFE_FREE(sname);
9050
9051 if (snum < 0) {
9052 return NULL;
9053 }
9054
9055 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9056 DEBUG(0, ("talloc failed\n"));
9057 return NULL;
9058 }
9059
9060 result->service = snum;
9061 return result;
9062}
9063
9064struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9065{
9066 struct share_iterator *result;
9067
9068 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9069 DEBUG(0, ("talloc failed\n"));
9070 return NULL;
9071 }
9072
9073 result->next_id = 0;
9074 return result;
9075}
9076
9077struct share_params *next_share(struct share_iterator *list)
9078{
9079 struct share_params *result;
9080
9081 while (!lp_snum_ok(list->next_id) &&
9082 (list->next_id < lp_numservices())) {
9083 list->next_id += 1;
9084 }
9085
9086 if (list->next_id >= lp_numservices()) {
9087 return NULL;
9088 }
9089
9090 if (!(result = TALLOC_P(list, struct share_params))) {
9091 DEBUG(0, ("talloc failed\n"));
9092 return NULL;
9093 }
9094
9095 result->service = list->next_id;
9096 list->next_id += 1;
9097 return result;
9098}
9099
9100struct share_params *next_printer(struct share_iterator *list)
9101{
9102 struct share_params *result;
9103
9104 while ((result = next_share(list)) != NULL) {
9105 if (lp_print_ok(result->service)) {
9106 break;
9107 }
9108 }
9109 return result;
9110}
9111
9112/*
9113 * This is a hack for a transition period until we transformed all code from
9114 * service numbers to struct share_params.
9115 */
9116
9117struct share_params *snum2params_static(int snum)
9118{
9119 static struct share_params result;
9120 result.service = snum;
9121 return &result;
9122}
9123
9124/*******************************************************************
9125 A useful volume label function.
9126********************************************************************/
9127
9128const char *volume_label(int snum)
9129{
9130 char *ret;
9131 const char *label = lp_volume(snum);
9132 if (!*label) {
9133 label = lp_servicename(snum);
9134 }
9135
9136 /* This returns a 33 byte guarenteed null terminated string. */
9137 ret = talloc_strndup(talloc_tos(), label, 32);
9138 if (!ret) {
9139 return "";
9140 }
9141 return ret;
9142}
9143
9144/*******************************************************************
9145 Set the server type we will announce as via nmbd.
9146********************************************************************/
9147
9148static void set_default_server_announce_type(void)
9149{
9150 default_server_announce = 0;
9151 default_server_announce |= SV_TYPE_WORKSTATION;
9152 default_server_announce |= SV_TYPE_SERVER;
9153 default_server_announce |= SV_TYPE_SERVER_UNIX;
9154
9155 /* note that the flag should be set only if we have a
9156 printer service but nmbd doesn't actually load the
9157 services so we can't tell --jerry */
9158
9159 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9160
9161 switch (lp_announce_as()) {
9162 case ANNOUNCE_AS_NT_SERVER:
9163 default_server_announce |= SV_TYPE_SERVER_NT;
9164 /* fall through... */
9165 case ANNOUNCE_AS_NT_WORKSTATION:
9166 default_server_announce |= SV_TYPE_NT;
9167 break;
9168 case ANNOUNCE_AS_WIN95:
9169 default_server_announce |= SV_TYPE_WIN95_PLUS;
9170 break;
9171 case ANNOUNCE_AS_WFW:
9172 default_server_announce |= SV_TYPE_WFW;
9173 break;
9174 default:
9175 break;
9176 }
9177
9178 switch (lp_server_role()) {
9179 case ROLE_DOMAIN_MEMBER:
9180 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9181 break;
9182 case ROLE_DOMAIN_PDC:
9183 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9184 break;
9185 case ROLE_DOMAIN_BDC:
9186 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9187 break;
9188 case ROLE_STANDALONE:
9189 default:
9190 break;
9191 }
9192 if (lp_time_server())
9193 default_server_announce |= SV_TYPE_TIME_SOURCE;
9194
9195 if (lp_host_msdfs())
9196 default_server_announce |= SV_TYPE_DFS_SERVER;
9197}
9198
9199/***********************************************************
9200 returns role of Samba server
9201************************************************************/
9202
9203int lp_server_role(void)
9204{
9205 return server_role;
9206}
9207
9208/***********************************************************
9209 If we are PDC then prefer us as DMB
9210************************************************************/
9211
9212bool lp_domain_master(void)
9213{
9214 if (Globals.iDomainMaster == Auto)
9215 return (lp_server_role() == ROLE_DOMAIN_PDC);
9216
9217 return (bool)Globals.iDomainMaster;
9218}
9219
9220/***********************************************************
9221 If we are DMB then prefer us as LMB
9222************************************************************/
9223
9224bool lp_preferred_master(void)
9225{
9226 if (Globals.iPreferredMaster == Auto)
9227 return (lp_local_master() && lp_domain_master());
9228
9229 return (bool)Globals.iPreferredMaster;
9230}
9231
9232/*******************************************************************
9233 Remove a service.
9234********************************************************************/
9235
9236void lp_remove_service(int snum)
9237{
9238 ServicePtrs[snum]->valid = False;
9239 invalid_services[num_invalid_services++] = snum;
9240}
9241
9242/*******************************************************************
9243 Copy a service.
9244********************************************************************/
9245
9246void lp_copy_service(int snum, const char *new_name)
9247{
9248 do_section(new_name, NULL);
9249 if (snum >= 0) {
9250 snum = lp_servicenumber(new_name);
9251 if (snum >= 0)
9252 lp_do_parameter(snum, "copy", lp_servicename(snum));
9253 }
9254}
9255
9256
9257/*******************************************************************
9258 Get the default server type we will announce as via nmbd.
9259********************************************************************/
9260
9261int lp_default_server_announce(void)
9262{
9263 return default_server_announce;
9264}
9265
9266/*******************************************************************
9267 Split the announce version into major and minor numbers.
9268********************************************************************/
9269
9270int lp_major_announce_version(void)
9271{
9272 static bool got_major = False;
9273 static int major_version = DEFAULT_MAJOR_VERSION;
9274 char *vers;
9275 char *p;
9276
9277 if (got_major)
9278 return major_version;
9279
9280 got_major = True;
9281 if ((vers = lp_announce_version()) == NULL)
9282 return major_version;
9283
9284 if ((p = strchr_m(vers, '.')) == 0)
9285 return major_version;
9286
9287 *p = '\0';
9288 major_version = atoi(vers);
9289 return major_version;
9290}
9291
9292int lp_minor_announce_version(void)
9293{
9294 static bool got_minor = False;
9295 static int minor_version = DEFAULT_MINOR_VERSION;
9296 char *vers;
9297 char *p;
9298
9299 if (got_minor)
9300 return minor_version;
9301
9302 got_minor = True;
9303 if ((vers = lp_announce_version()) == NULL)
9304 return minor_version;
9305
9306 if ((p = strchr_m(vers, '.')) == 0)
9307 return minor_version;
9308
9309 p++;
9310 minor_version = atoi(p);
9311 return minor_version;
9312}
9313
9314/***********************************************************
9315 Set the global name resolution order (used in smbclient).
9316************************************************************/
9317
9318void lp_set_name_resolve_order(const char *new_order)
9319{
9320 string_set(&Globals.szNameResolveOrder, new_order);
9321}
9322
9323const char *lp_printername(int snum)
9324{
9325 const char *ret = _lp_printername(snum);
9326 if (ret == NULL || (ret != NULL && *ret == '\0'))
9327 ret = lp_const_servicename(snum);
9328
9329 return ret;
9330}
9331
9332
9333/***********************************************************
9334 Allow daemons such as winbindd to fix their logfile name.
9335************************************************************/
9336
9337void lp_set_logfile(const char *name)
9338{
9339 string_set(&Globals.szLogFile, name);
9340 debug_set_logfile(name);
9341}
9342
9343/*******************************************************************
9344 Return the max print jobs per queue.
9345********************************************************************/
9346
9347int lp_maxprintjobs(int snum)
9348{
9349 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9350 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9351 maxjobs = PRINT_MAX_JOBID - 1;
9352
9353 return maxjobs;
9354}
9355
9356const char *lp_printcapname(void)
9357{
9358 if ((Globals.szPrintcapname != NULL) &&
9359 (Globals.szPrintcapname[0] != '\0'))
9360 return Globals.szPrintcapname;
9361
9362 if (sDefault.iPrinting == PRINT_CUPS) {
9363#ifdef HAVE_CUPS
9364 return "cups";
9365#else
9366 return "lpstat";
9367#endif
9368 }
9369
9370 if (sDefault.iPrinting == PRINT_BSD)
9371 return "/etc/printcap";
9372
9373 return PRINTCAP_NAME;
9374}
9375
9376/*******************************************************************
9377 Ensure we don't use sendfile if server smb signing is active.
9378********************************************************************/
9379
9380static uint32 spoolss_state;
9381
9382bool lp_disable_spoolss( void )
9383{
9384 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9385 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9386
9387 return spoolss_state == SVCCTL_STOPPED ? True : False;
9388}
9389
9390void lp_set_spoolss_state( uint32 state )
9391{
9392 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9393
9394 spoolss_state = state;
9395}
9396
9397uint32 lp_get_spoolss_state( void )
9398{
9399 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9400}
9401
9402/*******************************************************************
9403 Ensure we don't use sendfile if server smb signing is active.
9404********************************************************************/
9405
9406bool lp_use_sendfile(int snum)
9407{
9408 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9409 if (Protocol < PROTOCOL_NT1) {
9410 return False;
9411 }
9412 return (_lp_use_sendfile(snum) &&
9413 (get_remote_arch() != RA_WIN95) &&
9414 !srv_is_signing_active());
9415}
9416
9417/*******************************************************************
9418 Turn off sendfile if we find the underlying OS doesn't support it.
9419********************************************************************/
9420
9421void set_use_sendfile(int snum, bool val)
9422{
9423 if (LP_SNUM_OK(snum))
9424 ServicePtrs[snum]->bUseSendfile = val;
9425 else
9426 sDefault.bUseSendfile = val;
9427}
9428
9429/*******************************************************************
9430 Turn off storing DOS attributes if this share doesn't support it.
9431********************************************************************/
9432
9433void set_store_dos_attributes(int snum, bool val)
9434{
9435 if (!LP_SNUM_OK(snum))
9436 return;
9437 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9438}
9439
9440void lp_set_mangling_method(const char *new_method)
9441{
9442 string_set(&Globals.szManglingMethod, new_method);
9443}
9444
9445/*******************************************************************
9446 Global state for POSIX pathname processing.
9447********************************************************************/
9448
9449static bool posix_pathnames;
9450
9451bool lp_posix_pathnames(void)
9452{
9453 return posix_pathnames;
9454}
9455
9456/*******************************************************************
9457 Change everything needed to ensure POSIX pathname processing (currently
9458 not much).
9459********************************************************************/
9460
9461void lp_set_posix_pathnames(void)
9462{
9463 posix_pathnames = True;
9464}
9465
9466/*******************************************************************
9467 Global state for POSIX lock processing - CIFS unix extensions.
9468********************************************************************/
9469
9470bool posix_default_lock_was_set;
9471static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9472
9473enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9474{
9475 if (posix_default_lock_was_set) {
9476 return posix_cifsx_locktype;
9477 } else {
9478 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9479 }
9480}
9481
9482/*******************************************************************
9483********************************************************************/
9484
9485void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9486{
9487 posix_default_lock_was_set = True;
9488 posix_cifsx_locktype = val;
9489}
9490
9491int lp_min_receive_file_size(void)
9492{
9493 if (Globals.iminreceivefile < 0) {
9494 return 0;
9495 }
9496 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9497}
9498
9499/*******************************************************************
9500 If socket address is an empty character string, it is necessary to
9501 define it as "0.0.0.0".
9502********************************************************************/
9503
9504const char *lp_socket_address(void)
9505{
9506 char *sock_addr = Globals.szSocketAddress;
9507
9508 if (sock_addr[0] == '\0'){
9509 string_set(&Globals.szSocketAddress, "0.0.0.0");
9510 }
9511 return Globals.szSocketAddress;
9512}
Note: See TracBrowser for help on using the repository browser.