s3:loadparm: Change the "ldap deref" value "defualt" to "auto".
[Samba/bjacke.git] / source3 / param / loadparm.c
blobbd70ee1828d69f48e18a0d422fb0199865dfb23e
1 /*
2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12 Copyright (C) Michael Adam 2008
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.
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.
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/>.
29 * Load parameters.
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.
35 * To add a parameter:
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
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!
54 #include "includes.h"
55 #include "printing.h"
57 #ifdef HAVE_SYS_SYSCTL_H
58 #include <sys/sysctl.h>
59 #endif
61 #ifdef HAVE_HTTPCONNECTENCRYPT
62 #include <cups/http.h>
63 #endif
65 bool bLoaded = False;
67 extern userdom_struct current_user_info;
69 #ifndef GLOBAL_NAME
70 #define GLOBAL_NAME "global"
71 #endif
73 #ifndef PRINTERS_NAME
74 #define PRINTERS_NAME "printers"
75 #endif
77 #ifndef HOMES_NAME
78 #define HOMES_NAME "homes"
79 #endif
81 /* the special value for the include parameter
82 * to be interpreted not as a file name but to
83 * trigger loading of the global smb.conf options
84 * from registry. */
85 #ifndef INCLUDE_REGISTRY_NAME
86 #define INCLUDE_REGISTRY_NAME "registry"
87 #endif
89 static bool in_client = False; /* Not in the client by default */
90 static struct smbconf_csn conf_last_csn;
92 #define CONFIG_BACKEND_FILE 0
93 #define CONFIG_BACKEND_REGISTRY 1
95 static int config_backend = CONFIG_BACKEND_FILE;
97 /* some helpful bits */
98 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
99 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
101 #define USERSHARE_VALID 1
102 #define USERSHARE_PENDING_DELETE 2
104 static bool defaults_saved = False;
106 struct param_opt_struct {
107 struct param_opt_struct *prev, *next;
108 char *key;
109 char *value;
110 char **list;
114 * This structure describes global (ie., server-wide) parameters.
116 struct global {
117 int ConfigBackend;
118 char *smb_ports;
119 char *dos_charset;
120 char *unix_charset;
121 char *display_charset;
122 char *szPrintcapname;
123 char *szAddPortCommand;
124 char *szEnumPortsCommand;
125 char *szAddPrinterCommand;
126 char *szDeletePrinterCommand;
127 char *szOs2DriverMap;
128 char *szLockDir;
129 char *szStateDir;
130 char *szCacheDir;
131 char *szPidDir;
132 char *szRootdir;
133 char *szDefaultService;
134 char *szGetQuota;
135 char *szSetQuota;
136 char *szMsgCommand;
137 char *szServerString;
138 char *szAutoServices;
139 char *szPasswdProgram;
140 char *szPasswdChat;
141 char *szLogFile;
142 char *szConfigFile;
143 char *szSMBPasswdFile;
144 char *szPrivateDir;
145 char *szPassdbBackend;
146 char **szPreloadModules;
147 char *szPasswordServer;
148 char *szSocketOptions;
149 char *szRealm;
150 char *szAfsUsernameMap;
151 int iAfsTokenLifetime;
152 char *szLogNtTokenCommand;
153 char *szUsernameMap;
154 char *szLogonScript;
155 char *szLogonPath;
156 char *szLogonDrive;
157 char *szLogonHome;
158 char **szWINSservers;
159 char **szInterfaces;
160 char *szRemoteAnnounce;
161 char *szRemoteBrowseSync;
162 char *szSocketAddress;
163 char *szNISHomeMapName;
164 char *szAnnounceVersion; /* This is initialised in init_globals */
165 char *szWorkgroup;
166 char *szNetbiosName;
167 char **szNetbiosAliases;
168 char *szNetbiosScope;
169 char *szNameResolveOrder;
170 char *szPanicAction;
171 char *szAddUserScript;
172 char *szRenameUserScript;
173 char *szDelUserScript;
174 char *szAddGroupScript;
175 char *szDelGroupScript;
176 char *szAddUserToGroupScript;
177 char *szDelUserFromGroupScript;
178 char *szSetPrimaryGroupScript;
179 char *szAddMachineScript;
180 char *szShutdownScript;
181 char *szAbortShutdownScript;
182 char *szUsernameMapScript;
183 char *szCheckPasswordScript;
184 char *szWINSHook;
185 char *szUtmpDir;
186 char *szWtmpDir;
187 bool bUtmp;
188 char *szIdmapUID;
189 char *szIdmapGID;
190 bool bPassdbExpandExplicit;
191 int AlgorithmicRidBase;
192 char *szTemplateHomedir;
193 char *szTemplateShell;
194 char *szWinbindSeparator;
195 bool bWinbindEnumUsers;
196 bool bWinbindEnumGroups;
197 bool bWinbindUseDefaultDomain;
198 bool bWinbindTrustedDomainsOnly;
199 bool bWinbindNestedGroups;
200 int winbind_expand_groups;
201 bool bWinbindRefreshTickets;
202 bool bWinbindOfflineLogon;
203 bool bWinbindNormalizeNames;
204 bool bWinbindRpcOnly;
205 bool bCreateKrb5Conf;
206 char *szIdmapBackend;
207 char *szIdmapAllocBackend;
208 char *szAddShareCommand;
209 char *szChangeShareCommand;
210 char *szDeleteShareCommand;
211 char **szEventLogs;
212 char *szGuestaccount;
213 char *szManglingMethod;
214 char **szServicesList;
215 char *szUsersharePath;
216 char *szUsershareTemplateShare;
217 char **szUsersharePrefixAllowList;
218 char **szUsersharePrefixDenyList;
219 int mangle_prefix;
220 int max_log_size;
221 char *szLogLevel;
222 int max_xmit;
223 int max_mux;
224 int max_open_files;
225 int open_files_db_hash_size;
226 int pwordlevel;
227 int unamelevel;
228 int deadtime;
229 bool getwd_cache;
230 int maxprotocol;
231 int minprotocol;
232 int security;
233 char **AuthMethods;
234 bool paranoid_server_security;
235 int maxdisksize;
236 int lpqcachetime;
237 int iMaxSmbdProcesses;
238 bool bDisableSpoolss;
239 int syslog;
240 int os_level;
241 bool enhanced_browsing;
242 int max_ttl;
243 int max_wins_ttl;
244 int min_wins_ttl;
245 int lm_announce;
246 int lm_interval;
247 int announce_as; /* This is initialised in init_globals */
248 int machine_password_timeout;
249 int map_to_guest;
250 int oplock_break_wait_time;
251 int winbind_cache_time;
252 int winbind_reconnect_delay;
253 int winbind_max_idle_children;
254 char **szWinbindNssInfo;
255 int iLockSpinTime;
256 char *szLdapMachineSuffix;
257 char *szLdapUserSuffix;
258 char *szLdapIdmapSuffix;
259 char *szLdapGroupSuffix;
260 int ldap_ssl;
261 bool ldap_ssl_ads;
262 int ldap_deref;
263 int ldap_follow_referral;
264 char *szLdapSuffix;
265 char *szLdapAdminDn;
266 int ldap_debug_level;
267 int ldap_debug_threshold;
268 int iAclCompat;
269 char *szCupsServer;
270 int CupsEncrypt;
271 char *szIPrintServer;
272 char *ctdbdSocket;
273 char **szClusterAddresses;
274 bool clustering;
275 int ctdb_timeout;
276 int ldap_passwd_sync;
277 int ldap_replication_sleep;
278 int ldap_timeout; /* This is initialised in init_globals */
279 int ldap_connection_timeout;
280 int ldap_page_size;
281 bool ldap_delete_dn;
282 bool bMsAddPrinterWizard;
283 bool bDNSproxy;
284 bool bWINSsupport;
285 bool bWINSproxy;
286 bool bLocalMaster;
287 int iPreferredMaster;
288 int iDomainMaster;
289 bool bDomainLogons;
290 char **szInitLogonDelayedHosts;
291 int InitLogonDelay;
292 bool bEncryptPasswords;
293 bool bUpdateEncrypt;
294 int clientSchannel;
295 int serverSchannel;
296 bool bNullPasswords;
297 bool bObeyPamRestrictions;
298 bool bLoadPrinters;
299 int PrintcapCacheTime;
300 bool bLargeReadwrite;
301 bool bReadRaw;
302 bool bWriteRaw;
303 bool bSyslogOnly;
304 bool bBrowseList;
305 bool bNISHomeMap;
306 bool bTimeServer;
307 bool bBindInterfacesOnly;
308 bool bPamPasswordChange;
309 bool bUnixPasswdSync;
310 bool bPasswdChatDebug;
311 int iPasswdChatTimeout;
312 bool bTimestampLogs;
313 bool bNTSmbSupport;
314 bool bNTPipeSupport;
315 bool bNTStatusSupport;
316 bool bStatCache;
317 int iMaxStatCacheSize;
318 bool bKernelOplocks;
319 bool bAllowTrustedDomains;
320 bool bLanmanAuth;
321 bool bNTLMAuth;
322 bool bUseSpnego;
323 bool bClientLanManAuth;
324 bool bClientNTLMv2Auth;
325 bool bClientPlaintextAuth;
326 bool bClientUseSpnego;
327 bool bDebugPrefixTimestamp;
328 bool bDebugHiresTimestamp;
329 bool bDebugPid;
330 bool bDebugUid;
331 bool bDebugClass;
332 bool bEnableCoreFiles;
333 bool bHostMSDfs;
334 bool bUseMmap;
335 bool bHostnameLookups;
336 bool bUnixExtensions;
337 bool bDisableNetbios;
338 char * szDedicatedKeytabFile;
339 int iKerberosMethod;
340 bool bDeferSharingViolations;
341 bool bEnablePrivileges;
342 bool bASUSupport;
343 bool bUsershareOwnerOnly;
344 bool bUsershareAllowGuests;
345 bool bRegistryShares;
346 int restrict_anonymous;
347 int name_cache_timeout;
348 int client_signing;
349 int server_signing;
350 int client_ldap_sasl_wrapping;
351 int iUsershareMaxShares;
352 int iIdmapCacheTime;
353 int iIdmapNegativeCacheTime;
354 bool bResetOnZeroVC;
355 int iKeepalive;
356 int iminreceivefile;
357 struct param_opt_struct *param_opt;
358 int cups_connection_timeout;
359 char *szSMBPerfcountModule;
360 bool bMapUntrustedToDomain;
363 static struct global Globals;
366 * This structure describes a single service.
368 struct service {
369 bool valid;
370 bool autoloaded;
371 int usershare;
372 struct timespec usershare_last_mod;
373 char *szService;
374 char *szPath;
375 char *szUsername;
376 char **szInvalidUsers;
377 char **szValidUsers;
378 char **szAdminUsers;
379 char *szCopy;
380 char *szInclude;
381 char *szPreExec;
382 char *szPostExec;
383 char *szRootPreExec;
384 char *szRootPostExec;
385 char *szCupsOptions;
386 char *szPrintcommand;
387 char *szLpqcommand;
388 char *szLprmcommand;
389 char *szLppausecommand;
390 char *szLpresumecommand;
391 char *szQueuepausecommand;
392 char *szQueueresumecommand;
393 char *szPrintername;
394 char *szPrintjobUsername;
395 char *szDontdescend;
396 char **szHostsallow;
397 char **szHostsdeny;
398 char *szMagicScript;
399 char *szMagicOutput;
400 char *szVetoFiles;
401 char *szHideFiles;
402 char *szVetoOplockFiles;
403 char *comment;
404 char *force_user;
405 char *force_group;
406 char **readlist;
407 char **writelist;
408 char **printer_admin;
409 char *volume;
410 char *fstype;
411 char **szVfsObjects;
412 char *szMSDfsProxy;
413 char *szAioWriteBehind;
414 char *szDfree;
415 int iMinPrintSpace;
416 int iMaxPrintJobs;
417 int iMaxReportedPrintJobs;
418 int iWriteCacheSize;
419 int iCreate_mask;
420 int iCreate_force_mode;
421 int iSecurity_mask;
422 int iSecurity_force_mode;
423 int iDir_mask;
424 int iDir_force_mode;
425 int iDir_Security_mask;
426 int iDir_Security_force_mode;
427 int iMaxConnections;
428 int iDefaultCase;
429 int iPrinting;
430 int iOplockContentionLimit;
431 int iCSCPolicy;
432 int iBlock_size;
433 int iDfreeCacheTime;
434 bool bPreexecClose;
435 bool bRootpreexecClose;
436 int iCaseSensitive;
437 bool bCasePreserve;
438 bool bShortCasePreserve;
439 bool bHideDotFiles;
440 bool bHideSpecialFiles;
441 bool bHideUnReadable;
442 bool bHideUnWriteableFiles;
443 bool bBrowseable;
444 bool bAccessBasedShareEnum;
445 bool bAvailable;
446 bool bRead_only;
447 bool bNo_set_dir;
448 bool bGuest_only;
449 bool bAdministrative_share;
450 bool bGuest_ok;
451 bool bPrint_ok;
452 bool bMap_system;
453 bool bMap_hidden;
454 bool bMap_archive;
455 bool bStoreDosAttributes;
456 bool bDmapiSupport;
457 bool bLocking;
458 int iStrictLocking;
459 bool bPosixLocking;
460 bool bShareModes;
461 bool bOpLocks;
462 bool bLevel2OpLocks;
463 bool bOnlyUser;
464 bool bMangledNames;
465 bool bWidelinks;
466 bool bSymlinks;
467 bool bSyncAlways;
468 bool bStrictAllocate;
469 bool bStrictSync;
470 char magic_char;
471 struct bitmap *copymap;
472 bool bDeleteReadonly;
473 bool bFakeOplocks;
474 bool bDeleteVetoFiles;
475 bool bDosFilemode;
476 bool bDosFiletimes;
477 bool bDosFiletimeResolution;
478 bool bFakeDirCreateTimes;
479 bool bBlockingLocks;
480 bool bInheritPerms;
481 bool bInheritACLS;
482 bool bInheritOwner;
483 bool bMSDfsRoot;
484 bool bUseClientDriver;
485 bool bDefaultDevmode;
486 bool bForcePrintername;
487 bool bNTAclSupport;
488 bool bForceUnknownAclUser;
489 bool bUseSendfile;
490 bool bProfileAcls;
491 bool bMap_acl_inherit;
492 bool bAfs_Share;
493 bool bEASupport;
494 bool bAclCheckPermissions;
495 bool bAclMapFullControl;
496 bool bAclGroupControl;
497 bool bChangeNotify;
498 bool bKernelChangeNotify;
499 int iallocation_roundup_size;
500 int iAioReadSize;
501 int iAioWriteSize;
502 int iMap_readonly;
503 int iDirectoryNameCacheSize;
504 int ismb_encrypt;
505 struct param_opt_struct *param_opt;
507 char dummy[3]; /* for alignment */
511 /* This is a default service used to prime a services structure */
512 static struct service sDefault = {
513 True, /* valid */
514 False, /* not autoloaded */
515 0, /* not a usershare */
516 {0, }, /* No last mod time */
517 NULL, /* szService */
518 NULL, /* szPath */
519 NULL, /* szUsername */
520 NULL, /* szInvalidUsers */
521 NULL, /* szValidUsers */
522 NULL, /* szAdminUsers */
523 NULL, /* szCopy */
524 NULL, /* szInclude */
525 NULL, /* szPreExec */
526 NULL, /* szPostExec */
527 NULL, /* szRootPreExec */
528 NULL, /* szRootPostExec */
529 NULL, /* szCupsOptions */
530 NULL, /* szPrintcommand */
531 NULL, /* szLpqcommand */
532 NULL, /* szLprmcommand */
533 NULL, /* szLppausecommand */
534 NULL, /* szLpresumecommand */
535 NULL, /* szQueuepausecommand */
536 NULL, /* szQueueresumecommand */
537 NULL, /* szPrintername */
538 NULL, /* szPrintjobUsername */
539 NULL, /* szDontdescend */
540 NULL, /* szHostsallow */
541 NULL, /* szHostsdeny */
542 NULL, /* szMagicScript */
543 NULL, /* szMagicOutput */
544 NULL, /* szVetoFiles */
545 NULL, /* szHideFiles */
546 NULL, /* szVetoOplockFiles */
547 NULL, /* comment */
548 NULL, /* force user */
549 NULL, /* force group */
550 NULL, /* readlist */
551 NULL, /* writelist */
552 NULL, /* printer admin */
553 NULL, /* volume */
554 NULL, /* fstype */
555 NULL, /* vfs objects */
556 NULL, /* szMSDfsProxy */
557 NULL, /* szAioWriteBehind */
558 NULL, /* szDfree */
559 0, /* iMinPrintSpace */
560 1000, /* iMaxPrintJobs */
561 0, /* iMaxReportedPrintJobs */
562 0, /* iWriteCacheSize */
563 0744, /* iCreate_mask */
564 0000, /* iCreate_force_mode */
565 0777, /* iSecurity_mask */
566 0, /* iSecurity_force_mode */
567 0755, /* iDir_mask */
568 0000, /* iDir_force_mode */
569 0777, /* iDir_Security_mask */
570 0, /* iDir_Security_force_mode */
571 0, /* iMaxConnections */
572 CASE_LOWER, /* iDefaultCase */
573 DEFAULT_PRINTING, /* iPrinting */
574 2, /* iOplockContentionLimit */
575 0, /* iCSCPolicy */
576 1024, /* iBlock_size */
577 0, /* iDfreeCacheTime */
578 False, /* bPreexecClose */
579 False, /* bRootpreexecClose */
580 Auto, /* case sensitive */
581 True, /* case preserve */
582 True, /* short case preserve */
583 True, /* bHideDotFiles */
584 False, /* bHideSpecialFiles */
585 False, /* bHideUnReadable */
586 False, /* bHideUnWriteableFiles */
587 True, /* bBrowseable */
588 False, /* bAccessBasedShareEnum */
589 True, /* bAvailable */
590 True, /* bRead_only */
591 True, /* bNo_set_dir */
592 False, /* bGuest_only */
593 False, /* bAdministrative_share */
594 False, /* bGuest_ok */
595 False, /* bPrint_ok */
596 False, /* bMap_system */
597 False, /* bMap_hidden */
598 True, /* bMap_archive */
599 False, /* bStoreDosAttributes */
600 False, /* bDmapiSupport */
601 True, /* bLocking */
602 Auto, /* iStrictLocking */
603 True, /* bPosixLocking */
604 True, /* bShareModes */
605 True, /* bOpLocks */
606 True, /* bLevel2OpLocks */
607 False, /* bOnlyUser */
608 True, /* bMangledNames */
609 True, /* bWidelinks */
610 True, /* bSymlinks */
611 False, /* bSyncAlways */
612 False, /* bStrictAllocate */
613 False, /* bStrictSync */
614 '~', /* magic char */
615 NULL, /* copymap */
616 False, /* bDeleteReadonly */
617 False, /* bFakeOplocks */
618 False, /* bDeleteVetoFiles */
619 False, /* bDosFilemode */
620 True, /* bDosFiletimes */
621 False, /* bDosFiletimeResolution */
622 False, /* bFakeDirCreateTimes */
623 True, /* bBlockingLocks */
624 False, /* bInheritPerms */
625 False, /* bInheritACLS */
626 False, /* bInheritOwner */
627 False, /* bMSDfsRoot */
628 False, /* bUseClientDriver */
629 True, /* bDefaultDevmode */
630 False, /* bForcePrintername */
631 True, /* bNTAclSupport */
632 False, /* bForceUnknownAclUser */
633 False, /* bUseSendfile */
634 False, /* bProfileAcls */
635 False, /* bMap_acl_inherit */
636 False, /* bAfs_Share */
637 False, /* bEASupport */
638 True, /* bAclCheckPermissions */
639 True, /* bAclMapFullControl */
640 False, /* bAclGroupControl */
641 True, /* bChangeNotify */
642 True, /* bKernelChangeNotify */
643 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
644 0, /* iAioReadSize */
645 0, /* iAioWriteSize */
646 MAP_READONLY_YES, /* iMap_readonly */
647 #ifdef BROKEN_DIRECTORY_HANDLING
648 0, /* iDirectoryNameCacheSize */
649 #else
650 100, /* iDirectoryNameCacheSize */
651 #endif
652 Auto, /* ismb_encrypt */
653 NULL, /* Parametric options */
655 "" /* dummy */
658 /* local variables */
659 static struct service **ServicePtrs = NULL;
660 static int iNumServices = 0;
661 static int iServiceIndex = 0;
662 static struct db_context *ServiceHash;
663 static int *invalid_services = NULL;
664 static int num_invalid_services = 0;
665 static bool bInGlobalSection = True;
666 static bool bGlobalOnly = False;
667 static int server_role;
668 static int default_server_announce;
670 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
672 /* prototypes for the special type handlers */
673 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
674 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
675 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
676 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
677 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
678 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
679 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
680 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
681 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
682 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
683 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
684 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
686 static void set_server_role(void);
687 static void set_default_server_announce_type(void);
688 static void set_allowed_client_auth(void);
690 static void *lp_local_ptr(struct service *service, void *ptr);
692 static void add_to_file_list(const char *fname, const char *subfname);
694 static const struct enum_list enum_protocol[] = {
695 {PROTOCOL_SMB2, "SMB2"},
696 {PROTOCOL_NT1, "NT1"},
697 {PROTOCOL_LANMAN2, "LANMAN2"},
698 {PROTOCOL_LANMAN1, "LANMAN1"},
699 {PROTOCOL_CORE, "CORE"},
700 {PROTOCOL_COREPLUS, "COREPLUS"},
701 {PROTOCOL_COREPLUS, "CORE+"},
702 {-1, NULL}
705 static const struct enum_list enum_security[] = {
706 {SEC_SHARE, "SHARE"},
707 {SEC_USER, "USER"},
708 {SEC_SERVER, "SERVER"},
709 {SEC_DOMAIN, "DOMAIN"},
710 #ifdef HAVE_ADS
711 {SEC_ADS, "ADS"},
712 #endif
713 {-1, NULL}
716 static const struct enum_list enum_printing[] = {
717 {PRINT_SYSV, "sysv"},
718 {PRINT_AIX, "aix"},
719 {PRINT_HPUX, "hpux"},
720 {PRINT_BSD, "bsd"},
721 {PRINT_QNX, "qnx"},
722 {PRINT_PLP, "plp"},
723 {PRINT_LPRNG, "lprng"},
724 {PRINT_CUPS, "cups"},
725 {PRINT_IPRINT, "iprint"},
726 {PRINT_LPRNT, "nt"},
727 {PRINT_LPROS2, "os2"},
728 #ifdef DEVELOPER
729 {PRINT_TEST, "test"},
730 {PRINT_VLP, "vlp"},
731 #endif /* DEVELOPER */
732 {-1, NULL}
735 static const struct enum_list enum_ldap_sasl_wrapping[] = {
736 {0, "plain"},
737 {ADS_AUTH_SASL_SIGN, "sign"},
738 {ADS_AUTH_SASL_SEAL, "seal"},
739 {-1, NULL}
742 static const struct enum_list enum_ldap_ssl[] = {
743 {LDAP_SSL_OFF, "no"},
744 {LDAP_SSL_OFF, "off"},
745 {LDAP_SSL_START_TLS, "start tls"},
746 {LDAP_SSL_START_TLS, "start_tls"},
747 {-1, NULL}
750 /* LDAP Dereferencing Alias types */
751 #define SAMBA_LDAP_DEREF_NEVER 0
752 #define SAMBA_LDAP_DEREF_SEARCHING 1
753 #define SAMBA_LDAP_DEREF_FINDING 2
754 #define SAMBA_LDAP_DEREF_ALWAYS 3
756 static const struct enum_list enum_ldap_deref[] = {
757 {SAMBA_LDAP_DEREF_NEVER, "never"},
758 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
759 {SAMBA_LDAP_DEREF_FINDING, "finding"},
760 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
761 {-1, "auto"}
764 static const struct enum_list enum_ldap_passwd_sync[] = {
765 {LDAP_PASSWD_SYNC_OFF, "no"},
766 {LDAP_PASSWD_SYNC_OFF, "off"},
767 {LDAP_PASSWD_SYNC_ON, "yes"},
768 {LDAP_PASSWD_SYNC_ON, "on"},
769 {LDAP_PASSWD_SYNC_ONLY, "only"},
770 {-1, NULL}
773 /* Types of machine we can announce as. */
774 #define ANNOUNCE_AS_NT_SERVER 1
775 #define ANNOUNCE_AS_WIN95 2
776 #define ANNOUNCE_AS_WFW 3
777 #define ANNOUNCE_AS_NT_WORKSTATION 4
779 static const struct enum_list enum_announce_as[] = {
780 {ANNOUNCE_AS_NT_SERVER, "NT"},
781 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
782 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
783 {ANNOUNCE_AS_WIN95, "win95"},
784 {ANNOUNCE_AS_WFW, "WfW"},
785 {-1, NULL}
788 static const struct enum_list enum_map_readonly[] = {
789 {MAP_READONLY_NO, "no"},
790 {MAP_READONLY_NO, "false"},
791 {MAP_READONLY_NO, "0"},
792 {MAP_READONLY_YES, "yes"},
793 {MAP_READONLY_YES, "true"},
794 {MAP_READONLY_YES, "1"},
795 {MAP_READONLY_PERMISSIONS, "permissions"},
796 {MAP_READONLY_PERMISSIONS, "perms"},
797 {-1, NULL}
800 static const struct enum_list enum_case[] = {
801 {CASE_LOWER, "lower"},
802 {CASE_UPPER, "upper"},
803 {-1, NULL}
808 static const struct enum_list enum_bool_auto[] = {
809 {False, "No"},
810 {False, "False"},
811 {False, "0"},
812 {True, "Yes"},
813 {True, "True"},
814 {True, "1"},
815 {Auto, "Auto"},
816 {-1, NULL}
819 /* Client-side offline caching policy types */
820 #define CSC_POLICY_MANUAL 0
821 #define CSC_POLICY_DOCUMENTS 1
822 #define CSC_POLICY_PROGRAMS 2
823 #define CSC_POLICY_DISABLE 3
825 static const struct enum_list enum_csc_policy[] = {
826 {CSC_POLICY_MANUAL, "manual"},
827 {CSC_POLICY_DOCUMENTS, "documents"},
828 {CSC_POLICY_PROGRAMS, "programs"},
829 {CSC_POLICY_DISABLE, "disable"},
830 {-1, NULL}
833 /* SMB signing types. */
834 static const struct enum_list enum_smb_signing_vals[] = {
835 {False, "No"},
836 {False, "False"},
837 {False, "0"},
838 {False, "Off"},
839 {False, "disabled"},
840 {True, "Yes"},
841 {True, "True"},
842 {True, "1"},
843 {True, "On"},
844 {True, "enabled"},
845 {Auto, "auto"},
846 {Required, "required"},
847 {Required, "mandatory"},
848 {Required, "force"},
849 {Required, "forced"},
850 {Required, "enforced"},
851 {-1, NULL}
854 /* ACL compatibility options. */
855 static const struct enum_list enum_acl_compat_vals[] = {
856 { ACL_COMPAT_AUTO, "auto" },
857 { ACL_COMPAT_WINNT, "winnt" },
858 { ACL_COMPAT_WIN2K, "win2k" },
859 { -1, NULL}
863 Do you want session setups at user level security with a invalid
864 password to be rejected or allowed in as guest? WinNT rejects them
865 but it can be a pain as it means "net view" needs to use a password
867 You have 3 choices in the setting of map_to_guest:
869 "Never" means session setups with an invalid password
870 are rejected. This is the default.
872 "Bad User" means session setups with an invalid password
873 are rejected, unless the username does not exist, in which case it
874 is treated as a guest login
876 "Bad Password" means session setups with an invalid password
877 are treated as a guest login
879 Note that map_to_guest only has an effect in user or server
880 level security.
883 static const struct enum_list enum_map_to_guest[] = {
884 {NEVER_MAP_TO_GUEST, "Never"},
885 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
886 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
887 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
888 {-1, NULL}
891 /* Config backend options */
893 static const struct enum_list enum_config_backend[] = {
894 {CONFIG_BACKEND_FILE, "file"},
895 {CONFIG_BACKEND_REGISTRY, "registry"},
896 {-1, NULL}
899 /* ADS kerberos ticket verification options */
901 static const struct enum_list enum_kerberos_method[] = {
902 {KERBEROS_VERIFY_SECRETS, "default"},
903 {KERBEROS_VERIFY_SECRETS, "secrets only"},
904 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
905 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
906 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
907 {-1, NULL}
910 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
912 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
913 * screen in SWAT. This is used to exclude parameters as well as to squash all
914 * parameters that have been duplicated by pseudonyms.
916 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
917 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
918 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
919 * respective views.
921 * NOTE2: Handling of duplicated (synonym) parameters:
922 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
923 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
924 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
925 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
928 static struct parm_struct parm_table[] = {
929 {N_("Base Options"), P_SEP, P_SEPARATOR},
932 .label = "dos charset",
933 .type = P_STRING,
934 .p_class = P_GLOBAL,
935 .ptr = &Globals.dos_charset,
936 .special = handle_charset,
937 .enum_list = NULL,
938 .flags = FLAG_ADVANCED
941 .label = "unix charset",
942 .type = P_STRING,
943 .p_class = P_GLOBAL,
944 .ptr = &Globals.unix_charset,
945 .special = handle_charset,
946 .enum_list = NULL,
947 .flags = FLAG_ADVANCED
950 .label = "display charset",
951 .type = P_STRING,
952 .p_class = P_GLOBAL,
953 .ptr = &Globals.display_charset,
954 .special = handle_charset,
955 .enum_list = NULL,
956 .flags = FLAG_ADVANCED
959 .label = "comment",
960 .type = P_STRING,
961 .p_class = P_LOCAL,
962 .ptr = &sDefault.comment,
963 .special = NULL,
964 .enum_list = NULL,
965 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
968 .label = "path",
969 .type = P_STRING,
970 .p_class = P_LOCAL,
971 .ptr = &sDefault.szPath,
972 .special = NULL,
973 .enum_list = NULL,
974 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
977 .label = "directory",
978 .type = P_STRING,
979 .p_class = P_LOCAL,
980 .ptr = &sDefault.szPath,
981 .special = NULL,
982 .enum_list = NULL,
983 .flags = FLAG_HIDE,
986 .label = "workgroup",
987 .type = P_USTRING,
988 .p_class = P_GLOBAL,
989 .ptr = &Globals.szWorkgroup,
990 .special = handle_workgroup,
991 .enum_list = NULL,
992 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
994 #ifdef WITH_ADS
996 .label = "realm",
997 .type = P_USTRING,
998 .p_class = P_GLOBAL,
999 .ptr = &Globals.szRealm,
1000 .special = NULL,
1001 .enum_list = NULL,
1002 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1004 #endif
1006 .label = "netbios name",
1007 .type = P_USTRING,
1008 .p_class = P_GLOBAL,
1009 .ptr = &Globals.szNetbiosName,
1010 .special = handle_netbios_name,
1011 .enum_list = NULL,
1012 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1015 .label = "netbios aliases",
1016 .type = P_LIST,
1017 .p_class = P_GLOBAL,
1018 .ptr = &Globals.szNetbiosAliases,
1019 .special = handle_netbios_aliases,
1020 .enum_list = NULL,
1021 .flags = FLAG_ADVANCED,
1024 .label = "netbios scope",
1025 .type = P_USTRING,
1026 .p_class = P_GLOBAL,
1027 .ptr = &Globals.szNetbiosScope,
1028 .special = handle_netbios_scope,
1029 .enum_list = NULL,
1030 .flags = FLAG_ADVANCED,
1033 .label = "server string",
1034 .type = P_STRING,
1035 .p_class = P_GLOBAL,
1036 .ptr = &Globals.szServerString,
1037 .special = NULL,
1038 .enum_list = NULL,
1039 .flags = FLAG_BASIC | FLAG_ADVANCED,
1042 .label = "interfaces",
1043 .type = P_LIST,
1044 .p_class = P_GLOBAL,
1045 .ptr = &Globals.szInterfaces,
1046 .special = NULL,
1047 .enum_list = NULL,
1048 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1051 .label = "bind interfaces only",
1052 .type = P_BOOL,
1053 .p_class = P_GLOBAL,
1054 .ptr = &Globals.bBindInterfacesOnly,
1055 .special = NULL,
1056 .enum_list = NULL,
1057 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1060 .label = "config backend",
1061 .type = P_ENUM,
1062 .p_class = P_GLOBAL,
1063 .ptr = &Globals.ConfigBackend,
1064 .special = NULL,
1065 .enum_list = enum_config_backend,
1066 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1069 {N_("Security Options"), P_SEP, P_SEPARATOR},
1072 .label = "security",
1073 .type = P_ENUM,
1074 .p_class = P_GLOBAL,
1075 .ptr = &Globals.security,
1076 .special = NULL,
1077 .enum_list = enum_security,
1078 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1081 .label = "auth methods",
1082 .type = P_LIST,
1083 .p_class = P_GLOBAL,
1084 .ptr = &Globals.AuthMethods,
1085 .special = NULL,
1086 .enum_list = NULL,
1087 .flags = FLAG_ADVANCED,
1090 .label = "encrypt passwords",
1091 .type = P_BOOL,
1092 .p_class = P_GLOBAL,
1093 .ptr = &Globals.bEncryptPasswords,
1094 .special = NULL,
1095 .enum_list = NULL,
1096 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1099 .label = "update encrypted",
1100 .type = P_BOOL,
1101 .p_class = P_GLOBAL,
1102 .ptr = &Globals.bUpdateEncrypt,
1103 .special = NULL,
1104 .enum_list = NULL,
1105 .flags = FLAG_ADVANCED,
1108 .label = "client schannel",
1109 .type = P_ENUM,
1110 .p_class = P_GLOBAL,
1111 .ptr = &Globals.clientSchannel,
1112 .special = NULL,
1113 .enum_list = enum_bool_auto,
1114 .flags = FLAG_BASIC | FLAG_ADVANCED,
1117 .label = "server schannel",
1118 .type = P_ENUM,
1119 .p_class = P_GLOBAL,
1120 .ptr = &Globals.serverSchannel,
1121 .special = NULL,
1122 .enum_list = enum_bool_auto,
1123 .flags = FLAG_BASIC | FLAG_ADVANCED,
1126 .label = "allow trusted domains",
1127 .type = P_BOOL,
1128 .p_class = P_GLOBAL,
1129 .ptr = &Globals.bAllowTrustedDomains,
1130 .special = NULL,
1131 .enum_list = NULL,
1132 .flags = FLAG_ADVANCED,
1135 .label = "map to guest",
1136 .type = P_ENUM,
1137 .p_class = P_GLOBAL,
1138 .ptr = &Globals.map_to_guest,
1139 .special = NULL,
1140 .enum_list = enum_map_to_guest,
1141 .flags = FLAG_ADVANCED,
1144 .label = "null passwords",
1145 .type = P_BOOL,
1146 .p_class = P_GLOBAL,
1147 .ptr = &Globals.bNullPasswords,
1148 .special = NULL,
1149 .enum_list = NULL,
1150 .flags = FLAG_ADVANCED,
1153 .label = "obey pam restrictions",
1154 .type = P_BOOL,
1155 .p_class = P_GLOBAL,
1156 .ptr = &Globals.bObeyPamRestrictions,
1157 .special = NULL,
1158 .enum_list = NULL,
1159 .flags = FLAG_ADVANCED,
1162 .label = "password server",
1163 .type = P_STRING,
1164 .p_class = P_GLOBAL,
1165 .ptr = &Globals.szPasswordServer,
1166 .special = NULL,
1167 .enum_list = NULL,
1168 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1171 .label = "smb passwd file",
1172 .type = P_STRING,
1173 .p_class = P_GLOBAL,
1174 .ptr = &Globals.szSMBPasswdFile,
1175 .special = NULL,
1176 .enum_list = NULL,
1177 .flags = FLAG_ADVANCED,
1180 .label = "private dir",
1181 .type = P_STRING,
1182 .p_class = P_GLOBAL,
1183 .ptr = &Globals.szPrivateDir,
1184 .special = NULL,
1185 .enum_list = NULL,
1186 .flags = FLAG_ADVANCED,
1189 .label = "passdb backend",
1190 .type = P_STRING,
1191 .p_class = P_GLOBAL,
1192 .ptr = &Globals.szPassdbBackend,
1193 .special = NULL,
1194 .enum_list = NULL,
1195 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1198 .label = "algorithmic rid base",
1199 .type = P_INTEGER,
1200 .p_class = P_GLOBAL,
1201 .ptr = &Globals.AlgorithmicRidBase,
1202 .special = NULL,
1203 .enum_list = NULL,
1204 .flags = FLAG_ADVANCED,
1207 .label = "root directory",
1208 .type = P_STRING,
1209 .p_class = P_GLOBAL,
1210 .ptr = &Globals.szRootdir,
1211 .special = NULL,
1212 .enum_list = NULL,
1213 .flags = FLAG_ADVANCED,
1216 .label = "root dir",
1217 .type = P_STRING,
1218 .p_class = P_GLOBAL,
1219 .ptr = &Globals.szRootdir,
1220 .special = NULL,
1221 .enum_list = NULL,
1222 .flags = FLAG_HIDE,
1225 .label = "root",
1226 .type = P_STRING,
1227 .p_class = P_GLOBAL,
1228 .ptr = &Globals.szRootdir,
1229 .special = NULL,
1230 .enum_list = NULL,
1231 .flags = FLAG_HIDE,
1234 .label = "guest account",
1235 .type = P_STRING,
1236 .p_class = P_GLOBAL,
1237 .ptr = &Globals.szGuestaccount,
1238 .special = NULL,
1239 .enum_list = NULL,
1240 .flags = FLAG_BASIC | FLAG_ADVANCED,
1243 .label = "enable privileges",
1244 .type = P_BOOL,
1245 .p_class = P_GLOBAL,
1246 .ptr = &Globals.bEnablePrivileges,
1247 .special = NULL,
1248 .enum_list = NULL,
1249 .flags = FLAG_ADVANCED,
1253 .label = "pam password change",
1254 .type = P_BOOL,
1255 .p_class = P_GLOBAL,
1256 .ptr = &Globals.bPamPasswordChange,
1257 .special = NULL,
1258 .enum_list = NULL,
1259 .flags = FLAG_ADVANCED,
1262 .label = "passwd program",
1263 .type = P_STRING,
1264 .p_class = P_GLOBAL,
1265 .ptr = &Globals.szPasswdProgram,
1266 .special = NULL,
1267 .enum_list = NULL,
1268 .flags = FLAG_ADVANCED,
1271 .label = "passwd chat",
1272 .type = P_STRING,
1273 .p_class = P_GLOBAL,
1274 .ptr = &Globals.szPasswdChat,
1275 .special = NULL,
1276 .enum_list = NULL,
1277 .flags = FLAG_ADVANCED,
1280 .label = "passwd chat debug",
1281 .type = P_BOOL,
1282 .p_class = P_GLOBAL,
1283 .ptr = &Globals.bPasswdChatDebug,
1284 .special = NULL,
1285 .enum_list = NULL,
1286 .flags = FLAG_ADVANCED,
1289 .label = "passwd chat timeout",
1290 .type = P_INTEGER,
1291 .p_class = P_GLOBAL,
1292 .ptr = &Globals.iPasswdChatTimeout,
1293 .special = NULL,
1294 .enum_list = NULL,
1295 .flags = FLAG_ADVANCED,
1298 .label = "check password script",
1299 .type = P_STRING,
1300 .p_class = P_GLOBAL,
1301 .ptr = &Globals.szCheckPasswordScript,
1302 .special = NULL,
1303 .enum_list = NULL,
1304 .flags = FLAG_ADVANCED,
1307 .label = "username map",
1308 .type = P_STRING,
1309 .p_class = P_GLOBAL,
1310 .ptr = &Globals.szUsernameMap,
1311 .special = NULL,
1312 .enum_list = NULL,
1313 .flags = FLAG_ADVANCED,
1316 .label = "password level",
1317 .type = P_INTEGER,
1318 .p_class = P_GLOBAL,
1319 .ptr = &Globals.pwordlevel,
1320 .special = NULL,
1321 .enum_list = NULL,
1322 .flags = FLAG_ADVANCED,
1325 .label = "username level",
1326 .type = P_INTEGER,
1327 .p_class = P_GLOBAL,
1328 .ptr = &Globals.unamelevel,
1329 .special = NULL,
1330 .enum_list = NULL,
1331 .flags = FLAG_ADVANCED,
1334 .label = "unix password sync",
1335 .type = P_BOOL,
1336 .p_class = P_GLOBAL,
1337 .ptr = &Globals.bUnixPasswdSync,
1338 .special = NULL,
1339 .enum_list = NULL,
1340 .flags = FLAG_ADVANCED,
1343 .label = "restrict anonymous",
1344 .type = P_INTEGER,
1345 .p_class = P_GLOBAL,
1346 .ptr = &Globals.restrict_anonymous,
1347 .special = NULL,
1348 .enum_list = NULL,
1349 .flags = FLAG_ADVANCED,
1352 .label = "lanman auth",
1353 .type = P_BOOL,
1354 .p_class = P_GLOBAL,
1355 .ptr = &Globals.bLanmanAuth,
1356 .special = NULL,
1357 .enum_list = NULL,
1358 .flags = FLAG_ADVANCED,
1361 .label = "ntlm auth",
1362 .type = P_BOOL,
1363 .p_class = P_GLOBAL,
1364 .ptr = &Globals.bNTLMAuth,
1365 .special = NULL,
1366 .enum_list = NULL,
1367 .flags = FLAG_ADVANCED,
1370 .label = "client NTLMv2 auth",
1371 .type = P_BOOL,
1372 .p_class = P_GLOBAL,
1373 .ptr = &Globals.bClientNTLMv2Auth,
1374 .special = NULL,
1375 .enum_list = NULL,
1376 .flags = FLAG_ADVANCED,
1379 .label = "client lanman auth",
1380 .type = P_BOOL,
1381 .p_class = P_GLOBAL,
1382 .ptr = &Globals.bClientLanManAuth,
1383 .special = NULL,
1384 .enum_list = NULL,
1385 .flags = FLAG_ADVANCED,
1388 .label = "client plaintext auth",
1389 .type = P_BOOL,
1390 .p_class = P_GLOBAL,
1391 .ptr = &Globals.bClientPlaintextAuth,
1392 .special = NULL,
1393 .enum_list = NULL,
1394 .flags = FLAG_ADVANCED,
1397 .label = "username",
1398 .type = P_STRING,
1399 .p_class = P_LOCAL,
1400 .ptr = &sDefault.szUsername,
1401 .special = NULL,
1402 .enum_list = NULL,
1403 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1406 .label = "user",
1407 .type = P_STRING,
1408 .p_class = P_LOCAL,
1409 .ptr = &sDefault.szUsername,
1410 .special = NULL,
1411 .enum_list = NULL,
1412 .flags = FLAG_HIDE,
1415 .label = "users",
1416 .type = P_STRING,
1417 .p_class = P_LOCAL,
1418 .ptr = &sDefault.szUsername,
1419 .special = NULL,
1420 .enum_list = NULL,
1421 .flags = FLAG_HIDE,
1424 .label = "invalid users",
1425 .type = P_LIST,
1426 .p_class = P_LOCAL,
1427 .ptr = &sDefault.szInvalidUsers,
1428 .special = NULL,
1429 .enum_list = NULL,
1430 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1433 .label = "valid users",
1434 .type = P_LIST,
1435 .p_class = P_LOCAL,
1436 .ptr = &sDefault.szValidUsers,
1437 .special = NULL,
1438 .enum_list = NULL,
1439 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1442 .label = "admin users",
1443 .type = P_LIST,
1444 .p_class = P_LOCAL,
1445 .ptr = &sDefault.szAdminUsers,
1446 .special = NULL,
1447 .enum_list = NULL,
1448 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1451 .label = "read list",
1452 .type = P_LIST,
1453 .p_class = P_LOCAL,
1454 .ptr = &sDefault.readlist,
1455 .special = NULL,
1456 .enum_list = NULL,
1457 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1460 .label = "write list",
1461 .type = P_LIST,
1462 .p_class = P_LOCAL,
1463 .ptr = &sDefault.writelist,
1464 .special = NULL,
1465 .enum_list = NULL,
1466 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1469 .label = "printer admin",
1470 .type = P_LIST,
1471 .p_class = P_LOCAL,
1472 .ptr = &sDefault.printer_admin,
1473 .special = NULL,
1474 .enum_list = NULL,
1475 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1478 .label = "force user",
1479 .type = P_STRING,
1480 .p_class = P_LOCAL,
1481 .ptr = &sDefault.force_user,
1482 .special = NULL,
1483 .enum_list = NULL,
1484 .flags = FLAG_ADVANCED | FLAG_SHARE,
1487 .label = "force group",
1488 .type = P_STRING,
1489 .p_class = P_LOCAL,
1490 .ptr = &sDefault.force_group,
1491 .special = NULL,
1492 .enum_list = NULL,
1493 .flags = FLAG_ADVANCED | FLAG_SHARE,
1496 .label = "group",
1497 .type = P_STRING,
1498 .p_class = P_LOCAL,
1499 .ptr = &sDefault.force_group,
1500 .special = NULL,
1501 .enum_list = NULL,
1502 .flags = FLAG_ADVANCED,
1505 .label = "read only",
1506 .type = P_BOOL,
1507 .p_class = P_LOCAL,
1508 .ptr = &sDefault.bRead_only,
1509 .special = NULL,
1510 .enum_list = NULL,
1511 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1514 .label = "write ok",
1515 .type = P_BOOLREV,
1516 .p_class = P_LOCAL,
1517 .ptr = &sDefault.bRead_only,
1518 .special = NULL,
1519 .enum_list = NULL,
1520 .flags = FLAG_HIDE,
1523 .label = "writeable",
1524 .type = P_BOOLREV,
1525 .p_class = P_LOCAL,
1526 .ptr = &sDefault.bRead_only,
1527 .special = NULL,
1528 .enum_list = NULL,
1529 .flags = FLAG_HIDE,
1532 .label = "writable",
1533 .type = P_BOOLREV,
1534 .p_class = P_LOCAL,
1535 .ptr = &sDefault.bRead_only,
1536 .special = NULL,
1537 .enum_list = NULL,
1538 .flags = FLAG_HIDE,
1541 .label = "acl check permissions",
1542 .type = P_BOOL,
1543 .p_class = P_LOCAL,
1544 .ptr = &sDefault.bAclCheckPermissions,
1545 .special = NULL,
1546 .enum_list = NULL,
1547 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1550 .label = "acl group control",
1551 .type = P_BOOL,
1552 .p_class = P_LOCAL,
1553 .ptr = &sDefault.bAclGroupControl,
1554 .special = NULL,
1555 .enum_list = NULL,
1556 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1559 .label = "acl map full control",
1560 .type = P_BOOL,
1561 .p_class = P_LOCAL,
1562 .ptr = &sDefault.bAclMapFullControl,
1563 .special = NULL,
1564 .enum_list = NULL,
1565 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1568 .label = "create mask",
1569 .type = P_OCTAL,
1570 .p_class = P_LOCAL,
1571 .ptr = &sDefault.iCreate_mask,
1572 .special = NULL,
1573 .enum_list = NULL,
1574 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1577 .label = "create mode",
1578 .type = P_OCTAL,
1579 .p_class = P_LOCAL,
1580 .ptr = &sDefault.iCreate_mask,
1581 .special = NULL,
1582 .enum_list = NULL,
1583 .flags = FLAG_HIDE,
1586 .label = "force create mode",
1587 .type = P_OCTAL,
1588 .p_class = P_LOCAL,
1589 .ptr = &sDefault.iCreate_force_mode,
1590 .special = NULL,
1591 .enum_list = NULL,
1592 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1595 .label = "security mask",
1596 .type = P_OCTAL,
1597 .p_class = P_LOCAL,
1598 .ptr = &sDefault.iSecurity_mask,
1599 .special = NULL,
1600 .enum_list = NULL,
1601 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1604 .label = "force security mode",
1605 .type = P_OCTAL,
1606 .p_class = P_LOCAL,
1607 .ptr = &sDefault.iSecurity_force_mode,
1608 .special = NULL,
1609 .enum_list = NULL,
1610 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1613 .label = "directory mask",
1614 .type = P_OCTAL,
1615 .p_class = P_LOCAL,
1616 .ptr = &sDefault.iDir_mask,
1617 .special = NULL,
1618 .enum_list = NULL,
1619 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1622 .label = "directory mode",
1623 .type = P_OCTAL,
1624 .p_class = P_LOCAL,
1625 .ptr = &sDefault.iDir_mask,
1626 .special = NULL,
1627 .enum_list = NULL,
1628 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1631 .label = "force directory mode",
1632 .type = P_OCTAL,
1633 .p_class = P_LOCAL,
1634 .ptr = &sDefault.iDir_force_mode,
1635 .special = NULL,
1636 .enum_list = NULL,
1637 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1640 .label = "directory security mask",
1641 .type = P_OCTAL,
1642 .p_class = P_LOCAL,
1643 .ptr = &sDefault.iDir_Security_mask,
1644 .special = NULL,
1645 .enum_list = NULL,
1646 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1649 .label = "force directory security mode",
1650 .type = P_OCTAL,
1651 .p_class = P_LOCAL,
1652 .ptr = &sDefault.iDir_Security_force_mode,
1653 .special = NULL,
1654 .enum_list = NULL,
1655 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1658 .label = "force unknown acl user",
1659 .type = P_BOOL,
1660 .p_class = P_LOCAL,
1661 .ptr = &sDefault.bForceUnknownAclUser,
1662 .special = NULL,
1663 .enum_list = NULL,
1664 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1667 .label = "inherit permissions",
1668 .type = P_BOOL,
1669 .p_class = P_LOCAL,
1670 .ptr = &sDefault.bInheritPerms,
1671 .special = NULL,
1672 .enum_list = NULL,
1673 .flags = FLAG_ADVANCED | FLAG_SHARE,
1676 .label = "inherit acls",
1677 .type = P_BOOL,
1678 .p_class = P_LOCAL,
1679 .ptr = &sDefault.bInheritACLS,
1680 .special = NULL,
1681 .enum_list = NULL,
1682 .flags = FLAG_ADVANCED | FLAG_SHARE,
1685 .label = "inherit owner",
1686 .type = P_BOOL,
1687 .p_class = P_LOCAL,
1688 .ptr = &sDefault.bInheritOwner,
1689 .special = NULL,
1690 .enum_list = NULL,
1691 .flags = FLAG_ADVANCED | FLAG_SHARE,
1694 .label = "guest only",
1695 .type = P_BOOL,
1696 .p_class = P_LOCAL,
1697 .ptr = &sDefault.bGuest_only,
1698 .special = NULL,
1699 .enum_list = NULL,
1700 .flags = FLAG_ADVANCED | FLAG_SHARE,
1703 .label = "only guest",
1704 .type = P_BOOL,
1705 .p_class = P_LOCAL,
1706 .ptr = &sDefault.bGuest_only,
1707 .special = NULL,
1708 .enum_list = NULL,
1709 .flags = FLAG_HIDE,
1712 .label = "administrative share",
1713 .type = P_BOOL,
1714 .p_class = P_LOCAL,
1715 .ptr = &sDefault.bAdministrative_share,
1716 .special = NULL,
1717 .enum_list = NULL,
1718 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1722 .label = "guest ok",
1723 .type = P_BOOL,
1724 .p_class = P_LOCAL,
1725 .ptr = &sDefault.bGuest_ok,
1726 .special = NULL,
1727 .enum_list = NULL,
1728 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1731 .label = "public",
1732 .type = P_BOOL,
1733 .p_class = P_LOCAL,
1734 .ptr = &sDefault.bGuest_ok,
1735 .special = NULL,
1736 .enum_list = NULL,
1737 .flags = FLAG_HIDE,
1740 .label = "only user",
1741 .type = P_BOOL,
1742 .p_class = P_LOCAL,
1743 .ptr = &sDefault.bOnlyUser,
1744 .special = NULL,
1745 .enum_list = NULL,
1746 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1749 .label = "hosts allow",
1750 .type = P_LIST,
1751 .p_class = P_LOCAL,
1752 .ptr = &sDefault.szHostsallow,
1753 .special = NULL,
1754 .enum_list = NULL,
1755 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1758 .label = "allow hosts",
1759 .type = P_LIST,
1760 .p_class = P_LOCAL,
1761 .ptr = &sDefault.szHostsallow,
1762 .special = NULL,
1763 .enum_list = NULL,
1764 .flags = FLAG_HIDE,
1767 .label = "hosts deny",
1768 .type = P_LIST,
1769 .p_class = P_LOCAL,
1770 .ptr = &sDefault.szHostsdeny,
1771 .special = NULL,
1772 .enum_list = NULL,
1773 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1776 .label = "deny hosts",
1777 .type = P_LIST,
1778 .p_class = P_LOCAL,
1779 .ptr = &sDefault.szHostsdeny,
1780 .special = NULL,
1781 .enum_list = NULL,
1782 .flags = FLAG_HIDE,
1785 .label = "preload modules",
1786 .type = P_LIST,
1787 .p_class = P_GLOBAL,
1788 .ptr = &Globals.szPreloadModules,
1789 .special = NULL,
1790 .enum_list = NULL,
1791 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1794 .label = "dedicated keytab file",
1795 .type = P_STRING,
1796 .p_class = P_GLOBAL,
1797 .ptr = &Globals.szDedicatedKeytabFile,
1798 .special = NULL,
1799 .enum_list = NULL,
1800 .flags = FLAG_ADVANCED,
1803 .label = "kerberos method",
1804 .type = P_ENUM,
1805 .p_class = P_GLOBAL,
1806 .ptr = &Globals.iKerberosMethod,
1807 .special = NULL,
1808 .enum_list = enum_kerberos_method,
1809 .flags = FLAG_ADVANCED,
1812 .label = "map untrusted to domain",
1813 .type = P_BOOL,
1814 .p_class = P_GLOBAL,
1815 .ptr = &Globals.bMapUntrustedToDomain,
1816 .special = NULL,
1817 .enum_list = NULL,
1818 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1822 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1825 .label = "log level",
1826 .type = P_STRING,
1827 .p_class = P_GLOBAL,
1828 .ptr = &Globals.szLogLevel,
1829 .special = handle_debug_list,
1830 .enum_list = NULL,
1831 .flags = FLAG_ADVANCED,
1834 .label = "debuglevel",
1835 .type = P_STRING,
1836 .p_class = P_GLOBAL,
1837 .ptr = &Globals.szLogLevel,
1838 .special = handle_debug_list,
1839 .enum_list = NULL,
1840 .flags = FLAG_HIDE,
1843 .label = "syslog",
1844 .type = P_INTEGER,
1845 .p_class = P_GLOBAL,
1846 .ptr = &Globals.syslog,
1847 .special = NULL,
1848 .enum_list = NULL,
1849 .flags = FLAG_ADVANCED,
1852 .label = "syslog only",
1853 .type = P_BOOL,
1854 .p_class = P_GLOBAL,
1855 .ptr = &Globals.bSyslogOnly,
1856 .special = NULL,
1857 .enum_list = NULL,
1858 .flags = FLAG_ADVANCED,
1861 .label = "log file",
1862 .type = P_STRING,
1863 .p_class = P_GLOBAL,
1864 .ptr = &Globals.szLogFile,
1865 .special = NULL,
1866 .enum_list = NULL,
1867 .flags = FLAG_ADVANCED,
1870 .label = "max log size",
1871 .type = P_INTEGER,
1872 .p_class = P_GLOBAL,
1873 .ptr = &Globals.max_log_size,
1874 .special = NULL,
1875 .enum_list = NULL,
1876 .flags = FLAG_ADVANCED,
1879 .label = "debug timestamp",
1880 .type = P_BOOL,
1881 .p_class = P_GLOBAL,
1882 .ptr = &Globals.bTimestampLogs,
1883 .special = NULL,
1884 .enum_list = NULL,
1885 .flags = FLAG_ADVANCED,
1888 .label = "timestamp logs",
1889 .type = P_BOOL,
1890 .p_class = P_GLOBAL,
1891 .ptr = &Globals.bTimestampLogs,
1892 .special = NULL,
1893 .enum_list = NULL,
1894 .flags = FLAG_ADVANCED,
1897 .label = "debug prefix timestamp",
1898 .type = P_BOOL,
1899 .p_class = P_GLOBAL,
1900 .ptr = &Globals.bDebugPrefixTimestamp,
1901 .special = NULL,
1902 .enum_list = NULL,
1903 .flags = FLAG_ADVANCED,
1906 .label = "debug hires timestamp",
1907 .type = P_BOOL,
1908 .p_class = P_GLOBAL,
1909 .ptr = &Globals.bDebugHiresTimestamp,
1910 .special = NULL,
1911 .enum_list = NULL,
1912 .flags = FLAG_ADVANCED,
1915 .label = "debug pid",
1916 .type = P_BOOL,
1917 .p_class = P_GLOBAL,
1918 .ptr = &Globals.bDebugPid,
1919 .special = NULL,
1920 .enum_list = NULL,
1921 .flags = FLAG_ADVANCED,
1924 .label = "debug uid",
1925 .type = P_BOOL,
1926 .p_class = P_GLOBAL,
1927 .ptr = &Globals.bDebugUid,
1928 .special = NULL,
1929 .enum_list = NULL,
1930 .flags = FLAG_ADVANCED,
1933 .label = "debug class",
1934 .type = P_BOOL,
1935 .p_class = P_GLOBAL,
1936 .ptr = &Globals.bDebugClass,
1937 .special = NULL,
1938 .enum_list = NULL,
1939 .flags = FLAG_ADVANCED,
1942 .label = "enable core files",
1943 .type = P_BOOL,
1944 .p_class = P_GLOBAL,
1945 .ptr = &Globals.bEnableCoreFiles,
1946 .special = NULL,
1947 .enum_list = NULL,
1948 .flags = FLAG_ADVANCED,
1951 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1954 .label = "allocation roundup size",
1955 .type = P_INTEGER,
1956 .p_class = P_LOCAL,
1957 .ptr = &sDefault.iallocation_roundup_size,
1958 .special = NULL,
1959 .enum_list = NULL,
1960 .flags = FLAG_ADVANCED,
1963 .label = "aio read size",
1964 .type = P_INTEGER,
1965 .p_class = P_LOCAL,
1966 .ptr = &sDefault.iAioReadSize,
1967 .special = NULL,
1968 .enum_list = NULL,
1969 .flags = FLAG_ADVANCED,
1972 .label = "aio write size",
1973 .type = P_INTEGER,
1974 .p_class = P_LOCAL,
1975 .ptr = &sDefault.iAioWriteSize,
1976 .special = NULL,
1977 .enum_list = NULL,
1978 .flags = FLAG_ADVANCED,
1981 .label = "aio write behind",
1982 .type = P_STRING,
1983 .p_class = P_LOCAL,
1984 .ptr = &sDefault.szAioWriteBehind,
1985 .special = NULL,
1986 .enum_list = NULL,
1987 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1990 .label = "smb ports",
1991 .type = P_STRING,
1992 .p_class = P_GLOBAL,
1993 .ptr = &Globals.smb_ports,
1994 .special = NULL,
1995 .enum_list = NULL,
1996 .flags = FLAG_ADVANCED,
1999 .label = "large readwrite",
2000 .type = P_BOOL,
2001 .p_class = P_GLOBAL,
2002 .ptr = &Globals.bLargeReadwrite,
2003 .special = NULL,
2004 .enum_list = NULL,
2005 .flags = FLAG_ADVANCED,
2008 .label = "max protocol",
2009 .type = P_ENUM,
2010 .p_class = P_GLOBAL,
2011 .ptr = &Globals.maxprotocol,
2012 .special = NULL,
2013 .enum_list = enum_protocol,
2014 .flags = FLAG_ADVANCED,
2017 .label = "protocol",
2018 .type = P_ENUM,
2019 .p_class = P_GLOBAL,
2020 .ptr = &Globals.maxprotocol,
2021 .special = NULL,
2022 .enum_list = enum_protocol,
2023 .flags = FLAG_ADVANCED,
2026 .label = "min protocol",
2027 .type = P_ENUM,
2028 .p_class = P_GLOBAL,
2029 .ptr = &Globals.minprotocol,
2030 .special = NULL,
2031 .enum_list = enum_protocol,
2032 .flags = FLAG_ADVANCED,
2035 .label = "min receivefile size",
2036 .type = P_INTEGER,
2037 .p_class = P_GLOBAL,
2038 .ptr = &Globals.iminreceivefile,
2039 .special = NULL,
2040 .enum_list = NULL,
2041 .flags = FLAG_ADVANCED,
2044 .label = "read raw",
2045 .type = P_BOOL,
2046 .p_class = P_GLOBAL,
2047 .ptr = &Globals.bReadRaw,
2048 .special = NULL,
2049 .enum_list = NULL,
2050 .flags = FLAG_ADVANCED,
2053 .label = "write raw",
2054 .type = P_BOOL,
2055 .p_class = P_GLOBAL,
2056 .ptr = &Globals.bWriteRaw,
2057 .special = NULL,
2058 .enum_list = NULL,
2059 .flags = FLAG_ADVANCED,
2062 .label = "disable netbios",
2063 .type = P_BOOL,
2064 .p_class = P_GLOBAL,
2065 .ptr = &Globals.bDisableNetbios,
2066 .special = NULL,
2067 .enum_list = NULL,
2068 .flags = FLAG_ADVANCED,
2071 .label = "reset on zero vc",
2072 .type = P_BOOL,
2073 .p_class = P_GLOBAL,
2074 .ptr = &Globals.bResetOnZeroVC,
2075 .special = NULL,
2076 .enum_list = NULL,
2077 .flags = FLAG_ADVANCED,
2080 .label = "acl compatibility",
2081 .type = P_ENUM,
2082 .p_class = P_GLOBAL,
2083 .ptr = &Globals.iAclCompat,
2084 .special = NULL,
2085 .enum_list = enum_acl_compat_vals,
2086 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2089 .label = "defer sharing violations",
2090 .type = P_BOOL,
2091 .p_class = P_GLOBAL,
2092 .ptr = &Globals.bDeferSharingViolations,
2093 .special = NULL,
2094 .enum_list = NULL,
2095 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2098 .label = "ea support",
2099 .type = P_BOOL,
2100 .p_class = P_LOCAL,
2101 .ptr = &sDefault.bEASupport,
2102 .special = NULL,
2103 .enum_list = NULL,
2104 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2107 .label = "nt acl support",
2108 .type = P_BOOL,
2109 .p_class = P_LOCAL,
2110 .ptr = &sDefault.bNTAclSupport,
2111 .special = NULL,
2112 .enum_list = NULL,
2113 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2116 .label = "nt pipe support",
2117 .type = P_BOOL,
2118 .p_class = P_GLOBAL,
2119 .ptr = &Globals.bNTPipeSupport,
2120 .special = NULL,
2121 .enum_list = NULL,
2122 .flags = FLAG_ADVANCED,
2125 .label = "nt status support",
2126 .type = P_BOOL,
2127 .p_class = P_GLOBAL,
2128 .ptr = &Globals.bNTStatusSupport,
2129 .special = NULL,
2130 .enum_list = NULL,
2131 .flags = FLAG_ADVANCED,
2134 .label = "profile acls",
2135 .type = P_BOOL,
2136 .p_class = P_LOCAL,
2137 .ptr = &sDefault.bProfileAcls,
2138 .special = NULL,
2139 .enum_list = NULL,
2140 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2143 .label = "announce version",
2144 .type = P_STRING,
2145 .p_class = P_GLOBAL,
2146 .ptr = &Globals.szAnnounceVersion,
2147 .special = NULL,
2148 .enum_list = NULL,
2149 .flags = FLAG_ADVANCED,
2152 .label = "announce as",
2153 .type = P_ENUM,
2154 .p_class = P_GLOBAL,
2155 .ptr = &Globals.announce_as,
2156 .special = NULL,
2157 .enum_list = enum_announce_as,
2158 .flags = FLAG_ADVANCED,
2161 .label = "map acl inherit",
2162 .type = P_BOOL,
2163 .p_class = P_LOCAL,
2164 .ptr = &sDefault.bMap_acl_inherit,
2165 .special = NULL,
2166 .enum_list = NULL,
2167 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2170 .label = "afs share",
2171 .type = P_BOOL,
2172 .p_class = P_LOCAL,
2173 .ptr = &sDefault.bAfs_Share,
2174 .special = NULL,
2175 .enum_list = NULL,
2176 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2179 .label = "max mux",
2180 .type = P_INTEGER,
2181 .p_class = P_GLOBAL,
2182 .ptr = &Globals.max_mux,
2183 .special = NULL,
2184 .enum_list = NULL,
2185 .flags = FLAG_ADVANCED,
2188 .label = "max xmit",
2189 .type = P_INTEGER,
2190 .p_class = P_GLOBAL,
2191 .ptr = &Globals.max_xmit,
2192 .special = NULL,
2193 .enum_list = NULL,
2194 .flags = FLAG_ADVANCED,
2197 .label = "name resolve order",
2198 .type = P_STRING,
2199 .p_class = P_GLOBAL,
2200 .ptr = &Globals.szNameResolveOrder,
2201 .special = NULL,
2202 .enum_list = NULL,
2203 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2206 .label = "max ttl",
2207 .type = P_INTEGER,
2208 .p_class = P_GLOBAL,
2209 .ptr = &Globals.max_ttl,
2210 .special = NULL,
2211 .enum_list = NULL,
2212 .flags = FLAG_ADVANCED,
2215 .label = "max wins ttl",
2216 .type = P_INTEGER,
2217 .p_class = P_GLOBAL,
2218 .ptr = &Globals.max_wins_ttl,
2219 .special = NULL,
2220 .enum_list = NULL,
2221 .flags = FLAG_ADVANCED,
2224 .label = "min wins ttl",
2225 .type = P_INTEGER,
2226 .p_class = P_GLOBAL,
2227 .ptr = &Globals.min_wins_ttl,
2228 .special = NULL,
2229 .enum_list = NULL,
2230 .flags = FLAG_ADVANCED,
2233 .label = "time server",
2234 .type = P_BOOL,
2235 .p_class = P_GLOBAL,
2236 .ptr = &Globals.bTimeServer,
2237 .special = NULL,
2238 .enum_list = NULL,
2239 .flags = FLAG_ADVANCED,
2242 .label = "unix extensions",
2243 .type = P_BOOL,
2244 .p_class = P_GLOBAL,
2245 .ptr = &Globals.bUnixExtensions,
2246 .special = NULL,
2247 .enum_list = NULL,
2248 .flags = FLAG_ADVANCED,
2251 .label = "use spnego",
2252 .type = P_BOOL,
2253 .p_class = P_GLOBAL,
2254 .ptr = &Globals.bUseSpnego,
2255 .special = NULL,
2256 .enum_list = NULL,
2257 .flags = FLAG_ADVANCED,
2260 .label = "client signing",
2261 .type = P_ENUM,
2262 .p_class = P_GLOBAL,
2263 .ptr = &Globals.client_signing,
2264 .special = NULL,
2265 .enum_list = enum_smb_signing_vals,
2266 .flags = FLAG_ADVANCED,
2269 .label = "server signing",
2270 .type = P_ENUM,
2271 .p_class = P_GLOBAL,
2272 .ptr = &Globals.server_signing,
2273 .special = NULL,
2274 .enum_list = enum_smb_signing_vals,
2275 .flags = FLAG_ADVANCED,
2278 .label = "smb encrypt",
2279 .type = P_ENUM,
2280 .p_class = P_LOCAL,
2281 .ptr = &sDefault.ismb_encrypt,
2282 .special = NULL,
2283 .enum_list = enum_smb_signing_vals,
2284 .flags = FLAG_ADVANCED,
2287 .label = "client use spnego",
2288 .type = P_BOOL,
2289 .p_class = P_GLOBAL,
2290 .ptr = &Globals.bClientUseSpnego,
2291 .special = NULL,
2292 .enum_list = NULL,
2293 .flags = FLAG_ADVANCED,
2296 .label = "client ldap sasl wrapping",
2297 .type = P_ENUM,
2298 .p_class = P_GLOBAL,
2299 .ptr = &Globals.client_ldap_sasl_wrapping,
2300 .special = NULL,
2301 .enum_list = enum_ldap_sasl_wrapping,
2302 .flags = FLAG_ADVANCED,
2305 .label = "enable asu support",
2306 .type = P_BOOL,
2307 .p_class = P_GLOBAL,
2308 .ptr = &Globals.bASUSupport,
2309 .special = NULL,
2310 .enum_list = NULL,
2311 .flags = FLAG_ADVANCED,
2314 .label = "svcctl list",
2315 .type = P_LIST,
2316 .p_class = P_GLOBAL,
2317 .ptr = &Globals.szServicesList,
2318 .special = NULL,
2319 .enum_list = NULL,
2320 .flags = FLAG_ADVANCED,
2323 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2326 .label = "block size",
2327 .type = P_INTEGER,
2328 .p_class = P_LOCAL,
2329 .ptr = &sDefault.iBlock_size,
2330 .special = NULL,
2331 .enum_list = NULL,
2332 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2335 .label = "deadtime",
2336 .type = P_INTEGER,
2337 .p_class = P_GLOBAL,
2338 .ptr = &Globals.deadtime,
2339 .special = NULL,
2340 .enum_list = NULL,
2341 .flags = FLAG_ADVANCED,
2344 .label = "getwd cache",
2345 .type = P_BOOL,
2346 .p_class = P_GLOBAL,
2347 .ptr = &Globals.getwd_cache,
2348 .special = NULL,
2349 .enum_list = NULL,
2350 .flags = FLAG_ADVANCED,
2353 .label = "keepalive",
2354 .type = P_INTEGER,
2355 .p_class = P_GLOBAL,
2356 .ptr = &Globals.iKeepalive,
2357 .special = NULL,
2358 .enum_list = NULL,
2359 .flags = FLAG_ADVANCED,
2362 .label = "change notify",
2363 .type = P_BOOL,
2364 .p_class = P_LOCAL,
2365 .ptr = &sDefault.bChangeNotify,
2366 .special = NULL,
2367 .enum_list = NULL,
2368 .flags = FLAG_ADVANCED | FLAG_SHARE,
2371 .label = "directory name cache size",
2372 .type = P_INTEGER,
2373 .p_class = P_LOCAL,
2374 .ptr = &sDefault.iDirectoryNameCacheSize,
2375 .special = NULL,
2376 .enum_list = NULL,
2377 .flags = FLAG_ADVANCED | FLAG_SHARE,
2380 .label = "kernel change notify",
2381 .type = P_BOOL,
2382 .p_class = P_LOCAL,
2383 .ptr = &sDefault.bKernelChangeNotify,
2384 .special = NULL,
2385 .enum_list = NULL,
2386 .flags = FLAG_ADVANCED | FLAG_SHARE,
2389 .label = "lpq cache time",
2390 .type = P_INTEGER,
2391 .p_class = P_GLOBAL,
2392 .ptr = &Globals.lpqcachetime,
2393 .special = NULL,
2394 .enum_list = NULL,
2395 .flags = FLAG_ADVANCED,
2398 .label = "max smbd processes",
2399 .type = P_INTEGER,
2400 .p_class = P_GLOBAL,
2401 .ptr = &Globals.iMaxSmbdProcesses,
2402 .special = NULL,
2403 .enum_list = NULL,
2404 .flags = FLAG_ADVANCED,
2407 .label = "max connections",
2408 .type = P_INTEGER,
2409 .p_class = P_LOCAL,
2410 .ptr = &sDefault.iMaxConnections,
2411 .special = NULL,
2412 .enum_list = NULL,
2413 .flags = FLAG_ADVANCED | FLAG_SHARE,
2416 .label = "paranoid server security",
2417 .type = P_BOOL,
2418 .p_class = P_GLOBAL,
2419 .ptr = &Globals.paranoid_server_security,
2420 .special = NULL,
2421 .enum_list = NULL,
2422 .flags = FLAG_ADVANCED,
2425 .label = "max disk size",
2426 .type = P_INTEGER,
2427 .p_class = P_GLOBAL,
2428 .ptr = &Globals.maxdisksize,
2429 .special = NULL,
2430 .enum_list = NULL,
2431 .flags = FLAG_ADVANCED,
2434 .label = "max open files",
2435 .type = P_INTEGER,
2436 .p_class = P_GLOBAL,
2437 .ptr = &Globals.max_open_files,
2438 .special = NULL,
2439 .enum_list = NULL,
2440 .flags = FLAG_ADVANCED,
2443 .label = "min print space",
2444 .type = P_INTEGER,
2445 .p_class = P_LOCAL,
2446 .ptr = &sDefault.iMinPrintSpace,
2447 .special = NULL,
2448 .enum_list = NULL,
2449 .flags = FLAG_ADVANCED | FLAG_PRINT,
2452 .label = "socket options",
2453 .type = P_STRING,
2454 .p_class = P_GLOBAL,
2455 .ptr = &Globals.szSocketOptions,
2456 .special = NULL,
2457 .enum_list = NULL,
2458 .flags = FLAG_ADVANCED,
2461 .label = "strict allocate",
2462 .type = P_BOOL,
2463 .p_class = P_LOCAL,
2464 .ptr = &sDefault.bStrictAllocate,
2465 .special = NULL,
2466 .enum_list = NULL,
2467 .flags = FLAG_ADVANCED | FLAG_SHARE,
2470 .label = "strict sync",
2471 .type = P_BOOL,
2472 .p_class = P_LOCAL,
2473 .ptr = &sDefault.bStrictSync,
2474 .special = NULL,
2475 .enum_list = NULL,
2476 .flags = FLAG_ADVANCED | FLAG_SHARE,
2479 .label = "sync always",
2480 .type = P_BOOL,
2481 .p_class = P_LOCAL,
2482 .ptr = &sDefault.bSyncAlways,
2483 .special = NULL,
2484 .enum_list = NULL,
2485 .flags = FLAG_ADVANCED | FLAG_SHARE,
2488 .label = "use mmap",
2489 .type = P_BOOL,
2490 .p_class = P_GLOBAL,
2491 .ptr = &Globals.bUseMmap,
2492 .special = NULL,
2493 .enum_list = NULL,
2494 .flags = FLAG_ADVANCED,
2497 .label = "use sendfile",
2498 .type = P_BOOL,
2499 .p_class = P_LOCAL,
2500 .ptr = &sDefault.bUseSendfile,
2501 .special = NULL,
2502 .enum_list = NULL,
2503 .flags = FLAG_ADVANCED | FLAG_SHARE,
2506 .label = "hostname lookups",
2507 .type = P_BOOL,
2508 .p_class = P_GLOBAL,
2509 .ptr = &Globals.bHostnameLookups,
2510 .special = NULL,
2511 .enum_list = NULL,
2512 .flags = FLAG_ADVANCED,
2515 .label = "write cache size",
2516 .type = P_INTEGER,
2517 .p_class = P_LOCAL,
2518 .ptr = &sDefault.iWriteCacheSize,
2519 .special = NULL,
2520 .enum_list = NULL,
2521 .flags = FLAG_ADVANCED | FLAG_SHARE,
2524 .label = "name cache timeout",
2525 .type = P_INTEGER,
2526 .p_class = P_GLOBAL,
2527 .ptr = &Globals.name_cache_timeout,
2528 .special = NULL,
2529 .enum_list = NULL,
2530 .flags = FLAG_ADVANCED,
2533 .label = "ctdbd socket",
2534 .type = P_STRING,
2535 .p_class = P_GLOBAL,
2536 .ptr = &Globals.ctdbdSocket,
2537 .special = NULL,
2538 .enum_list = NULL,
2539 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2542 .label = "cluster addresses",
2543 .type = P_LIST,
2544 .p_class = P_GLOBAL,
2545 .ptr = &Globals.szClusterAddresses,
2546 .special = NULL,
2547 .enum_list = NULL,
2548 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2551 .label = "clustering",
2552 .type = P_BOOL,
2553 .p_class = P_GLOBAL,
2554 .ptr = &Globals.clustering,
2555 .special = NULL,
2556 .enum_list = NULL,
2557 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2560 .label = "ctdb timeout",
2561 .type = P_INTEGER,
2562 .p_class = P_GLOBAL,
2563 .ptr = &Globals.ctdb_timeout,
2564 .special = NULL,
2565 .enum_list = NULL,
2566 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2569 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2572 .label = "max reported print jobs",
2573 .type = P_INTEGER,
2574 .p_class = P_LOCAL,
2575 .ptr = &sDefault.iMaxReportedPrintJobs,
2576 .special = NULL,
2577 .enum_list = NULL,
2578 .flags = FLAG_ADVANCED | FLAG_PRINT,
2581 .label = "max print jobs",
2582 .type = P_INTEGER,
2583 .p_class = P_LOCAL,
2584 .ptr = &sDefault.iMaxPrintJobs,
2585 .special = NULL,
2586 .enum_list = NULL,
2587 .flags = FLAG_ADVANCED | FLAG_PRINT,
2590 .label = "load printers",
2591 .type = P_BOOL,
2592 .p_class = P_GLOBAL,
2593 .ptr = &Globals.bLoadPrinters,
2594 .special = NULL,
2595 .enum_list = NULL,
2596 .flags = FLAG_ADVANCED | FLAG_PRINT,
2599 .label = "printcap cache time",
2600 .type = P_INTEGER,
2601 .p_class = P_GLOBAL,
2602 .ptr = &Globals.PrintcapCacheTime,
2603 .special = NULL,
2604 .enum_list = NULL,
2605 .flags = FLAG_ADVANCED | FLAG_PRINT,
2608 .label = "printcap name",
2609 .type = P_STRING,
2610 .p_class = P_GLOBAL,
2611 .ptr = &Globals.szPrintcapname,
2612 .special = NULL,
2613 .enum_list = NULL,
2614 .flags = FLAG_ADVANCED | FLAG_PRINT,
2617 .label = "printcap",
2618 .type = P_STRING,
2619 .p_class = P_GLOBAL,
2620 .ptr = &Globals.szPrintcapname,
2621 .special = NULL,
2622 .enum_list = NULL,
2623 .flags = FLAG_HIDE,
2626 .label = "printable",
2627 .type = P_BOOL,
2628 .p_class = P_LOCAL,
2629 .ptr = &sDefault.bPrint_ok,
2630 .special = NULL,
2631 .enum_list = NULL,
2632 .flags = FLAG_ADVANCED | FLAG_PRINT,
2635 .label = "print ok",
2636 .type = P_BOOL,
2637 .p_class = P_LOCAL,
2638 .ptr = &sDefault.bPrint_ok,
2639 .special = NULL,
2640 .enum_list = NULL,
2641 .flags = FLAG_HIDE,
2644 .label = "printing",
2645 .type = P_ENUM,
2646 .p_class = P_LOCAL,
2647 .ptr = &sDefault.iPrinting,
2648 .special = handle_printing,
2649 .enum_list = enum_printing,
2650 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2653 .label = "cups options",
2654 .type = P_STRING,
2655 .p_class = P_LOCAL,
2656 .ptr = &sDefault.szCupsOptions,
2657 .special = NULL,
2658 .enum_list = NULL,
2659 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2662 .label = "cups server",
2663 .type = P_STRING,
2664 .p_class = P_GLOBAL,
2665 .ptr = &Globals.szCupsServer,
2666 .special = NULL,
2667 .enum_list = NULL,
2668 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2671 .label = "cups encrypt",
2672 .type = P_ENUM,
2673 .p_class = P_GLOBAL,
2674 .ptr = &Globals.CupsEncrypt,
2675 .special = NULL,
2676 .enum_list = enum_bool_auto,
2677 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2681 .label = "cups connection timeout",
2682 .type = P_INTEGER,
2683 .p_class = P_GLOBAL,
2684 .ptr = &Globals.cups_connection_timeout,
2685 .special = NULL,
2686 .enum_list = NULL,
2687 .flags = FLAG_ADVANCED,
2690 .label = "iprint server",
2691 .type = P_STRING,
2692 .p_class = P_GLOBAL,
2693 .ptr = &Globals.szIPrintServer,
2694 .special = NULL,
2695 .enum_list = NULL,
2696 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2699 .label = "print command",
2700 .type = P_STRING,
2701 .p_class = P_LOCAL,
2702 .ptr = &sDefault.szPrintcommand,
2703 .special = NULL,
2704 .enum_list = NULL,
2705 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2708 .label = "disable spoolss",
2709 .type = P_BOOL,
2710 .p_class = P_GLOBAL,
2711 .ptr = &Globals.bDisableSpoolss,
2712 .special = NULL,
2713 .enum_list = NULL,
2714 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2717 .label = "enable spoolss",
2718 .type = P_BOOLREV,
2719 .p_class = P_GLOBAL,
2720 .ptr = &Globals.bDisableSpoolss,
2721 .special = NULL,
2722 .enum_list = NULL,
2723 .flags = FLAG_HIDE,
2726 .label = "lpq command",
2727 .type = P_STRING,
2728 .p_class = P_LOCAL,
2729 .ptr = &sDefault.szLpqcommand,
2730 .special = NULL,
2731 .enum_list = NULL,
2732 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2735 .label = "lprm command",
2736 .type = P_STRING,
2737 .p_class = P_LOCAL,
2738 .ptr = &sDefault.szLprmcommand,
2739 .special = NULL,
2740 .enum_list = NULL,
2741 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2744 .label = "lppause command",
2745 .type = P_STRING,
2746 .p_class = P_LOCAL,
2747 .ptr = &sDefault.szLppausecommand,
2748 .special = NULL,
2749 .enum_list = NULL,
2750 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2753 .label = "lpresume command",
2754 .type = P_STRING,
2755 .p_class = P_LOCAL,
2756 .ptr = &sDefault.szLpresumecommand,
2757 .special = NULL,
2758 .enum_list = NULL,
2759 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2762 .label = "queuepause command",
2763 .type = P_STRING,
2764 .p_class = P_LOCAL,
2765 .ptr = &sDefault.szQueuepausecommand,
2766 .special = NULL,
2767 .enum_list = NULL,
2768 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2771 .label = "queueresume command",
2772 .type = P_STRING,
2773 .p_class = P_LOCAL,
2774 .ptr = &sDefault.szQueueresumecommand,
2775 .special = NULL,
2776 .enum_list = NULL,
2777 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2780 .label = "addport command",
2781 .type = P_STRING,
2782 .p_class = P_GLOBAL,
2783 .ptr = &Globals.szAddPortCommand,
2784 .special = NULL,
2785 .enum_list = NULL,
2786 .flags = FLAG_ADVANCED,
2789 .label = "enumports command",
2790 .type = P_STRING,
2791 .p_class = P_GLOBAL,
2792 .ptr = &Globals.szEnumPortsCommand,
2793 .special = NULL,
2794 .enum_list = NULL,
2795 .flags = FLAG_ADVANCED,
2798 .label = "addprinter command",
2799 .type = P_STRING,
2800 .p_class = P_GLOBAL,
2801 .ptr = &Globals.szAddPrinterCommand,
2802 .special = NULL,
2803 .enum_list = NULL,
2804 .flags = FLAG_ADVANCED,
2807 .label = "deleteprinter command",
2808 .type = P_STRING,
2809 .p_class = P_GLOBAL,
2810 .ptr = &Globals.szDeletePrinterCommand,
2811 .special = NULL,
2812 .enum_list = NULL,
2813 .flags = FLAG_ADVANCED,
2816 .label = "show add printer wizard",
2817 .type = P_BOOL,
2818 .p_class = P_GLOBAL,
2819 .ptr = &Globals.bMsAddPrinterWizard,
2820 .special = NULL,
2821 .enum_list = NULL,
2822 .flags = FLAG_ADVANCED,
2825 .label = "os2 driver map",
2826 .type = P_STRING,
2827 .p_class = P_GLOBAL,
2828 .ptr = &Globals.szOs2DriverMap,
2829 .special = NULL,
2830 .enum_list = NULL,
2831 .flags = FLAG_ADVANCED,
2835 .label = "printer name",
2836 .type = P_STRING,
2837 .p_class = P_LOCAL,
2838 .ptr = &sDefault.szPrintername,
2839 .special = NULL,
2840 .enum_list = NULL,
2841 .flags = FLAG_ADVANCED | FLAG_PRINT,
2844 .label = "printer",
2845 .type = P_STRING,
2846 .p_class = P_LOCAL,
2847 .ptr = &sDefault.szPrintername,
2848 .special = NULL,
2849 .enum_list = NULL,
2850 .flags = FLAG_HIDE,
2853 .label = "use client driver",
2854 .type = P_BOOL,
2855 .p_class = P_LOCAL,
2856 .ptr = &sDefault.bUseClientDriver,
2857 .special = NULL,
2858 .enum_list = NULL,
2859 .flags = FLAG_ADVANCED | FLAG_PRINT,
2862 .label = "default devmode",
2863 .type = P_BOOL,
2864 .p_class = P_LOCAL,
2865 .ptr = &sDefault.bDefaultDevmode,
2866 .special = NULL,
2867 .enum_list = NULL,
2868 .flags = FLAG_ADVANCED | FLAG_PRINT,
2871 .label = "force printername",
2872 .type = P_BOOL,
2873 .p_class = P_LOCAL,
2874 .ptr = &sDefault.bForcePrintername,
2875 .special = NULL,
2876 .enum_list = NULL,
2877 .flags = FLAG_ADVANCED | FLAG_PRINT,
2880 .label = "printjob username",
2881 .type = P_STRING,
2882 .p_class = P_LOCAL,
2883 .ptr = &sDefault.szPrintjobUsername,
2884 .special = NULL,
2885 .enum_list = NULL,
2886 .flags = FLAG_ADVANCED | FLAG_PRINT,
2889 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2892 .label = "mangling method",
2893 .type = P_STRING,
2894 .p_class = P_GLOBAL,
2895 .ptr = &Globals.szManglingMethod,
2896 .special = NULL,
2897 .enum_list = NULL,
2898 .flags = FLAG_ADVANCED,
2901 .label = "mangle prefix",
2902 .type = P_INTEGER,
2903 .p_class = P_GLOBAL,
2904 .ptr = &Globals.mangle_prefix,
2905 .special = NULL,
2906 .enum_list = NULL,
2907 .flags = FLAG_ADVANCED,
2911 .label = "default case",
2912 .type = P_ENUM,
2913 .p_class = P_LOCAL,
2914 .ptr = &sDefault.iDefaultCase,
2915 .special = NULL,
2916 .enum_list = enum_case,
2917 .flags = FLAG_ADVANCED | FLAG_SHARE,
2920 .label = "case sensitive",
2921 .type = P_ENUM,
2922 .p_class = P_LOCAL,
2923 .ptr = &sDefault.iCaseSensitive,
2924 .special = NULL,
2925 .enum_list = enum_bool_auto,
2926 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2929 .label = "casesignames",
2930 .type = P_ENUM,
2931 .p_class = P_LOCAL,
2932 .ptr = &sDefault.iCaseSensitive,
2933 .special = NULL,
2934 .enum_list = enum_bool_auto,
2935 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2938 .label = "preserve case",
2939 .type = P_BOOL,
2940 .p_class = P_LOCAL,
2941 .ptr = &sDefault.bCasePreserve,
2942 .special = NULL,
2943 .enum_list = NULL,
2944 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2947 .label = "short preserve case",
2948 .type = P_BOOL,
2949 .p_class = P_LOCAL,
2950 .ptr = &sDefault.bShortCasePreserve,
2951 .special = NULL,
2952 .enum_list = NULL,
2953 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2956 .label = "mangling char",
2957 .type = P_CHAR,
2958 .p_class = P_LOCAL,
2959 .ptr = &sDefault.magic_char,
2960 .special = NULL,
2961 .enum_list = NULL,
2962 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2965 .label = "hide dot files",
2966 .type = P_BOOL,
2967 .p_class = P_LOCAL,
2968 .ptr = &sDefault.bHideDotFiles,
2969 .special = NULL,
2970 .enum_list = NULL,
2971 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2974 .label = "hide special files",
2975 .type = P_BOOL,
2976 .p_class = P_LOCAL,
2977 .ptr = &sDefault.bHideSpecialFiles,
2978 .special = NULL,
2979 .enum_list = NULL,
2980 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2983 .label = "hide unreadable",
2984 .type = P_BOOL,
2985 .p_class = P_LOCAL,
2986 .ptr = &sDefault.bHideUnReadable,
2987 .special = NULL,
2988 .enum_list = NULL,
2989 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2992 .label = "hide unwriteable files",
2993 .type = P_BOOL,
2994 .p_class = P_LOCAL,
2995 .ptr = &sDefault.bHideUnWriteableFiles,
2996 .special = NULL,
2997 .enum_list = NULL,
2998 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3001 .label = "delete veto files",
3002 .type = P_BOOL,
3003 .p_class = P_LOCAL,
3004 .ptr = &sDefault.bDeleteVetoFiles,
3005 .special = NULL,
3006 .enum_list = NULL,
3007 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3010 .label = "veto files",
3011 .type = P_STRING,
3012 .p_class = P_LOCAL,
3013 .ptr = &sDefault.szVetoFiles,
3014 .special = NULL,
3015 .enum_list = NULL,
3016 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3019 .label = "hide files",
3020 .type = P_STRING,
3021 .p_class = P_LOCAL,
3022 .ptr = &sDefault.szHideFiles,
3023 .special = NULL,
3024 .enum_list = NULL,
3025 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3028 .label = "veto oplock files",
3029 .type = P_STRING,
3030 .p_class = P_LOCAL,
3031 .ptr = &sDefault.szVetoOplockFiles,
3032 .special = NULL,
3033 .enum_list = NULL,
3034 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3037 .label = "map archive",
3038 .type = P_BOOL,
3039 .p_class = P_LOCAL,
3040 .ptr = &sDefault.bMap_archive,
3041 .special = NULL,
3042 .enum_list = NULL,
3043 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3046 .label = "map hidden",
3047 .type = P_BOOL,
3048 .p_class = P_LOCAL,
3049 .ptr = &sDefault.bMap_hidden,
3050 .special = NULL,
3051 .enum_list = NULL,
3052 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3055 .label = "map system",
3056 .type = P_BOOL,
3057 .p_class = P_LOCAL,
3058 .ptr = &sDefault.bMap_system,
3059 .special = NULL,
3060 .enum_list = NULL,
3061 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3064 .label = "map readonly",
3065 .type = P_ENUM,
3066 .p_class = P_LOCAL,
3067 .ptr = &sDefault.iMap_readonly,
3068 .special = NULL,
3069 .enum_list = enum_map_readonly,
3070 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3073 .label = "mangled names",
3074 .type = P_BOOL,
3075 .p_class = P_LOCAL,
3076 .ptr = &sDefault.bMangledNames,
3077 .special = NULL,
3078 .enum_list = NULL,
3079 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3082 .label = "max stat cache size",
3083 .type = P_INTEGER,
3084 .p_class = P_GLOBAL,
3085 .ptr = &Globals.iMaxStatCacheSize,
3086 .special = NULL,
3087 .enum_list = NULL,
3088 .flags = FLAG_ADVANCED,
3091 .label = "stat cache",
3092 .type = P_BOOL,
3093 .p_class = P_GLOBAL,
3094 .ptr = &Globals.bStatCache,
3095 .special = NULL,
3096 .enum_list = NULL,
3097 .flags = FLAG_ADVANCED,
3100 .label = "store dos attributes",
3101 .type = P_BOOL,
3102 .p_class = P_LOCAL,
3103 .ptr = &sDefault.bStoreDosAttributes,
3104 .special = NULL,
3105 .enum_list = NULL,
3106 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3109 .label = "dmapi support",
3110 .type = P_BOOL,
3111 .p_class = P_LOCAL,
3112 .ptr = &sDefault.bDmapiSupport,
3113 .special = NULL,
3114 .enum_list = NULL,
3115 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3119 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3122 .label = "machine password timeout",
3123 .type = P_INTEGER,
3124 .p_class = P_GLOBAL,
3125 .ptr = &Globals.machine_password_timeout,
3126 .special = NULL,
3127 .enum_list = NULL,
3128 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3131 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3134 .label = "add user script",
3135 .type = P_STRING,
3136 .p_class = P_GLOBAL,
3137 .ptr = &Globals.szAddUserScript,
3138 .special = NULL,
3139 .enum_list = NULL,
3140 .flags = FLAG_ADVANCED,
3143 .label = "rename user script",
3144 .type = P_STRING,
3145 .p_class = P_GLOBAL,
3146 .ptr = &Globals.szRenameUserScript,
3147 .special = NULL,
3148 .enum_list = NULL,
3149 .flags = FLAG_ADVANCED,
3152 .label = "delete user script",
3153 .type = P_STRING,
3154 .p_class = P_GLOBAL,
3155 .ptr = &Globals.szDelUserScript,
3156 .special = NULL,
3157 .enum_list = NULL,
3158 .flags = FLAG_ADVANCED,
3161 .label = "add group script",
3162 .type = P_STRING,
3163 .p_class = P_GLOBAL,
3164 .ptr = &Globals.szAddGroupScript,
3165 .special = NULL,
3166 .enum_list = NULL,
3167 .flags = FLAG_ADVANCED,
3170 .label = "delete group script",
3171 .type = P_STRING,
3172 .p_class = P_GLOBAL,
3173 .ptr = &Globals.szDelGroupScript,
3174 .special = NULL,
3175 .enum_list = NULL,
3176 .flags = FLAG_ADVANCED,
3179 .label = "add user to group script",
3180 .type = P_STRING,
3181 .p_class = P_GLOBAL,
3182 .ptr = &Globals.szAddUserToGroupScript,
3183 .special = NULL,
3184 .enum_list = NULL,
3185 .flags = FLAG_ADVANCED,
3188 .label = "delete user from group script",
3189 .type = P_STRING,
3190 .p_class = P_GLOBAL,
3191 .ptr = &Globals.szDelUserFromGroupScript,
3192 .special = NULL,
3193 .enum_list = NULL,
3194 .flags = FLAG_ADVANCED,
3197 .label = "set primary group script",
3198 .type = P_STRING,
3199 .p_class = P_GLOBAL,
3200 .ptr = &Globals.szSetPrimaryGroupScript,
3201 .special = NULL,
3202 .enum_list = NULL,
3203 .flags = FLAG_ADVANCED,
3206 .label = "add machine script",
3207 .type = P_STRING,
3208 .p_class = P_GLOBAL,
3209 .ptr = &Globals.szAddMachineScript,
3210 .special = NULL,
3211 .enum_list = NULL,
3212 .flags = FLAG_ADVANCED,
3215 .label = "shutdown script",
3216 .type = P_STRING,
3217 .p_class = P_GLOBAL,
3218 .ptr = &Globals.szShutdownScript,
3219 .special = NULL,
3220 .enum_list = NULL,
3221 .flags = FLAG_ADVANCED,
3224 .label = "abort shutdown script",
3225 .type = P_STRING,
3226 .p_class = P_GLOBAL,
3227 .ptr = &Globals.szAbortShutdownScript,
3228 .special = NULL,
3229 .enum_list = NULL,
3230 .flags = FLAG_ADVANCED,
3233 .label = "username map script",
3234 .type = P_STRING,
3235 .p_class = P_GLOBAL,
3236 .ptr = &Globals.szUsernameMapScript,
3237 .special = NULL,
3238 .enum_list = NULL,
3239 .flags = FLAG_ADVANCED,
3242 .label = "logon script",
3243 .type = P_STRING,
3244 .p_class = P_GLOBAL,
3245 .ptr = &Globals.szLogonScript,
3246 .special = NULL,
3247 .enum_list = NULL,
3248 .flags = FLAG_ADVANCED,
3251 .label = "logon path",
3252 .type = P_STRING,
3253 .p_class = P_GLOBAL,
3254 .ptr = &Globals.szLogonPath,
3255 .special = NULL,
3256 .enum_list = NULL,
3257 .flags = FLAG_ADVANCED,
3260 .label = "logon drive",
3261 .type = P_STRING,
3262 .p_class = P_GLOBAL,
3263 .ptr = &Globals.szLogonDrive,
3264 .special = NULL,
3265 .enum_list = NULL,
3266 .flags = FLAG_ADVANCED,
3269 .label = "logon home",
3270 .type = P_STRING,
3271 .p_class = P_GLOBAL,
3272 .ptr = &Globals.szLogonHome,
3273 .special = NULL,
3274 .enum_list = NULL,
3275 .flags = FLAG_ADVANCED,
3278 .label = "domain logons",
3279 .type = P_BOOL,
3280 .p_class = P_GLOBAL,
3281 .ptr = &Globals.bDomainLogons,
3282 .special = NULL,
3283 .enum_list = NULL,
3284 .flags = FLAG_ADVANCED,
3288 .label = "init logon delayed hosts",
3289 .type = P_LIST,
3290 .p_class = P_GLOBAL,
3291 .ptr = &Globals.szInitLogonDelayedHosts,
3292 .special = NULL,
3293 .enum_list = NULL,
3294 .flags = FLAG_ADVANCED,
3298 .label = "init logon delay",
3299 .type = P_INTEGER,
3300 .p_class = P_GLOBAL,
3301 .ptr = &Globals.InitLogonDelay,
3302 .special = NULL,
3303 .enum_list = NULL,
3304 .flags = FLAG_ADVANCED,
3308 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3311 .label = "os level",
3312 .type = P_INTEGER,
3313 .p_class = P_GLOBAL,
3314 .ptr = &Globals.os_level,
3315 .special = NULL,
3316 .enum_list = NULL,
3317 .flags = FLAG_BASIC | FLAG_ADVANCED,
3320 .label = "lm announce",
3321 .type = P_ENUM,
3322 .p_class = P_GLOBAL,
3323 .ptr = &Globals.lm_announce,
3324 .special = NULL,
3325 .enum_list = enum_bool_auto,
3326 .flags = FLAG_ADVANCED,
3329 .label = "lm interval",
3330 .type = P_INTEGER,
3331 .p_class = P_GLOBAL,
3332 .ptr = &Globals.lm_interval,
3333 .special = NULL,
3334 .enum_list = NULL,
3335 .flags = FLAG_ADVANCED,
3338 .label = "preferred master",
3339 .type = P_ENUM,
3340 .p_class = P_GLOBAL,
3341 .ptr = &Globals.iPreferredMaster,
3342 .special = NULL,
3343 .enum_list = enum_bool_auto,
3344 .flags = FLAG_BASIC | FLAG_ADVANCED,
3347 .label = "prefered master",
3348 .type = P_ENUM,
3349 .p_class = P_GLOBAL,
3350 .ptr = &Globals.iPreferredMaster,
3351 .special = NULL,
3352 .enum_list = enum_bool_auto,
3353 .flags = FLAG_HIDE,
3356 .label = "local master",
3357 .type = P_BOOL,
3358 .p_class = P_GLOBAL,
3359 .ptr = &Globals.bLocalMaster,
3360 .special = NULL,
3361 .enum_list = NULL,
3362 .flags = FLAG_BASIC | FLAG_ADVANCED,
3365 .label = "domain master",
3366 .type = P_ENUM,
3367 .p_class = P_GLOBAL,
3368 .ptr = &Globals.iDomainMaster,
3369 .special = NULL,
3370 .enum_list = enum_bool_auto,
3371 .flags = FLAG_BASIC | FLAG_ADVANCED,
3374 .label = "browse list",
3375 .type = P_BOOL,
3376 .p_class = P_GLOBAL,
3377 .ptr = &Globals.bBrowseList,
3378 .special = NULL,
3379 .enum_list = NULL,
3380 .flags = FLAG_ADVANCED,
3383 .label = "browseable",
3384 .type = P_BOOL,
3385 .p_class = P_LOCAL,
3386 .ptr = &sDefault.bBrowseable,
3387 .special = NULL,
3388 .enum_list = NULL,
3389 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3392 .label = "browsable",
3393 .type = P_BOOL,
3394 .p_class = P_LOCAL,
3395 .ptr = &sDefault.bBrowseable,
3396 .special = NULL,
3397 .enum_list = NULL,
3398 .flags = FLAG_HIDE,
3401 .label = "access based share enum",
3402 .type = P_BOOL,
3403 .p_class = P_LOCAL,
3404 .ptr = &sDefault.bAccessBasedShareEnum,
3405 .special = NULL,
3406 .enum_list = NULL,
3407 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3410 .label = "enhanced browsing",
3411 .type = P_BOOL,
3412 .p_class = P_GLOBAL,
3413 .ptr = &Globals.enhanced_browsing,
3414 .special = NULL,
3415 .enum_list = NULL,
3416 .flags = FLAG_ADVANCED,
3419 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3422 .label = "dns proxy",
3423 .type = P_BOOL,
3424 .p_class = P_GLOBAL,
3425 .ptr = &Globals.bDNSproxy,
3426 .special = NULL,
3427 .enum_list = NULL,
3428 .flags = FLAG_ADVANCED,
3431 .label = "wins proxy",
3432 .type = P_BOOL,
3433 .p_class = P_GLOBAL,
3434 .ptr = &Globals.bWINSproxy,
3435 .special = NULL,
3436 .enum_list = NULL,
3437 .flags = FLAG_ADVANCED,
3440 .label = "wins server",
3441 .type = P_LIST,
3442 .p_class = P_GLOBAL,
3443 .ptr = &Globals.szWINSservers,
3444 .special = NULL,
3445 .enum_list = NULL,
3446 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3449 .label = "wins support",
3450 .type = P_BOOL,
3451 .p_class = P_GLOBAL,
3452 .ptr = &Globals.bWINSsupport,
3453 .special = NULL,
3454 .enum_list = NULL,
3455 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3458 .label = "wins hook",
3459 .type = P_STRING,
3460 .p_class = P_GLOBAL,
3461 .ptr = &Globals.szWINSHook,
3462 .special = NULL,
3463 .enum_list = NULL,
3464 .flags = FLAG_ADVANCED,
3467 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3470 .label = "blocking locks",
3471 .type = P_BOOL,
3472 .p_class = P_LOCAL,
3473 .ptr = &sDefault.bBlockingLocks,
3474 .special = NULL,
3475 .enum_list = NULL,
3476 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3479 .label = "csc policy",
3480 .type = P_ENUM,
3481 .p_class = P_LOCAL,
3482 .ptr = &sDefault.iCSCPolicy,
3483 .special = NULL,
3484 .enum_list = enum_csc_policy,
3485 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3488 .label = "fake oplocks",
3489 .type = P_BOOL,
3490 .p_class = P_LOCAL,
3491 .ptr = &sDefault.bFakeOplocks,
3492 .special = NULL,
3493 .enum_list = NULL,
3494 .flags = FLAG_ADVANCED | FLAG_SHARE,
3497 .label = "kernel oplocks",
3498 .type = P_BOOL,
3499 .p_class = P_GLOBAL,
3500 .ptr = &Globals.bKernelOplocks,
3501 .special = NULL,
3502 .enum_list = NULL,
3503 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3506 .label = "locking",
3507 .type = P_BOOL,
3508 .p_class = P_LOCAL,
3509 .ptr = &sDefault.bLocking,
3510 .special = NULL,
3511 .enum_list = NULL,
3512 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3515 .label = "lock spin time",
3516 .type = P_INTEGER,
3517 .p_class = P_GLOBAL,
3518 .ptr = &Globals.iLockSpinTime,
3519 .special = NULL,
3520 .enum_list = NULL,
3521 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3524 .label = "oplocks",
3525 .type = P_BOOL,
3526 .p_class = P_LOCAL,
3527 .ptr = &sDefault.bOpLocks,
3528 .special = NULL,
3529 .enum_list = NULL,
3530 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3533 .label = "level2 oplocks",
3534 .type = P_BOOL,
3535 .p_class = P_LOCAL,
3536 .ptr = &sDefault.bLevel2OpLocks,
3537 .special = NULL,
3538 .enum_list = NULL,
3539 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3542 .label = "oplock break wait time",
3543 .type = P_INTEGER,
3544 .p_class = P_GLOBAL,
3545 .ptr = &Globals.oplock_break_wait_time,
3546 .special = NULL,
3547 .enum_list = NULL,
3548 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3551 .label = "oplock contention limit",
3552 .type = P_INTEGER,
3553 .p_class = P_LOCAL,
3554 .ptr = &sDefault.iOplockContentionLimit,
3555 .special = NULL,
3556 .enum_list = NULL,
3557 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3560 .label = "posix locking",
3561 .type = P_BOOL,
3562 .p_class = P_LOCAL,
3563 .ptr = &sDefault.bPosixLocking,
3564 .special = NULL,
3565 .enum_list = NULL,
3566 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3569 .label = "strict locking",
3570 .type = P_ENUM,
3571 .p_class = P_LOCAL,
3572 .ptr = &sDefault.iStrictLocking,
3573 .special = NULL,
3574 .enum_list = enum_bool_auto,
3575 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3578 .label = "share modes",
3579 .type = P_BOOL,
3580 .p_class = P_LOCAL,
3581 .ptr = &sDefault.bShareModes,
3582 .special = NULL,
3583 .enum_list = NULL,
3584 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3587 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3590 .label = "ldap admin dn",
3591 .type = P_STRING,
3592 .p_class = P_GLOBAL,
3593 .ptr = &Globals.szLdapAdminDn,
3594 .special = NULL,
3595 .enum_list = NULL,
3596 .flags = FLAG_ADVANCED,
3599 .label = "ldap delete dn",
3600 .type = P_BOOL,
3601 .p_class = P_GLOBAL,
3602 .ptr = &Globals.ldap_delete_dn,
3603 .special = NULL,
3604 .enum_list = NULL,
3605 .flags = FLAG_ADVANCED,
3608 .label = "ldap group suffix",
3609 .type = P_STRING,
3610 .p_class = P_GLOBAL,
3611 .ptr = &Globals.szLdapGroupSuffix,
3612 .special = NULL,
3613 .enum_list = NULL,
3614 .flags = FLAG_ADVANCED,
3617 .label = "ldap idmap suffix",
3618 .type = P_STRING,
3619 .p_class = P_GLOBAL,
3620 .ptr = &Globals.szLdapIdmapSuffix,
3621 .special = NULL,
3622 .enum_list = NULL,
3623 .flags = FLAG_ADVANCED,
3626 .label = "ldap machine suffix",
3627 .type = P_STRING,
3628 .p_class = P_GLOBAL,
3629 .ptr = &Globals.szLdapMachineSuffix,
3630 .special = NULL,
3631 .enum_list = NULL,
3632 .flags = FLAG_ADVANCED,
3635 .label = "ldap passwd sync",
3636 .type = P_ENUM,
3637 .p_class = P_GLOBAL,
3638 .ptr = &Globals.ldap_passwd_sync,
3639 .special = NULL,
3640 .enum_list = enum_ldap_passwd_sync,
3641 .flags = FLAG_ADVANCED,
3644 .label = "ldap password sync",
3645 .type = P_ENUM,
3646 .p_class = P_GLOBAL,
3647 .ptr = &Globals.ldap_passwd_sync,
3648 .special = NULL,
3649 .enum_list = enum_ldap_passwd_sync,
3650 .flags = FLAG_HIDE,
3653 .label = "ldap replication sleep",
3654 .type = P_INTEGER,
3655 .p_class = P_GLOBAL,
3656 .ptr = &Globals.ldap_replication_sleep,
3657 .special = NULL,
3658 .enum_list = NULL,
3659 .flags = FLAG_ADVANCED,
3662 .label = "ldap suffix",
3663 .type = P_STRING,
3664 .p_class = P_GLOBAL,
3665 .ptr = &Globals.szLdapSuffix,
3666 .special = NULL,
3667 .enum_list = NULL,
3668 .flags = FLAG_ADVANCED,
3671 .label = "ldap ssl",
3672 .type = P_ENUM,
3673 .p_class = P_GLOBAL,
3674 .ptr = &Globals.ldap_ssl,
3675 .special = NULL,
3676 .enum_list = enum_ldap_ssl,
3677 .flags = FLAG_ADVANCED,
3680 .label = "ldap ssl ads",
3681 .type = P_BOOL,
3682 .p_class = P_GLOBAL,
3683 .ptr = &Globals.ldap_ssl_ads,
3684 .special = NULL,
3685 .enum_list = NULL,
3686 .flags = FLAG_ADVANCED,
3689 .label = "ldap deref",
3690 .type = P_ENUM,
3691 .p_class = P_GLOBAL,
3692 .ptr = &Globals.ldap_deref,
3693 .special = NULL,
3694 .enum_list = enum_ldap_deref,
3695 .flags = FLAG_ADVANCED,
3698 .label = "ldap follow referral",
3699 .type = P_ENUM,
3700 .p_class = P_GLOBAL,
3701 .ptr = &Globals.ldap_follow_referral,
3702 .special = NULL,
3703 .enum_list = enum_bool_auto,
3704 .flags = FLAG_ADVANCED,
3707 .label = "ldap timeout",
3708 .type = P_INTEGER,
3709 .p_class = P_GLOBAL,
3710 .ptr = &Globals.ldap_timeout,
3711 .special = NULL,
3712 .enum_list = NULL,
3713 .flags = FLAG_ADVANCED,
3716 .label = "ldap connection timeout",
3717 .type = P_INTEGER,
3718 .p_class = P_GLOBAL,
3719 .ptr = &Globals.ldap_connection_timeout,
3720 .special = NULL,
3721 .enum_list = NULL,
3722 .flags = FLAG_ADVANCED,
3725 .label = "ldap page size",
3726 .type = P_INTEGER,
3727 .p_class = P_GLOBAL,
3728 .ptr = &Globals.ldap_page_size,
3729 .special = NULL,
3730 .enum_list = NULL,
3731 .flags = FLAG_ADVANCED,
3734 .label = "ldap user suffix",
3735 .type = P_STRING,
3736 .p_class = P_GLOBAL,
3737 .ptr = &Globals.szLdapUserSuffix,
3738 .special = NULL,
3739 .enum_list = NULL,
3740 .flags = FLAG_ADVANCED,
3743 .label = "ldap debug level",
3744 .type = P_INTEGER,
3745 .p_class = P_GLOBAL,
3746 .ptr = &Globals.ldap_debug_level,
3747 .special = handle_ldap_debug_level,
3748 .enum_list = NULL,
3749 .flags = FLAG_ADVANCED,
3752 .label = "ldap debug threshold",
3753 .type = P_INTEGER,
3754 .p_class = P_GLOBAL,
3755 .ptr = &Globals.ldap_debug_threshold,
3756 .special = NULL,
3757 .enum_list = NULL,
3758 .flags = FLAG_ADVANCED,
3761 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3764 .label = "eventlog list",
3765 .type = P_LIST,
3766 .p_class = P_GLOBAL,
3767 .ptr = &Globals.szEventLogs,
3768 .special = NULL,
3769 .enum_list = NULL,
3770 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3773 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3776 .label = "add share command",
3777 .type = P_STRING,
3778 .p_class = P_GLOBAL,
3779 .ptr = &Globals.szAddShareCommand,
3780 .special = NULL,
3781 .enum_list = NULL,
3782 .flags = FLAG_ADVANCED,
3785 .label = "change share command",
3786 .type = P_STRING,
3787 .p_class = P_GLOBAL,
3788 .ptr = &Globals.szChangeShareCommand,
3789 .special = NULL,
3790 .enum_list = NULL,
3791 .flags = FLAG_ADVANCED,
3794 .label = "delete share command",
3795 .type = P_STRING,
3796 .p_class = P_GLOBAL,
3797 .ptr = &Globals.szDeleteShareCommand,
3798 .special = NULL,
3799 .enum_list = NULL,
3800 .flags = FLAG_ADVANCED,
3803 .label = "config file",
3804 .type = P_STRING,
3805 .p_class = P_GLOBAL,
3806 .ptr = &Globals.szConfigFile,
3807 .special = NULL,
3808 .enum_list = NULL,
3809 .flags = FLAG_HIDE|FLAG_META,
3812 .label = "preload",
3813 .type = P_STRING,
3814 .p_class = P_GLOBAL,
3815 .ptr = &Globals.szAutoServices,
3816 .special = NULL,
3817 .enum_list = NULL,
3818 .flags = FLAG_ADVANCED,
3821 .label = "auto services",
3822 .type = P_STRING,
3823 .p_class = P_GLOBAL,
3824 .ptr = &Globals.szAutoServices,
3825 .special = NULL,
3826 .enum_list = NULL,
3827 .flags = FLAG_ADVANCED,
3830 .label = "lock directory",
3831 .type = P_STRING,
3832 .p_class = P_GLOBAL,
3833 .ptr = &Globals.szLockDir,
3834 .special = NULL,
3835 .enum_list = NULL,
3836 .flags = FLAG_ADVANCED,
3839 .label = "lock dir",
3840 .type = P_STRING,
3841 .p_class = P_GLOBAL,
3842 .ptr = &Globals.szLockDir,
3843 .special = NULL,
3844 .enum_list = NULL,
3845 .flags = FLAG_HIDE,
3848 .label = "state directory",
3849 .type = P_STRING,
3850 .p_class = P_GLOBAL,
3851 .ptr = &Globals.szStateDir,
3852 .special = NULL,
3853 .enum_list = NULL,
3854 .flags = FLAG_ADVANCED,
3857 .label = "cache directory",
3858 .type = P_STRING,
3859 .p_class = P_GLOBAL,
3860 .ptr = &Globals.szCacheDir,
3861 .special = NULL,
3862 .enum_list = NULL,
3863 .flags = FLAG_ADVANCED,
3866 .label = "pid directory",
3867 .type = P_STRING,
3868 .p_class = P_GLOBAL,
3869 .ptr = &Globals.szPidDir,
3870 .special = NULL,
3871 .enum_list = NULL,
3872 .flags = FLAG_ADVANCED,
3874 #ifdef WITH_UTMP
3876 .label = "utmp directory",
3877 .type = P_STRING,
3878 .p_class = P_GLOBAL,
3879 .ptr = &Globals.szUtmpDir,
3880 .special = NULL,
3881 .enum_list = NULL,
3882 .flags = FLAG_ADVANCED,
3885 .label = "wtmp directory",
3886 .type = P_STRING,
3887 .p_class = P_GLOBAL,
3888 .ptr = &Globals.szWtmpDir,
3889 .special = NULL,
3890 .enum_list = NULL,
3891 .flags = FLAG_ADVANCED,
3894 .label = "utmp",
3895 .type = P_BOOL,
3896 .p_class = P_GLOBAL,
3897 .ptr = &Globals.bUtmp,
3898 .special = NULL,
3899 .enum_list = NULL,
3900 .flags = FLAG_ADVANCED,
3902 #endif
3904 .label = "default service",
3905 .type = P_STRING,
3906 .p_class = P_GLOBAL,
3907 .ptr = &Globals.szDefaultService,
3908 .special = NULL,
3909 .enum_list = NULL,
3910 .flags = FLAG_ADVANCED,
3913 .label = "default",
3914 .type = P_STRING,
3915 .p_class = P_GLOBAL,
3916 .ptr = &Globals.szDefaultService,
3917 .special = NULL,
3918 .enum_list = NULL,
3919 .flags = FLAG_ADVANCED,
3922 .label = "message command",
3923 .type = P_STRING,
3924 .p_class = P_GLOBAL,
3925 .ptr = &Globals.szMsgCommand,
3926 .special = NULL,
3927 .enum_list = NULL,
3928 .flags = FLAG_ADVANCED,
3931 .label = "dfree cache time",
3932 .type = P_INTEGER,
3933 .p_class = P_LOCAL,
3934 .ptr = &sDefault.iDfreeCacheTime,
3935 .special = NULL,
3936 .enum_list = NULL,
3937 .flags = FLAG_ADVANCED,
3940 .label = "dfree command",
3941 .type = P_STRING,
3942 .p_class = P_LOCAL,
3943 .ptr = &sDefault.szDfree,
3944 .special = NULL,
3945 .enum_list = NULL,
3946 .flags = FLAG_ADVANCED,
3949 .label = "get quota command",
3950 .type = P_STRING,
3951 .p_class = P_GLOBAL,
3952 .ptr = &Globals.szGetQuota,
3953 .special = NULL,
3954 .enum_list = NULL,
3955 .flags = FLAG_ADVANCED,
3958 .label = "set quota command",
3959 .type = P_STRING,
3960 .p_class = P_GLOBAL,
3961 .ptr = &Globals.szSetQuota,
3962 .special = NULL,
3963 .enum_list = NULL,
3964 .flags = FLAG_ADVANCED,
3967 .label = "remote announce",
3968 .type = P_STRING,
3969 .p_class = P_GLOBAL,
3970 .ptr = &Globals.szRemoteAnnounce,
3971 .special = NULL,
3972 .enum_list = NULL,
3973 .flags = FLAG_ADVANCED,
3976 .label = "remote browse sync",
3977 .type = P_STRING,
3978 .p_class = P_GLOBAL,
3979 .ptr = &Globals.szRemoteBrowseSync,
3980 .special = NULL,
3981 .enum_list = NULL,
3982 .flags = FLAG_ADVANCED,
3985 .label = "socket address",
3986 .type = P_STRING,
3987 .p_class = P_GLOBAL,
3988 .ptr = &Globals.szSocketAddress,
3989 .special = NULL,
3990 .enum_list = NULL,
3991 .flags = FLAG_ADVANCED,
3994 .label = "homedir map",
3995 .type = P_STRING,
3996 .p_class = P_GLOBAL,
3997 .ptr = &Globals.szNISHomeMapName,
3998 .special = NULL,
3999 .enum_list = NULL,
4000 .flags = FLAG_ADVANCED,
4003 .label = "afs username map",
4004 .type = P_STRING,
4005 .p_class = P_GLOBAL,
4006 .ptr = &Globals.szAfsUsernameMap,
4007 .special = NULL,
4008 .enum_list = NULL,
4009 .flags = FLAG_ADVANCED,
4012 .label = "afs token lifetime",
4013 .type = P_INTEGER,
4014 .p_class = P_GLOBAL,
4015 .ptr = &Globals.iAfsTokenLifetime,
4016 .special = NULL,
4017 .enum_list = NULL,
4018 .flags = FLAG_ADVANCED,
4021 .label = "log nt token command",
4022 .type = P_STRING,
4023 .p_class = P_GLOBAL,
4024 .ptr = &Globals.szLogNtTokenCommand,
4025 .special = NULL,
4026 .enum_list = NULL,
4027 .flags = FLAG_ADVANCED,
4030 .label = "time offset",
4031 .type = P_INTEGER,
4032 .p_class = P_GLOBAL,
4033 .ptr = &extra_time_offset,
4034 .special = NULL,
4035 .enum_list = NULL,
4036 .flags = FLAG_ADVANCED,
4039 .label = "NIS homedir",
4040 .type = P_BOOL,
4041 .p_class = P_GLOBAL,
4042 .ptr = &Globals.bNISHomeMap,
4043 .special = NULL,
4044 .enum_list = NULL,
4045 .flags = FLAG_ADVANCED,
4048 .label = "-valid",
4049 .type = P_BOOL,
4050 .p_class = P_LOCAL,
4051 .ptr = &sDefault.valid,
4052 .special = NULL,
4053 .enum_list = NULL,
4054 .flags = FLAG_HIDE,
4057 .label = "copy",
4058 .type = P_STRING,
4059 .p_class = P_LOCAL,
4060 .ptr = &sDefault.szCopy,
4061 .special = handle_copy,
4062 .enum_list = NULL,
4063 .flags = FLAG_HIDE,
4066 .label = "include",
4067 .type = P_STRING,
4068 .p_class = P_LOCAL,
4069 .ptr = &sDefault.szInclude,
4070 .special = handle_include,
4071 .enum_list = NULL,
4072 .flags = FLAG_HIDE|FLAG_META,
4075 .label = "preexec",
4076 .type = P_STRING,
4077 .p_class = P_LOCAL,
4078 .ptr = &sDefault.szPreExec,
4079 .special = NULL,
4080 .enum_list = NULL,
4081 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4084 .label = "exec",
4085 .type = P_STRING,
4086 .p_class = P_LOCAL,
4087 .ptr = &sDefault.szPreExec,
4088 .special = NULL,
4089 .enum_list = NULL,
4090 .flags = FLAG_ADVANCED,
4093 .label = "preexec close",
4094 .type = P_BOOL,
4095 .p_class = P_LOCAL,
4096 .ptr = &sDefault.bPreexecClose,
4097 .special = NULL,
4098 .enum_list = NULL,
4099 .flags = FLAG_ADVANCED | FLAG_SHARE,
4102 .label = "postexec",
4103 .type = P_STRING,
4104 .p_class = P_LOCAL,
4105 .ptr = &sDefault.szPostExec,
4106 .special = NULL,
4107 .enum_list = NULL,
4108 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4111 .label = "root preexec",
4112 .type = P_STRING,
4113 .p_class = P_LOCAL,
4114 .ptr = &sDefault.szRootPreExec,
4115 .special = NULL,
4116 .enum_list = NULL,
4117 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4120 .label = "root preexec close",
4121 .type = P_BOOL,
4122 .p_class = P_LOCAL,
4123 .ptr = &sDefault.bRootpreexecClose,
4124 .special = NULL,
4125 .enum_list = NULL,
4126 .flags = FLAG_ADVANCED | FLAG_SHARE,
4129 .label = "root postexec",
4130 .type = P_STRING,
4131 .p_class = P_LOCAL,
4132 .ptr = &sDefault.szRootPostExec,
4133 .special = NULL,
4134 .enum_list = NULL,
4135 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4138 .label = "available",
4139 .type = P_BOOL,
4140 .p_class = P_LOCAL,
4141 .ptr = &sDefault.bAvailable,
4142 .special = NULL,
4143 .enum_list = NULL,
4144 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4147 .label = "registry shares",
4148 .type = P_BOOL,
4149 .p_class = P_GLOBAL,
4150 .ptr = &Globals.bRegistryShares,
4151 .special = NULL,
4152 .enum_list = NULL,
4153 .flags = FLAG_ADVANCED,
4156 .label = "usershare allow guests",
4157 .type = P_BOOL,
4158 .p_class = P_GLOBAL,
4159 .ptr = &Globals.bUsershareAllowGuests,
4160 .special = NULL,
4161 .enum_list = NULL,
4162 .flags = FLAG_ADVANCED,
4165 .label = "usershare max shares",
4166 .type = P_INTEGER,
4167 .p_class = P_GLOBAL,
4168 .ptr = &Globals.iUsershareMaxShares,
4169 .special = NULL,
4170 .enum_list = NULL,
4171 .flags = FLAG_ADVANCED,
4174 .label = "usershare owner only",
4175 .type = P_BOOL,
4176 .p_class = P_GLOBAL,
4177 .ptr = &Globals.bUsershareOwnerOnly,
4178 .special = NULL,
4179 .enum_list = NULL,
4180 .flags = FLAG_ADVANCED,
4183 .label = "usershare path",
4184 .type = P_STRING,
4185 .p_class = P_GLOBAL,
4186 .ptr = &Globals.szUsersharePath,
4187 .special = NULL,
4188 .enum_list = NULL,
4189 .flags = FLAG_ADVANCED,
4192 .label = "usershare prefix allow list",
4193 .type = P_LIST,
4194 .p_class = P_GLOBAL,
4195 .ptr = &Globals.szUsersharePrefixAllowList,
4196 .special = NULL,
4197 .enum_list = NULL,
4198 .flags = FLAG_ADVANCED,
4201 .label = "usershare prefix deny list",
4202 .type = P_LIST,
4203 .p_class = P_GLOBAL,
4204 .ptr = &Globals.szUsersharePrefixDenyList,
4205 .special = NULL,
4206 .enum_list = NULL,
4207 .flags = FLAG_ADVANCED,
4210 .label = "usershare template share",
4211 .type = P_STRING,
4212 .p_class = P_GLOBAL,
4213 .ptr = &Globals.szUsershareTemplateShare,
4214 .special = NULL,
4215 .enum_list = NULL,
4216 .flags = FLAG_ADVANCED,
4219 .label = "volume",
4220 .type = P_STRING,
4221 .p_class = P_LOCAL,
4222 .ptr = &sDefault.volume,
4223 .special = NULL,
4224 .enum_list = NULL,
4225 .flags = FLAG_ADVANCED | FLAG_SHARE,
4228 .label = "fstype",
4229 .type = P_STRING,
4230 .p_class = P_LOCAL,
4231 .ptr = &sDefault.fstype,
4232 .special = NULL,
4233 .enum_list = NULL,
4234 .flags = FLAG_ADVANCED | FLAG_SHARE,
4237 .label = "set directory",
4238 .type = P_BOOLREV,
4239 .p_class = P_LOCAL,
4240 .ptr = &sDefault.bNo_set_dir,
4241 .special = NULL,
4242 .enum_list = NULL,
4243 .flags = FLAG_ADVANCED | FLAG_SHARE,
4246 .label = "wide links",
4247 .type = P_BOOL,
4248 .p_class = P_LOCAL,
4249 .ptr = &sDefault.bWidelinks,
4250 .special = NULL,
4251 .enum_list = NULL,
4252 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4255 .label = "follow symlinks",
4256 .type = P_BOOL,
4257 .p_class = P_LOCAL,
4258 .ptr = &sDefault.bSymlinks,
4259 .special = NULL,
4260 .enum_list = NULL,
4261 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4264 .label = "dont descend",
4265 .type = P_STRING,
4266 .p_class = P_LOCAL,
4267 .ptr = &sDefault.szDontdescend,
4268 .special = NULL,
4269 .enum_list = NULL,
4270 .flags = FLAG_ADVANCED | FLAG_SHARE,
4273 .label = "magic script",
4274 .type = P_STRING,
4275 .p_class = P_LOCAL,
4276 .ptr = &sDefault.szMagicScript,
4277 .special = NULL,
4278 .enum_list = NULL,
4279 .flags = FLAG_ADVANCED | FLAG_SHARE,
4282 .label = "magic output",
4283 .type = P_STRING,
4284 .p_class = P_LOCAL,
4285 .ptr = &sDefault.szMagicOutput,
4286 .special = NULL,
4287 .enum_list = NULL,
4288 .flags = FLAG_ADVANCED | FLAG_SHARE,
4291 .label = "delete readonly",
4292 .type = P_BOOL,
4293 .p_class = P_LOCAL,
4294 .ptr = &sDefault.bDeleteReadonly,
4295 .special = NULL,
4296 .enum_list = NULL,
4297 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4300 .label = "dos filemode",
4301 .type = P_BOOL,
4302 .p_class = P_LOCAL,
4303 .ptr = &sDefault.bDosFilemode,
4304 .special = NULL,
4305 .enum_list = NULL,
4306 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4309 .label = "dos filetimes",
4310 .type = P_BOOL,
4311 .p_class = P_LOCAL,
4312 .ptr = &sDefault.bDosFiletimes,
4313 .special = NULL,
4314 .enum_list = NULL,
4315 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4318 .label = "dos filetime resolution",
4319 .type = P_BOOL,
4320 .p_class = P_LOCAL,
4321 .ptr = &sDefault.bDosFiletimeResolution,
4322 .special = NULL,
4323 .enum_list = NULL,
4324 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4327 .label = "fake directory create times",
4328 .type = P_BOOL,
4329 .p_class = P_LOCAL,
4330 .ptr = &sDefault.bFakeDirCreateTimes,
4331 .special = NULL,
4332 .enum_list = NULL,
4333 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4336 .label = "panic action",
4337 .type = P_STRING,
4338 .p_class = P_GLOBAL,
4339 .ptr = &Globals.szPanicAction,
4340 .special = NULL,
4341 .enum_list = NULL,
4342 .flags = FLAG_ADVANCED,
4345 .label = "perfcount module",
4346 .type = P_STRING,
4347 .p_class = P_GLOBAL,
4348 .ptr = &Globals.szSMBPerfcountModule,
4349 .special = NULL,
4350 .enum_list = NULL,
4351 .flags = FLAG_ADVANCED,
4354 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4357 .label = "vfs objects",
4358 .type = P_LIST,
4359 .p_class = P_LOCAL,
4360 .ptr = &sDefault.szVfsObjects,
4361 .special = NULL,
4362 .enum_list = NULL,
4363 .flags = FLAG_ADVANCED | FLAG_SHARE,
4366 .label = "vfs object",
4367 .type = P_LIST,
4368 .p_class = P_LOCAL,
4369 .ptr = &sDefault.szVfsObjects,
4370 .special = NULL,
4371 .enum_list = NULL,
4372 .flags = FLAG_HIDE,
4376 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4379 .label = "msdfs root",
4380 .type = P_BOOL,
4381 .p_class = P_LOCAL,
4382 .ptr = &sDefault.bMSDfsRoot,
4383 .special = NULL,
4384 .enum_list = NULL,
4385 .flags = FLAG_ADVANCED | FLAG_SHARE,
4388 .label = "msdfs proxy",
4389 .type = P_STRING,
4390 .p_class = P_LOCAL,
4391 .ptr = &sDefault.szMSDfsProxy,
4392 .special = NULL,
4393 .enum_list = NULL,
4394 .flags = FLAG_ADVANCED | FLAG_SHARE,
4397 .label = "host msdfs",
4398 .type = P_BOOL,
4399 .p_class = P_GLOBAL,
4400 .ptr = &Globals.bHostMSDfs,
4401 .special = NULL,
4402 .enum_list = NULL,
4403 .flags = FLAG_ADVANCED,
4406 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4409 .label = "passdb expand explicit",
4410 .type = P_BOOL,
4411 .p_class = P_GLOBAL,
4412 .ptr = &Globals.bPassdbExpandExplicit,
4413 .special = NULL,
4414 .enum_list = NULL,
4415 .flags = FLAG_ADVANCED,
4418 .label = "idmap backend",
4419 .type = P_STRING,
4420 .p_class = P_GLOBAL,
4421 .ptr = &Globals.szIdmapBackend,
4422 .special = NULL,
4423 .enum_list = NULL,
4424 .flags = FLAG_ADVANCED,
4427 .label = "idmap alloc backend",
4428 .type = P_STRING,
4429 .p_class = P_GLOBAL,
4430 .ptr = &Globals.szIdmapAllocBackend,
4431 .special = NULL,
4432 .enum_list = NULL,
4433 .flags = FLAG_ADVANCED,
4436 .label = "idmap cache time",
4437 .type = P_INTEGER,
4438 .p_class = P_GLOBAL,
4439 .ptr = &Globals.iIdmapCacheTime,
4440 .special = NULL,
4441 .enum_list = NULL,
4442 .flags = FLAG_ADVANCED,
4445 .label = "idmap negative cache time",
4446 .type = P_INTEGER,
4447 .p_class = P_GLOBAL,
4448 .ptr = &Globals.iIdmapNegativeCacheTime,
4449 .special = NULL,
4450 .enum_list = NULL,
4451 .flags = FLAG_ADVANCED,
4454 .label = "idmap uid",
4455 .type = P_STRING,
4456 .p_class = P_GLOBAL,
4457 .ptr = &Globals.szIdmapUID,
4458 .special = handle_idmap_uid,
4459 .enum_list = NULL,
4460 .flags = FLAG_ADVANCED,
4463 .label = "winbind uid",
4464 .type = P_STRING,
4465 .p_class = P_GLOBAL,
4466 .ptr = &Globals.szIdmapUID,
4467 .special = handle_idmap_uid,
4468 .enum_list = NULL,
4469 .flags = FLAG_HIDE,
4472 .label = "idmap gid",
4473 .type = P_STRING,
4474 .p_class = P_GLOBAL,
4475 .ptr = &Globals.szIdmapGID,
4476 .special = handle_idmap_gid,
4477 .enum_list = NULL,
4478 .flags = FLAG_ADVANCED,
4481 .label = "winbind gid",
4482 .type = P_STRING,
4483 .p_class = P_GLOBAL,
4484 .ptr = &Globals.szIdmapGID,
4485 .special = handle_idmap_gid,
4486 .enum_list = NULL,
4487 .flags = FLAG_HIDE,
4490 .label = "template homedir",
4491 .type = P_STRING,
4492 .p_class = P_GLOBAL,
4493 .ptr = &Globals.szTemplateHomedir,
4494 .special = NULL,
4495 .enum_list = NULL,
4496 .flags = FLAG_ADVANCED,
4499 .label = "template shell",
4500 .type = P_STRING,
4501 .p_class = P_GLOBAL,
4502 .ptr = &Globals.szTemplateShell,
4503 .special = NULL,
4504 .enum_list = NULL,
4505 .flags = FLAG_ADVANCED,
4508 .label = "winbind separator",
4509 .type = P_STRING,
4510 .p_class = P_GLOBAL,
4511 .ptr = &Globals.szWinbindSeparator,
4512 .special = NULL,
4513 .enum_list = NULL,
4514 .flags = FLAG_ADVANCED,
4517 .label = "winbind cache time",
4518 .type = P_INTEGER,
4519 .p_class = P_GLOBAL,
4520 .ptr = &Globals.winbind_cache_time,
4521 .special = NULL,
4522 .enum_list = NULL,
4523 .flags = FLAG_ADVANCED,
4526 .label = "winbind reconnect delay",
4527 .type = P_INTEGER,
4528 .p_class = P_GLOBAL,
4529 .ptr = &Globals.winbind_reconnect_delay,
4530 .special = NULL,
4531 .enum_list = NULL,
4532 .flags = FLAG_ADVANCED,
4535 .label = "winbind enum users",
4536 .type = P_BOOL,
4537 .p_class = P_GLOBAL,
4538 .ptr = &Globals.bWinbindEnumUsers,
4539 .special = NULL,
4540 .enum_list = NULL,
4541 .flags = FLAG_ADVANCED,
4544 .label = "winbind enum groups",
4545 .type = P_BOOL,
4546 .p_class = P_GLOBAL,
4547 .ptr = &Globals.bWinbindEnumGroups,
4548 .special = NULL,
4549 .enum_list = NULL,
4550 .flags = FLAG_ADVANCED,
4553 .label = "winbind use default domain",
4554 .type = P_BOOL,
4555 .p_class = P_GLOBAL,
4556 .ptr = &Globals.bWinbindUseDefaultDomain,
4557 .special = NULL,
4558 .enum_list = NULL,
4559 .flags = FLAG_ADVANCED,
4562 .label = "winbind trusted domains only",
4563 .type = P_BOOL,
4564 .p_class = P_GLOBAL,
4565 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4566 .special = NULL,
4567 .enum_list = NULL,
4568 .flags = FLAG_ADVANCED,
4571 .label = "winbind nested groups",
4572 .type = P_BOOL,
4573 .p_class = P_GLOBAL,
4574 .ptr = &Globals.bWinbindNestedGroups,
4575 .special = NULL,
4576 .enum_list = NULL,
4577 .flags = FLAG_ADVANCED,
4580 .label = "winbind expand groups",
4581 .type = P_INTEGER,
4582 .p_class = P_GLOBAL,
4583 .ptr = &Globals.winbind_expand_groups,
4584 .special = NULL,
4585 .enum_list = NULL,
4586 .flags = FLAG_ADVANCED,
4589 .label = "winbind nss info",
4590 .type = P_LIST,
4591 .p_class = P_GLOBAL,
4592 .ptr = &Globals.szWinbindNssInfo,
4593 .special = NULL,
4594 .enum_list = NULL,
4595 .flags = FLAG_ADVANCED,
4598 .label = "winbind refresh tickets",
4599 .type = P_BOOL,
4600 .p_class = P_GLOBAL,
4601 .ptr = &Globals.bWinbindRefreshTickets,
4602 .special = NULL,
4603 .enum_list = NULL,
4604 .flags = FLAG_ADVANCED,
4607 .label = "winbind offline logon",
4608 .type = P_BOOL,
4609 .p_class = P_GLOBAL,
4610 .ptr = &Globals.bWinbindOfflineLogon,
4611 .special = NULL,
4612 .enum_list = NULL,
4613 .flags = FLAG_ADVANCED,
4616 .label = "winbind normalize names",
4617 .type = P_BOOL,
4618 .p_class = P_GLOBAL,
4619 .ptr = &Globals.bWinbindNormalizeNames,
4620 .special = NULL,
4621 .enum_list = NULL,
4622 .flags = FLAG_ADVANCED,
4625 .label = "winbind rpc only",
4626 .type = P_BOOL,
4627 .p_class = P_GLOBAL,
4628 .ptr = &Globals.bWinbindRpcOnly,
4629 .special = NULL,
4630 .enum_list = NULL,
4631 .flags = FLAG_ADVANCED,
4634 .label = "create krb5 conf",
4635 .type = P_BOOL,
4636 .p_class = P_GLOBAL,
4637 .ptr = &Globals.bCreateKrb5Conf,
4638 .special = NULL,
4639 .enum_list = NULL,
4640 .flags = FLAG_ADVANCED,
4643 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4646 /***************************************************************************
4647 Initialise the sDefault parameter structure for the printer values.
4648 ***************************************************************************/
4650 static void init_printer_values(struct service *pService)
4652 /* choose defaults depending on the type of printing */
4653 switch (pService->iPrinting) {
4654 case PRINT_BSD:
4655 case PRINT_AIX:
4656 case PRINT_LPRNT:
4657 case PRINT_LPROS2:
4658 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4659 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4660 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4661 break;
4663 case PRINT_LPRNG:
4664 case PRINT_PLP:
4665 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4666 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4667 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4668 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4669 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4670 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4671 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4672 break;
4674 case PRINT_CUPS:
4675 case PRINT_IPRINT:
4676 #ifdef HAVE_CUPS
4677 /* set the lpq command to contain the destination printer
4678 name only. This is used by cups_queue_get() */
4679 string_set(&pService->szLpqcommand, "%p");
4680 string_set(&pService->szLprmcommand, "");
4681 string_set(&pService->szPrintcommand, "");
4682 string_set(&pService->szLppausecommand, "");
4683 string_set(&pService->szLpresumecommand, "");
4684 string_set(&pService->szQueuepausecommand, "");
4685 string_set(&pService->szQueueresumecommand, "");
4686 #else
4687 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4688 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4689 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4690 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4691 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4692 string_set(&pService->szQueuepausecommand, "disable '%p'");
4693 string_set(&pService->szQueueresumecommand, "enable '%p'");
4694 #endif /* HAVE_CUPS */
4695 break;
4697 case PRINT_SYSV:
4698 case PRINT_HPUX:
4699 string_set(&pService->szLpqcommand, "lpstat -o%p");
4700 string_set(&pService->szLprmcommand, "cancel %p-%j");
4701 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4702 string_set(&pService->szQueuepausecommand, "disable %p");
4703 string_set(&pService->szQueueresumecommand, "enable %p");
4704 #ifndef HPUX
4705 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4706 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4707 #endif /* HPUX */
4708 break;
4710 case PRINT_QNX:
4711 string_set(&pService->szLpqcommand, "lpq -P%p");
4712 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4713 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4714 break;
4716 #ifdef DEVELOPER
4717 case PRINT_TEST:
4718 case PRINT_VLP:
4719 string_set(&pService->szPrintcommand, "vlp print %p %s");
4720 string_set(&pService->szLpqcommand, "vlp lpq %p");
4721 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4722 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4723 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4724 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4725 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4726 break;
4727 #endif /* DEVELOPER */
4732 * Function to return the default value for the maximum number of open
4733 * file descriptors permitted. This function tries to consult the
4734 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4735 * the smaller of those.
4737 static int max_open_files(void)
4739 int sysctl_max = MAX_OPEN_FILES;
4740 int rlimit_max = MAX_OPEN_FILES;
4742 #ifdef HAVE_SYSCTLBYNAME
4744 size_t size = sizeof(sysctl_max);
4745 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4748 #endif
4750 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4752 struct rlimit rl;
4754 ZERO_STRUCT(rl);
4756 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4757 rlimit_max = rl.rlim_cur;
4759 #if defined(RLIM_INFINITY)
4760 if(rl.rlim_cur == RLIM_INFINITY)
4761 rlimit_max = MAX_OPEN_FILES;
4763 #endif
4764 #endif
4766 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4767 DEBUG(2,("max_open_files: sysctl_max (%d) below "
4768 "minimum Windows limit (%d)\n",
4769 sysctl_max,
4770 MIN_OPEN_FILES_WINDOWS));
4771 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4774 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4775 DEBUG(2,("rlimit_max: rlimit_max (%d) below "
4776 "minimum Windows limit (%d)\n",
4777 rlimit_max,
4778 MIN_OPEN_FILES_WINDOWS));
4779 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4782 return MIN(sysctl_max, rlimit_max);
4786 * Common part of freeing allocated data for one parameter.
4788 static void free_one_parameter_common(void *parm_ptr,
4789 struct parm_struct parm)
4791 if ((parm.type == P_STRING) ||
4792 (parm.type == P_USTRING))
4794 string_free((char**)parm_ptr);
4795 } else if (parm.type == P_LIST) {
4796 TALLOC_FREE(*((char***)parm_ptr));
4801 * Free the allocated data for one parameter for a share
4802 * given as a service struct.
4804 static void free_one_parameter(struct service *service,
4805 struct parm_struct parm)
4807 void *parm_ptr;
4809 if (parm.p_class != P_LOCAL) {
4810 return;
4813 parm_ptr = lp_local_ptr(service, parm.ptr);
4815 free_one_parameter_common(parm_ptr, parm);
4819 * Free the allocated parameter data of a share given
4820 * as a service struct.
4822 static void free_parameters(struct service *service)
4824 uint32_t i;
4826 for (i=0; parm_table[i].label; i++) {
4827 free_one_parameter(service, parm_table[i]);
4832 * Free the allocated data for one parameter for a given share
4833 * specified by an snum.
4835 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4837 void *parm_ptr;
4839 if (parm.ptr == NULL) {
4840 return;
4843 if (snum < 0) {
4844 parm_ptr = parm.ptr;
4845 } else if (parm.p_class != P_LOCAL) {
4846 return;
4847 } else {
4848 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4851 free_one_parameter_common(parm_ptr, parm);
4855 * Free the allocated parameter data for a share specified
4856 * by an snum.
4858 static void free_parameters_by_snum(int snum)
4860 uint32_t i;
4862 for (i=0; parm_table[i].label; i++) {
4863 free_one_parameter_by_snum(snum, parm_table[i]);
4868 * Free the allocated global parameters.
4870 static void free_global_parameters(void)
4872 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4875 /***************************************************************************
4876 Initialise the global parameter structure.
4877 ***************************************************************************/
4879 static void init_globals(bool first_time_only)
4881 static bool done_init = False;
4882 char *s = NULL;
4883 int i;
4885 /* If requested to initialize only once and we've already done it... */
4886 if (first_time_only && done_init) {
4887 /* ... then we have nothing more to do */
4888 return;
4891 if (!done_init) {
4892 /* The logfile can be set before this is invoked. Free it if so. */
4893 if (Globals.szLogFile != NULL) {
4894 string_free(&Globals.szLogFile);
4895 Globals.szLogFile = NULL;
4897 done_init = True;
4898 } else {
4899 free_global_parameters();
4902 memset((void *)&Globals, '\0', sizeof(Globals));
4904 for (i = 0; parm_table[i].label; i++) {
4905 if ((parm_table[i].type == P_STRING ||
4906 parm_table[i].type == P_USTRING) &&
4907 parm_table[i].ptr)
4909 string_set((char **)parm_table[i].ptr, "");
4913 string_set(&sDefault.fstype, FSTYPE_STRING);
4914 string_set(&sDefault.szPrintjobUsername, "%U");
4916 init_printer_values(&sDefault);
4919 DEBUG(3, ("Initialising global parameters\n"));
4921 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4922 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4924 /* use the new 'hash2' method by default, with a prefix of 1 */
4925 string_set(&Globals.szManglingMethod, "hash2");
4926 Globals.mangle_prefix = 1;
4928 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4930 /* using UTF8 by default allows us to support all chars */
4931 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4933 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4934 /* If the system supports nl_langinfo(), try to grab the value
4935 from the user's locale */
4936 string_set(&Globals.display_charset, "LOCALE");
4937 #else
4938 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4939 #endif
4941 /* Use codepage 850 as a default for the dos character set */
4942 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4945 * Allow the default PASSWD_CHAT to be overridden in local.h.
4947 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4949 set_global_myname(myhostname());
4950 string_set(&Globals.szNetbiosName,global_myname());
4952 set_global_myworkgroup(WORKGROUP);
4953 string_set(&Globals.szWorkgroup, lp_workgroup());
4955 string_set(&Globals.szPasswdProgram, "");
4956 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4957 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4958 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4959 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4960 string_set(&Globals.szSocketAddress, "0.0.0.0");
4962 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4963 smb_panic("init_globals: ENOMEM");
4965 string_set(&Globals.szServerString, s);
4966 SAFE_FREE(s);
4967 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4968 DEFAULT_MINOR_VERSION) < 0) {
4969 smb_panic("init_globals: ENOMEM");
4971 string_set(&Globals.szAnnounceVersion, s);
4972 SAFE_FREE(s);
4973 #ifdef DEVELOPER
4974 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4975 #endif
4977 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4979 string_set(&Globals.szLogonDrive, "");
4980 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4981 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4982 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4984 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4985 string_set(&Globals.szPasswordServer, "*");
4987 Globals.AlgorithmicRidBase = BASE_RID;
4989 Globals.bLoadPrinters = True;
4990 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4992 Globals.ConfigBackend = config_backend;
4994 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4995 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4996 Globals.max_xmit = 0x4104;
4997 Globals.max_mux = 50; /* This is *needed* for profile support. */
4998 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4999 Globals.bDisableSpoolss = False;
5000 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5001 Globals.pwordlevel = 0;
5002 Globals.unamelevel = 0;
5003 Globals.deadtime = 0;
5004 Globals.getwd_cache = true;
5005 Globals.bLargeReadwrite = True;
5006 Globals.max_log_size = 5000;
5007 Globals.max_open_files = max_open_files();
5008 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5009 Globals.maxprotocol = PROTOCOL_NT1;
5010 Globals.minprotocol = PROTOCOL_CORE;
5011 Globals.security = SEC_USER;
5012 Globals.paranoid_server_security = True;
5013 Globals.bEncryptPasswords = True;
5014 Globals.bUpdateEncrypt = False;
5015 Globals.clientSchannel = Auto;
5016 Globals.serverSchannel = Auto;
5017 Globals.bReadRaw = True;
5018 Globals.bWriteRaw = True;
5019 Globals.bNullPasswords = False;
5020 Globals.bObeyPamRestrictions = False;
5021 Globals.syslog = 1;
5022 Globals.bSyslogOnly = False;
5023 Globals.bTimestampLogs = True;
5024 string_set(&Globals.szLogLevel, "0");
5025 Globals.bDebugPrefixTimestamp = False;
5026 Globals.bDebugHiresTimestamp = true;
5027 Globals.bDebugPid = False;
5028 Globals.bDebugUid = False;
5029 Globals.bDebugClass = False;
5030 Globals.bEnableCoreFiles = True;
5031 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
5032 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
5033 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
5034 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
5035 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
5036 Globals.lm_interval = 60;
5037 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5038 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5039 Globals.bNISHomeMap = False;
5040 #ifdef WITH_NISPLUS_HOME
5041 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5042 #else
5043 string_set(&Globals.szNISHomeMapName, "auto.home");
5044 #endif
5045 #endif
5046 Globals.bTimeServer = False;
5047 Globals.bBindInterfacesOnly = False;
5048 Globals.bUnixPasswdSync = False;
5049 Globals.bPamPasswordChange = False;
5050 Globals.bPasswdChatDebug = False;
5051 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5052 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
5053 Globals.bNTStatusSupport = True; /* Use NT status by default. */
5054 Globals.bStatCache = True; /* use stat cache by default */
5055 Globals.iMaxStatCacheSize = 256; /* 256k by default */
5056 Globals.restrict_anonymous = 0;
5057 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
5058 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
5059 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
5060 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5061 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
5062 /* Note, that we will use NTLM2 session security (which is different), if it is available */
5064 Globals.map_to_guest = 0; /* By Default, "Never" */
5065 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
5066 Globals.enhanced_browsing = true;
5067 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5068 #ifdef MMAP_BLACKLIST
5069 Globals.bUseMmap = False;
5070 #else
5071 Globals.bUseMmap = True;
5072 #endif
5073 Globals.bUnixExtensions = True;
5074 Globals.bResetOnZeroVC = False;
5075 Globals.bCreateKrb5Conf = true;
5077 /* hostname lookups can be very expensive and are broken on
5078 a large number of sites (tridge) */
5079 Globals.bHostnameLookups = False;
5081 string_set(&Globals.szPassdbBackend, "tdbsam");
5082 string_set(&Globals.szLdapSuffix, "");
5083 string_set(&Globals.szLdapMachineSuffix, "");
5084 string_set(&Globals.szLdapUserSuffix, "");
5085 string_set(&Globals.szLdapGroupSuffix, "");
5086 string_set(&Globals.szLdapIdmapSuffix, "");
5088 string_set(&Globals.szLdapAdminDn, "");
5089 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5090 Globals.ldap_ssl_ads = False;
5091 Globals.ldap_deref = -1;
5092 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5093 Globals.ldap_delete_dn = False;
5094 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5095 Globals.ldap_follow_referral = Auto;
5096 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5097 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5098 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5100 Globals.ldap_debug_level = 0;
5101 Globals.ldap_debug_threshold = 10;
5103 /* This is what we tell the afs client. in reality we set the token
5104 * to never expire, though, when this runs out the afs client will
5105 * forget the token. Set to 0 to get NEVERDATE.*/
5106 Globals.iAfsTokenLifetime = 604800;
5107 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5109 /* these parameters are set to defaults that are more appropriate
5110 for the increasing samba install base:
5112 as a member of the workgroup, that will possibly become a
5113 _local_ master browser (lm = True). this is opposed to a forced
5114 local master browser startup (pm = True).
5116 doesn't provide WINS server service by default (wsupp = False),
5117 and doesn't provide domain master browser services by default, either.
5121 Globals.bMsAddPrinterWizard = True;
5122 Globals.os_level = 20;
5123 Globals.bLocalMaster = True;
5124 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5125 Globals.bDomainLogons = False;
5126 Globals.bBrowseList = True;
5127 Globals.bWINSsupport = False;
5128 Globals.bWINSproxy = False;
5130 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5131 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5133 Globals.bDNSproxy = True;
5135 /* this just means to use them if they exist */
5136 Globals.bKernelOplocks = True;
5138 Globals.bAllowTrustedDomains = True;
5139 string_set(&Globals.szIdmapBackend, "tdb");
5141 string_set(&Globals.szTemplateShell, "/bin/false");
5142 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5143 string_set(&Globals.szWinbindSeparator, "\\");
5145 string_set(&Globals.szCupsServer, "");
5146 string_set(&Globals.szIPrintServer, "");
5148 string_set(&Globals.ctdbdSocket, "");
5149 Globals.szClusterAddresses = NULL;
5150 Globals.clustering = False;
5151 Globals.ctdb_timeout = 0;
5153 Globals.winbind_cache_time = 300; /* 5 minutes */
5154 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5155 Globals.bWinbindEnumUsers = False;
5156 Globals.bWinbindEnumGroups = False;
5157 Globals.bWinbindUseDefaultDomain = False;
5158 Globals.bWinbindTrustedDomainsOnly = False;
5159 Globals.bWinbindNestedGroups = True;
5160 Globals.winbind_expand_groups = 1;
5161 Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5162 Globals.bWinbindRefreshTickets = False;
5163 Globals.bWinbindOfflineLogon = False;
5165 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5166 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5168 Globals.bPassdbExpandExplicit = False;
5170 Globals.name_cache_timeout = 660; /* In seconds */
5172 Globals.bUseSpnego = True;
5173 Globals.bClientUseSpnego = True;
5175 Globals.client_signing = Auto;
5176 Globals.server_signing = False;
5178 Globals.bDeferSharingViolations = True;
5179 string_set(&Globals.smb_ports, SMB_PORTS);
5181 Globals.bEnablePrivileges = True;
5182 Globals.bHostMSDfs = True;
5183 Globals.bASUSupport = False;
5185 /* User defined shares. */
5186 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5187 smb_panic("init_globals: ENOMEM");
5189 string_set(&Globals.szUsersharePath, s);
5190 SAFE_FREE(s);
5191 string_set(&Globals.szUsershareTemplateShare, "");
5192 Globals.iUsershareMaxShares = 0;
5193 /* By default disallow sharing of directories not owned by the sharer. */
5194 Globals.bUsershareOwnerOnly = True;
5195 /* By default disallow guest access to usershares. */
5196 Globals.bUsershareAllowGuests = False;
5198 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5200 /* By default no shares out of the registry */
5201 Globals.bRegistryShares = False;
5203 Globals.iminreceivefile = 0;
5205 Globals.bMapUntrustedToDomain = false;
5208 /*******************************************************************
5209 Convenience routine to grab string parameters into temporary memory
5210 and run standard_sub_basic on them. The buffers can be written to by
5211 callers without affecting the source string.
5212 ********************************************************************/
5214 static char *lp_string(const char *s)
5216 char *ret;
5217 TALLOC_CTX *ctx = talloc_tos();
5219 /* The follow debug is useful for tracking down memory problems
5220 especially if you have an inner loop that is calling a lp_*()
5221 function that returns a string. Perhaps this debug should be
5222 present all the time? */
5224 #if 0
5225 DEBUG(10, ("lp_string(%s)\n", s));
5226 #endif
5227 if (!s) {
5228 return NULL;
5231 ret = talloc_sub_basic(ctx,
5232 get_current_username(),
5233 current_user_info.domain,
5235 if (trim_char(ret, '\"', '\"')) {
5236 if (strchr(ret,'\"') != NULL) {
5237 TALLOC_FREE(ret);
5238 ret = talloc_sub_basic(ctx,
5239 get_current_username(),
5240 current_user_info.domain,
5244 return ret;
5248 In this section all the functions that are used to access the
5249 parameters from the rest of the program are defined
5252 #define FN_GLOBAL_STRING(fn_name,ptr) \
5253 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5254 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5255 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5256 #define FN_GLOBAL_LIST(fn_name,ptr) \
5257 const char **fn_name(void) {return(*(const char ***)(ptr));}
5258 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5259 bool fn_name(void) {return(*(bool *)(ptr));}
5260 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5261 char fn_name(void) {return(*(char *)(ptr));}
5262 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5263 int fn_name(void) {return(*(int *)(ptr));}
5265 #define FN_LOCAL_STRING(fn_name,val) \
5266 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5267 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5268 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5269 #define FN_LOCAL_LIST(fn_name,val) \
5270 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5271 #define FN_LOCAL_BOOL(fn_name,val) \
5272 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5273 #define FN_LOCAL_INTEGER(fn_name,val) \
5274 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5276 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5277 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5278 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5279 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5280 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5281 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));}
5282 #define FN_LOCAL_CHAR(fn_name,val) \
5283 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5285 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5286 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5287 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5288 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5289 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5290 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5291 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5292 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5293 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5294 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5295 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5296 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5297 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5298 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5299 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5300 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5301 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5302 * build process or in smb.conf, we use that value. Otherwise they
5303 * default to the value of lp_lockdir(). */
5304 char *lp_statedir(void) {
5305 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5306 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5307 return(lp_string(*(char **)(&Globals.szStateDir) ?
5308 *(char **)(&Globals.szStateDir) : ""));
5309 else
5310 return(lp_string(*(char **)(&Globals.szLockDir) ?
5311 *(char **)(&Globals.szLockDir) : ""));
5313 char *lp_cachedir(void) {
5314 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5315 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5316 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5317 *(char **)(&Globals.szCacheDir) : ""));
5318 else
5319 return(lp_string(*(char **)(&Globals.szLockDir) ?
5320 *(char **)(&Globals.szLockDir) : ""));
5322 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5323 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5324 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5325 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5326 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5327 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5328 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5329 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5330 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5331 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5332 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5333 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5334 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5335 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5336 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5337 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5338 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5339 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5340 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5341 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5342 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5343 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5344 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5345 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5346 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5347 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5348 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5349 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5350 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5351 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5352 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5353 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5354 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5355 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5356 * lp_passdb_backend() should be replace by the this macro again after
5357 * some releases.
5358 * */
5359 const char *lp_passdb_backend(void)
5361 char *delim, *quote;
5363 delim = strchr( Globals.szPassdbBackend, ' ');
5364 /* no space at all */
5365 if (delim == NULL) {
5366 goto out;
5369 quote = strchr(Globals.szPassdbBackend, '"');
5370 /* no quote char or non in the first part */
5371 if (quote == NULL || quote > delim) {
5372 *delim = '\0';
5373 goto warn;
5376 quote = strchr(quote+1, '"');
5377 if (quote == NULL) {
5378 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5379 goto out;
5380 } else if (*(quote+1) == '\0') {
5381 /* space, fitting quote char, and one backend only */
5382 goto out;
5383 } else {
5384 /* terminate string after the fitting quote char */
5385 *(quote+1) = '\0';
5388 warn:
5389 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5390 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5391 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5392 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5394 out:
5395 return Globals.szPassdbBackend;
5397 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5398 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5399 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5400 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5401 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5403 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5404 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5405 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5406 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5407 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5408 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5410 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5412 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5413 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5414 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5416 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5418 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5419 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5420 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5421 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5422 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5423 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5424 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5425 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5426 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5427 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5428 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5429 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5430 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5431 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5432 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5433 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5435 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5436 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5437 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5438 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5439 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5440 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5442 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5443 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5444 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5445 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5446 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5447 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5448 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5449 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5450 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5451 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5452 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5453 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5454 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5455 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5456 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5457 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5458 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5459 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5460 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5461 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5463 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5465 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5466 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5467 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5468 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5469 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5470 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5471 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5472 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5473 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5474 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5475 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5476 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5477 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5478 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5479 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5480 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5481 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5482 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5483 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5484 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5485 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5486 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5487 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5488 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5489 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5490 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5491 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5492 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5493 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5494 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5495 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5496 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5497 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5498 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5499 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5500 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5501 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5502 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5503 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5504 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5505 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5506 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5507 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5508 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5509 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5510 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5511 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5512 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5513 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5514 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5515 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5516 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5517 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5518 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5519 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5520 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5521 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5522 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5523 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5524 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5525 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5526 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5527 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5528 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5529 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5530 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5531 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5532 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5533 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5534 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5535 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5536 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5537 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5538 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5539 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5540 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5541 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5542 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5543 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5544 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5545 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5546 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5547 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5548 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5549 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5550 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5551 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5552 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5553 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5554 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5555 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5556 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5557 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5558 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5559 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5560 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5561 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5562 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5563 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5564 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5566 FN_LOCAL_STRING(lp_preexec, szPreExec)
5567 FN_LOCAL_STRING(lp_postexec, szPostExec)
5568 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5569 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5570 FN_LOCAL_STRING(lp_servicename, szService)
5571 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5572 FN_LOCAL_STRING(lp_pathname, szPath)
5573 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5574 FN_LOCAL_STRING(lp_username, szUsername)
5575 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5576 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5577 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5578 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5579 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5580 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5581 int lp_cups_encrypt(void)
5583 #ifdef HAVE_HTTPCONNECTENCRYPT
5584 switch (Globals.CupsEncrypt) {
5585 case Auto:
5586 Globals.CupsEncrypt = HTTP_ENCRYPT_REQUIRED;
5587 break;
5588 case True:
5589 Globals.CupsEncrypt = HTTP_ENCRYPT_ALWAYS;
5590 break;
5591 case False:
5592 Globals.CupsEncrypt = HTTP_ENCRYPT_NEVER;
5593 break;
5595 #endif
5596 return Globals.CupsEncrypt;
5598 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5599 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5600 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5601 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5602 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5603 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5604 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5605 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5606 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5607 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5608 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5609 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5610 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5611 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5612 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5613 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5614 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5615 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5616 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5617 FN_LOCAL_STRING(lp_comment, comment)
5618 FN_LOCAL_STRING(lp_force_user, force_user)
5619 FN_LOCAL_STRING(lp_force_group, force_group)
5620 FN_LOCAL_LIST(lp_readlist, readlist)
5621 FN_LOCAL_LIST(lp_writelist, writelist)
5622 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5623 FN_LOCAL_STRING(lp_fstype, fstype)
5624 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5625 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5626 static FN_LOCAL_STRING(lp_volume, volume)
5627 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5628 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5629 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5630 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5631 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5632 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5633 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5634 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5635 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5636 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5637 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5638 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5639 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5640 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5641 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5642 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5643 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5644 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5645 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5646 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5647 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5648 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5649 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5650 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5651 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5652 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5653 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5654 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5655 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5656 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5657 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5658 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5659 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5660 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5661 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5662 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5663 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5664 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5665 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5666 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5667 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5668 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5669 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5670 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5671 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5672 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5673 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5674 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5675 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5676 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5677 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5678 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5679 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5680 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5681 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5682 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5683 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5684 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5685 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5686 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5687 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5688 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5689 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5690 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5691 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5692 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5693 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5694 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5695 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5696 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5697 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5698 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5699 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5700 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5701 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5702 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5703 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5704 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5705 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5706 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5707 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5708 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5709 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5710 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5711 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5712 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5713 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5714 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5715 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5716 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5717 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5718 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5719 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5720 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5721 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5722 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5723 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5724 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5725 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5727 /* local prototypes */
5729 static int map_parameter(const char *pszParmName);
5730 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5731 static const char *get_boolean(bool bool_value);
5732 static int getservicebyname(const char *pszServiceName,
5733 struct service *pserviceDest);
5734 static void copy_service(struct service *pserviceDest,
5735 struct service *pserviceSource,
5736 struct bitmap *pcopymapDest);
5737 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5738 void *userdata);
5739 static bool do_section(const char *pszSectionName, void *userdata);
5740 static void init_copymap(struct service *pservice);
5741 static bool hash_a_service(const char *name, int number);
5742 static void free_service_byindex(int iService);
5743 static void free_param_opts(struct param_opt_struct **popts);
5744 static char * canonicalize_servicename(const char *name);
5745 static void show_parameter(int parmIndex);
5746 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5749 * This is a helper function for parametrical options support. It returns a
5750 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5751 * parametrical functions are quite simple
5753 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5754 const char *option)
5756 bool global_section = False;
5757 char* param_key;
5758 struct param_opt_struct *data;
5760 if (snum >= iNumServices) return NULL;
5762 if (snum < 0) {
5763 data = Globals.param_opt;
5764 global_section = True;
5765 } else {
5766 data = ServicePtrs[snum]->param_opt;
5769 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5770 DEBUG(0,("asprintf failed!\n"));
5771 return NULL;
5774 while (data) {
5775 if (strwicmp(data->key, param_key) == 0) {
5776 string_free(&param_key);
5777 return data;
5779 data = data->next;
5782 if (!global_section) {
5783 /* Try to fetch the same option but from globals */
5784 /* but only if we are not already working with Globals */
5785 data = Globals.param_opt;
5786 while (data) {
5787 if (strwicmp(data->key, param_key) == 0) {
5788 string_free(&param_key);
5789 return data;
5791 data = data->next;
5795 string_free(&param_key);
5797 return NULL;
5801 #define MISSING_PARAMETER(name) \
5802 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5804 /*******************************************************************
5805 convenience routine to return int parameters.
5806 ********************************************************************/
5807 static int lp_int(const char *s)
5810 if (!s || !*s) {
5811 MISSING_PARAMETER(lp_int);
5812 return (-1);
5815 return (int)strtol(s, NULL, 0);
5818 /*******************************************************************
5819 convenience routine to return unsigned long parameters.
5820 ********************************************************************/
5821 static unsigned long lp_ulong(const char *s)
5824 if (!s || !*s) {
5825 MISSING_PARAMETER(lp_ulong);
5826 return (0);
5829 return strtoul(s, NULL, 0);
5832 /*******************************************************************
5833 convenience routine to return boolean parameters.
5834 ********************************************************************/
5835 static bool lp_bool(const char *s)
5837 bool ret = False;
5839 if (!s || !*s) {
5840 MISSING_PARAMETER(lp_bool);
5841 return False;
5844 if (!set_boolean(s, &ret)) {
5845 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5846 return False;
5849 return ret;
5852 /*******************************************************************
5853 convenience routine to return enum parameters.
5854 ********************************************************************/
5855 static int lp_enum(const char *s,const struct enum_list *_enum)
5857 int i;
5859 if (!s || !*s || !_enum) {
5860 MISSING_PARAMETER(lp_enum);
5861 return (-1);
5864 for (i=0; _enum[i].name; i++) {
5865 if (strequal(_enum[i].name,s))
5866 return _enum[i].value;
5869 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5870 return (-1);
5873 #undef MISSING_PARAMETER
5875 /* DO NOT USE lp_parm_string ANYMORE!!!!
5876 * use lp_parm_const_string or lp_parm_talloc_string
5878 * lp_parm_string is only used to let old modules find this symbol
5880 #undef lp_parm_string
5881 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5882 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5884 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5887 /* Return parametric option from a given service. Type is a part of option before ':' */
5888 /* Parametric option has following syntax: 'Type: option = value' */
5889 /* the returned value is talloced on the talloc_tos() */
5890 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5892 struct param_opt_struct *data = get_parametrics(snum, type, option);
5894 if (data == NULL||data->value==NULL) {
5895 if (def) {
5896 return lp_string(def);
5897 } else {
5898 return NULL;
5902 return lp_string(data->value);
5905 /* Return parametric option from a given service. Type is a part of option before ':' */
5906 /* Parametric option has following syntax: 'Type: option = value' */
5907 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5909 struct param_opt_struct *data = get_parametrics(snum, type, option);
5911 if (data == NULL||data->value==NULL)
5912 return def;
5914 return data->value;
5917 /* Return parametric option from a given service. Type is a part of option before ':' */
5918 /* Parametric option has following syntax: 'Type: option = value' */
5920 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5922 struct param_opt_struct *data = get_parametrics(snum, type, option);
5924 if (data == NULL||data->value==NULL)
5925 return (const char **)def;
5927 if (data->list==NULL) {
5928 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
5931 return (const char **)data->list;
5934 /* Return parametric option from a given service. Type is a part of option before ':' */
5935 /* Parametric option has following syntax: 'Type: option = value' */
5937 int lp_parm_int(int snum, const char *type, const char *option, int def)
5939 struct param_opt_struct *data = get_parametrics(snum, type, option);
5941 if (data && data->value && *data->value)
5942 return lp_int(data->value);
5944 return def;
5947 /* Return parametric option from a given service. Type is a part of option before ':' */
5948 /* Parametric option has following syntax: 'Type: option = value' */
5950 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5952 struct param_opt_struct *data = get_parametrics(snum, type, option);
5954 if (data && data->value && *data->value)
5955 return lp_ulong(data->value);
5957 return def;
5960 /* Return parametric option from a given service. Type is a part of option before ':' */
5961 /* Parametric option has following syntax: 'Type: option = value' */
5963 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5965 struct param_opt_struct *data = get_parametrics(snum, type, option);
5967 if (data && data->value && *data->value)
5968 return lp_bool(data->value);
5970 return def;
5973 /* Return parametric option from a given service. Type is a part of option before ':' */
5974 /* Parametric option has following syntax: 'Type: option = value' */
5976 int lp_parm_enum(int snum, const char *type, const char *option,
5977 const struct enum_list *_enum, int def)
5979 struct param_opt_struct *data = get_parametrics(snum, type, option);
5981 if (data && data->value && *data->value && _enum)
5982 return lp_enum(data->value, _enum);
5984 return def;
5988 /***************************************************************************
5989 Initialise a service to the defaults.
5990 ***************************************************************************/
5992 static void init_service(struct service *pservice)
5994 memset((char *)pservice, '\0', sizeof(struct service));
5995 copy_service(pservice, &sDefault, NULL);
6000 * free a param_opts structure.
6001 * param_opts handling should be moved to talloc;
6002 * then this whole functions reduces to a TALLOC_FREE().
6005 static void free_param_opts(struct param_opt_struct **popts)
6007 struct param_opt_struct *opt, *next_opt;
6009 if (popts == NULL) {
6010 return;
6013 if (*popts != NULL) {
6014 DEBUG(5, ("Freeing parametrics:\n"));
6016 opt = *popts;
6017 while (opt != NULL) {
6018 string_free(&opt->key);
6019 string_free(&opt->value);
6020 TALLOC_FREE(opt->list);
6021 next_opt = opt->next;
6022 SAFE_FREE(opt);
6023 opt = next_opt;
6025 *popts = NULL;
6028 /***************************************************************************
6029 Free the dynamically allocated parts of a service struct.
6030 ***************************************************************************/
6032 static void free_service(struct service *pservice)
6034 if (!pservice)
6035 return;
6037 if (pservice->szService)
6038 DEBUG(5, ("free_service: Freeing service %s\n",
6039 pservice->szService));
6041 free_parameters(pservice);
6043 string_free(&pservice->szService);
6044 bitmap_free(pservice->copymap);
6046 free_param_opts(&pservice->param_opt);
6048 ZERO_STRUCTP(pservice);
6052 /***************************************************************************
6053 remove a service indexed in the ServicePtrs array from the ServiceHash
6054 and free the dynamically allocated parts
6055 ***************************************************************************/
6057 static void free_service_byindex(int idx)
6059 if ( !LP_SNUM_OK(idx) )
6060 return;
6062 ServicePtrs[idx]->valid = False;
6063 invalid_services[num_invalid_services++] = idx;
6065 /* we have to cleanup the hash record */
6067 if (ServicePtrs[idx]->szService) {
6068 char *canon_name = canonicalize_servicename(
6069 ServicePtrs[idx]->szService );
6071 dbwrap_delete_bystring(ServiceHash, canon_name );
6072 TALLOC_FREE(canon_name);
6075 free_service(ServicePtrs[idx]);
6078 /***************************************************************************
6079 Add a new service to the services array initialising it with the given
6080 service.
6081 ***************************************************************************/
6083 static int add_a_service(const struct service *pservice, const char *name)
6085 int i;
6086 struct service tservice;
6087 int num_to_alloc = iNumServices + 1;
6089 tservice = *pservice;
6091 /* it might already exist */
6092 if (name) {
6093 i = getservicebyname(name, NULL);
6094 if (i >= 0) {
6095 /* Clean all parametric options for service */
6096 /* They will be added during parsing again */
6097 free_param_opts(&ServicePtrs[i]->param_opt);
6098 return (i);
6102 /* find an invalid one */
6103 i = iNumServices;
6104 if (num_invalid_services > 0) {
6105 i = invalid_services[--num_invalid_services];
6108 /* if not, then create one */
6109 if (i == iNumServices) {
6110 struct service **tsp;
6111 int *tinvalid;
6113 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6114 if (tsp == NULL) {
6115 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6116 return (-1);
6118 ServicePtrs = tsp;
6119 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6120 if (!ServicePtrs[iNumServices]) {
6121 DEBUG(0,("add_a_service: out of memory!\n"));
6122 return (-1);
6124 iNumServices++;
6126 /* enlarge invalid_services here for now... */
6127 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6128 num_to_alloc);
6129 if (tinvalid == NULL) {
6130 DEBUG(0,("add_a_service: failed to enlarge "
6131 "invalid_services!\n"));
6132 return (-1);
6134 invalid_services = tinvalid;
6135 } else {
6136 free_service_byindex(i);
6139 ServicePtrs[i]->valid = True;
6141 init_service(ServicePtrs[i]);
6142 copy_service(ServicePtrs[i], &tservice, NULL);
6143 if (name)
6144 string_set(&ServicePtrs[i]->szService, name);
6146 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6147 i, ServicePtrs[i]->szService));
6149 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6150 return (-1);
6153 return (i);
6156 /***************************************************************************
6157 Convert a string to uppercase and remove whitespaces.
6158 ***************************************************************************/
6160 static char *canonicalize_servicename(const char *src)
6162 char *result;
6164 if ( !src ) {
6165 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6166 return NULL;
6169 result = talloc_strdup(talloc_tos(), src);
6170 SMB_ASSERT(result != NULL);
6172 strlower_m(result);
6173 return result;
6176 /***************************************************************************
6177 Add a name/index pair for the services array to the hash table.
6178 ***************************************************************************/
6180 static bool hash_a_service(const char *name, int idx)
6182 char *canon_name;
6184 if ( !ServiceHash ) {
6185 DEBUG(10,("hash_a_service: creating servicehash\n"));
6186 ServiceHash = db_open_rbt(NULL);
6187 if ( !ServiceHash ) {
6188 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6189 return False;
6193 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6194 idx, name));
6196 canon_name = canonicalize_servicename( name );
6198 dbwrap_store_bystring(ServiceHash, canon_name,
6199 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6200 TDB_REPLACE);
6202 TALLOC_FREE(canon_name);
6204 return True;
6207 /***************************************************************************
6208 Add a new home service, with the specified home directory, defaults coming
6209 from service ifrom.
6210 ***************************************************************************/
6212 bool lp_add_home(const char *pszHomename, int iDefaultService,
6213 const char *user, const char *pszHomedir)
6215 int i;
6217 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6218 pszHomedir[0] == '\0') {
6219 return false;
6222 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6224 if (i < 0)
6225 return (False);
6227 if (!(*(ServicePtrs[iDefaultService]->szPath))
6228 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6229 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6232 if (!(*(ServicePtrs[i]->comment))) {
6233 char *comment = NULL;
6234 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6235 return false;
6237 string_set(&ServicePtrs[i]->comment, comment);
6238 SAFE_FREE(comment);
6241 /* set the browseable flag from the global default */
6243 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6244 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6246 ServicePtrs[i]->autoloaded = True;
6248 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6249 user, ServicePtrs[i]->szPath ));
6251 return (True);
6254 /***************************************************************************
6255 Add a new service, based on an old one.
6256 ***************************************************************************/
6258 int lp_add_service(const char *pszService, int iDefaultService)
6260 if (iDefaultService < 0) {
6261 return add_a_service(&sDefault, pszService);
6264 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6267 /***************************************************************************
6268 Add the IPC service.
6269 ***************************************************************************/
6271 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6273 char *comment = NULL;
6274 int i = add_a_service(&sDefault, ipc_name);
6276 if (i < 0)
6277 return (False);
6279 if (asprintf(&comment, "IPC Service (%s)",
6280 Globals.szServerString) < 0) {
6281 return (False);
6284 string_set(&ServicePtrs[i]->szPath, tmpdir());
6285 string_set(&ServicePtrs[i]->szUsername, "");
6286 string_set(&ServicePtrs[i]->comment, comment);
6287 string_set(&ServicePtrs[i]->fstype, "IPC");
6288 ServicePtrs[i]->iMaxConnections = 0;
6289 ServicePtrs[i]->bAvailable = True;
6290 ServicePtrs[i]->bRead_only = True;
6291 ServicePtrs[i]->bGuest_only = False;
6292 ServicePtrs[i]->bAdministrative_share = True;
6293 ServicePtrs[i]->bGuest_ok = guest_ok;
6294 ServicePtrs[i]->bPrint_ok = False;
6295 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6297 DEBUG(3, ("adding IPC service\n"));
6299 SAFE_FREE(comment);
6300 return (True);
6303 /***************************************************************************
6304 Add a new printer service, with defaults coming from service iFrom.
6305 ***************************************************************************/
6307 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6309 const char *comment = "From Printcap";
6310 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6312 if (i < 0)
6313 return (False);
6315 /* note that we do NOT default the availability flag to True - */
6316 /* we take it from the default service passed. This allows all */
6317 /* dynamic printers to be disabled by disabling the [printers] */
6318 /* entry (if/when the 'available' keyword is implemented!). */
6320 /* the printer name is set to the service name. */
6321 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6322 string_set(&ServicePtrs[i]->comment, comment);
6324 /* set the browseable flag from the gloabl default */
6325 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6327 /* Printers cannot be read_only. */
6328 ServicePtrs[i]->bRead_only = False;
6329 /* No share modes on printer services. */
6330 ServicePtrs[i]->bShareModes = False;
6331 /* No oplocks on printer services. */
6332 ServicePtrs[i]->bOpLocks = False;
6333 /* Printer services must be printable. */
6334 ServicePtrs[i]->bPrint_ok = True;
6336 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6338 return (True);
6342 /***************************************************************************
6343 Check whether the given parameter name is valid.
6344 Parametric options (names containing a colon) are considered valid.
6345 ***************************************************************************/
6347 bool lp_parameter_is_valid(const char *pszParmName)
6349 return ((map_parameter(pszParmName) != -1) ||
6350 (strchr(pszParmName, ':') != NULL));
6353 /***************************************************************************
6354 Check whether the given name is the name of a global parameter.
6355 Returns True for strings belonging to parameters of class
6356 P_GLOBAL, False for all other strings, also for parametric options
6357 and strings not belonging to any option.
6358 ***************************************************************************/
6360 bool lp_parameter_is_global(const char *pszParmName)
6362 int num = map_parameter(pszParmName);
6364 if (num >= 0) {
6365 return (parm_table[num].p_class == P_GLOBAL);
6368 return False;
6371 /**************************************************************************
6372 Check whether the given name is the canonical name of a parameter.
6373 Returns False if it is not a valid parameter Name.
6374 For parametric options, True is returned.
6375 **************************************************************************/
6377 bool lp_parameter_is_canonical(const char *parm_name)
6379 if (!lp_parameter_is_valid(parm_name)) {
6380 return False;
6383 return (map_parameter(parm_name) ==
6384 map_parameter_canonical(parm_name, NULL));
6387 /**************************************************************************
6388 Determine the canonical name for a parameter.
6389 Indicate when it is an inverse (boolean) synonym instead of a
6390 "usual" synonym.
6391 **************************************************************************/
6393 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6394 bool *inverse)
6396 int num;
6398 if (!lp_parameter_is_valid(parm_name)) {
6399 *canon_parm = NULL;
6400 return False;
6403 num = map_parameter_canonical(parm_name, inverse);
6404 if (num < 0) {
6405 /* parametric option */
6406 *canon_parm = parm_name;
6407 } else {
6408 *canon_parm = parm_table[num].label;
6411 return True;
6415 /**************************************************************************
6416 Determine the canonical name for a parameter.
6417 Turn the value given into the inverse boolean expression when
6418 the synonym is an invers boolean synonym.
6420 Return True if parm_name is a valid parameter name and
6421 in case it is an invers boolean synonym, if the val string could
6422 successfully be converted to the reverse bool.
6423 Return false in all other cases.
6424 **************************************************************************/
6426 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6427 const char *val,
6428 const char **canon_parm,
6429 const char **canon_val)
6431 int num;
6432 bool inverse;
6434 if (!lp_parameter_is_valid(parm_name)) {
6435 *canon_parm = NULL;
6436 *canon_val = NULL;
6437 return False;
6440 num = map_parameter_canonical(parm_name, &inverse);
6441 if (num < 0) {
6442 /* parametric option */
6443 *canon_parm = parm_name;
6444 *canon_val = val;
6445 } else {
6446 *canon_parm = parm_table[num].label;
6447 if (inverse) {
6448 if (!lp_invert_boolean(val, canon_val)) {
6449 *canon_val = NULL;
6450 return False;
6452 } else {
6453 *canon_val = val;
6457 return True;
6460 /***************************************************************************
6461 Map a parameter's string representation to something we can use.
6462 Returns False if the parameter string is not recognised, else TRUE.
6463 ***************************************************************************/
6465 static int map_parameter(const char *pszParmName)
6467 int iIndex;
6469 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6470 return (-1);
6472 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6473 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6474 return (iIndex);
6476 /* Warn only if it isn't parametric option */
6477 if (strchr(pszParmName, ':') == NULL)
6478 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6479 /* We do return 'fail' for parametric options as well because they are
6480 stored in different storage
6482 return (-1);
6485 /***************************************************************************
6486 Map a parameter's string representation to the index of the canonical
6487 form of the parameter (it might be a synonym).
6488 Returns -1 if the parameter string is not recognised.
6489 ***************************************************************************/
6491 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6493 int parm_num, canon_num;
6494 bool loc_inverse = False;
6496 parm_num = map_parameter(pszParmName);
6497 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6498 /* invalid, parametric or no canidate for synonyms ... */
6499 goto done;
6502 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6503 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6504 parm_num = canon_num;
6505 goto done;
6509 done:
6510 if (inverse != NULL) {
6511 *inverse = loc_inverse;
6513 return parm_num;
6516 /***************************************************************************
6517 return true if parameter number parm1 is a synonym of parameter
6518 number parm2 (parm2 being the principal name).
6519 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6520 False otherwise.
6521 ***************************************************************************/
6523 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6525 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6526 (parm_table[parm1].flags & FLAG_HIDE) &&
6527 !(parm_table[parm2].flags & FLAG_HIDE))
6529 if (inverse != NULL) {
6530 if ((parm_table[parm1].type == P_BOOLREV) &&
6531 (parm_table[parm2].type == P_BOOL))
6533 *inverse = True;
6534 } else {
6535 *inverse = False;
6538 return True;
6540 return False;
6543 /***************************************************************************
6544 Show one parameter's name, type, [values,] and flags.
6545 (helper functions for show_parameter_list)
6546 ***************************************************************************/
6548 static void show_parameter(int parmIndex)
6550 int enumIndex, flagIndex;
6551 int parmIndex2;
6552 bool hadFlag;
6553 bool hadSyn;
6554 bool inverse;
6555 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6556 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6557 "P_ENUM", "P_SEP"};
6558 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6559 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6560 FLAG_HIDE, FLAG_DOS_STRING};
6561 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6562 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6563 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6565 printf("%s=%s", parm_table[parmIndex].label,
6566 type[parm_table[parmIndex].type]);
6567 if (parm_table[parmIndex].type == P_ENUM) {
6568 printf(",");
6569 for (enumIndex=0;
6570 parm_table[parmIndex].enum_list[enumIndex].name;
6571 enumIndex++)
6573 printf("%s%s",
6574 enumIndex ? "|" : "",
6575 parm_table[parmIndex].enum_list[enumIndex].name);
6578 printf(",");
6579 hadFlag = False;
6580 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6581 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6582 printf("%s%s",
6583 hadFlag ? "|" : "",
6584 flag_names[flagIndex]);
6585 hadFlag = True;
6589 /* output synonyms */
6590 hadSyn = False;
6591 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6592 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6593 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6594 parm_table[parmIndex2].label);
6595 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6596 if (!hadSyn) {
6597 printf(" (synonyms: ");
6598 hadSyn = True;
6599 } else {
6600 printf(", ");
6602 printf("%s%s", parm_table[parmIndex2].label,
6603 inverse ? "[i]" : "");
6606 if (hadSyn) {
6607 printf(")");
6610 printf("\n");
6613 /***************************************************************************
6614 Show all parameter's name, type, [values,] and flags.
6615 ***************************************************************************/
6617 void show_parameter_list(void)
6619 int classIndex, parmIndex;
6620 const char *section_names[] = { "local", "global", NULL};
6622 for (classIndex=0; section_names[classIndex]; classIndex++) {
6623 printf("[%s]\n", section_names[classIndex]);
6624 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6625 if (parm_table[parmIndex].p_class == classIndex) {
6626 show_parameter(parmIndex);
6632 /***************************************************************************
6633 Check if a given string correctly represents a boolean value.
6634 ***************************************************************************/
6636 bool lp_string_is_valid_boolean(const char *parm_value)
6638 return set_boolean(parm_value, NULL);
6641 /***************************************************************************
6642 Get the standard string representation of a boolean value ("yes" or "no")
6643 ***************************************************************************/
6645 static const char *get_boolean(bool bool_value)
6647 static const char *yes_str = "yes";
6648 static const char *no_str = "no";
6650 return (bool_value ? yes_str : no_str);
6653 /***************************************************************************
6654 Provide the string of the negated boolean value associated to the boolean
6655 given as a string. Returns False if the passed string does not correctly
6656 represent a boolean.
6657 ***************************************************************************/
6659 bool lp_invert_boolean(const char *str, const char **inverse_str)
6661 bool val;
6663 if (!set_boolean(str, &val)) {
6664 return False;
6667 *inverse_str = get_boolean(!val);
6668 return True;
6671 /***************************************************************************
6672 Provide the canonical string representation of a boolean value given
6673 as a string. Return True on success, False if the string given does
6674 not correctly represent a boolean.
6675 ***************************************************************************/
6677 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6679 bool val;
6681 if (!set_boolean(str, &val)) {
6682 return False;
6685 *canon_str = get_boolean(val);
6686 return True;
6689 /***************************************************************************
6690 Find a service by name. Otherwise works like get_service.
6691 ***************************************************************************/
6693 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6695 int iService = -1;
6696 char *canon_name;
6697 TDB_DATA data;
6699 if (ServiceHash == NULL) {
6700 return -1;
6703 canon_name = canonicalize_servicename(pszServiceName);
6705 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6707 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6708 iService = *(int *)data.dptr;
6711 TALLOC_FREE(canon_name);
6713 if ((iService != -1) && (LP_SNUM_OK(iService))
6714 && (pserviceDest != NULL)) {
6715 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6718 return (iService);
6721 /***************************************************************************
6722 Copy a service structure to another.
6723 If pcopymapDest is NULL then copy all fields
6724 ***************************************************************************/
6727 * Add a parametric option to a param_opt_struct,
6728 * replacing old value, if already present.
6730 static void set_param_opt(struct param_opt_struct **opt_list,
6731 const char *opt_name,
6732 const char *opt_value)
6734 struct param_opt_struct *new_opt, *opt;
6735 bool not_added;
6737 if (opt_list == NULL) {
6738 return;
6741 opt = *opt_list;
6742 not_added = true;
6744 /* Traverse destination */
6745 while (opt) {
6746 /* If we already have same option, override it */
6747 if (strwicmp(opt->key, opt_name) == 0) {
6748 string_free(&opt->value);
6749 TALLOC_FREE(opt->list);
6750 opt->value = SMB_STRDUP(opt_value);
6751 not_added = false;
6752 break;
6754 opt = opt->next;
6756 if (not_added) {
6757 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6758 new_opt->key = SMB_STRDUP(opt_name);
6759 new_opt->value = SMB_STRDUP(opt_value);
6760 new_opt->list = NULL;
6761 DLIST_ADD(*opt_list, new_opt);
6765 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6766 struct bitmap *pcopymapDest)
6768 int i;
6769 bool bcopyall = (pcopymapDest == NULL);
6770 struct param_opt_struct *data;
6772 for (i = 0; parm_table[i].label; i++)
6773 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6774 (bcopyall || bitmap_query(pcopymapDest,i))) {
6775 void *def_ptr = parm_table[i].ptr;
6776 void *src_ptr =
6777 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6778 &sDefault);
6779 void *dest_ptr =
6780 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6781 &sDefault);
6783 switch (parm_table[i].type) {
6784 case P_BOOL:
6785 case P_BOOLREV:
6786 *(bool *)dest_ptr = *(bool *)src_ptr;
6787 break;
6789 case P_INTEGER:
6790 case P_ENUM:
6791 case P_OCTAL:
6792 *(int *)dest_ptr = *(int *)src_ptr;
6793 break;
6795 case P_CHAR:
6796 *(char *)dest_ptr = *(char *)src_ptr;
6797 break;
6799 case P_STRING:
6800 string_set((char **)dest_ptr,
6801 *(char **)src_ptr);
6802 break;
6804 case P_USTRING:
6805 string_set((char **)dest_ptr,
6806 *(char **)src_ptr);
6807 strupper_m(*(char **)dest_ptr);
6808 break;
6809 case P_LIST:
6810 TALLOC_FREE(*((char ***)dest_ptr));
6811 *((char ***)dest_ptr) = str_list_copy(NULL,
6812 *(const char ***)src_ptr);
6813 break;
6814 default:
6815 break;
6819 if (bcopyall) {
6820 init_copymap(pserviceDest);
6821 if (pserviceSource->copymap)
6822 bitmap_copy(pserviceDest->copymap,
6823 pserviceSource->copymap);
6826 data = pserviceSource->param_opt;
6827 while (data) {
6828 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6829 data = data->next;
6833 /***************************************************************************
6834 Check a service for consistency. Return False if the service is in any way
6835 incomplete or faulty, else True.
6836 ***************************************************************************/
6838 bool service_ok(int iService)
6840 bool bRetval;
6842 bRetval = True;
6843 if (ServicePtrs[iService]->szService[0] == '\0') {
6844 DEBUG(0, ("The following message indicates an internal error:\n"));
6845 DEBUG(0, ("No service name in service entry.\n"));
6846 bRetval = False;
6849 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6850 /* I can't see why you'd want a non-printable printer service... */
6851 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6852 if (!ServicePtrs[iService]->bPrint_ok) {
6853 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6854 ServicePtrs[iService]->szService));
6855 ServicePtrs[iService]->bPrint_ok = True;
6857 /* [printers] service must also be non-browsable. */
6858 if (ServicePtrs[iService]->bBrowseable)
6859 ServicePtrs[iService]->bBrowseable = False;
6862 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6863 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6864 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6866 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6867 ServicePtrs[iService]->szService));
6868 ServicePtrs[iService]->bAvailable = False;
6871 /* If a service is flagged unavailable, log the fact at level 1. */
6872 if (!ServicePtrs[iService]->bAvailable)
6873 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6874 ServicePtrs[iService]->szService));
6876 return (bRetval);
6879 static struct smbconf_ctx *lp_smbconf_ctx(void)
6881 WERROR werr;
6882 static struct smbconf_ctx *conf_ctx = NULL;
6884 if (conf_ctx == NULL) {
6885 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6886 if (!W_ERROR_IS_OK(werr)) {
6887 DEBUG(1, ("error initializing registry configuration: "
6888 "%s\n", win_errstr(werr)));
6889 conf_ctx = NULL;
6893 return conf_ctx;
6896 static bool process_smbconf_service(struct smbconf_service *service)
6898 uint32_t count;
6899 bool ret;
6901 if (service == NULL) {
6902 return false;
6905 ret = do_section(service->name, NULL);
6906 if (ret != true) {
6907 return false;
6909 for (count = 0; count < service->num_params; count++) {
6910 ret = do_parameter(service->param_names[count],
6911 service->param_values[count],
6912 NULL);
6913 if (ret != true) {
6914 return false;
6917 if (iServiceIndex >= 0) {
6918 return service_ok(iServiceIndex);
6920 return true;
6924 * load a service from registry and activate it
6926 bool process_registry_service(const char *service_name)
6928 WERROR werr;
6929 struct smbconf_service *service = NULL;
6930 TALLOC_CTX *mem_ctx = talloc_stackframe();
6931 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6932 bool ret = false;
6934 if (conf_ctx == NULL) {
6935 goto done;
6938 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6940 if (!smbconf_share_exists(conf_ctx, service_name)) {
6942 * Registry does not contain data for this service (yet),
6943 * but make sure lp_load doesn't return false.
6945 ret = true;
6946 goto done;
6949 werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6950 if (!W_ERROR_IS_OK(werr)) {
6951 goto done;
6954 ret = process_smbconf_service(service);
6955 if (!ret) {
6956 goto done;
6959 /* store the csn */
6960 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6962 done:
6963 TALLOC_FREE(mem_ctx);
6964 return ret;
6968 * process_registry_globals
6970 static bool process_registry_globals(void)
6972 bool ret;
6974 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6976 ret = do_parameter("registry shares", "yes", NULL);
6977 if (!ret) {
6978 return ret;
6981 return process_registry_service(GLOBAL_NAME);
6984 bool process_registry_shares(void)
6986 WERROR werr;
6987 uint32_t count;
6988 struct smbconf_service **service = NULL;
6989 uint32_t num_shares = 0;
6990 TALLOC_CTX *mem_ctx = talloc_stackframe();
6991 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6992 bool ret = false;
6994 if (conf_ctx == NULL) {
6995 goto done;
6998 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6999 if (!W_ERROR_IS_OK(werr)) {
7000 goto done;
7003 ret = true;
7005 for (count = 0; count < num_shares; count++) {
7006 if (strequal(service[count]->name, GLOBAL_NAME)) {
7007 continue;
7009 ret = process_smbconf_service(service[count]);
7010 if (!ret) {
7011 goto done;
7015 /* store the csn */
7016 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7018 done:
7019 TALLOC_FREE(mem_ctx);
7020 return ret;
7023 #define MAX_INCLUDE_DEPTH 100
7025 static uint8_t include_depth;
7027 static struct file_lists {
7028 struct file_lists *next;
7029 char *name;
7030 char *subfname;
7031 time_t modtime;
7032 } *file_lists = NULL;
7034 /*******************************************************************
7035 Keep a linked list of all config files so we know when one has changed
7036 it's date and needs to be reloaded.
7037 ********************************************************************/
7039 static void add_to_file_list(const char *fname, const char *subfname)
7041 struct file_lists *f = file_lists;
7043 while (f) {
7044 if (f->name && !strcmp(f->name, fname))
7045 break;
7046 f = f->next;
7049 if (!f) {
7050 f = SMB_MALLOC_P(struct file_lists);
7051 if (!f)
7052 return;
7053 f->next = file_lists;
7054 f->name = SMB_STRDUP(fname);
7055 if (!f->name) {
7056 SAFE_FREE(f);
7057 return;
7059 f->subfname = SMB_STRDUP(subfname);
7060 if (!f->subfname) {
7061 SAFE_FREE(f->name);
7062 SAFE_FREE(f);
7063 return;
7065 file_lists = f;
7066 f->modtime = file_modtime(subfname);
7067 } else {
7068 time_t t = file_modtime(subfname);
7069 if (t)
7070 f->modtime = t;
7072 return;
7076 * Free the file lists
7078 static void free_file_list(void)
7080 struct file_lists *f;
7081 struct file_lists *next;
7083 f = file_lists;
7084 while( f ) {
7085 next = f->next;
7086 SAFE_FREE( f->name );
7087 SAFE_FREE( f->subfname );
7088 SAFE_FREE( f );
7089 f = next;
7091 file_lists = NULL;
7096 * Utility function for outsiders to check if we're running on registry.
7098 bool lp_config_backend_is_registry(void)
7100 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7104 * Utility function to check if the config backend is FILE.
7106 bool lp_config_backend_is_file(void)
7108 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7111 /*******************************************************************
7112 Check if a config file has changed date.
7113 ********************************************************************/
7115 bool lp_file_list_changed(void)
7117 struct file_lists *f = file_lists;
7119 DEBUG(6, ("lp_file_list_changed()\n"));
7121 while (f) {
7122 time_t mod_time;
7124 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7125 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7127 if (conf_ctx == NULL) {
7128 return false;
7130 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7131 NULL))
7133 DEBUGADD(6, ("registry config changed\n"));
7134 return true;
7136 } else {
7137 char *n2 = NULL;
7138 n2 = talloc_sub_basic(talloc_tos(),
7139 get_current_username(),
7140 current_user_info.domain,
7141 f->name);
7142 if (!n2) {
7143 return false;
7145 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7146 f->name, n2, ctime(&f->modtime)));
7148 mod_time = file_modtime(n2);
7150 if (mod_time &&
7151 ((f->modtime != mod_time) ||
7152 (f->subfname == NULL) ||
7153 (strcmp(n2, f->subfname) != 0)))
7155 DEBUGADD(6,
7156 ("file %s modified: %s\n", n2,
7157 ctime(&mod_time)));
7158 f->modtime = mod_time;
7159 SAFE_FREE(f->subfname);
7160 f->subfname = SMB_STRDUP(n2);
7161 TALLOC_FREE(n2);
7162 return true;
7164 TALLOC_FREE(n2);
7166 f = f->next;
7168 return (False);
7172 /***************************************************************************
7173 Run standard_sub_basic on netbios name... needed because global_myname
7174 is not accessed through any lp_ macro.
7175 Note: We must *NOT* use string_set() here as ptr points to global_myname.
7176 ***************************************************************************/
7178 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7180 bool ret;
7181 char *netbios_name = talloc_sub_basic(
7182 talloc_tos(), get_current_username(), current_user_info.domain,
7183 pszParmValue);
7185 ret = set_global_myname(netbios_name);
7186 TALLOC_FREE(netbios_name);
7187 string_set(&Globals.szNetbiosName,global_myname());
7189 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7190 global_myname()));
7192 return ret;
7195 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7197 if (strcmp(*ptr, pszParmValue) != 0) {
7198 string_set(ptr, pszParmValue);
7199 init_iconv();
7201 return True;
7206 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7208 bool ret;
7210 ret = set_global_myworkgroup(pszParmValue);
7211 string_set(&Globals.szWorkgroup,lp_workgroup());
7213 return ret;
7216 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7218 bool ret;
7220 ret = set_global_scope(pszParmValue);
7221 string_set(&Globals.szNetbiosScope,global_scope());
7223 return ret;
7226 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7228 TALLOC_FREE(Globals.szNetbiosAliases);
7229 Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7230 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7233 /***************************************************************************
7234 Handle the include operation.
7235 ***************************************************************************/
7236 static bool bAllowIncludeRegistry = true;
7238 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7240 char *fname;
7242 if (include_depth >= MAX_INCLUDE_DEPTH) {
7243 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7244 include_depth));
7245 return false;
7248 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7249 if (!bAllowIncludeRegistry) {
7250 return true;
7252 if (bInGlobalSection) {
7253 bool ret;
7254 include_depth++;
7255 ret = process_registry_globals();
7256 include_depth--;
7257 return ret;
7258 } else {
7259 DEBUG(1, ("\"include = registry\" only effective "
7260 "in %s section\n", GLOBAL_NAME));
7261 return false;
7265 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7266 current_user_info.domain,
7267 pszParmValue);
7269 add_to_file_list(pszParmValue, fname);
7271 string_set(ptr, fname);
7273 if (file_exist(fname)) {
7274 bool ret;
7275 include_depth++;
7276 ret = pm_process(fname, do_section, do_parameter, NULL);
7277 include_depth--;
7278 TALLOC_FREE(fname);
7279 return ret;
7282 DEBUG(2, ("Can't find include file %s\n", fname));
7283 TALLOC_FREE(fname);
7284 return true;
7287 /***************************************************************************
7288 Handle the interpretation of the copy parameter.
7289 ***************************************************************************/
7291 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7293 bool bRetval;
7294 int iTemp;
7295 struct service serviceTemp;
7297 string_set(ptr, pszParmValue);
7299 init_service(&serviceTemp);
7301 bRetval = False;
7303 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7305 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7306 if (iTemp == iServiceIndex) {
7307 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7308 } else {
7309 copy_service(ServicePtrs[iServiceIndex],
7310 &serviceTemp,
7311 ServicePtrs[iServiceIndex]->copymap);
7312 bRetval = True;
7314 } else {
7315 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7316 bRetval = False;
7319 free_service(&serviceTemp);
7320 return (bRetval);
7323 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7325 Globals.ldap_debug_level = lp_int(pszParmValue);
7326 init_ldap_debugging();
7327 return true;
7330 /***************************************************************************
7331 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7332 parameters is:
7334 [global]
7336 idmap uid = 1000-1999
7337 idmap gid = 700-899
7339 We only do simple parsing checks here. The strings are parsed into useful
7340 structures in the idmap daemon code.
7342 ***************************************************************************/
7344 /* Some lp_ routines to return idmap [ug]id information */
7346 static uid_t idmap_uid_low, idmap_uid_high;
7347 static gid_t idmap_gid_low, idmap_gid_high;
7349 bool lp_idmap_uid(uid_t *low, uid_t *high)
7351 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7352 return False;
7354 if (low)
7355 *low = idmap_uid_low;
7357 if (high)
7358 *high = idmap_uid_high;
7360 return True;
7363 bool lp_idmap_gid(gid_t *low, gid_t *high)
7365 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7366 return False;
7368 if (low)
7369 *low = idmap_gid_low;
7371 if (high)
7372 *high = idmap_gid_high;
7374 return True;
7377 /* Do some simple checks on "idmap [ug]id" parameter values */
7379 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7381 uint32 low, high;
7383 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7384 return False;
7386 /* Parse OK */
7388 string_set(ptr, pszParmValue);
7390 idmap_uid_low = low;
7391 idmap_uid_high = high;
7393 return True;
7396 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7398 uint32 low, high;
7400 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7401 return False;
7403 /* Parse OK */
7405 string_set(ptr, pszParmValue);
7407 idmap_gid_low = low;
7408 idmap_gid_high = high;
7410 return True;
7413 /***************************************************************************
7414 Handle the DEBUG level list.
7415 ***************************************************************************/
7417 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7419 string_set(ptr, pszParmValueIn);
7420 return debug_parse_levels(pszParmValueIn);
7423 /***************************************************************************
7424 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7425 ***************************************************************************/
7427 static const char *append_ldap_suffix( const char *str )
7429 const char *suffix_string;
7432 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7433 Globals.szLdapSuffix );
7434 if ( !suffix_string ) {
7435 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7436 return "";
7439 return suffix_string;
7442 const char *lp_ldap_machine_suffix(void)
7444 if (Globals.szLdapMachineSuffix[0])
7445 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7447 return lp_string(Globals.szLdapSuffix);
7450 const char *lp_ldap_user_suffix(void)
7452 if (Globals.szLdapUserSuffix[0])
7453 return append_ldap_suffix(Globals.szLdapUserSuffix);
7455 return lp_string(Globals.szLdapSuffix);
7458 const char *lp_ldap_group_suffix(void)
7460 if (Globals.szLdapGroupSuffix[0])
7461 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7463 return lp_string(Globals.szLdapSuffix);
7466 const char *lp_ldap_idmap_suffix(void)
7468 if (Globals.szLdapIdmapSuffix[0])
7469 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7471 return lp_string(Globals.szLdapSuffix);
7474 /****************************************************************************
7475 set the value for a P_ENUM
7476 ***************************************************************************/
7478 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7479 int *ptr )
7481 int i;
7483 for (i = 0; parm->enum_list[i].name; i++) {
7484 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7485 *ptr = parm->enum_list[i].value;
7486 return;
7489 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7490 pszParmValue, parm->label));
7493 /***************************************************************************
7494 ***************************************************************************/
7496 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7498 static int parm_num = -1;
7499 struct service *s;
7501 if ( parm_num == -1 )
7502 parm_num = map_parameter( "printing" );
7504 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7506 if ( snum < 0 )
7507 s = &sDefault;
7508 else
7509 s = ServicePtrs[snum];
7511 init_printer_values( s );
7513 return True;
7517 /***************************************************************************
7518 Initialise a copymap.
7519 ***************************************************************************/
7521 static void init_copymap(struct service *pservice)
7523 int i;
7524 if (pservice->copymap) {
7525 bitmap_free(pservice->copymap);
7527 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7528 if (!pservice->copymap)
7529 DEBUG(0,
7530 ("Couldn't allocate copymap!! (size %d)\n",
7531 (int)NUMPARAMETERS));
7532 else
7533 for (i = 0; i < NUMPARAMETERS; i++)
7534 bitmap_set(pservice->copymap, i);
7537 /***************************************************************************
7538 Return the local pointer to a parameter given a service struct and the
7539 pointer into the default structure.
7540 ***************************************************************************/
7542 static void *lp_local_ptr(struct service *service, void *ptr)
7544 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7547 /***************************************************************************
7548 Return the local pointer to a parameter given the service number and the
7549 pointer into the default structure.
7550 ***************************************************************************/
7552 void *lp_local_ptr_by_snum(int snum, void *ptr)
7554 return lp_local_ptr(ServicePtrs[snum], ptr);
7557 /***************************************************************************
7558 Process a parameter for a particular service number. If snum < 0
7559 then assume we are in the globals.
7560 ***************************************************************************/
7562 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7564 int parmnum, i;
7565 void *parm_ptr = NULL; /* where we are going to store the result */
7566 void *def_ptr = NULL;
7567 struct param_opt_struct **opt_list;
7569 parmnum = map_parameter(pszParmName);
7571 if (parmnum < 0) {
7572 if (strchr(pszParmName, ':') == NULL) {
7573 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7574 pszParmName));
7575 return (True);
7579 * We've got a parametric option
7582 opt_list = (snum < 0)
7583 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7584 set_param_opt(opt_list, pszParmName, pszParmValue);
7586 return (True);
7589 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7590 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7591 pszParmName));
7594 def_ptr = parm_table[parmnum].ptr;
7596 /* we might point at a service, the default service or a global */
7597 if (snum < 0) {
7598 parm_ptr = def_ptr;
7599 } else {
7600 if (parm_table[parmnum].p_class == P_GLOBAL) {
7601 DEBUG(0,
7602 ("Global parameter %s found in service section!\n",
7603 pszParmName));
7604 return (True);
7606 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7609 if (snum >= 0) {
7610 if (!ServicePtrs[snum]->copymap)
7611 init_copymap(ServicePtrs[snum]);
7613 /* this handles the aliases - set the copymap for other entries with
7614 the same data pointer */
7615 for (i = 0; parm_table[i].label; i++)
7616 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7617 bitmap_clear(ServicePtrs[snum]->copymap, i);
7620 /* if it is a special case then go ahead */
7621 if (parm_table[parmnum].special) {
7622 return parm_table[parmnum].special(snum, pszParmValue,
7623 (char **)parm_ptr);
7626 /* now switch on the type of variable it is */
7627 switch (parm_table[parmnum].type)
7629 case P_BOOL:
7630 *(bool *)parm_ptr = lp_bool(pszParmValue);
7631 break;
7633 case P_BOOLREV:
7634 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7635 break;
7637 case P_INTEGER:
7638 *(int *)parm_ptr = lp_int(pszParmValue);
7639 break;
7641 case P_CHAR:
7642 *(char *)parm_ptr = *pszParmValue;
7643 break;
7645 case P_OCTAL:
7646 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7647 if ( i != 1 ) {
7648 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7650 break;
7652 case P_LIST:
7653 TALLOC_FREE(*((char ***)parm_ptr));
7654 *(char ***)parm_ptr = str_list_make_v3(
7655 talloc_autofree_context(), pszParmValue, NULL);
7656 break;
7658 case P_STRING:
7659 string_set((char **)parm_ptr, pszParmValue);
7660 break;
7662 case P_USTRING:
7663 string_set((char **)parm_ptr, pszParmValue);
7664 strupper_m(*(char **)parm_ptr);
7665 break;
7667 case P_ENUM:
7668 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7669 break;
7670 case P_SEP:
7671 break;
7674 return (True);
7677 /***************************************************************************
7678 Process a parameter.
7679 ***************************************************************************/
7681 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7682 void *userdata)
7684 if (!bInGlobalSection && bGlobalOnly)
7685 return (True);
7687 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7689 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7690 pszParmName, pszParmValue));
7693 /***************************************************************************
7694 Print a parameter of the specified type.
7695 ***************************************************************************/
7697 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7699 int i;
7700 switch (p->type)
7702 case P_ENUM:
7703 for (i = 0; p->enum_list[i].name; i++) {
7704 if (*(int *)ptr == p->enum_list[i].value) {
7705 fprintf(f, "%s",
7706 p->enum_list[i].name);
7707 break;
7710 break;
7712 case P_BOOL:
7713 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7714 break;
7716 case P_BOOLREV:
7717 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7718 break;
7720 case P_INTEGER:
7721 fprintf(f, "%d", *(int *)ptr);
7722 break;
7724 case P_CHAR:
7725 fprintf(f, "%c", *(char *)ptr);
7726 break;
7728 case P_OCTAL: {
7729 char *o = octal_string(*(int *)ptr);
7730 fprintf(f, "%s", o);
7731 TALLOC_FREE(o);
7732 break;
7735 case P_LIST:
7736 if ((char ***)ptr && *(char ***)ptr) {
7737 char **list = *(char ***)ptr;
7738 for (; *list; list++) {
7739 /* surround strings with whitespace in double quotes */
7740 if ( strchr_m( *list, ' ' ) )
7741 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7742 else
7743 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7746 break;
7748 case P_STRING:
7749 case P_USTRING:
7750 if (*(char **)ptr) {
7751 fprintf(f, "%s", *(char **)ptr);
7753 break;
7754 case P_SEP:
7755 break;
7759 /***************************************************************************
7760 Check if two parameters are equal.
7761 ***************************************************************************/
7763 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7765 switch (type) {
7766 case P_BOOL:
7767 case P_BOOLREV:
7768 return (*((bool *)ptr1) == *((bool *)ptr2));
7770 case P_INTEGER:
7771 case P_ENUM:
7772 case P_OCTAL:
7773 return (*((int *)ptr1) == *((int *)ptr2));
7775 case P_CHAR:
7776 return (*((char *)ptr1) == *((char *)ptr2));
7778 case P_LIST:
7779 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7781 case P_STRING:
7782 case P_USTRING:
7784 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7785 if (p1 && !*p1)
7786 p1 = NULL;
7787 if (p2 && !*p2)
7788 p2 = NULL;
7789 return (p1 == p2 || strequal(p1, p2));
7791 case P_SEP:
7792 break;
7794 return (False);
7797 /***************************************************************************
7798 Initialize any local varients in the sDefault table.
7799 ***************************************************************************/
7801 void init_locals(void)
7803 /* None as yet. */
7806 /***************************************************************************
7807 Process a new section (service). At this stage all sections are services.
7808 Later we'll have special sections that permit server parameters to be set.
7809 Returns True on success, False on failure.
7810 ***************************************************************************/
7812 static bool do_section(const char *pszSectionName, void *userdata)
7814 bool bRetval;
7815 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7816 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7817 bRetval = False;
7819 /* if we were in a global section then do the local inits */
7820 if (bInGlobalSection && !isglobal)
7821 init_locals();
7823 /* if we've just struck a global section, note the fact. */
7824 bInGlobalSection = isglobal;
7826 /* check for multiple global sections */
7827 if (bInGlobalSection) {
7828 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7829 return (True);
7832 if (!bInGlobalSection && bGlobalOnly)
7833 return (True);
7835 /* if we have a current service, tidy it up before moving on */
7836 bRetval = True;
7838 if (iServiceIndex >= 0)
7839 bRetval = service_ok(iServiceIndex);
7841 /* if all is still well, move to the next record in the services array */
7842 if (bRetval) {
7843 /* We put this here to avoid an odd message order if messages are */
7844 /* issued by the post-processing of a previous section. */
7845 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7847 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7848 < 0) {
7849 DEBUG(0, ("Failed to add a new service\n"));
7850 return (False);
7854 return (bRetval);
7858 /***************************************************************************
7859 Determine if a partcular base parameter is currentl set to the default value.
7860 ***************************************************************************/
7862 static bool is_default(int i)
7864 if (!defaults_saved)
7865 return False;
7866 switch (parm_table[i].type) {
7867 case P_LIST:
7868 return str_list_equal((const char **)parm_table[i].def.lvalue,
7869 *(const char ***)parm_table[i].ptr);
7870 case P_STRING:
7871 case P_USTRING:
7872 return strequal(parm_table[i].def.svalue,
7873 *(char **)parm_table[i].ptr);
7874 case P_BOOL:
7875 case P_BOOLREV:
7876 return parm_table[i].def.bvalue ==
7877 *(bool *)parm_table[i].ptr;
7878 case P_CHAR:
7879 return parm_table[i].def.cvalue ==
7880 *(char *)parm_table[i].ptr;
7881 case P_INTEGER:
7882 case P_OCTAL:
7883 case P_ENUM:
7884 return parm_table[i].def.ivalue ==
7885 *(int *)parm_table[i].ptr;
7886 case P_SEP:
7887 break;
7889 return False;
7892 /***************************************************************************
7893 Display the contents of the global structure.
7894 ***************************************************************************/
7896 static void dump_globals(FILE *f)
7898 int i;
7899 struct param_opt_struct *data;
7901 fprintf(f, "[global]\n");
7903 for (i = 0; parm_table[i].label; i++)
7904 if (parm_table[i].p_class == P_GLOBAL &&
7905 !(parm_table[i].flags & FLAG_META) &&
7906 parm_table[i].ptr &&
7907 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7908 if (defaults_saved && is_default(i))
7909 continue;
7910 fprintf(f, "\t%s = ", parm_table[i].label);
7911 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7912 fprintf(f, "\n");
7914 if (Globals.param_opt != NULL) {
7915 data = Globals.param_opt;
7916 while(data) {
7917 fprintf(f, "\t%s = %s\n", data->key, data->value);
7918 data = data->next;
7924 /***************************************************************************
7925 Return True if a local parameter is currently set to the global default.
7926 ***************************************************************************/
7928 bool lp_is_default(int snum, struct parm_struct *parm)
7930 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7932 return equal_parameter(parm->type,
7933 ((char *)ServicePtrs[snum]) + pdiff,
7934 ((char *)&sDefault) + pdiff);
7937 /***************************************************************************
7938 Display the contents of a single services record.
7939 ***************************************************************************/
7941 static void dump_a_service(struct service *pService, FILE * f)
7943 int i;
7944 struct param_opt_struct *data;
7946 if (pService != &sDefault)
7947 fprintf(f, "[%s]\n", pService->szService);
7949 for (i = 0; parm_table[i].label; i++) {
7951 if (parm_table[i].p_class == P_LOCAL &&
7952 !(parm_table[i].flags & FLAG_META) &&
7953 parm_table[i].ptr &&
7954 (*parm_table[i].label != '-') &&
7955 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7957 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7959 if (pService == &sDefault) {
7960 if (defaults_saved && is_default(i))
7961 continue;
7962 } else {
7963 if (equal_parameter(parm_table[i].type,
7964 ((char *)pService) +
7965 pdiff,
7966 ((char *)&sDefault) +
7967 pdiff))
7968 continue;
7971 fprintf(f, "\t%s = ", parm_table[i].label);
7972 print_parameter(&parm_table[i],
7973 ((char *)pService) + pdiff, f);
7974 fprintf(f, "\n");
7978 if (pService->param_opt != NULL) {
7979 data = pService->param_opt;
7980 while(data) {
7981 fprintf(f, "\t%s = %s\n", data->key, data->value);
7982 data = data->next;
7987 /***************************************************************************
7988 Display the contents of a parameter of a single services record.
7989 ***************************************************************************/
7991 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7993 int i;
7994 bool result = False;
7995 parm_class p_class;
7996 unsigned flag = 0;
7997 fstring local_parm_name;
7998 char *parm_opt;
7999 const char *parm_opt_value;
8001 /* check for parametrical option */
8002 fstrcpy( local_parm_name, parm_name);
8003 parm_opt = strchr( local_parm_name, ':');
8005 if (parm_opt) {
8006 *parm_opt = '\0';
8007 parm_opt++;
8008 if (strlen(parm_opt)) {
8009 parm_opt_value = lp_parm_const_string( snum,
8010 local_parm_name, parm_opt, NULL);
8011 if (parm_opt_value) {
8012 printf( "%s\n", parm_opt_value);
8013 result = True;
8016 return result;
8019 /* check for a key and print the value */
8020 if (isGlobal) {
8021 p_class = P_GLOBAL;
8022 flag = FLAG_GLOBAL;
8023 } else
8024 p_class = P_LOCAL;
8026 for (i = 0; parm_table[i].label; i++) {
8027 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8028 !(parm_table[i].flags & FLAG_META) &&
8029 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8030 parm_table[i].ptr &&
8031 (*parm_table[i].label != '-') &&
8032 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8034 void *ptr;
8036 if (isGlobal) {
8037 ptr = parm_table[i].ptr;
8038 } else {
8039 struct service *pService = ServicePtrs[snum];
8040 ptr = ((char *)pService) +
8041 PTR_DIFF(parm_table[i].ptr, &sDefault);
8044 print_parameter(&parm_table[i],
8045 ptr, f);
8046 fprintf(f, "\n");
8047 result = True;
8048 break;
8052 return result;
8055 /***************************************************************************
8056 Return info about the requested parameter (given as a string).
8057 Return NULL when the string is not a valid parameter name.
8058 ***************************************************************************/
8060 struct parm_struct *lp_get_parameter(const char *param_name)
8062 int num = map_parameter(param_name);
8064 if (num < 0) {
8065 return NULL;
8068 return &parm_table[num];
8071 /***************************************************************************
8072 Return info about the next parameter in a service.
8073 snum==GLOBAL_SECTION_SNUM gives the globals.
8074 Return NULL when out of parameters.
8075 ***************************************************************************/
8077 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8079 if (snum < 0) {
8080 /* do the globals */
8081 for (; parm_table[*i].label; (*i)++) {
8082 if (parm_table[*i].p_class == P_SEPARATOR)
8083 return &parm_table[(*i)++];
8085 if (!parm_table[*i].ptr
8086 || (*parm_table[*i].label == '-'))
8087 continue;
8089 if ((*i) > 0
8090 && (parm_table[*i].ptr ==
8091 parm_table[(*i) - 1].ptr))
8092 continue;
8094 if (is_default(*i) && !allparameters)
8095 continue;
8097 return &parm_table[(*i)++];
8099 } else {
8100 struct service *pService = ServicePtrs[snum];
8102 for (; parm_table[*i].label; (*i)++) {
8103 if (parm_table[*i].p_class == P_SEPARATOR)
8104 return &parm_table[(*i)++];
8106 if (parm_table[*i].p_class == P_LOCAL &&
8107 parm_table[*i].ptr &&
8108 (*parm_table[*i].label != '-') &&
8109 ((*i) == 0 ||
8110 (parm_table[*i].ptr !=
8111 parm_table[(*i) - 1].ptr)))
8113 int pdiff =
8114 PTR_DIFF(parm_table[*i].ptr,
8115 &sDefault);
8117 if (allparameters ||
8118 !equal_parameter(parm_table[*i].type,
8119 ((char *)pService) +
8120 pdiff,
8121 ((char *)&sDefault) +
8122 pdiff))
8124 return &parm_table[(*i)++];
8130 return NULL;
8134 #if 0
8135 /***************************************************************************
8136 Display the contents of a single copy structure.
8137 ***************************************************************************/
8138 static void dump_copy_map(bool *pcopymap)
8140 int i;
8141 if (!pcopymap)
8142 return;
8144 printf("\n\tNon-Copied parameters:\n");
8146 for (i = 0; parm_table[i].label; i++)
8147 if (parm_table[i].p_class == P_LOCAL &&
8148 parm_table[i].ptr && !pcopymap[i] &&
8149 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8151 printf("\t\t%s\n", parm_table[i].label);
8154 #endif
8156 /***************************************************************************
8157 Return TRUE if the passed service number is within range.
8158 ***************************************************************************/
8160 bool lp_snum_ok(int iService)
8162 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8165 /***************************************************************************
8166 Auto-load some home services.
8167 ***************************************************************************/
8169 static void lp_add_auto_services(char *str)
8171 char *s;
8172 char *p;
8173 int homes;
8174 char *saveptr;
8176 if (!str)
8177 return;
8179 s = SMB_STRDUP(str);
8180 if (!s)
8181 return;
8183 homes = lp_servicenumber(HOMES_NAME);
8185 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8186 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8187 char *home;
8189 if (lp_servicenumber(p) >= 0)
8190 continue;
8192 home = get_user_home_dir(talloc_tos(), p);
8194 if (home && home[0] && homes >= 0)
8195 lp_add_home(p, homes, p, home);
8197 TALLOC_FREE(home);
8199 SAFE_FREE(s);
8202 /***************************************************************************
8203 Auto-load one printer.
8204 ***************************************************************************/
8206 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8208 int printers = lp_servicenumber(PRINTERS_NAME);
8209 int i;
8211 if (lp_servicenumber(name) < 0) {
8212 lp_add_printer(name, printers);
8213 if ((i = lp_servicenumber(name)) >= 0) {
8214 string_set(&ServicePtrs[i]->comment, comment);
8215 ServicePtrs[i]->autoloaded = True;
8220 /***************************************************************************
8221 Have we loaded a services file yet?
8222 ***************************************************************************/
8224 bool lp_loaded(void)
8226 return (bLoaded);
8229 /***************************************************************************
8230 Unload unused services.
8231 ***************************************************************************/
8233 void lp_killunused(bool (*snumused) (int))
8235 int i;
8236 for (i = 0; i < iNumServices; i++) {
8237 if (!VALID(i))
8238 continue;
8240 /* don't kill autoloaded or usershare services */
8241 if ( ServicePtrs[i]->autoloaded ||
8242 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8243 continue;
8246 if (!snumused || !snumused(i)) {
8247 free_service_byindex(i);
8253 * Kill all except autoloaded and usershare services - convenience wrapper
8255 void lp_kill_all_services(void)
8257 lp_killunused(NULL);
8260 /***************************************************************************
8261 Unload a service.
8262 ***************************************************************************/
8264 void lp_killservice(int iServiceIn)
8266 if (VALID(iServiceIn)) {
8267 free_service_byindex(iServiceIn);
8271 /***************************************************************************
8272 Save the curent values of all global and sDefault parameters into the
8273 defaults union. This allows swat and testparm to show only the
8274 changed (ie. non-default) parameters.
8275 ***************************************************************************/
8277 static void lp_save_defaults(void)
8279 int i;
8280 for (i = 0; parm_table[i].label; i++) {
8281 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8282 continue;
8283 switch (parm_table[i].type) {
8284 case P_LIST:
8285 parm_table[i].def.lvalue = str_list_copy(
8286 NULL, *(const char ***)parm_table[i].ptr);
8287 break;
8288 case P_STRING:
8289 case P_USTRING:
8290 if (parm_table[i].ptr) {
8291 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8292 } else {
8293 parm_table[i].def.svalue = NULL;
8295 break;
8296 case P_BOOL:
8297 case P_BOOLREV:
8298 parm_table[i].def.bvalue =
8299 *(bool *)parm_table[i].ptr;
8300 break;
8301 case P_CHAR:
8302 parm_table[i].def.cvalue =
8303 *(char *)parm_table[i].ptr;
8304 break;
8305 case P_INTEGER:
8306 case P_OCTAL:
8307 case P_ENUM:
8308 parm_table[i].def.ivalue =
8309 *(int *)parm_table[i].ptr;
8310 break;
8311 case P_SEP:
8312 break;
8315 defaults_saved = True;
8318 /*******************************************************************
8319 Set the server type we will announce as via nmbd.
8320 ********************************************************************/
8322 static const struct srv_role_tab {
8323 uint32 role;
8324 const char *role_str;
8325 } srv_role_tab [] = {
8326 { ROLE_STANDALONE, "ROLE_STANDALONE" },
8327 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8328 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8329 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8330 { 0, NULL }
8333 const char* server_role_str(uint32 role)
8335 int i = 0;
8336 for (i=0; srv_role_tab[i].role_str; i++) {
8337 if (role == srv_role_tab[i].role) {
8338 return srv_role_tab[i].role_str;
8341 return NULL;
8344 static void set_server_role(void)
8346 server_role = ROLE_STANDALONE;
8348 switch (lp_security()) {
8349 case SEC_SHARE:
8350 if (lp_domain_logons())
8351 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8352 break;
8353 case SEC_SERVER:
8354 if (lp_domain_logons())
8355 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8356 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8357 server_role = ROLE_STANDALONE;
8358 break;
8359 case SEC_DOMAIN:
8360 if (lp_domain_logons()) {
8361 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8362 server_role = ROLE_DOMAIN_BDC;
8363 break;
8365 server_role = ROLE_DOMAIN_MEMBER;
8366 break;
8367 case SEC_ADS:
8368 if (lp_domain_logons()) {
8369 server_role = ROLE_DOMAIN_PDC;
8370 break;
8372 server_role = ROLE_DOMAIN_MEMBER;
8373 break;
8374 case SEC_USER:
8375 if (lp_domain_logons()) {
8377 if (Globals.iDomainMaster) /* auto or yes */
8378 server_role = ROLE_DOMAIN_PDC;
8379 else
8380 server_role = ROLE_DOMAIN_BDC;
8382 break;
8383 default:
8384 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8385 break;
8388 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8391 /***********************************************************
8392 If we should send plaintext/LANMAN passwords in the clinet
8393 ************************************************************/
8395 static void set_allowed_client_auth(void)
8397 if (Globals.bClientNTLMv2Auth) {
8398 Globals.bClientLanManAuth = False;
8400 if (!Globals.bClientLanManAuth) {
8401 Globals.bClientPlaintextAuth = False;
8405 /***************************************************************************
8406 JRA.
8407 The following code allows smbd to read a user defined share file.
8408 Yes, this is my intent. Yes, I'm comfortable with that...
8410 THE FOLLOWING IS SECURITY CRITICAL CODE.
8412 It washes your clothes, it cleans your house, it guards you while you sleep...
8413 Do not f%^k with it....
8414 ***************************************************************************/
8416 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8418 /***************************************************************************
8419 Check allowed stat state of a usershare file.
8420 Ensure we print out who is dicking with us so the admin can
8421 get their sorry ass fired.
8422 ***************************************************************************/
8424 static bool check_usershare_stat(const char *fname,
8425 const SMB_STRUCT_STAT *psbuf)
8427 if (!S_ISREG(psbuf->st_ex_mode)) {
8428 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8429 "not a regular file\n",
8430 fname, (unsigned int)psbuf->st_ex_uid ));
8431 return False;
8434 /* Ensure this doesn't have the other write bit set. */
8435 if (psbuf->st_ex_mode & S_IWOTH) {
8436 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8437 "public write. Refusing to allow as a usershare file.\n",
8438 fname, (unsigned int)psbuf->st_ex_uid ));
8439 return False;
8442 /* Should be 10k or less. */
8443 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8444 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8445 "too large (%u) to be a user share file.\n",
8446 fname, (unsigned int)psbuf->st_ex_uid,
8447 (unsigned int)psbuf->st_ex_size ));
8448 return False;
8451 return True;
8454 /***************************************************************************
8455 Parse the contents of a usershare file.
8456 ***************************************************************************/
8458 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8459 SMB_STRUCT_STAT *psbuf,
8460 const char *servicename,
8461 int snum,
8462 char **lines,
8463 int numlines,
8464 char **pp_sharepath,
8465 char **pp_comment,
8466 SEC_DESC **ppsd,
8467 bool *pallow_guest)
8469 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8470 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8471 int us_vers;
8472 SMB_STRUCT_DIR *dp;
8473 SMB_STRUCT_STAT sbuf;
8474 char *sharepath = NULL;
8475 char *comment = NULL;
8477 *pp_sharepath = NULL;
8478 *pp_comment = NULL;
8480 *pallow_guest = False;
8482 if (numlines < 4) {
8483 return USERSHARE_MALFORMED_FILE;
8486 if (strcmp(lines[0], "#VERSION 1") == 0) {
8487 us_vers = 1;
8488 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8489 us_vers = 2;
8490 if (numlines < 5) {
8491 return USERSHARE_MALFORMED_FILE;
8493 } else {
8494 return USERSHARE_BAD_VERSION;
8497 if (strncmp(lines[1], "path=", 5) != 0) {
8498 return USERSHARE_MALFORMED_PATH;
8501 sharepath = talloc_strdup(ctx, &lines[1][5]);
8502 if (!sharepath) {
8503 return USERSHARE_POSIX_ERR;
8505 trim_string(sharepath, " ", " ");
8507 if (strncmp(lines[2], "comment=", 8) != 0) {
8508 return USERSHARE_MALFORMED_COMMENT_DEF;
8511 comment = talloc_strdup(ctx, &lines[2][8]);
8512 if (!comment) {
8513 return USERSHARE_POSIX_ERR;
8515 trim_string(comment, " ", " ");
8516 trim_char(comment, '"', '"');
8518 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8519 return USERSHARE_MALFORMED_ACL_DEF;
8522 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8523 return USERSHARE_ACL_ERR;
8526 if (us_vers == 2) {
8527 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8528 return USERSHARE_MALFORMED_ACL_DEF;
8530 if (lines[4][9] == 'y') {
8531 *pallow_guest = True;
8535 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8536 /* Path didn't change, no checks needed. */
8537 *pp_sharepath = sharepath;
8538 *pp_comment = comment;
8539 return USERSHARE_OK;
8542 /* The path *must* be absolute. */
8543 if (sharepath[0] != '/') {
8544 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8545 servicename, sharepath));
8546 return USERSHARE_PATH_NOT_ABSOLUTE;
8549 /* If there is a usershare prefix deny list ensure one of these paths
8550 doesn't match the start of the user given path. */
8551 if (prefixdenylist) {
8552 int i;
8553 for ( i=0; prefixdenylist[i]; i++ ) {
8554 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8555 servicename, i, prefixdenylist[i], sharepath ));
8556 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8557 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8558 "usershare prefix deny list entries.\n",
8559 servicename, sharepath));
8560 return USERSHARE_PATH_IS_DENIED;
8565 /* If there is a usershare prefix allow list ensure one of these paths
8566 does match the start of the user given path. */
8568 if (prefixallowlist) {
8569 int i;
8570 for ( i=0; prefixallowlist[i]; i++ ) {
8571 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8572 servicename, i, prefixallowlist[i], sharepath ));
8573 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8574 break;
8577 if (prefixallowlist[i] == NULL) {
8578 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8579 "usershare prefix allow list entries.\n",
8580 servicename, sharepath));
8581 return USERSHARE_PATH_NOT_ALLOWED;
8585 /* Ensure this is pointing to a directory. */
8586 dp = sys_opendir(sharepath);
8588 if (!dp) {
8589 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8590 servicename, sharepath));
8591 return USERSHARE_PATH_NOT_DIRECTORY;
8594 /* Ensure the owner of the usershare file has permission to share
8595 this directory. */
8597 if (sys_stat(sharepath, &sbuf, false) == -1) {
8598 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8599 servicename, sharepath, strerror(errno) ));
8600 sys_closedir(dp);
8601 return USERSHARE_POSIX_ERR;
8604 sys_closedir(dp);
8606 if (!S_ISDIR(sbuf.st_ex_mode)) {
8607 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8608 servicename, sharepath ));
8609 return USERSHARE_PATH_NOT_DIRECTORY;
8612 /* Check if sharing is restricted to owner-only. */
8613 /* psbuf is the stat of the usershare definition file,
8614 sbuf is the stat of the target directory to be shared. */
8616 if (lp_usershare_owner_only()) {
8617 /* root can share anything. */
8618 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8619 return USERSHARE_PATH_NOT_ALLOWED;
8623 *pp_sharepath = sharepath;
8624 *pp_comment = comment;
8625 return USERSHARE_OK;
8628 /***************************************************************************
8629 Deal with a usershare file.
8630 Returns:
8631 >= 0 - snum
8632 -1 - Bad name, invalid contents.
8633 - service name already existed and not a usershare, problem
8634 with permissions to share directory etc.
8635 ***************************************************************************/
8637 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8639 SMB_STRUCT_STAT sbuf;
8640 SMB_STRUCT_STAT lsbuf;
8641 char *fname = NULL;
8642 char *sharepath = NULL;
8643 char *comment = NULL;
8644 fstring service_name;
8645 char **lines = NULL;
8646 int numlines = 0;
8647 int fd = -1;
8648 int iService = -1;
8649 TALLOC_CTX *ctx = NULL;
8650 SEC_DESC *psd = NULL;
8651 bool guest_ok = False;
8653 /* Ensure share name doesn't contain invalid characters. */
8654 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8655 DEBUG(0,("process_usershare_file: share name %s contains "
8656 "invalid characters (any of %s)\n",
8657 file_name, INVALID_SHARENAME_CHARS ));
8658 return -1;
8661 fstrcpy(service_name, file_name);
8663 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8666 /* Minimize the race condition by doing an lstat before we
8667 open and fstat. Ensure this isn't a symlink link. */
8669 if (sys_lstat(fname, &lsbuf, false) != 0) {
8670 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8671 fname, strerror(errno) ));
8672 SAFE_FREE(fname);
8673 return -1;
8676 /* This must be a regular file, not a symlink, directory or
8677 other strange filetype. */
8678 if (!check_usershare_stat(fname, &lsbuf)) {
8679 SAFE_FREE(fname);
8680 return -1;
8684 char *canon_name = canonicalize_servicename(service_name);
8685 TDB_DATA data = dbwrap_fetch_bystring(
8686 ServiceHash, canon_name, canon_name);
8688 iService = -1;
8690 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8691 iService = *(int *)data.dptr;
8693 TALLOC_FREE(canon_name);
8696 if (iService != -1 &&
8697 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8698 &lsbuf.st_ex_mtime) == 0) {
8699 /* Nothing changed - Mark valid and return. */
8700 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8701 service_name ));
8702 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8703 SAFE_FREE(fname);
8704 return iService;
8707 /* Try and open the file read only - no symlinks allowed. */
8708 #ifdef O_NOFOLLOW
8709 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8710 #else
8711 fd = sys_open(fname, O_RDONLY, 0);
8712 #endif
8714 if (fd == -1) {
8715 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8716 fname, strerror(errno) ));
8717 SAFE_FREE(fname);
8718 return -1;
8721 /* Now fstat to be *SURE* it's a regular file. */
8722 if (sys_fstat(fd, &sbuf, false) != 0) {
8723 close(fd);
8724 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8725 fname, strerror(errno) ));
8726 SAFE_FREE(fname);
8727 return -1;
8730 /* Is it the same dev/inode as was lstated ? */
8731 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8732 close(fd);
8733 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8734 "Symlink spoofing going on ?\n", fname ));
8735 SAFE_FREE(fname);
8736 return -1;
8739 /* This must be a regular file, not a symlink, directory or
8740 other strange filetype. */
8741 if (!check_usershare_stat(fname, &sbuf)) {
8742 SAFE_FREE(fname);
8743 return -1;
8746 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8748 close(fd);
8749 if (lines == NULL) {
8750 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8751 fname, (unsigned int)sbuf.st_ex_uid ));
8752 SAFE_FREE(fname);
8753 return -1;
8756 SAFE_FREE(fname);
8758 /* Should we allow printers to be shared... ? */
8759 ctx = talloc_init("usershare_sd_xctx");
8760 if (!ctx) {
8761 TALLOC_FREE(lines);
8762 return 1;
8765 if (parse_usershare_file(ctx, &sbuf, service_name,
8766 iService, lines, numlines, &sharepath,
8767 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8768 talloc_destroy(ctx);
8769 TALLOC_FREE(lines);
8770 return -1;
8773 TALLOC_FREE(lines);
8775 /* Everything ok - add the service possibly using a template. */
8776 if (iService < 0) {
8777 const struct service *sp = &sDefault;
8778 if (snum_template != -1) {
8779 sp = ServicePtrs[snum_template];
8782 if ((iService = add_a_service(sp, service_name)) < 0) {
8783 DEBUG(0, ("process_usershare_file: Failed to add "
8784 "new service %s\n", service_name));
8785 talloc_destroy(ctx);
8786 return -1;
8789 /* Read only is controlled by usershare ACL below. */
8790 ServicePtrs[iService]->bRead_only = False;
8793 /* Write the ACL of the new/modified share. */
8794 if (!set_share_security(service_name, psd)) {
8795 DEBUG(0, ("process_usershare_file: Failed to set share "
8796 "security for user share %s\n",
8797 service_name ));
8798 lp_remove_service(iService);
8799 talloc_destroy(ctx);
8800 return -1;
8803 /* If from a template it may be marked invalid. */
8804 ServicePtrs[iService]->valid = True;
8806 /* Set the service as a valid usershare. */
8807 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8809 /* Set guest access. */
8810 if (lp_usershare_allow_guests()) {
8811 ServicePtrs[iService]->bGuest_ok = guest_ok;
8814 /* And note when it was loaded. */
8815 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8816 string_set(&ServicePtrs[iService]->szPath, sharepath);
8817 string_set(&ServicePtrs[iService]->comment, comment);
8819 talloc_destroy(ctx);
8821 return iService;
8824 /***************************************************************************
8825 Checks if a usershare entry has been modified since last load.
8826 ***************************************************************************/
8828 static bool usershare_exists(int iService, struct timespec *last_mod)
8830 SMB_STRUCT_STAT lsbuf;
8831 const char *usersharepath = Globals.szUsersharePath;
8832 char *fname;
8834 if (asprintf(&fname, "%s/%s",
8835 usersharepath,
8836 ServicePtrs[iService]->szService) < 0) {
8837 return false;
8840 if (sys_lstat(fname, &lsbuf, false) != 0) {
8841 SAFE_FREE(fname);
8842 return false;
8845 if (!S_ISREG(lsbuf.st_ex_mode)) {
8846 SAFE_FREE(fname);
8847 return false;
8850 SAFE_FREE(fname);
8851 *last_mod = lsbuf.st_ex_mtime;
8852 return true;
8855 /***************************************************************************
8856 Load a usershare service by name. Returns a valid servicenumber or -1.
8857 ***************************************************************************/
8859 int load_usershare_service(const char *servicename)
8861 SMB_STRUCT_STAT sbuf;
8862 const char *usersharepath = Globals.szUsersharePath;
8863 int max_user_shares = Globals.iUsershareMaxShares;
8864 int snum_template = -1;
8866 if (*usersharepath == 0 || max_user_shares == 0) {
8867 return -1;
8870 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8871 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8872 usersharepath, strerror(errno) ));
8873 return -1;
8876 if (!S_ISDIR(sbuf.st_ex_mode)) {
8877 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8878 usersharepath ));
8879 return -1;
8883 * This directory must be owned by root, and have the 't' bit set.
8884 * It also must not be writable by "other".
8887 #ifdef S_ISVTX
8888 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8889 #else
8890 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8891 #endif
8892 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8893 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8894 usersharepath ));
8895 return -1;
8898 /* Ensure the template share exists if it's set. */
8899 if (Globals.szUsershareTemplateShare[0]) {
8900 /* We can't use lp_servicenumber here as we are recommending that
8901 template shares have -valid=False set. */
8902 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8903 if (ServicePtrs[snum_template]->szService &&
8904 strequal(ServicePtrs[snum_template]->szService,
8905 Globals.szUsershareTemplateShare)) {
8906 break;
8910 if (snum_template == -1) {
8911 DEBUG(0,("load_usershare_service: usershare template share %s "
8912 "does not exist.\n",
8913 Globals.szUsershareTemplateShare ));
8914 return -1;
8918 return process_usershare_file(usersharepath, servicename, snum_template);
8921 /***************************************************************************
8922 Load all user defined shares from the user share directory.
8923 We only do this if we're enumerating the share list.
8924 This is the function that can delete usershares that have
8925 been removed.
8926 ***************************************************************************/
8928 int load_usershare_shares(void)
8930 SMB_STRUCT_DIR *dp;
8931 SMB_STRUCT_STAT sbuf;
8932 SMB_STRUCT_DIRENT *de;
8933 int num_usershares = 0;
8934 int max_user_shares = Globals.iUsershareMaxShares;
8935 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8936 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8937 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8938 int iService;
8939 int snum_template = -1;
8940 const char *usersharepath = Globals.szUsersharePath;
8941 int ret = lp_numservices();
8943 if (max_user_shares == 0 || *usersharepath == '\0') {
8944 return lp_numservices();
8947 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8948 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8949 usersharepath, strerror(errno) ));
8950 return ret;
8954 * This directory must be owned by root, and have the 't' bit set.
8955 * It also must not be writable by "other".
8958 #ifdef S_ISVTX
8959 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8960 #else
8961 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8962 #endif
8963 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8964 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8965 usersharepath ));
8966 return ret;
8969 /* Ensure the template share exists if it's set. */
8970 if (Globals.szUsershareTemplateShare[0]) {
8971 /* We can't use lp_servicenumber here as we are recommending that
8972 template shares have -valid=False set. */
8973 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8974 if (ServicePtrs[snum_template]->szService &&
8975 strequal(ServicePtrs[snum_template]->szService,
8976 Globals.szUsershareTemplateShare)) {
8977 break;
8981 if (snum_template == -1) {
8982 DEBUG(0,("load_usershare_shares: usershare template share %s "
8983 "does not exist.\n",
8984 Globals.szUsershareTemplateShare ));
8985 return ret;
8989 /* Mark all existing usershares as pending delete. */
8990 for (iService = iNumServices - 1; iService >= 0; iService--) {
8991 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8992 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8996 dp = sys_opendir(usersharepath);
8997 if (!dp) {
8998 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8999 usersharepath, strerror(errno) ));
9000 return ret;
9003 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9004 (de = sys_readdir(dp));
9005 num_dir_entries++ ) {
9006 int r;
9007 const char *n = de->d_name;
9009 /* Ignore . and .. */
9010 if (*n == '.') {
9011 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9012 continue;
9016 if (n[0] == ':') {
9017 /* Temporary file used when creating a share. */
9018 num_tmp_dir_entries++;
9021 /* Allow 20% tmp entries. */
9022 if (num_tmp_dir_entries > allowed_tmp_entries) {
9023 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9024 "in directory %s\n",
9025 num_tmp_dir_entries, usersharepath));
9026 break;
9029 r = process_usershare_file(usersharepath, n, snum_template);
9030 if (r == 0) {
9031 /* Update the services count. */
9032 num_usershares++;
9033 if (num_usershares >= max_user_shares) {
9034 DEBUG(0,("load_usershare_shares: max user shares reached "
9035 "on file %s in directory %s\n",
9036 n, usersharepath ));
9037 break;
9039 } else if (r == -1) {
9040 num_bad_dir_entries++;
9043 /* Allow 20% bad entries. */
9044 if (num_bad_dir_entries > allowed_bad_entries) {
9045 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9046 "in directory %s\n",
9047 num_bad_dir_entries, usersharepath));
9048 break;
9051 /* Allow 20% bad entries. */
9052 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9053 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9054 "in directory %s\n",
9055 num_dir_entries, usersharepath));
9056 break;
9060 sys_closedir(dp);
9062 /* Sweep through and delete any non-refreshed usershares that are
9063 not currently in use. */
9064 for (iService = iNumServices - 1; iService >= 0; iService--) {
9065 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9066 if (conn_snum_used(iService)) {
9067 continue;
9069 /* Remove from the share ACL db. */
9070 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9071 lp_servicename(iService) ));
9072 delete_share_security(lp_servicename(iService));
9073 free_service_byindex(iService);
9077 return lp_numservices();
9080 /********************************************************
9081 Destroy global resources allocated in this file
9082 ********************************************************/
9084 void gfree_loadparm(void)
9086 int i;
9088 free_file_list();
9090 /* Free resources allocated to services */
9092 for ( i = 0; i < iNumServices; i++ ) {
9093 if ( VALID(i) ) {
9094 free_service_byindex(i);
9098 SAFE_FREE( ServicePtrs );
9099 iNumServices = 0;
9101 /* Now release all resources allocated to global
9102 parameters and the default service */
9104 free_global_parameters();
9108 /***************************************************************************
9109 Allow client apps to specify that they are a client
9110 ***************************************************************************/
9111 void lp_set_in_client(bool b)
9113 in_client = b;
9117 /***************************************************************************
9118 Determine if we're running in a client app
9119 ***************************************************************************/
9120 bool lp_is_in_client(void)
9122 return in_client;
9125 /***************************************************************************
9126 Load the services array from the services file. Return True on success,
9127 False on failure.
9128 ***************************************************************************/
9130 bool lp_load_ex(const char *pszFname,
9131 bool global_only,
9132 bool save_defaults,
9133 bool add_ipc,
9134 bool initialize_globals,
9135 bool allow_include_registry,
9136 bool allow_registry_shares)
9138 char *n2 = NULL;
9139 bool bRetval;
9141 bRetval = False;
9143 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9145 bInGlobalSection = True;
9146 bGlobalOnly = global_only;
9147 bAllowIncludeRegistry = allow_include_registry;
9149 init_globals(! initialize_globals);
9150 debug_init();
9152 free_file_list();
9154 if (save_defaults) {
9155 init_locals();
9156 lp_save_defaults();
9159 free_param_opts(&Globals.param_opt);
9161 /* We get sections first, so have to start 'behind' to make up */
9162 iServiceIndex = -1;
9164 if (lp_config_backend_is_file()) {
9165 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9166 current_user_info.domain,
9167 pszFname);
9168 if (!n2) {
9169 smb_panic("lp_load_ex: out of memory");
9172 add_to_file_list(pszFname, n2);
9174 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9175 TALLOC_FREE(n2);
9177 /* finish up the last section */
9178 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9179 if (bRetval) {
9180 if (iServiceIndex >= 0) {
9181 bRetval = service_ok(iServiceIndex);
9185 if (lp_config_backend_is_registry()) {
9186 /* config backend changed to registry in config file */
9188 * We need to use this extra global variable here to
9189 * survive restart: init_globals uses this as a default
9190 * for ConfigBackend. Otherwise, init_globals would
9191 * send us into an endless loop here.
9193 config_backend = CONFIG_BACKEND_REGISTRY;
9194 /* start over */
9195 DEBUG(1, ("lp_load_ex: changing to config backend "
9196 "registry\n"));
9197 init_globals(false);
9198 lp_kill_all_services();
9199 return lp_load_ex(pszFname, global_only, save_defaults,
9200 add_ipc, initialize_globals,
9201 allow_include_registry,
9202 allow_registry_shares);
9204 } else if (lp_config_backend_is_registry()) {
9205 bRetval = process_registry_globals();
9206 } else {
9207 DEBUG(0, ("Illegal config backend given: %d\n",
9208 lp_config_backend()));
9209 bRetval = false;
9212 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9213 bRetval = process_registry_shares();
9216 lp_add_auto_services(lp_auto_services());
9218 if (add_ipc) {
9219 /* When 'restrict anonymous = 2' guest connections to ipc$
9220 are denied */
9221 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9222 if ( lp_enable_asu_support() ) {
9223 lp_add_ipc("ADMIN$", false);
9227 set_server_role();
9228 set_default_server_announce_type();
9229 set_allowed_client_auth();
9231 bLoaded = True;
9233 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9234 /* if bWINSsupport is true and we are in the client */
9235 if (lp_is_in_client() && Globals.bWINSsupport) {
9236 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9239 init_iconv();
9241 bAllowIncludeRegistry = true;
9243 return (bRetval);
9246 bool lp_load(const char *pszFname,
9247 bool global_only,
9248 bool save_defaults,
9249 bool add_ipc,
9250 bool initialize_globals)
9252 return lp_load_ex(pszFname,
9253 global_only,
9254 save_defaults,
9255 add_ipc,
9256 initialize_globals,
9257 true, false);
9260 bool lp_load_initial_only(const char *pszFname)
9262 return lp_load_ex(pszFname,
9263 true,
9264 false,
9265 false,
9266 true,
9267 false,
9268 false);
9271 bool lp_load_with_registry_shares(const char *pszFname,
9272 bool global_only,
9273 bool save_defaults,
9274 bool add_ipc,
9275 bool initialize_globals)
9277 return lp_load_ex(pszFname,
9278 global_only,
9279 save_defaults,
9280 add_ipc,
9281 initialize_globals,
9282 true,
9283 true);
9286 /***************************************************************************
9287 Return the max number of services.
9288 ***************************************************************************/
9290 int lp_numservices(void)
9292 return (iNumServices);
9295 /***************************************************************************
9296 Display the contents of the services array in human-readable form.
9297 ***************************************************************************/
9299 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9301 int iService;
9303 if (show_defaults)
9304 defaults_saved = False;
9306 dump_globals(f);
9308 dump_a_service(&sDefault, f);
9310 for (iService = 0; iService < maxtoprint; iService++) {
9311 fprintf(f,"\n");
9312 lp_dump_one(f, show_defaults, iService);
9316 /***************************************************************************
9317 Display the contents of one service in human-readable form.
9318 ***************************************************************************/
9320 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9322 if (VALID(snum)) {
9323 if (ServicePtrs[snum]->szService[0] == '\0')
9324 return;
9325 dump_a_service(ServicePtrs[snum], f);
9329 /***************************************************************************
9330 Return the number of the service with the given name, or -1 if it doesn't
9331 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9332 getservicebyname()! This works ONLY if all services have been loaded, and
9333 does not copy the found service.
9334 ***************************************************************************/
9336 int lp_servicenumber(const char *pszServiceName)
9338 int iService;
9339 fstring serviceName;
9341 if (!pszServiceName) {
9342 return GLOBAL_SECTION_SNUM;
9345 for (iService = iNumServices - 1; iService >= 0; iService--) {
9346 if (VALID(iService) && ServicePtrs[iService]->szService) {
9348 * The substitution here is used to support %U is
9349 * service names
9351 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9352 standard_sub_basic(get_current_username(),
9353 current_user_info.domain,
9354 serviceName,sizeof(serviceName));
9355 if (strequal(serviceName, pszServiceName)) {
9356 break;
9361 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9362 struct timespec last_mod;
9364 if (!usershare_exists(iService, &last_mod)) {
9365 /* Remove the share security tdb entry for it. */
9366 delete_share_security(lp_servicename(iService));
9367 /* Remove it from the array. */
9368 free_service_byindex(iService);
9369 /* Doesn't exist anymore. */
9370 return GLOBAL_SECTION_SNUM;
9373 /* Has it been modified ? If so delete and reload. */
9374 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9375 &last_mod) < 0) {
9376 /* Remove it from the array. */
9377 free_service_byindex(iService);
9378 /* and now reload it. */
9379 iService = load_usershare_service(pszServiceName);
9383 if (iService < 0) {
9384 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9385 return GLOBAL_SECTION_SNUM;
9388 return (iService);
9391 bool share_defined(const char *service_name)
9393 return (lp_servicenumber(service_name) != -1);
9396 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9397 const char *sharename)
9399 struct share_params *result;
9400 char *sname;
9401 int snum;
9403 if (!(sname = SMB_STRDUP(sharename))) {
9404 return NULL;
9407 snum = find_service(sname);
9408 SAFE_FREE(sname);
9410 if (snum < 0) {
9411 return NULL;
9414 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9415 DEBUG(0, ("talloc failed\n"));
9416 return NULL;
9419 result->service = snum;
9420 return result;
9423 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9425 struct share_iterator *result;
9427 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9428 DEBUG(0, ("talloc failed\n"));
9429 return NULL;
9432 result->next_id = 0;
9433 return result;
9436 struct share_params *next_share(struct share_iterator *list)
9438 struct share_params *result;
9440 while (!lp_snum_ok(list->next_id) &&
9441 (list->next_id < lp_numservices())) {
9442 list->next_id += 1;
9445 if (list->next_id >= lp_numservices()) {
9446 return NULL;
9449 if (!(result = TALLOC_P(list, struct share_params))) {
9450 DEBUG(0, ("talloc failed\n"));
9451 return NULL;
9454 result->service = list->next_id;
9455 list->next_id += 1;
9456 return result;
9459 struct share_params *next_printer(struct share_iterator *list)
9461 struct share_params *result;
9463 while ((result = next_share(list)) != NULL) {
9464 if (lp_print_ok(result->service)) {
9465 break;
9468 return result;
9472 * This is a hack for a transition period until we transformed all code from
9473 * service numbers to struct share_params.
9476 struct share_params *snum2params_static(int snum)
9478 static struct share_params result;
9479 result.service = snum;
9480 return &result;
9483 /*******************************************************************
9484 A useful volume label function.
9485 ********************************************************************/
9487 const char *volume_label(int snum)
9489 char *ret;
9490 const char *label = lp_volume(snum);
9491 if (!*label) {
9492 label = lp_servicename(snum);
9495 /* This returns a 33 byte guarenteed null terminated string. */
9496 ret = talloc_strndup(talloc_tos(), label, 32);
9497 if (!ret) {
9498 return "";
9500 return ret;
9503 /*******************************************************************
9504 Set the server type we will announce as via nmbd.
9505 ********************************************************************/
9507 static void set_default_server_announce_type(void)
9509 default_server_announce = 0;
9510 default_server_announce |= SV_TYPE_WORKSTATION;
9511 default_server_announce |= SV_TYPE_SERVER;
9512 default_server_announce |= SV_TYPE_SERVER_UNIX;
9514 /* note that the flag should be set only if we have a
9515 printer service but nmbd doesn't actually load the
9516 services so we can't tell --jerry */
9518 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9520 switch (lp_announce_as()) {
9521 case ANNOUNCE_AS_NT_SERVER:
9522 default_server_announce |= SV_TYPE_SERVER_NT;
9523 /* fall through... */
9524 case ANNOUNCE_AS_NT_WORKSTATION:
9525 default_server_announce |= SV_TYPE_NT;
9526 break;
9527 case ANNOUNCE_AS_WIN95:
9528 default_server_announce |= SV_TYPE_WIN95_PLUS;
9529 break;
9530 case ANNOUNCE_AS_WFW:
9531 default_server_announce |= SV_TYPE_WFW;
9532 break;
9533 default:
9534 break;
9537 switch (lp_server_role()) {
9538 case ROLE_DOMAIN_MEMBER:
9539 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9540 break;
9541 case ROLE_DOMAIN_PDC:
9542 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9543 break;
9544 case ROLE_DOMAIN_BDC:
9545 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9546 break;
9547 case ROLE_STANDALONE:
9548 default:
9549 break;
9551 if (lp_time_server())
9552 default_server_announce |= SV_TYPE_TIME_SOURCE;
9554 if (lp_host_msdfs())
9555 default_server_announce |= SV_TYPE_DFS_SERVER;
9558 /***********************************************************
9559 returns role of Samba server
9560 ************************************************************/
9562 int lp_server_role(void)
9564 return server_role;
9567 /***********************************************************
9568 If we are PDC then prefer us as DMB
9569 ************************************************************/
9571 bool lp_domain_master(void)
9573 if (Globals.iDomainMaster == Auto)
9574 return (lp_server_role() == ROLE_DOMAIN_PDC);
9576 return (bool)Globals.iDomainMaster;
9579 /***********************************************************
9580 If we are DMB then prefer us as LMB
9581 ************************************************************/
9583 bool lp_preferred_master(void)
9585 if (Globals.iPreferredMaster == Auto)
9586 return (lp_local_master() && lp_domain_master());
9588 return (bool)Globals.iPreferredMaster;
9591 /*******************************************************************
9592 Remove a service.
9593 ********************************************************************/
9595 void lp_remove_service(int snum)
9597 ServicePtrs[snum]->valid = False;
9598 invalid_services[num_invalid_services++] = snum;
9601 /*******************************************************************
9602 Copy a service.
9603 ********************************************************************/
9605 void lp_copy_service(int snum, const char *new_name)
9607 do_section(new_name, NULL);
9608 if (snum >= 0) {
9609 snum = lp_servicenumber(new_name);
9610 if (snum >= 0)
9611 lp_do_parameter(snum, "copy", lp_servicename(snum));
9616 /*******************************************************************
9617 Get the default server type we will announce as via nmbd.
9618 ********************************************************************/
9620 int lp_default_server_announce(void)
9622 return default_server_announce;
9625 /*******************************************************************
9626 Split the announce version into major and minor numbers.
9627 ********************************************************************/
9629 int lp_major_announce_version(void)
9631 static bool got_major = False;
9632 static int major_version = DEFAULT_MAJOR_VERSION;
9633 char *vers;
9634 char *p;
9636 if (got_major)
9637 return major_version;
9639 got_major = True;
9640 if ((vers = lp_announce_version()) == NULL)
9641 return major_version;
9643 if ((p = strchr_m(vers, '.')) == 0)
9644 return major_version;
9646 *p = '\0';
9647 major_version = atoi(vers);
9648 return major_version;
9651 int lp_minor_announce_version(void)
9653 static bool got_minor = False;
9654 static int minor_version = DEFAULT_MINOR_VERSION;
9655 char *vers;
9656 char *p;
9658 if (got_minor)
9659 return minor_version;
9661 got_minor = True;
9662 if ((vers = lp_announce_version()) == NULL)
9663 return minor_version;
9665 if ((p = strchr_m(vers, '.')) == 0)
9666 return minor_version;
9668 p++;
9669 minor_version = atoi(p);
9670 return minor_version;
9673 /***********************************************************
9674 Set the global name resolution order (used in smbclient).
9675 ************************************************************/
9677 void lp_set_name_resolve_order(const char *new_order)
9679 string_set(&Globals.szNameResolveOrder, new_order);
9682 const char *lp_printername(int snum)
9684 const char *ret = _lp_printername(snum);
9685 if (ret == NULL || (ret != NULL && *ret == '\0'))
9686 ret = lp_const_servicename(snum);
9688 return ret;
9692 /***********************************************************
9693 Allow daemons such as winbindd to fix their logfile name.
9694 ************************************************************/
9696 void lp_set_logfile(const char *name)
9698 string_set(&Globals.szLogFile, name);
9699 debug_set_logfile(name);
9702 /*******************************************************************
9703 Return the max print jobs per queue.
9704 ********************************************************************/
9706 int lp_maxprintjobs(int snum)
9708 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9709 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9710 maxjobs = PRINT_MAX_JOBID - 1;
9712 return maxjobs;
9715 const char *lp_printcapname(void)
9717 if ((Globals.szPrintcapname != NULL) &&
9718 (Globals.szPrintcapname[0] != '\0'))
9719 return Globals.szPrintcapname;
9721 if (sDefault.iPrinting == PRINT_CUPS) {
9722 #ifdef HAVE_CUPS
9723 return "cups";
9724 #else
9725 return "lpstat";
9726 #endif
9729 if (sDefault.iPrinting == PRINT_BSD)
9730 return "/etc/printcap";
9732 return PRINTCAP_NAME;
9735 static uint32 spoolss_state;
9737 bool lp_disable_spoolss( void )
9739 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9740 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9742 return spoolss_state == SVCCTL_STOPPED ? True : False;
9745 void lp_set_spoolss_state( uint32 state )
9747 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9749 spoolss_state = state;
9752 uint32 lp_get_spoolss_state( void )
9754 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9757 /*******************************************************************
9758 Ensure we don't use sendfile if server smb signing is active.
9759 ********************************************************************/
9761 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9763 bool sign_active = false;
9765 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9766 if (get_Protocol() < PROTOCOL_NT1) {
9767 return false;
9769 if (signing_state) {
9770 sign_active = smb_signing_is_active(signing_state);
9772 return (_lp_use_sendfile(snum) &&
9773 (get_remote_arch() != RA_WIN95) &&
9774 !sign_active);
9777 /*******************************************************************
9778 Turn off sendfile if we find the underlying OS doesn't support it.
9779 ********************************************************************/
9781 void set_use_sendfile(int snum, bool val)
9783 if (LP_SNUM_OK(snum))
9784 ServicePtrs[snum]->bUseSendfile = val;
9785 else
9786 sDefault.bUseSendfile = val;
9789 /*******************************************************************
9790 Turn off storing DOS attributes if this share doesn't support it.
9791 ********************************************************************/
9793 void set_store_dos_attributes(int snum, bool val)
9795 if (!LP_SNUM_OK(snum))
9796 return;
9797 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9800 void lp_set_mangling_method(const char *new_method)
9802 string_set(&Globals.szManglingMethod, new_method);
9805 /*******************************************************************
9806 Global state for POSIX pathname processing.
9807 ********************************************************************/
9809 static bool posix_pathnames;
9811 bool lp_posix_pathnames(void)
9813 return posix_pathnames;
9816 /*******************************************************************
9817 Change everything needed to ensure POSIX pathname processing (currently
9818 not much).
9819 ********************************************************************/
9821 void lp_set_posix_pathnames(void)
9823 posix_pathnames = True;
9826 /*******************************************************************
9827 Global state for POSIX lock processing - CIFS unix extensions.
9828 ********************************************************************/
9830 bool posix_default_lock_was_set;
9831 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9833 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9835 if (posix_default_lock_was_set) {
9836 return posix_cifsx_locktype;
9837 } else {
9838 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9842 /*******************************************************************
9843 ********************************************************************/
9845 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9847 posix_default_lock_was_set = True;
9848 posix_cifsx_locktype = val;
9851 int lp_min_receive_file_size(void)
9853 if (Globals.iminreceivefile < 0) {
9854 return 0;
9856 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9859 /*******************************************************************
9860 If socket address is an empty character string, it is necessary to
9861 define it as "0.0.0.0".
9862 ********************************************************************/
9864 const char *lp_socket_address(void)
9866 char *sock_addr = Globals.szSocketAddress;
9868 if (sock_addr[0] == '\0'){
9869 string_set(&Globals.szSocketAddress, "0.0.0.0");
9871 return Globals.szSocketAddress;
9874 void lp_set_passdb_backend(const char *backend)
9876 string_set(&Globals.szPassdbBackend, backend);