Parameterize "smb2 max read", "smb2 max write", "smb2 max trans".
[Samba/wip.git] / source3 / param / loadparm.c
blob077fc6355f2a725c04f0db94744f98a3037031d3
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 bool bNmbdBindExplicitBroadcast;
164 char *szNISHomeMapName;
165 char *szAnnounceVersion; /* This is initialised in init_globals */
166 char *szWorkgroup;
167 char *szNetbiosName;
168 char **szNetbiosAliases;
169 char *szNetbiosScope;
170 char *szNameResolveOrder;
171 char *szPanicAction;
172 char *szAddUserScript;
173 char *szRenameUserScript;
174 char *szDelUserScript;
175 char *szAddGroupScript;
176 char *szDelGroupScript;
177 char *szAddUserToGroupScript;
178 char *szDelUserFromGroupScript;
179 char *szSetPrimaryGroupScript;
180 char *szAddMachineScript;
181 char *szShutdownScript;
182 char *szAbortShutdownScript;
183 char *szUsernameMapScript;
184 char *szCheckPasswordScript;
185 char *szWINSHook;
186 char *szUtmpDir;
187 char *szWtmpDir;
188 bool bUtmp;
189 char *szIdmapUID;
190 char *szIdmapGID;
191 bool bPassdbExpandExplicit;
192 int AlgorithmicRidBase;
193 char *szTemplateHomedir;
194 char *szTemplateShell;
195 char *szWinbindSeparator;
196 bool bWinbindEnumUsers;
197 bool bWinbindEnumGroups;
198 bool bWinbindUseDefaultDomain;
199 bool bWinbindTrustedDomainsOnly;
200 bool bWinbindNestedGroups;
201 int winbind_expand_groups;
202 bool bWinbindRefreshTickets;
203 bool bWinbindOfflineLogon;
204 bool bWinbindNormalizeNames;
205 bool bWinbindRpcOnly;
206 bool bCreateKrb5Conf;
207 char *szIdmapBackend;
208 char *szIdmapAllocBackend;
209 char *szAddShareCommand;
210 char *szChangeShareCommand;
211 char *szDeleteShareCommand;
212 char **szEventLogs;
213 char *szGuestaccount;
214 char *szManglingMethod;
215 char **szServicesList;
216 char *szUsersharePath;
217 char *szUsershareTemplateShare;
218 char **szUsersharePrefixAllowList;
219 char **szUsersharePrefixDenyList;
220 int mangle_prefix;
221 int max_log_size;
222 char *szLogLevel;
223 int max_xmit;
224 int max_mux;
225 int max_open_files;
226 int open_files_db_hash_size;
227 int pwordlevel;
228 int unamelevel;
229 int deadtime;
230 bool getwd_cache;
231 int maxprotocol;
232 int minprotocol;
233 int security;
234 char **AuthMethods;
235 bool paranoid_server_security;
236 int maxdisksize;
237 int lpqcachetime;
238 int iMaxSmbdProcesses;
239 bool bDisableSpoolss;
240 int syslog;
241 int os_level;
242 bool enhanced_browsing;
243 int max_ttl;
244 int max_wins_ttl;
245 int min_wins_ttl;
246 int lm_announce;
247 int lm_interval;
248 int announce_as; /* This is initialised in init_globals */
249 int machine_password_timeout;
250 int map_to_guest;
251 int oplock_break_wait_time;
252 int winbind_cache_time;
253 int winbind_reconnect_delay;
254 int winbind_max_idle_children;
255 char **szWinbindNssInfo;
256 int iLockSpinTime;
257 char *szLdapMachineSuffix;
258 char *szLdapUserSuffix;
259 char *szLdapIdmapSuffix;
260 char *szLdapGroupSuffix;
261 int ldap_ssl;
262 bool ldap_ssl_ads;
263 int ldap_deref;
264 int ldap_follow_referral;
265 char *szLdapSuffix;
266 char *szLdapAdminDn;
267 int ldap_debug_level;
268 int ldap_debug_threshold;
269 int iAclCompat;
270 char *szCupsServer;
271 int CupsEncrypt;
272 char *szIPrintServer;
273 char *ctdbdSocket;
274 char **szClusterAddresses;
275 bool clustering;
276 int ctdb_timeout;
277 int ctdb_locktime_warn_threshold;
278 int ldap_passwd_sync;
279 int ldap_replication_sleep;
280 int ldap_timeout; /* This is initialised in init_globals */
281 int ldap_connection_timeout;
282 int ldap_page_size;
283 bool ldap_delete_dn;
284 bool bMsAddPrinterWizard;
285 bool bDNSproxy;
286 bool bWINSsupport;
287 bool bWINSproxy;
288 bool bLocalMaster;
289 int iPreferredMaster;
290 int iDomainMaster;
291 bool bDomainLogons;
292 char **szInitLogonDelayedHosts;
293 int InitLogonDelay;
294 bool bEncryptPasswords;
295 bool bUpdateEncrypt;
296 int clientSchannel;
297 int serverSchannel;
298 bool bNullPasswords;
299 bool bObeyPamRestrictions;
300 bool bLoadPrinters;
301 int PrintcapCacheTime;
302 bool bLargeReadwrite;
303 bool bReadRaw;
304 bool bWriteRaw;
305 bool bSyslogOnly;
306 bool bBrowseList;
307 bool bNISHomeMap;
308 bool bTimeServer;
309 bool bBindInterfacesOnly;
310 bool bPamPasswordChange;
311 bool bUnixPasswdSync;
312 bool bPasswdChatDebug;
313 int iPasswdChatTimeout;
314 bool bTimestampLogs;
315 bool bNTSmbSupport;
316 bool bNTPipeSupport;
317 bool bNTStatusSupport;
318 bool bStatCache;
319 int iMaxStatCacheSize;
320 bool bKernelOplocks;
321 bool bAllowTrustedDomains;
322 bool bLanmanAuth;
323 bool bNTLMAuth;
324 bool bUseSpnego;
325 bool bClientLanManAuth;
326 bool bClientNTLMv2Auth;
327 bool bClientPlaintextAuth;
328 bool bClientUseSpnego;
329 bool bDebugPrefixTimestamp;
330 bool bDebugHiresTimestamp;
331 bool bDebugPid;
332 bool bDebugUid;
333 bool bDebugClass;
334 bool bEnableCoreFiles;
335 bool bHostMSDfs;
336 bool bUseMmap;
337 bool bHostnameLookups;
338 bool bUnixExtensions;
339 bool bDisableNetbios;
340 char * szDedicatedKeytabFile;
341 int iKerberosMethod;
342 bool bDeferSharingViolations;
343 bool bEnablePrivileges;
344 bool bASUSupport;
345 bool bUsershareOwnerOnly;
346 bool bUsershareAllowGuests;
347 bool bRegistryShares;
348 int restrict_anonymous;
349 int name_cache_timeout;
350 int client_signing;
351 int server_signing;
352 int client_ldap_sasl_wrapping;
353 int iUsershareMaxShares;
354 int iIdmapCacheTime;
355 int iIdmapNegativeCacheTime;
356 bool bResetOnZeroVC;
357 bool bLogWriteableFilesOnExit;
358 int iKeepalive;
359 int iminreceivefile;
360 struct param_opt_struct *param_opt;
361 int cups_connection_timeout;
362 char *szSMBPerfcountModule;
363 bool bMapUntrustedToDomain;
364 bool bAsyncSMBEchoHandler;
365 int ismb2_max_read;
366 int ismb2_max_write;
367 int ismb2_max_trans;
370 static struct global Globals;
373 * This structure describes a single service.
375 struct service {
376 bool valid;
377 bool autoloaded;
378 int usershare;
379 struct timespec usershare_last_mod;
380 char *szService;
381 char *szPath;
382 char *szUsername;
383 char **szInvalidUsers;
384 char **szValidUsers;
385 char **szAdminUsers;
386 char *szCopy;
387 char *szInclude;
388 char *szPreExec;
389 char *szPostExec;
390 char *szRootPreExec;
391 char *szRootPostExec;
392 char *szCupsOptions;
393 char *szPrintcommand;
394 char *szLpqcommand;
395 char *szLprmcommand;
396 char *szLppausecommand;
397 char *szLpresumecommand;
398 char *szQueuepausecommand;
399 char *szQueueresumecommand;
400 char *szPrintername;
401 char *szPrintjobUsername;
402 char *szDontdescend;
403 char **szHostsallow;
404 char **szHostsdeny;
405 char *szMagicScript;
406 char *szMagicOutput;
407 char *szVetoFiles;
408 char *szHideFiles;
409 char *szVetoOplockFiles;
410 char *comment;
411 char *force_user;
412 char *force_group;
413 char **readlist;
414 char **writelist;
415 char **printer_admin;
416 char *volume;
417 char *fstype;
418 char **szVfsObjects;
419 char *szMSDfsProxy;
420 char *szAioWriteBehind;
421 char *szDfree;
422 int iMinPrintSpace;
423 int iMaxPrintJobs;
424 int iMaxReportedPrintJobs;
425 int iWriteCacheSize;
426 int iCreate_mask;
427 int iCreate_force_mode;
428 int iSecurity_mask;
429 int iSecurity_force_mode;
430 int iDir_mask;
431 int iDir_force_mode;
432 int iDir_Security_mask;
433 int iDir_Security_force_mode;
434 int iMaxConnections;
435 int iDefaultCase;
436 int iPrinting;
437 int iOplockContentionLimit;
438 int iCSCPolicy;
439 int iBlock_size;
440 int iDfreeCacheTime;
441 bool bPreexecClose;
442 bool bRootpreexecClose;
443 int iCaseSensitive;
444 bool bCasePreserve;
445 bool bShortCasePreserve;
446 bool bHideDotFiles;
447 bool bHideSpecialFiles;
448 bool bHideUnReadable;
449 bool bHideUnWriteableFiles;
450 bool bBrowseable;
451 bool bAccessBasedShareEnum;
452 bool bAvailable;
453 bool bRead_only;
454 bool bNo_set_dir;
455 bool bGuest_only;
456 bool bAdministrative_share;
457 bool bGuest_ok;
458 bool bPrint_ok;
459 bool bMap_system;
460 bool bMap_hidden;
461 bool bMap_archive;
462 bool bStoreDosAttributes;
463 bool bDmapiSupport;
464 bool bLocking;
465 int iStrictLocking;
466 bool bPosixLocking;
467 bool bShareModes;
468 bool bOpLocks;
469 bool bLevel2OpLocks;
470 bool bOnlyUser;
471 bool bMangledNames;
472 bool bWidelinks;
473 bool bSymlinks;
474 bool bSyncAlways;
475 bool bStrictAllocate;
476 bool bStrictSync;
477 char magic_char;
478 struct bitmap *copymap;
479 bool bDeleteReadonly;
480 bool bFakeOplocks;
481 bool bDeleteVetoFiles;
482 bool bDosFilemode;
483 bool bDosFiletimes;
484 bool bDosFiletimeResolution;
485 bool bFakeDirCreateTimes;
486 bool bBlockingLocks;
487 bool bInheritPerms;
488 bool bInheritACLS;
489 bool bInheritOwner;
490 bool bMSDfsRoot;
491 bool bUseClientDriver;
492 bool bDefaultDevmode;
493 bool bForcePrintername;
494 bool bNTAclSupport;
495 bool bForceUnknownAclUser;
496 bool bUseSendfile;
497 bool bProfileAcls;
498 bool bMap_acl_inherit;
499 bool bAfs_Share;
500 bool bEASupport;
501 bool bAclCheckPermissions;
502 bool bAclMapFullControl;
503 bool bAclGroupControl;
504 bool bChangeNotify;
505 bool bKernelChangeNotify;
506 int iallocation_roundup_size;
507 int iAioReadSize;
508 int iAioWriteSize;
509 int iMap_readonly;
510 int iDirectoryNameCacheSize;
511 int ismb_encrypt;
512 struct param_opt_struct *param_opt;
514 char dummy[3]; /* for alignment */
518 /* This is a default service used to prime a services structure */
519 static struct service sDefault = {
520 True, /* valid */
521 False, /* not autoloaded */
522 0, /* not a usershare */
523 {0, }, /* No last mod time */
524 NULL, /* szService */
525 NULL, /* szPath */
526 NULL, /* szUsername */
527 NULL, /* szInvalidUsers */
528 NULL, /* szValidUsers */
529 NULL, /* szAdminUsers */
530 NULL, /* szCopy */
531 NULL, /* szInclude */
532 NULL, /* szPreExec */
533 NULL, /* szPostExec */
534 NULL, /* szRootPreExec */
535 NULL, /* szRootPostExec */
536 NULL, /* szCupsOptions */
537 NULL, /* szPrintcommand */
538 NULL, /* szLpqcommand */
539 NULL, /* szLprmcommand */
540 NULL, /* szLppausecommand */
541 NULL, /* szLpresumecommand */
542 NULL, /* szQueuepausecommand */
543 NULL, /* szQueueresumecommand */
544 NULL, /* szPrintername */
545 NULL, /* szPrintjobUsername */
546 NULL, /* szDontdescend */
547 NULL, /* szHostsallow */
548 NULL, /* szHostsdeny */
549 NULL, /* szMagicScript */
550 NULL, /* szMagicOutput */
551 NULL, /* szVetoFiles */
552 NULL, /* szHideFiles */
553 NULL, /* szVetoOplockFiles */
554 NULL, /* comment */
555 NULL, /* force user */
556 NULL, /* force group */
557 NULL, /* readlist */
558 NULL, /* writelist */
559 NULL, /* printer admin */
560 NULL, /* volume */
561 NULL, /* fstype */
562 NULL, /* vfs objects */
563 NULL, /* szMSDfsProxy */
564 NULL, /* szAioWriteBehind */
565 NULL, /* szDfree */
566 0, /* iMinPrintSpace */
567 1000, /* iMaxPrintJobs */
568 0, /* iMaxReportedPrintJobs */
569 0, /* iWriteCacheSize */
570 0744, /* iCreate_mask */
571 0000, /* iCreate_force_mode */
572 0777, /* iSecurity_mask */
573 0, /* iSecurity_force_mode */
574 0755, /* iDir_mask */
575 0000, /* iDir_force_mode */
576 0777, /* iDir_Security_mask */
577 0, /* iDir_Security_force_mode */
578 0, /* iMaxConnections */
579 CASE_LOWER, /* iDefaultCase */
580 DEFAULT_PRINTING, /* iPrinting */
581 2, /* iOplockContentionLimit */
582 0, /* iCSCPolicy */
583 1024, /* iBlock_size */
584 0, /* iDfreeCacheTime */
585 False, /* bPreexecClose */
586 False, /* bRootpreexecClose */
587 Auto, /* case sensitive */
588 True, /* case preserve */
589 True, /* short case preserve */
590 True, /* bHideDotFiles */
591 False, /* bHideSpecialFiles */
592 False, /* bHideUnReadable */
593 False, /* bHideUnWriteableFiles */
594 True, /* bBrowseable */
595 False, /* bAccessBasedShareEnum */
596 True, /* bAvailable */
597 True, /* bRead_only */
598 True, /* bNo_set_dir */
599 False, /* bGuest_only */
600 False, /* bAdministrative_share */
601 False, /* bGuest_ok */
602 False, /* bPrint_ok */
603 False, /* bMap_system */
604 False, /* bMap_hidden */
605 True, /* bMap_archive */
606 False, /* bStoreDosAttributes */
607 False, /* bDmapiSupport */
608 True, /* bLocking */
609 Auto, /* iStrictLocking */
610 True, /* bPosixLocking */
611 True, /* bShareModes */
612 True, /* bOpLocks */
613 True, /* bLevel2OpLocks */
614 False, /* bOnlyUser */
615 True, /* bMangledNames */
616 false, /* bWidelinks */
617 True, /* bSymlinks */
618 False, /* bSyncAlways */
619 False, /* bStrictAllocate */
620 False, /* bStrictSync */
621 '~', /* magic char */
622 NULL, /* copymap */
623 False, /* bDeleteReadonly */
624 False, /* bFakeOplocks */
625 False, /* bDeleteVetoFiles */
626 False, /* bDosFilemode */
627 True, /* bDosFiletimes */
628 False, /* bDosFiletimeResolution */
629 False, /* bFakeDirCreateTimes */
630 True, /* bBlockingLocks */
631 False, /* bInheritPerms */
632 False, /* bInheritACLS */
633 False, /* bInheritOwner */
634 False, /* bMSDfsRoot */
635 False, /* bUseClientDriver */
636 True, /* bDefaultDevmode */
637 False, /* bForcePrintername */
638 True, /* bNTAclSupport */
639 False, /* bForceUnknownAclUser */
640 False, /* bUseSendfile */
641 False, /* bProfileAcls */
642 False, /* bMap_acl_inherit */
643 False, /* bAfs_Share */
644 False, /* bEASupport */
645 True, /* bAclCheckPermissions */
646 True, /* bAclMapFullControl */
647 False, /* bAclGroupControl */
648 True, /* bChangeNotify */
649 True, /* bKernelChangeNotify */
650 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
651 0, /* iAioReadSize */
652 0, /* iAioWriteSize */
653 MAP_READONLY_YES, /* iMap_readonly */
654 #ifdef BROKEN_DIRECTORY_HANDLING
655 0, /* iDirectoryNameCacheSize */
656 #else
657 100, /* iDirectoryNameCacheSize */
658 #endif
659 Auto, /* ismb_encrypt */
660 NULL, /* Parametric options */
662 "" /* dummy */
665 /* local variables */
666 static struct service **ServicePtrs = NULL;
667 static int iNumServices = 0;
668 static int iServiceIndex = 0;
669 static struct db_context *ServiceHash;
670 static int *invalid_services = NULL;
671 static int num_invalid_services = 0;
672 static bool bInGlobalSection = True;
673 static bool bGlobalOnly = False;
674 static int server_role;
675 static int default_server_announce;
677 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
679 /* prototypes for the special type handlers */
680 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
681 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
682 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
683 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
684 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
685 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
686 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
687 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
688 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
689 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
690 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
691 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
693 static void set_server_role(void);
694 static void set_default_server_announce_type(void);
695 static void set_allowed_client_auth(void);
697 static void *lp_local_ptr(struct service *service, void *ptr);
699 static void add_to_file_list(const char *fname, const char *subfname);
701 static const struct enum_list enum_protocol[] = {
702 {PROTOCOL_SMB2, "SMB2"},
703 {PROTOCOL_NT1, "NT1"},
704 {PROTOCOL_LANMAN2, "LANMAN2"},
705 {PROTOCOL_LANMAN1, "LANMAN1"},
706 {PROTOCOL_CORE, "CORE"},
707 {PROTOCOL_COREPLUS, "COREPLUS"},
708 {PROTOCOL_COREPLUS, "CORE+"},
709 {-1, NULL}
712 static const struct enum_list enum_security[] = {
713 {SEC_SHARE, "SHARE"},
714 {SEC_USER, "USER"},
715 {SEC_SERVER, "SERVER"},
716 {SEC_DOMAIN, "DOMAIN"},
717 #ifdef HAVE_ADS
718 {SEC_ADS, "ADS"},
719 #endif
720 {-1, NULL}
723 static const struct enum_list enum_printing[] = {
724 {PRINT_SYSV, "sysv"},
725 {PRINT_AIX, "aix"},
726 {PRINT_HPUX, "hpux"},
727 {PRINT_BSD, "bsd"},
728 {PRINT_QNX, "qnx"},
729 {PRINT_PLP, "plp"},
730 {PRINT_LPRNG, "lprng"},
731 {PRINT_CUPS, "cups"},
732 {PRINT_IPRINT, "iprint"},
733 {PRINT_LPRNT, "nt"},
734 {PRINT_LPROS2, "os2"},
735 #ifdef DEVELOPER
736 {PRINT_TEST, "test"},
737 {PRINT_VLP, "vlp"},
738 #endif /* DEVELOPER */
739 {-1, NULL}
742 static const struct enum_list enum_ldap_sasl_wrapping[] = {
743 {0, "plain"},
744 {ADS_AUTH_SASL_SIGN, "sign"},
745 {ADS_AUTH_SASL_SEAL, "seal"},
746 {-1, NULL}
749 static const struct enum_list enum_ldap_ssl[] = {
750 {LDAP_SSL_OFF, "no"},
751 {LDAP_SSL_OFF, "off"},
752 {LDAP_SSL_START_TLS, "start tls"},
753 {LDAP_SSL_START_TLS, "start_tls"},
754 {-1, NULL}
757 /* LDAP Dereferencing Alias types */
758 #define SAMBA_LDAP_DEREF_NEVER 0
759 #define SAMBA_LDAP_DEREF_SEARCHING 1
760 #define SAMBA_LDAP_DEREF_FINDING 2
761 #define SAMBA_LDAP_DEREF_ALWAYS 3
763 static const struct enum_list enum_ldap_deref[] = {
764 {SAMBA_LDAP_DEREF_NEVER, "never"},
765 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
766 {SAMBA_LDAP_DEREF_FINDING, "finding"},
767 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
768 {-1, "auto"}
771 static const struct enum_list enum_ldap_passwd_sync[] = {
772 {LDAP_PASSWD_SYNC_OFF, "no"},
773 {LDAP_PASSWD_SYNC_OFF, "off"},
774 {LDAP_PASSWD_SYNC_ON, "yes"},
775 {LDAP_PASSWD_SYNC_ON, "on"},
776 {LDAP_PASSWD_SYNC_ONLY, "only"},
777 {-1, NULL}
780 /* Types of machine we can announce as. */
781 #define ANNOUNCE_AS_NT_SERVER 1
782 #define ANNOUNCE_AS_WIN95 2
783 #define ANNOUNCE_AS_WFW 3
784 #define ANNOUNCE_AS_NT_WORKSTATION 4
786 static const struct enum_list enum_announce_as[] = {
787 {ANNOUNCE_AS_NT_SERVER, "NT"},
788 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
789 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
790 {ANNOUNCE_AS_WIN95, "win95"},
791 {ANNOUNCE_AS_WFW, "WfW"},
792 {-1, NULL}
795 static const struct enum_list enum_map_readonly[] = {
796 {MAP_READONLY_NO, "no"},
797 {MAP_READONLY_NO, "false"},
798 {MAP_READONLY_NO, "0"},
799 {MAP_READONLY_YES, "yes"},
800 {MAP_READONLY_YES, "true"},
801 {MAP_READONLY_YES, "1"},
802 {MAP_READONLY_PERMISSIONS, "permissions"},
803 {MAP_READONLY_PERMISSIONS, "perms"},
804 {-1, NULL}
807 static const struct enum_list enum_case[] = {
808 {CASE_LOWER, "lower"},
809 {CASE_UPPER, "upper"},
810 {-1, NULL}
815 static const struct enum_list enum_bool_auto[] = {
816 {False, "No"},
817 {False, "False"},
818 {False, "0"},
819 {True, "Yes"},
820 {True, "True"},
821 {True, "1"},
822 {Auto, "Auto"},
823 {-1, NULL}
826 /* Client-side offline caching policy types */
827 #define CSC_POLICY_MANUAL 0
828 #define CSC_POLICY_DOCUMENTS 1
829 #define CSC_POLICY_PROGRAMS 2
830 #define CSC_POLICY_DISABLE 3
832 static const struct enum_list enum_csc_policy[] = {
833 {CSC_POLICY_MANUAL, "manual"},
834 {CSC_POLICY_DOCUMENTS, "documents"},
835 {CSC_POLICY_PROGRAMS, "programs"},
836 {CSC_POLICY_DISABLE, "disable"},
837 {-1, NULL}
840 /* SMB signing types. */
841 static const struct enum_list enum_smb_signing_vals[] = {
842 {False, "No"},
843 {False, "False"},
844 {False, "0"},
845 {False, "Off"},
846 {False, "disabled"},
847 {True, "Yes"},
848 {True, "True"},
849 {True, "1"},
850 {True, "On"},
851 {True, "enabled"},
852 {Auto, "auto"},
853 {Required, "required"},
854 {Required, "mandatory"},
855 {Required, "force"},
856 {Required, "forced"},
857 {Required, "enforced"},
858 {-1, NULL}
861 /* ACL compatibility options. */
862 static const struct enum_list enum_acl_compat_vals[] = {
863 { ACL_COMPAT_AUTO, "auto" },
864 { ACL_COMPAT_WINNT, "winnt" },
865 { ACL_COMPAT_WIN2K, "win2k" },
866 { -1, NULL}
870 Do you want session setups at user level security with a invalid
871 password to be rejected or allowed in as guest? WinNT rejects them
872 but it can be a pain as it means "net view" needs to use a password
874 You have 3 choices in the setting of map_to_guest:
876 "Never" means session setups with an invalid password
877 are rejected. This is the default.
879 "Bad User" means session setups with an invalid password
880 are rejected, unless the username does not exist, in which case it
881 is treated as a guest login
883 "Bad Password" means session setups with an invalid password
884 are treated as a guest login
886 Note that map_to_guest only has an effect in user or server
887 level security.
890 static const struct enum_list enum_map_to_guest[] = {
891 {NEVER_MAP_TO_GUEST, "Never"},
892 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
893 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
894 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
895 {-1, NULL}
898 /* Config backend options */
900 static const struct enum_list enum_config_backend[] = {
901 {CONFIG_BACKEND_FILE, "file"},
902 {CONFIG_BACKEND_REGISTRY, "registry"},
903 {-1, NULL}
906 /* ADS kerberos ticket verification options */
908 static const struct enum_list enum_kerberos_method[] = {
909 {KERBEROS_VERIFY_SECRETS, "default"},
910 {KERBEROS_VERIFY_SECRETS, "secrets only"},
911 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
912 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
913 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
914 {-1, NULL}
917 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
919 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
920 * screen in SWAT. This is used to exclude parameters as well as to squash all
921 * parameters that have been duplicated by pseudonyms.
923 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
924 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
925 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
926 * respective views.
928 * NOTE2: Handling of duplicated (synonym) parameters:
929 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
930 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
931 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
932 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
935 static struct parm_struct parm_table[] = {
936 {N_("Base Options"), P_SEP, P_SEPARATOR},
939 .label = "dos charset",
940 .type = P_STRING,
941 .p_class = P_GLOBAL,
942 .ptr = &Globals.dos_charset,
943 .special = handle_charset,
944 .enum_list = NULL,
945 .flags = FLAG_ADVANCED
948 .label = "unix charset",
949 .type = P_STRING,
950 .p_class = P_GLOBAL,
951 .ptr = &Globals.unix_charset,
952 .special = handle_charset,
953 .enum_list = NULL,
954 .flags = FLAG_ADVANCED
957 .label = "display charset",
958 .type = P_STRING,
959 .p_class = P_GLOBAL,
960 .ptr = &Globals.display_charset,
961 .special = handle_charset,
962 .enum_list = NULL,
963 .flags = FLAG_ADVANCED
966 .label = "comment",
967 .type = P_STRING,
968 .p_class = P_LOCAL,
969 .ptr = &sDefault.comment,
970 .special = NULL,
971 .enum_list = NULL,
972 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
975 .label = "path",
976 .type = P_STRING,
977 .p_class = P_LOCAL,
978 .ptr = &sDefault.szPath,
979 .special = NULL,
980 .enum_list = NULL,
981 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
984 .label = "directory",
985 .type = P_STRING,
986 .p_class = P_LOCAL,
987 .ptr = &sDefault.szPath,
988 .special = NULL,
989 .enum_list = NULL,
990 .flags = FLAG_HIDE,
993 .label = "workgroup",
994 .type = P_USTRING,
995 .p_class = P_GLOBAL,
996 .ptr = &Globals.szWorkgroup,
997 .special = handle_workgroup,
998 .enum_list = NULL,
999 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1001 #ifdef WITH_ADS
1003 .label = "realm",
1004 .type = P_USTRING,
1005 .p_class = P_GLOBAL,
1006 .ptr = &Globals.szRealm,
1007 .special = NULL,
1008 .enum_list = NULL,
1009 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1011 #endif
1013 .label = "netbios name",
1014 .type = P_USTRING,
1015 .p_class = P_GLOBAL,
1016 .ptr = &Globals.szNetbiosName,
1017 .special = handle_netbios_name,
1018 .enum_list = NULL,
1019 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1022 .label = "netbios aliases",
1023 .type = P_LIST,
1024 .p_class = P_GLOBAL,
1025 .ptr = &Globals.szNetbiosAliases,
1026 .special = handle_netbios_aliases,
1027 .enum_list = NULL,
1028 .flags = FLAG_ADVANCED,
1031 .label = "netbios scope",
1032 .type = P_USTRING,
1033 .p_class = P_GLOBAL,
1034 .ptr = &Globals.szNetbiosScope,
1035 .special = handle_netbios_scope,
1036 .enum_list = NULL,
1037 .flags = FLAG_ADVANCED,
1040 .label = "server string",
1041 .type = P_STRING,
1042 .p_class = P_GLOBAL,
1043 .ptr = &Globals.szServerString,
1044 .special = NULL,
1045 .enum_list = NULL,
1046 .flags = FLAG_BASIC | FLAG_ADVANCED,
1049 .label = "interfaces",
1050 .type = P_LIST,
1051 .p_class = P_GLOBAL,
1052 .ptr = &Globals.szInterfaces,
1053 .special = NULL,
1054 .enum_list = NULL,
1055 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1058 .label = "bind interfaces only",
1059 .type = P_BOOL,
1060 .p_class = P_GLOBAL,
1061 .ptr = &Globals.bBindInterfacesOnly,
1062 .special = NULL,
1063 .enum_list = NULL,
1064 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1067 .label = "config backend",
1068 .type = P_ENUM,
1069 .p_class = P_GLOBAL,
1070 .ptr = &Globals.ConfigBackend,
1071 .special = NULL,
1072 .enum_list = enum_config_backend,
1073 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1076 {N_("Security Options"), P_SEP, P_SEPARATOR},
1079 .label = "security",
1080 .type = P_ENUM,
1081 .p_class = P_GLOBAL,
1082 .ptr = &Globals.security,
1083 .special = NULL,
1084 .enum_list = enum_security,
1085 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1088 .label = "auth methods",
1089 .type = P_LIST,
1090 .p_class = P_GLOBAL,
1091 .ptr = &Globals.AuthMethods,
1092 .special = NULL,
1093 .enum_list = NULL,
1094 .flags = FLAG_ADVANCED,
1097 .label = "encrypt passwords",
1098 .type = P_BOOL,
1099 .p_class = P_GLOBAL,
1100 .ptr = &Globals.bEncryptPasswords,
1101 .special = NULL,
1102 .enum_list = NULL,
1103 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1106 .label = "update encrypted",
1107 .type = P_BOOL,
1108 .p_class = P_GLOBAL,
1109 .ptr = &Globals.bUpdateEncrypt,
1110 .special = NULL,
1111 .enum_list = NULL,
1112 .flags = FLAG_ADVANCED,
1115 .label = "client schannel",
1116 .type = P_ENUM,
1117 .p_class = P_GLOBAL,
1118 .ptr = &Globals.clientSchannel,
1119 .special = NULL,
1120 .enum_list = enum_bool_auto,
1121 .flags = FLAG_BASIC | FLAG_ADVANCED,
1124 .label = "server schannel",
1125 .type = P_ENUM,
1126 .p_class = P_GLOBAL,
1127 .ptr = &Globals.serverSchannel,
1128 .special = NULL,
1129 .enum_list = enum_bool_auto,
1130 .flags = FLAG_BASIC | FLAG_ADVANCED,
1133 .label = "allow trusted domains",
1134 .type = P_BOOL,
1135 .p_class = P_GLOBAL,
1136 .ptr = &Globals.bAllowTrustedDomains,
1137 .special = NULL,
1138 .enum_list = NULL,
1139 .flags = FLAG_ADVANCED,
1142 .label = "map to guest",
1143 .type = P_ENUM,
1144 .p_class = P_GLOBAL,
1145 .ptr = &Globals.map_to_guest,
1146 .special = NULL,
1147 .enum_list = enum_map_to_guest,
1148 .flags = FLAG_ADVANCED,
1151 .label = "null passwords",
1152 .type = P_BOOL,
1153 .p_class = P_GLOBAL,
1154 .ptr = &Globals.bNullPasswords,
1155 .special = NULL,
1156 .enum_list = NULL,
1157 .flags = FLAG_ADVANCED,
1160 .label = "obey pam restrictions",
1161 .type = P_BOOL,
1162 .p_class = P_GLOBAL,
1163 .ptr = &Globals.bObeyPamRestrictions,
1164 .special = NULL,
1165 .enum_list = NULL,
1166 .flags = FLAG_ADVANCED,
1169 .label = "password server",
1170 .type = P_STRING,
1171 .p_class = P_GLOBAL,
1172 .ptr = &Globals.szPasswordServer,
1173 .special = NULL,
1174 .enum_list = NULL,
1175 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1178 .label = "smb passwd file",
1179 .type = P_STRING,
1180 .p_class = P_GLOBAL,
1181 .ptr = &Globals.szSMBPasswdFile,
1182 .special = NULL,
1183 .enum_list = NULL,
1184 .flags = FLAG_ADVANCED,
1187 .label = "private dir",
1188 .type = P_STRING,
1189 .p_class = P_GLOBAL,
1190 .ptr = &Globals.szPrivateDir,
1191 .special = NULL,
1192 .enum_list = NULL,
1193 .flags = FLAG_ADVANCED,
1196 .label = "passdb backend",
1197 .type = P_STRING,
1198 .p_class = P_GLOBAL,
1199 .ptr = &Globals.szPassdbBackend,
1200 .special = NULL,
1201 .enum_list = NULL,
1202 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1205 .label = "algorithmic rid base",
1206 .type = P_INTEGER,
1207 .p_class = P_GLOBAL,
1208 .ptr = &Globals.AlgorithmicRidBase,
1209 .special = NULL,
1210 .enum_list = NULL,
1211 .flags = FLAG_ADVANCED,
1214 .label = "root directory",
1215 .type = P_STRING,
1216 .p_class = P_GLOBAL,
1217 .ptr = &Globals.szRootdir,
1218 .special = NULL,
1219 .enum_list = NULL,
1220 .flags = FLAG_ADVANCED,
1223 .label = "root dir",
1224 .type = P_STRING,
1225 .p_class = P_GLOBAL,
1226 .ptr = &Globals.szRootdir,
1227 .special = NULL,
1228 .enum_list = NULL,
1229 .flags = FLAG_HIDE,
1232 .label = "root",
1233 .type = P_STRING,
1234 .p_class = P_GLOBAL,
1235 .ptr = &Globals.szRootdir,
1236 .special = NULL,
1237 .enum_list = NULL,
1238 .flags = FLAG_HIDE,
1241 .label = "guest account",
1242 .type = P_STRING,
1243 .p_class = P_GLOBAL,
1244 .ptr = &Globals.szGuestaccount,
1245 .special = NULL,
1246 .enum_list = NULL,
1247 .flags = FLAG_BASIC | FLAG_ADVANCED,
1250 .label = "enable privileges",
1251 .type = P_BOOL,
1252 .p_class = P_GLOBAL,
1253 .ptr = &Globals.bEnablePrivileges,
1254 .special = NULL,
1255 .enum_list = NULL,
1256 .flags = FLAG_ADVANCED,
1260 .label = "pam password change",
1261 .type = P_BOOL,
1262 .p_class = P_GLOBAL,
1263 .ptr = &Globals.bPamPasswordChange,
1264 .special = NULL,
1265 .enum_list = NULL,
1266 .flags = FLAG_ADVANCED,
1269 .label = "passwd program",
1270 .type = P_STRING,
1271 .p_class = P_GLOBAL,
1272 .ptr = &Globals.szPasswdProgram,
1273 .special = NULL,
1274 .enum_list = NULL,
1275 .flags = FLAG_ADVANCED,
1278 .label = "passwd chat",
1279 .type = P_STRING,
1280 .p_class = P_GLOBAL,
1281 .ptr = &Globals.szPasswdChat,
1282 .special = NULL,
1283 .enum_list = NULL,
1284 .flags = FLAG_ADVANCED,
1287 .label = "passwd chat debug",
1288 .type = P_BOOL,
1289 .p_class = P_GLOBAL,
1290 .ptr = &Globals.bPasswdChatDebug,
1291 .special = NULL,
1292 .enum_list = NULL,
1293 .flags = FLAG_ADVANCED,
1296 .label = "passwd chat timeout",
1297 .type = P_INTEGER,
1298 .p_class = P_GLOBAL,
1299 .ptr = &Globals.iPasswdChatTimeout,
1300 .special = NULL,
1301 .enum_list = NULL,
1302 .flags = FLAG_ADVANCED,
1305 .label = "check password script",
1306 .type = P_STRING,
1307 .p_class = P_GLOBAL,
1308 .ptr = &Globals.szCheckPasswordScript,
1309 .special = NULL,
1310 .enum_list = NULL,
1311 .flags = FLAG_ADVANCED,
1314 .label = "username map",
1315 .type = P_STRING,
1316 .p_class = P_GLOBAL,
1317 .ptr = &Globals.szUsernameMap,
1318 .special = NULL,
1319 .enum_list = NULL,
1320 .flags = FLAG_ADVANCED,
1323 .label = "password level",
1324 .type = P_INTEGER,
1325 .p_class = P_GLOBAL,
1326 .ptr = &Globals.pwordlevel,
1327 .special = NULL,
1328 .enum_list = NULL,
1329 .flags = FLAG_ADVANCED,
1332 .label = "username level",
1333 .type = P_INTEGER,
1334 .p_class = P_GLOBAL,
1335 .ptr = &Globals.unamelevel,
1336 .special = NULL,
1337 .enum_list = NULL,
1338 .flags = FLAG_ADVANCED,
1341 .label = "unix password sync",
1342 .type = P_BOOL,
1343 .p_class = P_GLOBAL,
1344 .ptr = &Globals.bUnixPasswdSync,
1345 .special = NULL,
1346 .enum_list = NULL,
1347 .flags = FLAG_ADVANCED,
1350 .label = "restrict anonymous",
1351 .type = P_INTEGER,
1352 .p_class = P_GLOBAL,
1353 .ptr = &Globals.restrict_anonymous,
1354 .special = NULL,
1355 .enum_list = NULL,
1356 .flags = FLAG_ADVANCED,
1359 .label = "lanman auth",
1360 .type = P_BOOL,
1361 .p_class = P_GLOBAL,
1362 .ptr = &Globals.bLanmanAuth,
1363 .special = NULL,
1364 .enum_list = NULL,
1365 .flags = FLAG_ADVANCED,
1368 .label = "ntlm auth",
1369 .type = P_BOOL,
1370 .p_class = P_GLOBAL,
1371 .ptr = &Globals.bNTLMAuth,
1372 .special = NULL,
1373 .enum_list = NULL,
1374 .flags = FLAG_ADVANCED,
1377 .label = "client NTLMv2 auth",
1378 .type = P_BOOL,
1379 .p_class = P_GLOBAL,
1380 .ptr = &Globals.bClientNTLMv2Auth,
1381 .special = NULL,
1382 .enum_list = NULL,
1383 .flags = FLAG_ADVANCED,
1386 .label = "client lanman auth",
1387 .type = P_BOOL,
1388 .p_class = P_GLOBAL,
1389 .ptr = &Globals.bClientLanManAuth,
1390 .special = NULL,
1391 .enum_list = NULL,
1392 .flags = FLAG_ADVANCED,
1395 .label = "client plaintext auth",
1396 .type = P_BOOL,
1397 .p_class = P_GLOBAL,
1398 .ptr = &Globals.bClientPlaintextAuth,
1399 .special = NULL,
1400 .enum_list = NULL,
1401 .flags = FLAG_ADVANCED,
1404 .label = "username",
1405 .type = P_STRING,
1406 .p_class = P_LOCAL,
1407 .ptr = &sDefault.szUsername,
1408 .special = NULL,
1409 .enum_list = NULL,
1410 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1413 .label = "user",
1414 .type = P_STRING,
1415 .p_class = P_LOCAL,
1416 .ptr = &sDefault.szUsername,
1417 .special = NULL,
1418 .enum_list = NULL,
1419 .flags = FLAG_HIDE,
1422 .label = "users",
1423 .type = P_STRING,
1424 .p_class = P_LOCAL,
1425 .ptr = &sDefault.szUsername,
1426 .special = NULL,
1427 .enum_list = NULL,
1428 .flags = FLAG_HIDE,
1431 .label = "invalid users",
1432 .type = P_LIST,
1433 .p_class = P_LOCAL,
1434 .ptr = &sDefault.szInvalidUsers,
1435 .special = NULL,
1436 .enum_list = NULL,
1437 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1440 .label = "valid users",
1441 .type = P_LIST,
1442 .p_class = P_LOCAL,
1443 .ptr = &sDefault.szValidUsers,
1444 .special = NULL,
1445 .enum_list = NULL,
1446 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1449 .label = "admin users",
1450 .type = P_LIST,
1451 .p_class = P_LOCAL,
1452 .ptr = &sDefault.szAdminUsers,
1453 .special = NULL,
1454 .enum_list = NULL,
1455 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1458 .label = "read list",
1459 .type = P_LIST,
1460 .p_class = P_LOCAL,
1461 .ptr = &sDefault.readlist,
1462 .special = NULL,
1463 .enum_list = NULL,
1464 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1467 .label = "write list",
1468 .type = P_LIST,
1469 .p_class = P_LOCAL,
1470 .ptr = &sDefault.writelist,
1471 .special = NULL,
1472 .enum_list = NULL,
1473 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1476 .label = "printer admin",
1477 .type = P_LIST,
1478 .p_class = P_LOCAL,
1479 .ptr = &sDefault.printer_admin,
1480 .special = NULL,
1481 .enum_list = NULL,
1482 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1485 .label = "force user",
1486 .type = P_STRING,
1487 .p_class = P_LOCAL,
1488 .ptr = &sDefault.force_user,
1489 .special = NULL,
1490 .enum_list = NULL,
1491 .flags = FLAG_ADVANCED | FLAG_SHARE,
1494 .label = "force group",
1495 .type = P_STRING,
1496 .p_class = P_LOCAL,
1497 .ptr = &sDefault.force_group,
1498 .special = NULL,
1499 .enum_list = NULL,
1500 .flags = FLAG_ADVANCED | FLAG_SHARE,
1503 .label = "group",
1504 .type = P_STRING,
1505 .p_class = P_LOCAL,
1506 .ptr = &sDefault.force_group,
1507 .special = NULL,
1508 .enum_list = NULL,
1509 .flags = FLAG_ADVANCED,
1512 .label = "read only",
1513 .type = P_BOOL,
1514 .p_class = P_LOCAL,
1515 .ptr = &sDefault.bRead_only,
1516 .special = NULL,
1517 .enum_list = NULL,
1518 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1521 .label = "write ok",
1522 .type = P_BOOLREV,
1523 .p_class = P_LOCAL,
1524 .ptr = &sDefault.bRead_only,
1525 .special = NULL,
1526 .enum_list = NULL,
1527 .flags = FLAG_HIDE,
1530 .label = "writeable",
1531 .type = P_BOOLREV,
1532 .p_class = P_LOCAL,
1533 .ptr = &sDefault.bRead_only,
1534 .special = NULL,
1535 .enum_list = NULL,
1536 .flags = FLAG_HIDE,
1539 .label = "writable",
1540 .type = P_BOOLREV,
1541 .p_class = P_LOCAL,
1542 .ptr = &sDefault.bRead_only,
1543 .special = NULL,
1544 .enum_list = NULL,
1545 .flags = FLAG_HIDE,
1548 .label = "acl check permissions",
1549 .type = P_BOOL,
1550 .p_class = P_LOCAL,
1551 .ptr = &sDefault.bAclCheckPermissions,
1552 .special = NULL,
1553 .enum_list = NULL,
1554 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1557 .label = "acl group control",
1558 .type = P_BOOL,
1559 .p_class = P_LOCAL,
1560 .ptr = &sDefault.bAclGroupControl,
1561 .special = NULL,
1562 .enum_list = NULL,
1563 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1566 .label = "acl map full control",
1567 .type = P_BOOL,
1568 .p_class = P_LOCAL,
1569 .ptr = &sDefault.bAclMapFullControl,
1570 .special = NULL,
1571 .enum_list = NULL,
1572 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1575 .label = "create mask",
1576 .type = P_OCTAL,
1577 .p_class = P_LOCAL,
1578 .ptr = &sDefault.iCreate_mask,
1579 .special = NULL,
1580 .enum_list = NULL,
1581 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1584 .label = "create mode",
1585 .type = P_OCTAL,
1586 .p_class = P_LOCAL,
1587 .ptr = &sDefault.iCreate_mask,
1588 .special = NULL,
1589 .enum_list = NULL,
1590 .flags = FLAG_HIDE,
1593 .label = "force create mode",
1594 .type = P_OCTAL,
1595 .p_class = P_LOCAL,
1596 .ptr = &sDefault.iCreate_force_mode,
1597 .special = NULL,
1598 .enum_list = NULL,
1599 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1602 .label = "security mask",
1603 .type = P_OCTAL,
1604 .p_class = P_LOCAL,
1605 .ptr = &sDefault.iSecurity_mask,
1606 .special = NULL,
1607 .enum_list = NULL,
1608 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1611 .label = "force security mode",
1612 .type = P_OCTAL,
1613 .p_class = P_LOCAL,
1614 .ptr = &sDefault.iSecurity_force_mode,
1615 .special = NULL,
1616 .enum_list = NULL,
1617 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1620 .label = "directory mask",
1621 .type = P_OCTAL,
1622 .p_class = P_LOCAL,
1623 .ptr = &sDefault.iDir_mask,
1624 .special = NULL,
1625 .enum_list = NULL,
1626 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1629 .label = "directory mode",
1630 .type = P_OCTAL,
1631 .p_class = P_LOCAL,
1632 .ptr = &sDefault.iDir_mask,
1633 .special = NULL,
1634 .enum_list = NULL,
1635 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1638 .label = "force directory mode",
1639 .type = P_OCTAL,
1640 .p_class = P_LOCAL,
1641 .ptr = &sDefault.iDir_force_mode,
1642 .special = NULL,
1643 .enum_list = NULL,
1644 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1647 .label = "directory security mask",
1648 .type = P_OCTAL,
1649 .p_class = P_LOCAL,
1650 .ptr = &sDefault.iDir_Security_mask,
1651 .special = NULL,
1652 .enum_list = NULL,
1653 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1656 .label = "force directory security mode",
1657 .type = P_OCTAL,
1658 .p_class = P_LOCAL,
1659 .ptr = &sDefault.iDir_Security_force_mode,
1660 .special = NULL,
1661 .enum_list = NULL,
1662 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1665 .label = "force unknown acl user",
1666 .type = P_BOOL,
1667 .p_class = P_LOCAL,
1668 .ptr = &sDefault.bForceUnknownAclUser,
1669 .special = NULL,
1670 .enum_list = NULL,
1671 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1674 .label = "inherit permissions",
1675 .type = P_BOOL,
1676 .p_class = P_LOCAL,
1677 .ptr = &sDefault.bInheritPerms,
1678 .special = NULL,
1679 .enum_list = NULL,
1680 .flags = FLAG_ADVANCED | FLAG_SHARE,
1683 .label = "inherit acls",
1684 .type = P_BOOL,
1685 .p_class = P_LOCAL,
1686 .ptr = &sDefault.bInheritACLS,
1687 .special = NULL,
1688 .enum_list = NULL,
1689 .flags = FLAG_ADVANCED | FLAG_SHARE,
1692 .label = "inherit owner",
1693 .type = P_BOOL,
1694 .p_class = P_LOCAL,
1695 .ptr = &sDefault.bInheritOwner,
1696 .special = NULL,
1697 .enum_list = NULL,
1698 .flags = FLAG_ADVANCED | FLAG_SHARE,
1701 .label = "guest only",
1702 .type = P_BOOL,
1703 .p_class = P_LOCAL,
1704 .ptr = &sDefault.bGuest_only,
1705 .special = NULL,
1706 .enum_list = NULL,
1707 .flags = FLAG_ADVANCED | FLAG_SHARE,
1710 .label = "only guest",
1711 .type = P_BOOL,
1712 .p_class = P_LOCAL,
1713 .ptr = &sDefault.bGuest_only,
1714 .special = NULL,
1715 .enum_list = NULL,
1716 .flags = FLAG_HIDE,
1719 .label = "administrative share",
1720 .type = P_BOOL,
1721 .p_class = P_LOCAL,
1722 .ptr = &sDefault.bAdministrative_share,
1723 .special = NULL,
1724 .enum_list = NULL,
1725 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1729 .label = "guest ok",
1730 .type = P_BOOL,
1731 .p_class = P_LOCAL,
1732 .ptr = &sDefault.bGuest_ok,
1733 .special = NULL,
1734 .enum_list = NULL,
1735 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1738 .label = "public",
1739 .type = P_BOOL,
1740 .p_class = P_LOCAL,
1741 .ptr = &sDefault.bGuest_ok,
1742 .special = NULL,
1743 .enum_list = NULL,
1744 .flags = FLAG_HIDE,
1747 .label = "only user",
1748 .type = P_BOOL,
1749 .p_class = P_LOCAL,
1750 .ptr = &sDefault.bOnlyUser,
1751 .special = NULL,
1752 .enum_list = NULL,
1753 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1756 .label = "hosts allow",
1757 .type = P_LIST,
1758 .p_class = P_LOCAL,
1759 .ptr = &sDefault.szHostsallow,
1760 .special = NULL,
1761 .enum_list = NULL,
1762 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1765 .label = "allow hosts",
1766 .type = P_LIST,
1767 .p_class = P_LOCAL,
1768 .ptr = &sDefault.szHostsallow,
1769 .special = NULL,
1770 .enum_list = NULL,
1771 .flags = FLAG_HIDE,
1774 .label = "hosts deny",
1775 .type = P_LIST,
1776 .p_class = P_LOCAL,
1777 .ptr = &sDefault.szHostsdeny,
1778 .special = NULL,
1779 .enum_list = NULL,
1780 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1783 .label = "deny hosts",
1784 .type = P_LIST,
1785 .p_class = P_LOCAL,
1786 .ptr = &sDefault.szHostsdeny,
1787 .special = NULL,
1788 .enum_list = NULL,
1789 .flags = FLAG_HIDE,
1792 .label = "preload modules",
1793 .type = P_LIST,
1794 .p_class = P_GLOBAL,
1795 .ptr = &Globals.szPreloadModules,
1796 .special = NULL,
1797 .enum_list = NULL,
1798 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1801 .label = "dedicated keytab file",
1802 .type = P_STRING,
1803 .p_class = P_GLOBAL,
1804 .ptr = &Globals.szDedicatedKeytabFile,
1805 .special = NULL,
1806 .enum_list = NULL,
1807 .flags = FLAG_ADVANCED,
1810 .label = "kerberos method",
1811 .type = P_ENUM,
1812 .p_class = P_GLOBAL,
1813 .ptr = &Globals.iKerberosMethod,
1814 .special = NULL,
1815 .enum_list = enum_kerberos_method,
1816 .flags = FLAG_ADVANCED,
1819 .label = "map untrusted to domain",
1820 .type = P_BOOL,
1821 .p_class = P_GLOBAL,
1822 .ptr = &Globals.bMapUntrustedToDomain,
1823 .special = NULL,
1824 .enum_list = NULL,
1825 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1829 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1832 .label = "log level",
1833 .type = P_STRING,
1834 .p_class = P_GLOBAL,
1835 .ptr = &Globals.szLogLevel,
1836 .special = handle_debug_list,
1837 .enum_list = NULL,
1838 .flags = FLAG_ADVANCED,
1841 .label = "debuglevel",
1842 .type = P_STRING,
1843 .p_class = P_GLOBAL,
1844 .ptr = &Globals.szLogLevel,
1845 .special = handle_debug_list,
1846 .enum_list = NULL,
1847 .flags = FLAG_HIDE,
1850 .label = "syslog",
1851 .type = P_INTEGER,
1852 .p_class = P_GLOBAL,
1853 .ptr = &Globals.syslog,
1854 .special = NULL,
1855 .enum_list = NULL,
1856 .flags = FLAG_ADVANCED,
1859 .label = "syslog only",
1860 .type = P_BOOL,
1861 .p_class = P_GLOBAL,
1862 .ptr = &Globals.bSyslogOnly,
1863 .special = NULL,
1864 .enum_list = NULL,
1865 .flags = FLAG_ADVANCED,
1868 .label = "log file",
1869 .type = P_STRING,
1870 .p_class = P_GLOBAL,
1871 .ptr = &Globals.szLogFile,
1872 .special = NULL,
1873 .enum_list = NULL,
1874 .flags = FLAG_ADVANCED,
1877 .label = "max log size",
1878 .type = P_INTEGER,
1879 .p_class = P_GLOBAL,
1880 .ptr = &Globals.max_log_size,
1881 .special = NULL,
1882 .enum_list = NULL,
1883 .flags = FLAG_ADVANCED,
1886 .label = "debug timestamp",
1887 .type = P_BOOL,
1888 .p_class = P_GLOBAL,
1889 .ptr = &Globals.bTimestampLogs,
1890 .special = NULL,
1891 .enum_list = NULL,
1892 .flags = FLAG_ADVANCED,
1895 .label = "timestamp logs",
1896 .type = P_BOOL,
1897 .p_class = P_GLOBAL,
1898 .ptr = &Globals.bTimestampLogs,
1899 .special = NULL,
1900 .enum_list = NULL,
1901 .flags = FLAG_ADVANCED,
1904 .label = "debug prefix timestamp",
1905 .type = P_BOOL,
1906 .p_class = P_GLOBAL,
1907 .ptr = &Globals.bDebugPrefixTimestamp,
1908 .special = NULL,
1909 .enum_list = NULL,
1910 .flags = FLAG_ADVANCED,
1913 .label = "debug hires timestamp",
1914 .type = P_BOOL,
1915 .p_class = P_GLOBAL,
1916 .ptr = &Globals.bDebugHiresTimestamp,
1917 .special = NULL,
1918 .enum_list = NULL,
1919 .flags = FLAG_ADVANCED,
1922 .label = "debug pid",
1923 .type = P_BOOL,
1924 .p_class = P_GLOBAL,
1925 .ptr = &Globals.bDebugPid,
1926 .special = NULL,
1927 .enum_list = NULL,
1928 .flags = FLAG_ADVANCED,
1931 .label = "debug uid",
1932 .type = P_BOOL,
1933 .p_class = P_GLOBAL,
1934 .ptr = &Globals.bDebugUid,
1935 .special = NULL,
1936 .enum_list = NULL,
1937 .flags = FLAG_ADVANCED,
1940 .label = "debug class",
1941 .type = P_BOOL,
1942 .p_class = P_GLOBAL,
1943 .ptr = &Globals.bDebugClass,
1944 .special = NULL,
1945 .enum_list = NULL,
1946 .flags = FLAG_ADVANCED,
1949 .label = "enable core files",
1950 .type = P_BOOL,
1951 .p_class = P_GLOBAL,
1952 .ptr = &Globals.bEnableCoreFiles,
1953 .special = NULL,
1954 .enum_list = NULL,
1955 .flags = FLAG_ADVANCED,
1958 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1961 .label = "allocation roundup size",
1962 .type = P_INTEGER,
1963 .p_class = P_LOCAL,
1964 .ptr = &sDefault.iallocation_roundup_size,
1965 .special = NULL,
1966 .enum_list = NULL,
1967 .flags = FLAG_ADVANCED,
1970 .label = "aio read size",
1971 .type = P_INTEGER,
1972 .p_class = P_LOCAL,
1973 .ptr = &sDefault.iAioReadSize,
1974 .special = NULL,
1975 .enum_list = NULL,
1976 .flags = FLAG_ADVANCED,
1979 .label = "aio write size",
1980 .type = P_INTEGER,
1981 .p_class = P_LOCAL,
1982 .ptr = &sDefault.iAioWriteSize,
1983 .special = NULL,
1984 .enum_list = NULL,
1985 .flags = FLAG_ADVANCED,
1988 .label = "aio write behind",
1989 .type = P_STRING,
1990 .p_class = P_LOCAL,
1991 .ptr = &sDefault.szAioWriteBehind,
1992 .special = NULL,
1993 .enum_list = NULL,
1994 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1997 .label = "smb ports",
1998 .type = P_STRING,
1999 .p_class = P_GLOBAL,
2000 .ptr = &Globals.smb_ports,
2001 .special = NULL,
2002 .enum_list = NULL,
2003 .flags = FLAG_ADVANCED,
2006 .label = "large readwrite",
2007 .type = P_BOOL,
2008 .p_class = P_GLOBAL,
2009 .ptr = &Globals.bLargeReadwrite,
2010 .special = NULL,
2011 .enum_list = NULL,
2012 .flags = FLAG_ADVANCED,
2015 .label = "max protocol",
2016 .type = P_ENUM,
2017 .p_class = P_GLOBAL,
2018 .ptr = &Globals.maxprotocol,
2019 .special = NULL,
2020 .enum_list = enum_protocol,
2021 .flags = FLAG_ADVANCED,
2024 .label = "protocol",
2025 .type = P_ENUM,
2026 .p_class = P_GLOBAL,
2027 .ptr = &Globals.maxprotocol,
2028 .special = NULL,
2029 .enum_list = enum_protocol,
2030 .flags = FLAG_ADVANCED,
2033 .label = "min protocol",
2034 .type = P_ENUM,
2035 .p_class = P_GLOBAL,
2036 .ptr = &Globals.minprotocol,
2037 .special = NULL,
2038 .enum_list = enum_protocol,
2039 .flags = FLAG_ADVANCED,
2042 .label = "min receivefile size",
2043 .type = P_INTEGER,
2044 .p_class = P_GLOBAL,
2045 .ptr = &Globals.iminreceivefile,
2046 .special = NULL,
2047 .enum_list = NULL,
2048 .flags = FLAG_ADVANCED,
2051 .label = "read raw",
2052 .type = P_BOOL,
2053 .p_class = P_GLOBAL,
2054 .ptr = &Globals.bReadRaw,
2055 .special = NULL,
2056 .enum_list = NULL,
2057 .flags = FLAG_ADVANCED,
2060 .label = "write raw",
2061 .type = P_BOOL,
2062 .p_class = P_GLOBAL,
2063 .ptr = &Globals.bWriteRaw,
2064 .special = NULL,
2065 .enum_list = NULL,
2066 .flags = FLAG_ADVANCED,
2069 .label = "disable netbios",
2070 .type = P_BOOL,
2071 .p_class = P_GLOBAL,
2072 .ptr = &Globals.bDisableNetbios,
2073 .special = NULL,
2074 .enum_list = NULL,
2075 .flags = FLAG_ADVANCED,
2078 .label = "reset on zero vc",
2079 .type = P_BOOL,
2080 .p_class = P_GLOBAL,
2081 .ptr = &Globals.bResetOnZeroVC,
2082 .special = NULL,
2083 .enum_list = NULL,
2084 .flags = FLAG_ADVANCED,
2087 .label = "log writeable files on exit",
2088 .type = P_BOOL,
2089 .p_class = P_GLOBAL,
2090 .ptr = &Globals.bLogWriteableFilesOnExit,
2091 .special = NULL,
2092 .enum_list = NULL,
2093 .flags = FLAG_ADVANCED,
2096 .label = "acl compatibility",
2097 .type = P_ENUM,
2098 .p_class = P_GLOBAL,
2099 .ptr = &Globals.iAclCompat,
2100 .special = NULL,
2101 .enum_list = enum_acl_compat_vals,
2102 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2105 .label = "defer sharing violations",
2106 .type = P_BOOL,
2107 .p_class = P_GLOBAL,
2108 .ptr = &Globals.bDeferSharingViolations,
2109 .special = NULL,
2110 .enum_list = NULL,
2111 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2114 .label = "ea support",
2115 .type = P_BOOL,
2116 .p_class = P_LOCAL,
2117 .ptr = &sDefault.bEASupport,
2118 .special = NULL,
2119 .enum_list = NULL,
2120 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2123 .label = "nt acl support",
2124 .type = P_BOOL,
2125 .p_class = P_LOCAL,
2126 .ptr = &sDefault.bNTAclSupport,
2127 .special = NULL,
2128 .enum_list = NULL,
2129 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2132 .label = "nt pipe support",
2133 .type = P_BOOL,
2134 .p_class = P_GLOBAL,
2135 .ptr = &Globals.bNTPipeSupport,
2136 .special = NULL,
2137 .enum_list = NULL,
2138 .flags = FLAG_ADVANCED,
2141 .label = "nt status support",
2142 .type = P_BOOL,
2143 .p_class = P_GLOBAL,
2144 .ptr = &Globals.bNTStatusSupport,
2145 .special = NULL,
2146 .enum_list = NULL,
2147 .flags = FLAG_ADVANCED,
2150 .label = "profile acls",
2151 .type = P_BOOL,
2152 .p_class = P_LOCAL,
2153 .ptr = &sDefault.bProfileAcls,
2154 .special = NULL,
2155 .enum_list = NULL,
2156 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2159 .label = "announce version",
2160 .type = P_STRING,
2161 .p_class = P_GLOBAL,
2162 .ptr = &Globals.szAnnounceVersion,
2163 .special = NULL,
2164 .enum_list = NULL,
2165 .flags = FLAG_ADVANCED,
2168 .label = "announce as",
2169 .type = P_ENUM,
2170 .p_class = P_GLOBAL,
2171 .ptr = &Globals.announce_as,
2172 .special = NULL,
2173 .enum_list = enum_announce_as,
2174 .flags = FLAG_ADVANCED,
2177 .label = "map acl inherit",
2178 .type = P_BOOL,
2179 .p_class = P_LOCAL,
2180 .ptr = &sDefault.bMap_acl_inherit,
2181 .special = NULL,
2182 .enum_list = NULL,
2183 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2186 .label = "afs share",
2187 .type = P_BOOL,
2188 .p_class = P_LOCAL,
2189 .ptr = &sDefault.bAfs_Share,
2190 .special = NULL,
2191 .enum_list = NULL,
2192 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2195 .label = "max mux",
2196 .type = P_INTEGER,
2197 .p_class = P_GLOBAL,
2198 .ptr = &Globals.max_mux,
2199 .special = NULL,
2200 .enum_list = NULL,
2201 .flags = FLAG_ADVANCED,
2204 .label = "max xmit",
2205 .type = P_INTEGER,
2206 .p_class = P_GLOBAL,
2207 .ptr = &Globals.max_xmit,
2208 .special = NULL,
2209 .enum_list = NULL,
2210 .flags = FLAG_ADVANCED,
2213 .label = "name resolve order",
2214 .type = P_STRING,
2215 .p_class = P_GLOBAL,
2216 .ptr = &Globals.szNameResolveOrder,
2217 .special = NULL,
2218 .enum_list = NULL,
2219 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2222 .label = "max ttl",
2223 .type = P_INTEGER,
2224 .p_class = P_GLOBAL,
2225 .ptr = &Globals.max_ttl,
2226 .special = NULL,
2227 .enum_list = NULL,
2228 .flags = FLAG_ADVANCED,
2231 .label = "max wins ttl",
2232 .type = P_INTEGER,
2233 .p_class = P_GLOBAL,
2234 .ptr = &Globals.max_wins_ttl,
2235 .special = NULL,
2236 .enum_list = NULL,
2237 .flags = FLAG_ADVANCED,
2240 .label = "min wins ttl",
2241 .type = P_INTEGER,
2242 .p_class = P_GLOBAL,
2243 .ptr = &Globals.min_wins_ttl,
2244 .special = NULL,
2245 .enum_list = NULL,
2246 .flags = FLAG_ADVANCED,
2249 .label = "time server",
2250 .type = P_BOOL,
2251 .p_class = P_GLOBAL,
2252 .ptr = &Globals.bTimeServer,
2253 .special = NULL,
2254 .enum_list = NULL,
2255 .flags = FLAG_ADVANCED,
2258 .label = "unix extensions",
2259 .type = P_BOOL,
2260 .p_class = P_GLOBAL,
2261 .ptr = &Globals.bUnixExtensions,
2262 .special = NULL,
2263 .enum_list = NULL,
2264 .flags = FLAG_ADVANCED,
2267 .label = "use spnego",
2268 .type = P_BOOL,
2269 .p_class = P_GLOBAL,
2270 .ptr = &Globals.bUseSpnego,
2271 .special = NULL,
2272 .enum_list = NULL,
2273 .flags = FLAG_ADVANCED,
2276 .label = "client signing",
2277 .type = P_ENUM,
2278 .p_class = P_GLOBAL,
2279 .ptr = &Globals.client_signing,
2280 .special = NULL,
2281 .enum_list = enum_smb_signing_vals,
2282 .flags = FLAG_ADVANCED,
2285 .label = "server signing",
2286 .type = P_ENUM,
2287 .p_class = P_GLOBAL,
2288 .ptr = &Globals.server_signing,
2289 .special = NULL,
2290 .enum_list = enum_smb_signing_vals,
2291 .flags = FLAG_ADVANCED,
2294 .label = "smb encrypt",
2295 .type = P_ENUM,
2296 .p_class = P_LOCAL,
2297 .ptr = &sDefault.ismb_encrypt,
2298 .special = NULL,
2299 .enum_list = enum_smb_signing_vals,
2300 .flags = FLAG_ADVANCED,
2303 .label = "client use spnego",
2304 .type = P_BOOL,
2305 .p_class = P_GLOBAL,
2306 .ptr = &Globals.bClientUseSpnego,
2307 .special = NULL,
2308 .enum_list = NULL,
2309 .flags = FLAG_ADVANCED,
2312 .label = "client ldap sasl wrapping",
2313 .type = P_ENUM,
2314 .p_class = P_GLOBAL,
2315 .ptr = &Globals.client_ldap_sasl_wrapping,
2316 .special = NULL,
2317 .enum_list = enum_ldap_sasl_wrapping,
2318 .flags = FLAG_ADVANCED,
2321 .label = "enable asu support",
2322 .type = P_BOOL,
2323 .p_class = P_GLOBAL,
2324 .ptr = &Globals.bASUSupport,
2325 .special = NULL,
2326 .enum_list = NULL,
2327 .flags = FLAG_ADVANCED,
2330 .label = "svcctl list",
2331 .type = P_LIST,
2332 .p_class = P_GLOBAL,
2333 .ptr = &Globals.szServicesList,
2334 .special = NULL,
2335 .enum_list = NULL,
2336 .flags = FLAG_ADVANCED,
2339 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2342 .label = "block size",
2343 .type = P_INTEGER,
2344 .p_class = P_LOCAL,
2345 .ptr = &sDefault.iBlock_size,
2346 .special = NULL,
2347 .enum_list = NULL,
2348 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2351 .label = "deadtime",
2352 .type = P_INTEGER,
2353 .p_class = P_GLOBAL,
2354 .ptr = &Globals.deadtime,
2355 .special = NULL,
2356 .enum_list = NULL,
2357 .flags = FLAG_ADVANCED,
2360 .label = "getwd cache",
2361 .type = P_BOOL,
2362 .p_class = P_GLOBAL,
2363 .ptr = &Globals.getwd_cache,
2364 .special = NULL,
2365 .enum_list = NULL,
2366 .flags = FLAG_ADVANCED,
2369 .label = "keepalive",
2370 .type = P_INTEGER,
2371 .p_class = P_GLOBAL,
2372 .ptr = &Globals.iKeepalive,
2373 .special = NULL,
2374 .enum_list = NULL,
2375 .flags = FLAG_ADVANCED,
2378 .label = "change notify",
2379 .type = P_BOOL,
2380 .p_class = P_LOCAL,
2381 .ptr = &sDefault.bChangeNotify,
2382 .special = NULL,
2383 .enum_list = NULL,
2384 .flags = FLAG_ADVANCED | FLAG_SHARE,
2387 .label = "directory name cache size",
2388 .type = P_INTEGER,
2389 .p_class = P_LOCAL,
2390 .ptr = &sDefault.iDirectoryNameCacheSize,
2391 .special = NULL,
2392 .enum_list = NULL,
2393 .flags = FLAG_ADVANCED | FLAG_SHARE,
2396 .label = "kernel change notify",
2397 .type = P_BOOL,
2398 .p_class = P_LOCAL,
2399 .ptr = &sDefault.bKernelChangeNotify,
2400 .special = NULL,
2401 .enum_list = NULL,
2402 .flags = FLAG_ADVANCED | FLAG_SHARE,
2405 .label = "lpq cache time",
2406 .type = P_INTEGER,
2407 .p_class = P_GLOBAL,
2408 .ptr = &Globals.lpqcachetime,
2409 .special = NULL,
2410 .enum_list = NULL,
2411 .flags = FLAG_ADVANCED,
2414 .label = "max smbd processes",
2415 .type = P_INTEGER,
2416 .p_class = P_GLOBAL,
2417 .ptr = &Globals.iMaxSmbdProcesses,
2418 .special = NULL,
2419 .enum_list = NULL,
2420 .flags = FLAG_ADVANCED,
2423 .label = "max connections",
2424 .type = P_INTEGER,
2425 .p_class = P_LOCAL,
2426 .ptr = &sDefault.iMaxConnections,
2427 .special = NULL,
2428 .enum_list = NULL,
2429 .flags = FLAG_ADVANCED | FLAG_SHARE,
2432 .label = "paranoid server security",
2433 .type = P_BOOL,
2434 .p_class = P_GLOBAL,
2435 .ptr = &Globals.paranoid_server_security,
2436 .special = NULL,
2437 .enum_list = NULL,
2438 .flags = FLAG_ADVANCED,
2441 .label = "max disk size",
2442 .type = P_INTEGER,
2443 .p_class = P_GLOBAL,
2444 .ptr = &Globals.maxdisksize,
2445 .special = NULL,
2446 .enum_list = NULL,
2447 .flags = FLAG_ADVANCED,
2450 .label = "max open files",
2451 .type = P_INTEGER,
2452 .p_class = P_GLOBAL,
2453 .ptr = &Globals.max_open_files,
2454 .special = NULL,
2455 .enum_list = NULL,
2456 .flags = FLAG_ADVANCED,
2459 .label = "min print space",
2460 .type = P_INTEGER,
2461 .p_class = P_LOCAL,
2462 .ptr = &sDefault.iMinPrintSpace,
2463 .special = NULL,
2464 .enum_list = NULL,
2465 .flags = FLAG_ADVANCED | FLAG_PRINT,
2468 .label = "socket options",
2469 .type = P_STRING,
2470 .p_class = P_GLOBAL,
2471 .ptr = &Globals.szSocketOptions,
2472 .special = NULL,
2473 .enum_list = NULL,
2474 .flags = FLAG_ADVANCED,
2477 .label = "strict allocate",
2478 .type = P_BOOL,
2479 .p_class = P_LOCAL,
2480 .ptr = &sDefault.bStrictAllocate,
2481 .special = NULL,
2482 .enum_list = NULL,
2483 .flags = FLAG_ADVANCED | FLAG_SHARE,
2486 .label = "strict sync",
2487 .type = P_BOOL,
2488 .p_class = P_LOCAL,
2489 .ptr = &sDefault.bStrictSync,
2490 .special = NULL,
2491 .enum_list = NULL,
2492 .flags = FLAG_ADVANCED | FLAG_SHARE,
2495 .label = "sync always",
2496 .type = P_BOOL,
2497 .p_class = P_LOCAL,
2498 .ptr = &sDefault.bSyncAlways,
2499 .special = NULL,
2500 .enum_list = NULL,
2501 .flags = FLAG_ADVANCED | FLAG_SHARE,
2504 .label = "use mmap",
2505 .type = P_BOOL,
2506 .p_class = P_GLOBAL,
2507 .ptr = &Globals.bUseMmap,
2508 .special = NULL,
2509 .enum_list = NULL,
2510 .flags = FLAG_ADVANCED,
2513 .label = "use sendfile",
2514 .type = P_BOOL,
2515 .p_class = P_LOCAL,
2516 .ptr = &sDefault.bUseSendfile,
2517 .special = NULL,
2518 .enum_list = NULL,
2519 .flags = FLAG_ADVANCED | FLAG_SHARE,
2522 .label = "hostname lookups",
2523 .type = P_BOOL,
2524 .p_class = P_GLOBAL,
2525 .ptr = &Globals.bHostnameLookups,
2526 .special = NULL,
2527 .enum_list = NULL,
2528 .flags = FLAG_ADVANCED,
2531 .label = "write cache size",
2532 .type = P_INTEGER,
2533 .p_class = P_LOCAL,
2534 .ptr = &sDefault.iWriteCacheSize,
2535 .special = NULL,
2536 .enum_list = NULL,
2537 .flags = FLAG_ADVANCED | FLAG_SHARE,
2540 .label = "name cache timeout",
2541 .type = P_INTEGER,
2542 .p_class = P_GLOBAL,
2543 .ptr = &Globals.name_cache_timeout,
2544 .special = NULL,
2545 .enum_list = NULL,
2546 .flags = FLAG_ADVANCED,
2549 .label = "ctdbd socket",
2550 .type = P_STRING,
2551 .p_class = P_GLOBAL,
2552 .ptr = &Globals.ctdbdSocket,
2553 .special = NULL,
2554 .enum_list = NULL,
2555 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2558 .label = "cluster addresses",
2559 .type = P_LIST,
2560 .p_class = P_GLOBAL,
2561 .ptr = &Globals.szClusterAddresses,
2562 .special = NULL,
2563 .enum_list = NULL,
2564 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2567 .label = "clustering",
2568 .type = P_BOOL,
2569 .p_class = P_GLOBAL,
2570 .ptr = &Globals.clustering,
2571 .special = NULL,
2572 .enum_list = NULL,
2573 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2576 .label = "ctdb timeout",
2577 .type = P_INTEGER,
2578 .p_class = P_GLOBAL,
2579 .ptr = &Globals.ctdb_timeout,
2580 .special = NULL,
2581 .enum_list = NULL,
2582 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2585 .label = "ctdb locktime warn threshold",
2586 .type = P_INTEGER,
2587 .p_class = P_GLOBAL,
2588 .ptr = &Globals.ctdb_locktime_warn_threshold,
2589 .special = NULL,
2590 .enum_list = NULL,
2591 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2594 .label = "smb2 max read",
2595 .type = P_INTEGER,
2596 .p_class = P_GLOBAL,
2597 .ptr = &Globals.ismb2_max_read,
2598 .special = NULL,
2599 .enum_list = NULL,
2600 .flags = FLAG_ADVANCED,
2603 .label = "smb2 max write",
2604 .type = P_INTEGER,
2605 .p_class = P_GLOBAL,
2606 .ptr = &Globals.ismb2_max_write,
2607 .special = NULL,
2608 .enum_list = NULL,
2609 .flags = FLAG_ADVANCED,
2612 .label = "smb2 max trans",
2613 .type = P_INTEGER,
2614 .p_class = P_GLOBAL,
2615 .ptr = &Globals.ismb2_max_trans,
2616 .special = NULL,
2617 .enum_list = NULL,
2618 .flags = FLAG_ADVANCED,
2621 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2624 .label = "max reported print jobs",
2625 .type = P_INTEGER,
2626 .p_class = P_LOCAL,
2627 .ptr = &sDefault.iMaxReportedPrintJobs,
2628 .special = NULL,
2629 .enum_list = NULL,
2630 .flags = FLAG_ADVANCED | FLAG_PRINT,
2633 .label = "max print jobs",
2634 .type = P_INTEGER,
2635 .p_class = P_LOCAL,
2636 .ptr = &sDefault.iMaxPrintJobs,
2637 .special = NULL,
2638 .enum_list = NULL,
2639 .flags = FLAG_ADVANCED | FLAG_PRINT,
2642 .label = "load printers",
2643 .type = P_BOOL,
2644 .p_class = P_GLOBAL,
2645 .ptr = &Globals.bLoadPrinters,
2646 .special = NULL,
2647 .enum_list = NULL,
2648 .flags = FLAG_ADVANCED | FLAG_PRINT,
2651 .label = "printcap cache time",
2652 .type = P_INTEGER,
2653 .p_class = P_GLOBAL,
2654 .ptr = &Globals.PrintcapCacheTime,
2655 .special = NULL,
2656 .enum_list = NULL,
2657 .flags = FLAG_ADVANCED | FLAG_PRINT,
2660 .label = "printcap name",
2661 .type = P_STRING,
2662 .p_class = P_GLOBAL,
2663 .ptr = &Globals.szPrintcapname,
2664 .special = NULL,
2665 .enum_list = NULL,
2666 .flags = FLAG_ADVANCED | FLAG_PRINT,
2669 .label = "printcap",
2670 .type = P_STRING,
2671 .p_class = P_GLOBAL,
2672 .ptr = &Globals.szPrintcapname,
2673 .special = NULL,
2674 .enum_list = NULL,
2675 .flags = FLAG_HIDE,
2678 .label = "printable",
2679 .type = P_BOOL,
2680 .p_class = P_LOCAL,
2681 .ptr = &sDefault.bPrint_ok,
2682 .special = NULL,
2683 .enum_list = NULL,
2684 .flags = FLAG_ADVANCED | FLAG_PRINT,
2687 .label = "print ok",
2688 .type = P_BOOL,
2689 .p_class = P_LOCAL,
2690 .ptr = &sDefault.bPrint_ok,
2691 .special = NULL,
2692 .enum_list = NULL,
2693 .flags = FLAG_HIDE,
2696 .label = "printing",
2697 .type = P_ENUM,
2698 .p_class = P_LOCAL,
2699 .ptr = &sDefault.iPrinting,
2700 .special = handle_printing,
2701 .enum_list = enum_printing,
2702 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2705 .label = "cups options",
2706 .type = P_STRING,
2707 .p_class = P_LOCAL,
2708 .ptr = &sDefault.szCupsOptions,
2709 .special = NULL,
2710 .enum_list = NULL,
2711 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2714 .label = "cups server",
2715 .type = P_STRING,
2716 .p_class = P_GLOBAL,
2717 .ptr = &Globals.szCupsServer,
2718 .special = NULL,
2719 .enum_list = NULL,
2720 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2723 .label = "cups encrypt",
2724 .type = P_ENUM,
2725 .p_class = P_GLOBAL,
2726 .ptr = &Globals.CupsEncrypt,
2727 .special = NULL,
2728 .enum_list = enum_bool_auto,
2729 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2733 .label = "cups connection timeout",
2734 .type = P_INTEGER,
2735 .p_class = P_GLOBAL,
2736 .ptr = &Globals.cups_connection_timeout,
2737 .special = NULL,
2738 .enum_list = NULL,
2739 .flags = FLAG_ADVANCED,
2742 .label = "iprint server",
2743 .type = P_STRING,
2744 .p_class = P_GLOBAL,
2745 .ptr = &Globals.szIPrintServer,
2746 .special = NULL,
2747 .enum_list = NULL,
2748 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2751 .label = "print command",
2752 .type = P_STRING,
2753 .p_class = P_LOCAL,
2754 .ptr = &sDefault.szPrintcommand,
2755 .special = NULL,
2756 .enum_list = NULL,
2757 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2760 .label = "disable spoolss",
2761 .type = P_BOOL,
2762 .p_class = P_GLOBAL,
2763 .ptr = &Globals.bDisableSpoolss,
2764 .special = NULL,
2765 .enum_list = NULL,
2766 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2769 .label = "enable spoolss",
2770 .type = P_BOOLREV,
2771 .p_class = P_GLOBAL,
2772 .ptr = &Globals.bDisableSpoolss,
2773 .special = NULL,
2774 .enum_list = NULL,
2775 .flags = FLAG_HIDE,
2778 .label = "lpq command",
2779 .type = P_STRING,
2780 .p_class = P_LOCAL,
2781 .ptr = &sDefault.szLpqcommand,
2782 .special = NULL,
2783 .enum_list = NULL,
2784 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2787 .label = "lprm command",
2788 .type = P_STRING,
2789 .p_class = P_LOCAL,
2790 .ptr = &sDefault.szLprmcommand,
2791 .special = NULL,
2792 .enum_list = NULL,
2793 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2796 .label = "lppause command",
2797 .type = P_STRING,
2798 .p_class = P_LOCAL,
2799 .ptr = &sDefault.szLppausecommand,
2800 .special = NULL,
2801 .enum_list = NULL,
2802 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2805 .label = "lpresume command",
2806 .type = P_STRING,
2807 .p_class = P_LOCAL,
2808 .ptr = &sDefault.szLpresumecommand,
2809 .special = NULL,
2810 .enum_list = NULL,
2811 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2814 .label = "queuepause command",
2815 .type = P_STRING,
2816 .p_class = P_LOCAL,
2817 .ptr = &sDefault.szQueuepausecommand,
2818 .special = NULL,
2819 .enum_list = NULL,
2820 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2823 .label = "queueresume command",
2824 .type = P_STRING,
2825 .p_class = P_LOCAL,
2826 .ptr = &sDefault.szQueueresumecommand,
2827 .special = NULL,
2828 .enum_list = NULL,
2829 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2832 .label = "addport command",
2833 .type = P_STRING,
2834 .p_class = P_GLOBAL,
2835 .ptr = &Globals.szAddPortCommand,
2836 .special = NULL,
2837 .enum_list = NULL,
2838 .flags = FLAG_ADVANCED,
2841 .label = "enumports command",
2842 .type = P_STRING,
2843 .p_class = P_GLOBAL,
2844 .ptr = &Globals.szEnumPortsCommand,
2845 .special = NULL,
2846 .enum_list = NULL,
2847 .flags = FLAG_ADVANCED,
2850 .label = "addprinter command",
2851 .type = P_STRING,
2852 .p_class = P_GLOBAL,
2853 .ptr = &Globals.szAddPrinterCommand,
2854 .special = NULL,
2855 .enum_list = NULL,
2856 .flags = FLAG_ADVANCED,
2859 .label = "deleteprinter command",
2860 .type = P_STRING,
2861 .p_class = P_GLOBAL,
2862 .ptr = &Globals.szDeletePrinterCommand,
2863 .special = NULL,
2864 .enum_list = NULL,
2865 .flags = FLAG_ADVANCED,
2868 .label = "show add printer wizard",
2869 .type = P_BOOL,
2870 .p_class = P_GLOBAL,
2871 .ptr = &Globals.bMsAddPrinterWizard,
2872 .special = NULL,
2873 .enum_list = NULL,
2874 .flags = FLAG_ADVANCED,
2877 .label = "os2 driver map",
2878 .type = P_STRING,
2879 .p_class = P_GLOBAL,
2880 .ptr = &Globals.szOs2DriverMap,
2881 .special = NULL,
2882 .enum_list = NULL,
2883 .flags = FLAG_ADVANCED,
2887 .label = "printer name",
2888 .type = P_STRING,
2889 .p_class = P_LOCAL,
2890 .ptr = &sDefault.szPrintername,
2891 .special = NULL,
2892 .enum_list = NULL,
2893 .flags = FLAG_ADVANCED | FLAG_PRINT,
2896 .label = "printer",
2897 .type = P_STRING,
2898 .p_class = P_LOCAL,
2899 .ptr = &sDefault.szPrintername,
2900 .special = NULL,
2901 .enum_list = NULL,
2902 .flags = FLAG_HIDE,
2905 .label = "use client driver",
2906 .type = P_BOOL,
2907 .p_class = P_LOCAL,
2908 .ptr = &sDefault.bUseClientDriver,
2909 .special = NULL,
2910 .enum_list = NULL,
2911 .flags = FLAG_ADVANCED | FLAG_PRINT,
2914 .label = "default devmode",
2915 .type = P_BOOL,
2916 .p_class = P_LOCAL,
2917 .ptr = &sDefault.bDefaultDevmode,
2918 .special = NULL,
2919 .enum_list = NULL,
2920 .flags = FLAG_ADVANCED | FLAG_PRINT,
2923 .label = "force printername",
2924 .type = P_BOOL,
2925 .p_class = P_LOCAL,
2926 .ptr = &sDefault.bForcePrintername,
2927 .special = NULL,
2928 .enum_list = NULL,
2929 .flags = FLAG_ADVANCED | FLAG_PRINT,
2932 .label = "printjob username",
2933 .type = P_STRING,
2934 .p_class = P_LOCAL,
2935 .ptr = &sDefault.szPrintjobUsername,
2936 .special = NULL,
2937 .enum_list = NULL,
2938 .flags = FLAG_ADVANCED | FLAG_PRINT,
2941 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2944 .label = "mangling method",
2945 .type = P_STRING,
2946 .p_class = P_GLOBAL,
2947 .ptr = &Globals.szManglingMethod,
2948 .special = NULL,
2949 .enum_list = NULL,
2950 .flags = FLAG_ADVANCED,
2953 .label = "mangle prefix",
2954 .type = P_INTEGER,
2955 .p_class = P_GLOBAL,
2956 .ptr = &Globals.mangle_prefix,
2957 .special = NULL,
2958 .enum_list = NULL,
2959 .flags = FLAG_ADVANCED,
2963 .label = "default case",
2964 .type = P_ENUM,
2965 .p_class = P_LOCAL,
2966 .ptr = &sDefault.iDefaultCase,
2967 .special = NULL,
2968 .enum_list = enum_case,
2969 .flags = FLAG_ADVANCED | FLAG_SHARE,
2972 .label = "case sensitive",
2973 .type = P_ENUM,
2974 .p_class = P_LOCAL,
2975 .ptr = &sDefault.iCaseSensitive,
2976 .special = NULL,
2977 .enum_list = enum_bool_auto,
2978 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2981 .label = "casesignames",
2982 .type = P_ENUM,
2983 .p_class = P_LOCAL,
2984 .ptr = &sDefault.iCaseSensitive,
2985 .special = NULL,
2986 .enum_list = enum_bool_auto,
2987 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2990 .label = "preserve case",
2991 .type = P_BOOL,
2992 .p_class = P_LOCAL,
2993 .ptr = &sDefault.bCasePreserve,
2994 .special = NULL,
2995 .enum_list = NULL,
2996 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2999 .label = "short preserve case",
3000 .type = P_BOOL,
3001 .p_class = P_LOCAL,
3002 .ptr = &sDefault.bShortCasePreserve,
3003 .special = NULL,
3004 .enum_list = NULL,
3005 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3008 .label = "mangling char",
3009 .type = P_CHAR,
3010 .p_class = P_LOCAL,
3011 .ptr = &sDefault.magic_char,
3012 .special = NULL,
3013 .enum_list = NULL,
3014 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3017 .label = "hide dot files",
3018 .type = P_BOOL,
3019 .p_class = P_LOCAL,
3020 .ptr = &sDefault.bHideDotFiles,
3021 .special = NULL,
3022 .enum_list = NULL,
3023 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3026 .label = "hide special files",
3027 .type = P_BOOL,
3028 .p_class = P_LOCAL,
3029 .ptr = &sDefault.bHideSpecialFiles,
3030 .special = NULL,
3031 .enum_list = NULL,
3032 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3035 .label = "hide unreadable",
3036 .type = P_BOOL,
3037 .p_class = P_LOCAL,
3038 .ptr = &sDefault.bHideUnReadable,
3039 .special = NULL,
3040 .enum_list = NULL,
3041 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3044 .label = "hide unwriteable files",
3045 .type = P_BOOL,
3046 .p_class = P_LOCAL,
3047 .ptr = &sDefault.bHideUnWriteableFiles,
3048 .special = NULL,
3049 .enum_list = NULL,
3050 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3053 .label = "delete veto files",
3054 .type = P_BOOL,
3055 .p_class = P_LOCAL,
3056 .ptr = &sDefault.bDeleteVetoFiles,
3057 .special = NULL,
3058 .enum_list = NULL,
3059 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3062 .label = "veto files",
3063 .type = P_STRING,
3064 .p_class = P_LOCAL,
3065 .ptr = &sDefault.szVetoFiles,
3066 .special = NULL,
3067 .enum_list = NULL,
3068 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3071 .label = "hide files",
3072 .type = P_STRING,
3073 .p_class = P_LOCAL,
3074 .ptr = &sDefault.szHideFiles,
3075 .special = NULL,
3076 .enum_list = NULL,
3077 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3080 .label = "veto oplock files",
3081 .type = P_STRING,
3082 .p_class = P_LOCAL,
3083 .ptr = &sDefault.szVetoOplockFiles,
3084 .special = NULL,
3085 .enum_list = NULL,
3086 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3089 .label = "map archive",
3090 .type = P_BOOL,
3091 .p_class = P_LOCAL,
3092 .ptr = &sDefault.bMap_archive,
3093 .special = NULL,
3094 .enum_list = NULL,
3095 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3098 .label = "map hidden",
3099 .type = P_BOOL,
3100 .p_class = P_LOCAL,
3101 .ptr = &sDefault.bMap_hidden,
3102 .special = NULL,
3103 .enum_list = NULL,
3104 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3107 .label = "map system",
3108 .type = P_BOOL,
3109 .p_class = P_LOCAL,
3110 .ptr = &sDefault.bMap_system,
3111 .special = NULL,
3112 .enum_list = NULL,
3113 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3116 .label = "map readonly",
3117 .type = P_ENUM,
3118 .p_class = P_LOCAL,
3119 .ptr = &sDefault.iMap_readonly,
3120 .special = NULL,
3121 .enum_list = enum_map_readonly,
3122 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3125 .label = "mangled names",
3126 .type = P_BOOL,
3127 .p_class = P_LOCAL,
3128 .ptr = &sDefault.bMangledNames,
3129 .special = NULL,
3130 .enum_list = NULL,
3131 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3134 .label = "max stat cache size",
3135 .type = P_INTEGER,
3136 .p_class = P_GLOBAL,
3137 .ptr = &Globals.iMaxStatCacheSize,
3138 .special = NULL,
3139 .enum_list = NULL,
3140 .flags = FLAG_ADVANCED,
3143 .label = "stat cache",
3144 .type = P_BOOL,
3145 .p_class = P_GLOBAL,
3146 .ptr = &Globals.bStatCache,
3147 .special = NULL,
3148 .enum_list = NULL,
3149 .flags = FLAG_ADVANCED,
3152 .label = "store dos attributes",
3153 .type = P_BOOL,
3154 .p_class = P_LOCAL,
3155 .ptr = &sDefault.bStoreDosAttributes,
3156 .special = NULL,
3157 .enum_list = NULL,
3158 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3161 .label = "dmapi support",
3162 .type = P_BOOL,
3163 .p_class = P_LOCAL,
3164 .ptr = &sDefault.bDmapiSupport,
3165 .special = NULL,
3166 .enum_list = NULL,
3167 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3171 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3174 .label = "machine password timeout",
3175 .type = P_INTEGER,
3176 .p_class = P_GLOBAL,
3177 .ptr = &Globals.machine_password_timeout,
3178 .special = NULL,
3179 .enum_list = NULL,
3180 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3183 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3186 .label = "add user script",
3187 .type = P_STRING,
3188 .p_class = P_GLOBAL,
3189 .ptr = &Globals.szAddUserScript,
3190 .special = NULL,
3191 .enum_list = NULL,
3192 .flags = FLAG_ADVANCED,
3195 .label = "rename user script",
3196 .type = P_STRING,
3197 .p_class = P_GLOBAL,
3198 .ptr = &Globals.szRenameUserScript,
3199 .special = NULL,
3200 .enum_list = NULL,
3201 .flags = FLAG_ADVANCED,
3204 .label = "delete user script",
3205 .type = P_STRING,
3206 .p_class = P_GLOBAL,
3207 .ptr = &Globals.szDelUserScript,
3208 .special = NULL,
3209 .enum_list = NULL,
3210 .flags = FLAG_ADVANCED,
3213 .label = "add group script",
3214 .type = P_STRING,
3215 .p_class = P_GLOBAL,
3216 .ptr = &Globals.szAddGroupScript,
3217 .special = NULL,
3218 .enum_list = NULL,
3219 .flags = FLAG_ADVANCED,
3222 .label = "delete group script",
3223 .type = P_STRING,
3224 .p_class = P_GLOBAL,
3225 .ptr = &Globals.szDelGroupScript,
3226 .special = NULL,
3227 .enum_list = NULL,
3228 .flags = FLAG_ADVANCED,
3231 .label = "add user to group script",
3232 .type = P_STRING,
3233 .p_class = P_GLOBAL,
3234 .ptr = &Globals.szAddUserToGroupScript,
3235 .special = NULL,
3236 .enum_list = NULL,
3237 .flags = FLAG_ADVANCED,
3240 .label = "delete user from group script",
3241 .type = P_STRING,
3242 .p_class = P_GLOBAL,
3243 .ptr = &Globals.szDelUserFromGroupScript,
3244 .special = NULL,
3245 .enum_list = NULL,
3246 .flags = FLAG_ADVANCED,
3249 .label = "set primary group script",
3250 .type = P_STRING,
3251 .p_class = P_GLOBAL,
3252 .ptr = &Globals.szSetPrimaryGroupScript,
3253 .special = NULL,
3254 .enum_list = NULL,
3255 .flags = FLAG_ADVANCED,
3258 .label = "add machine script",
3259 .type = P_STRING,
3260 .p_class = P_GLOBAL,
3261 .ptr = &Globals.szAddMachineScript,
3262 .special = NULL,
3263 .enum_list = NULL,
3264 .flags = FLAG_ADVANCED,
3267 .label = "shutdown script",
3268 .type = P_STRING,
3269 .p_class = P_GLOBAL,
3270 .ptr = &Globals.szShutdownScript,
3271 .special = NULL,
3272 .enum_list = NULL,
3273 .flags = FLAG_ADVANCED,
3276 .label = "abort shutdown script",
3277 .type = P_STRING,
3278 .p_class = P_GLOBAL,
3279 .ptr = &Globals.szAbortShutdownScript,
3280 .special = NULL,
3281 .enum_list = NULL,
3282 .flags = FLAG_ADVANCED,
3285 .label = "username map script",
3286 .type = P_STRING,
3287 .p_class = P_GLOBAL,
3288 .ptr = &Globals.szUsernameMapScript,
3289 .special = NULL,
3290 .enum_list = NULL,
3291 .flags = FLAG_ADVANCED,
3294 .label = "logon script",
3295 .type = P_STRING,
3296 .p_class = P_GLOBAL,
3297 .ptr = &Globals.szLogonScript,
3298 .special = NULL,
3299 .enum_list = NULL,
3300 .flags = FLAG_ADVANCED,
3303 .label = "logon path",
3304 .type = P_STRING,
3305 .p_class = P_GLOBAL,
3306 .ptr = &Globals.szLogonPath,
3307 .special = NULL,
3308 .enum_list = NULL,
3309 .flags = FLAG_ADVANCED,
3312 .label = "logon drive",
3313 .type = P_STRING,
3314 .p_class = P_GLOBAL,
3315 .ptr = &Globals.szLogonDrive,
3316 .special = NULL,
3317 .enum_list = NULL,
3318 .flags = FLAG_ADVANCED,
3321 .label = "logon home",
3322 .type = P_STRING,
3323 .p_class = P_GLOBAL,
3324 .ptr = &Globals.szLogonHome,
3325 .special = NULL,
3326 .enum_list = NULL,
3327 .flags = FLAG_ADVANCED,
3330 .label = "domain logons",
3331 .type = P_BOOL,
3332 .p_class = P_GLOBAL,
3333 .ptr = &Globals.bDomainLogons,
3334 .special = NULL,
3335 .enum_list = NULL,
3336 .flags = FLAG_ADVANCED,
3340 .label = "init logon delayed hosts",
3341 .type = P_LIST,
3342 .p_class = P_GLOBAL,
3343 .ptr = &Globals.szInitLogonDelayedHosts,
3344 .special = NULL,
3345 .enum_list = NULL,
3346 .flags = FLAG_ADVANCED,
3350 .label = "init logon delay",
3351 .type = P_INTEGER,
3352 .p_class = P_GLOBAL,
3353 .ptr = &Globals.InitLogonDelay,
3354 .special = NULL,
3355 .enum_list = NULL,
3356 .flags = FLAG_ADVANCED,
3360 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3363 .label = "os level",
3364 .type = P_INTEGER,
3365 .p_class = P_GLOBAL,
3366 .ptr = &Globals.os_level,
3367 .special = NULL,
3368 .enum_list = NULL,
3369 .flags = FLAG_BASIC | FLAG_ADVANCED,
3372 .label = "lm announce",
3373 .type = P_ENUM,
3374 .p_class = P_GLOBAL,
3375 .ptr = &Globals.lm_announce,
3376 .special = NULL,
3377 .enum_list = enum_bool_auto,
3378 .flags = FLAG_ADVANCED,
3381 .label = "lm interval",
3382 .type = P_INTEGER,
3383 .p_class = P_GLOBAL,
3384 .ptr = &Globals.lm_interval,
3385 .special = NULL,
3386 .enum_list = NULL,
3387 .flags = FLAG_ADVANCED,
3390 .label = "preferred master",
3391 .type = P_ENUM,
3392 .p_class = P_GLOBAL,
3393 .ptr = &Globals.iPreferredMaster,
3394 .special = NULL,
3395 .enum_list = enum_bool_auto,
3396 .flags = FLAG_BASIC | FLAG_ADVANCED,
3399 .label = "prefered master",
3400 .type = P_ENUM,
3401 .p_class = P_GLOBAL,
3402 .ptr = &Globals.iPreferredMaster,
3403 .special = NULL,
3404 .enum_list = enum_bool_auto,
3405 .flags = FLAG_HIDE,
3408 .label = "local master",
3409 .type = P_BOOL,
3410 .p_class = P_GLOBAL,
3411 .ptr = &Globals.bLocalMaster,
3412 .special = NULL,
3413 .enum_list = NULL,
3414 .flags = FLAG_BASIC | FLAG_ADVANCED,
3417 .label = "domain master",
3418 .type = P_ENUM,
3419 .p_class = P_GLOBAL,
3420 .ptr = &Globals.iDomainMaster,
3421 .special = NULL,
3422 .enum_list = enum_bool_auto,
3423 .flags = FLAG_BASIC | FLAG_ADVANCED,
3426 .label = "browse list",
3427 .type = P_BOOL,
3428 .p_class = P_GLOBAL,
3429 .ptr = &Globals.bBrowseList,
3430 .special = NULL,
3431 .enum_list = NULL,
3432 .flags = FLAG_ADVANCED,
3435 .label = "browseable",
3436 .type = P_BOOL,
3437 .p_class = P_LOCAL,
3438 .ptr = &sDefault.bBrowseable,
3439 .special = NULL,
3440 .enum_list = NULL,
3441 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3444 .label = "browsable",
3445 .type = P_BOOL,
3446 .p_class = P_LOCAL,
3447 .ptr = &sDefault.bBrowseable,
3448 .special = NULL,
3449 .enum_list = NULL,
3450 .flags = FLAG_HIDE,
3453 .label = "access based share enum",
3454 .type = P_BOOL,
3455 .p_class = P_LOCAL,
3456 .ptr = &sDefault.bAccessBasedShareEnum,
3457 .special = NULL,
3458 .enum_list = NULL,
3459 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3462 .label = "enhanced browsing",
3463 .type = P_BOOL,
3464 .p_class = P_GLOBAL,
3465 .ptr = &Globals.enhanced_browsing,
3466 .special = NULL,
3467 .enum_list = NULL,
3468 .flags = FLAG_ADVANCED,
3471 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3474 .label = "dns proxy",
3475 .type = P_BOOL,
3476 .p_class = P_GLOBAL,
3477 .ptr = &Globals.bDNSproxy,
3478 .special = NULL,
3479 .enum_list = NULL,
3480 .flags = FLAG_ADVANCED,
3483 .label = "wins proxy",
3484 .type = P_BOOL,
3485 .p_class = P_GLOBAL,
3486 .ptr = &Globals.bWINSproxy,
3487 .special = NULL,
3488 .enum_list = NULL,
3489 .flags = FLAG_ADVANCED,
3492 .label = "wins server",
3493 .type = P_LIST,
3494 .p_class = P_GLOBAL,
3495 .ptr = &Globals.szWINSservers,
3496 .special = NULL,
3497 .enum_list = NULL,
3498 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3501 .label = "wins support",
3502 .type = P_BOOL,
3503 .p_class = P_GLOBAL,
3504 .ptr = &Globals.bWINSsupport,
3505 .special = NULL,
3506 .enum_list = NULL,
3507 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3510 .label = "wins hook",
3511 .type = P_STRING,
3512 .p_class = P_GLOBAL,
3513 .ptr = &Globals.szWINSHook,
3514 .special = NULL,
3515 .enum_list = NULL,
3516 .flags = FLAG_ADVANCED,
3519 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3522 .label = "blocking locks",
3523 .type = P_BOOL,
3524 .p_class = P_LOCAL,
3525 .ptr = &sDefault.bBlockingLocks,
3526 .special = NULL,
3527 .enum_list = NULL,
3528 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3531 .label = "csc policy",
3532 .type = P_ENUM,
3533 .p_class = P_LOCAL,
3534 .ptr = &sDefault.iCSCPolicy,
3535 .special = NULL,
3536 .enum_list = enum_csc_policy,
3537 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3540 .label = "fake oplocks",
3541 .type = P_BOOL,
3542 .p_class = P_LOCAL,
3543 .ptr = &sDefault.bFakeOplocks,
3544 .special = NULL,
3545 .enum_list = NULL,
3546 .flags = FLAG_ADVANCED | FLAG_SHARE,
3549 .label = "kernel oplocks",
3550 .type = P_BOOL,
3551 .p_class = P_GLOBAL,
3552 .ptr = &Globals.bKernelOplocks,
3553 .special = NULL,
3554 .enum_list = NULL,
3555 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3558 .label = "locking",
3559 .type = P_BOOL,
3560 .p_class = P_LOCAL,
3561 .ptr = &sDefault.bLocking,
3562 .special = NULL,
3563 .enum_list = NULL,
3564 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3567 .label = "lock spin time",
3568 .type = P_INTEGER,
3569 .p_class = P_GLOBAL,
3570 .ptr = &Globals.iLockSpinTime,
3571 .special = NULL,
3572 .enum_list = NULL,
3573 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3576 .label = "oplocks",
3577 .type = P_BOOL,
3578 .p_class = P_LOCAL,
3579 .ptr = &sDefault.bOpLocks,
3580 .special = NULL,
3581 .enum_list = NULL,
3582 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3585 .label = "level2 oplocks",
3586 .type = P_BOOL,
3587 .p_class = P_LOCAL,
3588 .ptr = &sDefault.bLevel2OpLocks,
3589 .special = NULL,
3590 .enum_list = NULL,
3591 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3594 .label = "oplock break wait time",
3595 .type = P_INTEGER,
3596 .p_class = P_GLOBAL,
3597 .ptr = &Globals.oplock_break_wait_time,
3598 .special = NULL,
3599 .enum_list = NULL,
3600 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3603 .label = "oplock contention limit",
3604 .type = P_INTEGER,
3605 .p_class = P_LOCAL,
3606 .ptr = &sDefault.iOplockContentionLimit,
3607 .special = NULL,
3608 .enum_list = NULL,
3609 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3612 .label = "posix locking",
3613 .type = P_BOOL,
3614 .p_class = P_LOCAL,
3615 .ptr = &sDefault.bPosixLocking,
3616 .special = NULL,
3617 .enum_list = NULL,
3618 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3621 .label = "strict locking",
3622 .type = P_ENUM,
3623 .p_class = P_LOCAL,
3624 .ptr = &sDefault.iStrictLocking,
3625 .special = NULL,
3626 .enum_list = enum_bool_auto,
3627 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3630 .label = "share modes",
3631 .type = P_BOOL,
3632 .p_class = P_LOCAL,
3633 .ptr = &sDefault.bShareModes,
3634 .special = NULL,
3635 .enum_list = NULL,
3636 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3639 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3642 .label = "ldap admin dn",
3643 .type = P_STRING,
3644 .p_class = P_GLOBAL,
3645 .ptr = &Globals.szLdapAdminDn,
3646 .special = NULL,
3647 .enum_list = NULL,
3648 .flags = FLAG_ADVANCED,
3651 .label = "ldap delete dn",
3652 .type = P_BOOL,
3653 .p_class = P_GLOBAL,
3654 .ptr = &Globals.ldap_delete_dn,
3655 .special = NULL,
3656 .enum_list = NULL,
3657 .flags = FLAG_ADVANCED,
3660 .label = "ldap group suffix",
3661 .type = P_STRING,
3662 .p_class = P_GLOBAL,
3663 .ptr = &Globals.szLdapGroupSuffix,
3664 .special = NULL,
3665 .enum_list = NULL,
3666 .flags = FLAG_ADVANCED,
3669 .label = "ldap idmap suffix",
3670 .type = P_STRING,
3671 .p_class = P_GLOBAL,
3672 .ptr = &Globals.szLdapIdmapSuffix,
3673 .special = NULL,
3674 .enum_list = NULL,
3675 .flags = FLAG_ADVANCED,
3678 .label = "ldap machine suffix",
3679 .type = P_STRING,
3680 .p_class = P_GLOBAL,
3681 .ptr = &Globals.szLdapMachineSuffix,
3682 .special = NULL,
3683 .enum_list = NULL,
3684 .flags = FLAG_ADVANCED,
3687 .label = "ldap passwd sync",
3688 .type = P_ENUM,
3689 .p_class = P_GLOBAL,
3690 .ptr = &Globals.ldap_passwd_sync,
3691 .special = NULL,
3692 .enum_list = enum_ldap_passwd_sync,
3693 .flags = FLAG_ADVANCED,
3696 .label = "ldap password sync",
3697 .type = P_ENUM,
3698 .p_class = P_GLOBAL,
3699 .ptr = &Globals.ldap_passwd_sync,
3700 .special = NULL,
3701 .enum_list = enum_ldap_passwd_sync,
3702 .flags = FLAG_HIDE,
3705 .label = "ldap replication sleep",
3706 .type = P_INTEGER,
3707 .p_class = P_GLOBAL,
3708 .ptr = &Globals.ldap_replication_sleep,
3709 .special = NULL,
3710 .enum_list = NULL,
3711 .flags = FLAG_ADVANCED,
3714 .label = "ldap suffix",
3715 .type = P_STRING,
3716 .p_class = P_GLOBAL,
3717 .ptr = &Globals.szLdapSuffix,
3718 .special = NULL,
3719 .enum_list = NULL,
3720 .flags = FLAG_ADVANCED,
3723 .label = "ldap ssl",
3724 .type = P_ENUM,
3725 .p_class = P_GLOBAL,
3726 .ptr = &Globals.ldap_ssl,
3727 .special = NULL,
3728 .enum_list = enum_ldap_ssl,
3729 .flags = FLAG_ADVANCED,
3732 .label = "ldap ssl ads",
3733 .type = P_BOOL,
3734 .p_class = P_GLOBAL,
3735 .ptr = &Globals.ldap_ssl_ads,
3736 .special = NULL,
3737 .enum_list = NULL,
3738 .flags = FLAG_ADVANCED,
3741 .label = "ldap deref",
3742 .type = P_ENUM,
3743 .p_class = P_GLOBAL,
3744 .ptr = &Globals.ldap_deref,
3745 .special = NULL,
3746 .enum_list = enum_ldap_deref,
3747 .flags = FLAG_ADVANCED,
3750 .label = "ldap follow referral",
3751 .type = P_ENUM,
3752 .p_class = P_GLOBAL,
3753 .ptr = &Globals.ldap_follow_referral,
3754 .special = NULL,
3755 .enum_list = enum_bool_auto,
3756 .flags = FLAG_ADVANCED,
3759 .label = "ldap timeout",
3760 .type = P_INTEGER,
3761 .p_class = P_GLOBAL,
3762 .ptr = &Globals.ldap_timeout,
3763 .special = NULL,
3764 .enum_list = NULL,
3765 .flags = FLAG_ADVANCED,
3768 .label = "ldap connection timeout",
3769 .type = P_INTEGER,
3770 .p_class = P_GLOBAL,
3771 .ptr = &Globals.ldap_connection_timeout,
3772 .special = NULL,
3773 .enum_list = NULL,
3774 .flags = FLAG_ADVANCED,
3777 .label = "ldap page size",
3778 .type = P_INTEGER,
3779 .p_class = P_GLOBAL,
3780 .ptr = &Globals.ldap_page_size,
3781 .special = NULL,
3782 .enum_list = NULL,
3783 .flags = FLAG_ADVANCED,
3786 .label = "ldap user suffix",
3787 .type = P_STRING,
3788 .p_class = P_GLOBAL,
3789 .ptr = &Globals.szLdapUserSuffix,
3790 .special = NULL,
3791 .enum_list = NULL,
3792 .flags = FLAG_ADVANCED,
3795 .label = "ldap debug level",
3796 .type = P_INTEGER,
3797 .p_class = P_GLOBAL,
3798 .ptr = &Globals.ldap_debug_level,
3799 .special = handle_ldap_debug_level,
3800 .enum_list = NULL,
3801 .flags = FLAG_ADVANCED,
3804 .label = "ldap debug threshold",
3805 .type = P_INTEGER,
3806 .p_class = P_GLOBAL,
3807 .ptr = &Globals.ldap_debug_threshold,
3808 .special = NULL,
3809 .enum_list = NULL,
3810 .flags = FLAG_ADVANCED,
3813 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3816 .label = "eventlog list",
3817 .type = P_LIST,
3818 .p_class = P_GLOBAL,
3819 .ptr = &Globals.szEventLogs,
3820 .special = NULL,
3821 .enum_list = NULL,
3822 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3825 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3828 .label = "add share command",
3829 .type = P_STRING,
3830 .p_class = P_GLOBAL,
3831 .ptr = &Globals.szAddShareCommand,
3832 .special = NULL,
3833 .enum_list = NULL,
3834 .flags = FLAG_ADVANCED,
3837 .label = "change share command",
3838 .type = P_STRING,
3839 .p_class = P_GLOBAL,
3840 .ptr = &Globals.szChangeShareCommand,
3841 .special = NULL,
3842 .enum_list = NULL,
3843 .flags = FLAG_ADVANCED,
3846 .label = "delete share command",
3847 .type = P_STRING,
3848 .p_class = P_GLOBAL,
3849 .ptr = &Globals.szDeleteShareCommand,
3850 .special = NULL,
3851 .enum_list = NULL,
3852 .flags = FLAG_ADVANCED,
3855 .label = "config file",
3856 .type = P_STRING,
3857 .p_class = P_GLOBAL,
3858 .ptr = &Globals.szConfigFile,
3859 .special = NULL,
3860 .enum_list = NULL,
3861 .flags = FLAG_HIDE|FLAG_META,
3864 .label = "preload",
3865 .type = P_STRING,
3866 .p_class = P_GLOBAL,
3867 .ptr = &Globals.szAutoServices,
3868 .special = NULL,
3869 .enum_list = NULL,
3870 .flags = FLAG_ADVANCED,
3873 .label = "auto services",
3874 .type = P_STRING,
3875 .p_class = P_GLOBAL,
3876 .ptr = &Globals.szAutoServices,
3877 .special = NULL,
3878 .enum_list = NULL,
3879 .flags = FLAG_ADVANCED,
3882 .label = "lock directory",
3883 .type = P_STRING,
3884 .p_class = P_GLOBAL,
3885 .ptr = &Globals.szLockDir,
3886 .special = NULL,
3887 .enum_list = NULL,
3888 .flags = FLAG_ADVANCED,
3891 .label = "lock dir",
3892 .type = P_STRING,
3893 .p_class = P_GLOBAL,
3894 .ptr = &Globals.szLockDir,
3895 .special = NULL,
3896 .enum_list = NULL,
3897 .flags = FLAG_HIDE,
3900 .label = "state directory",
3901 .type = P_STRING,
3902 .p_class = P_GLOBAL,
3903 .ptr = &Globals.szStateDir,
3904 .special = NULL,
3905 .enum_list = NULL,
3906 .flags = FLAG_ADVANCED,
3909 .label = "cache directory",
3910 .type = P_STRING,
3911 .p_class = P_GLOBAL,
3912 .ptr = &Globals.szCacheDir,
3913 .special = NULL,
3914 .enum_list = NULL,
3915 .flags = FLAG_ADVANCED,
3918 .label = "pid directory",
3919 .type = P_STRING,
3920 .p_class = P_GLOBAL,
3921 .ptr = &Globals.szPidDir,
3922 .special = NULL,
3923 .enum_list = NULL,
3924 .flags = FLAG_ADVANCED,
3926 #ifdef WITH_UTMP
3928 .label = "utmp directory",
3929 .type = P_STRING,
3930 .p_class = P_GLOBAL,
3931 .ptr = &Globals.szUtmpDir,
3932 .special = NULL,
3933 .enum_list = NULL,
3934 .flags = FLAG_ADVANCED,
3937 .label = "wtmp directory",
3938 .type = P_STRING,
3939 .p_class = P_GLOBAL,
3940 .ptr = &Globals.szWtmpDir,
3941 .special = NULL,
3942 .enum_list = NULL,
3943 .flags = FLAG_ADVANCED,
3946 .label = "utmp",
3947 .type = P_BOOL,
3948 .p_class = P_GLOBAL,
3949 .ptr = &Globals.bUtmp,
3950 .special = NULL,
3951 .enum_list = NULL,
3952 .flags = FLAG_ADVANCED,
3954 #endif
3956 .label = "default service",
3957 .type = P_STRING,
3958 .p_class = P_GLOBAL,
3959 .ptr = &Globals.szDefaultService,
3960 .special = NULL,
3961 .enum_list = NULL,
3962 .flags = FLAG_ADVANCED,
3965 .label = "default",
3966 .type = P_STRING,
3967 .p_class = P_GLOBAL,
3968 .ptr = &Globals.szDefaultService,
3969 .special = NULL,
3970 .enum_list = NULL,
3971 .flags = FLAG_ADVANCED,
3974 .label = "message command",
3975 .type = P_STRING,
3976 .p_class = P_GLOBAL,
3977 .ptr = &Globals.szMsgCommand,
3978 .special = NULL,
3979 .enum_list = NULL,
3980 .flags = FLAG_ADVANCED,
3983 .label = "dfree cache time",
3984 .type = P_INTEGER,
3985 .p_class = P_LOCAL,
3986 .ptr = &sDefault.iDfreeCacheTime,
3987 .special = NULL,
3988 .enum_list = NULL,
3989 .flags = FLAG_ADVANCED,
3992 .label = "dfree command",
3993 .type = P_STRING,
3994 .p_class = P_LOCAL,
3995 .ptr = &sDefault.szDfree,
3996 .special = NULL,
3997 .enum_list = NULL,
3998 .flags = FLAG_ADVANCED,
4001 .label = "get quota command",
4002 .type = P_STRING,
4003 .p_class = P_GLOBAL,
4004 .ptr = &Globals.szGetQuota,
4005 .special = NULL,
4006 .enum_list = NULL,
4007 .flags = FLAG_ADVANCED,
4010 .label = "set quota command",
4011 .type = P_STRING,
4012 .p_class = P_GLOBAL,
4013 .ptr = &Globals.szSetQuota,
4014 .special = NULL,
4015 .enum_list = NULL,
4016 .flags = FLAG_ADVANCED,
4019 .label = "remote announce",
4020 .type = P_STRING,
4021 .p_class = P_GLOBAL,
4022 .ptr = &Globals.szRemoteAnnounce,
4023 .special = NULL,
4024 .enum_list = NULL,
4025 .flags = FLAG_ADVANCED,
4028 .label = "remote browse sync",
4029 .type = P_STRING,
4030 .p_class = P_GLOBAL,
4031 .ptr = &Globals.szRemoteBrowseSync,
4032 .special = NULL,
4033 .enum_list = NULL,
4034 .flags = FLAG_ADVANCED,
4037 .label = "socket address",
4038 .type = P_STRING,
4039 .p_class = P_GLOBAL,
4040 .ptr = &Globals.szSocketAddress,
4041 .special = NULL,
4042 .enum_list = NULL,
4043 .flags = FLAG_ADVANCED,
4046 .label = "nmbd bind explicit broadcast",
4047 .type = P_BOOL,
4048 .p_class = P_GLOBAL,
4049 .ptr = &Globals.bNmbdBindExplicitBroadcast,
4050 .special = NULL,
4051 .enum_list = NULL,
4052 .flags = FLAG_ADVANCED,
4055 .label = "homedir map",
4056 .type = P_STRING,
4057 .p_class = P_GLOBAL,
4058 .ptr = &Globals.szNISHomeMapName,
4059 .special = NULL,
4060 .enum_list = NULL,
4061 .flags = FLAG_ADVANCED,
4064 .label = "afs username map",
4065 .type = P_STRING,
4066 .p_class = P_GLOBAL,
4067 .ptr = &Globals.szAfsUsernameMap,
4068 .special = NULL,
4069 .enum_list = NULL,
4070 .flags = FLAG_ADVANCED,
4073 .label = "afs token lifetime",
4074 .type = P_INTEGER,
4075 .p_class = P_GLOBAL,
4076 .ptr = &Globals.iAfsTokenLifetime,
4077 .special = NULL,
4078 .enum_list = NULL,
4079 .flags = FLAG_ADVANCED,
4082 .label = "log nt token command",
4083 .type = P_STRING,
4084 .p_class = P_GLOBAL,
4085 .ptr = &Globals.szLogNtTokenCommand,
4086 .special = NULL,
4087 .enum_list = NULL,
4088 .flags = FLAG_ADVANCED,
4091 .label = "time offset",
4092 .type = P_INTEGER,
4093 .p_class = P_GLOBAL,
4094 .ptr = &extra_time_offset,
4095 .special = NULL,
4096 .enum_list = NULL,
4097 .flags = FLAG_ADVANCED,
4100 .label = "NIS homedir",
4101 .type = P_BOOL,
4102 .p_class = P_GLOBAL,
4103 .ptr = &Globals.bNISHomeMap,
4104 .special = NULL,
4105 .enum_list = NULL,
4106 .flags = FLAG_ADVANCED,
4109 .label = "-valid",
4110 .type = P_BOOL,
4111 .p_class = P_LOCAL,
4112 .ptr = &sDefault.valid,
4113 .special = NULL,
4114 .enum_list = NULL,
4115 .flags = FLAG_HIDE,
4118 .label = "copy",
4119 .type = P_STRING,
4120 .p_class = P_LOCAL,
4121 .ptr = &sDefault.szCopy,
4122 .special = handle_copy,
4123 .enum_list = NULL,
4124 .flags = FLAG_HIDE,
4127 .label = "include",
4128 .type = P_STRING,
4129 .p_class = P_LOCAL,
4130 .ptr = &sDefault.szInclude,
4131 .special = handle_include,
4132 .enum_list = NULL,
4133 .flags = FLAG_HIDE|FLAG_META,
4136 .label = "preexec",
4137 .type = P_STRING,
4138 .p_class = P_LOCAL,
4139 .ptr = &sDefault.szPreExec,
4140 .special = NULL,
4141 .enum_list = NULL,
4142 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4145 .label = "exec",
4146 .type = P_STRING,
4147 .p_class = P_LOCAL,
4148 .ptr = &sDefault.szPreExec,
4149 .special = NULL,
4150 .enum_list = NULL,
4151 .flags = FLAG_ADVANCED,
4154 .label = "preexec close",
4155 .type = P_BOOL,
4156 .p_class = P_LOCAL,
4157 .ptr = &sDefault.bPreexecClose,
4158 .special = NULL,
4159 .enum_list = NULL,
4160 .flags = FLAG_ADVANCED | FLAG_SHARE,
4163 .label = "postexec",
4164 .type = P_STRING,
4165 .p_class = P_LOCAL,
4166 .ptr = &sDefault.szPostExec,
4167 .special = NULL,
4168 .enum_list = NULL,
4169 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4172 .label = "root preexec",
4173 .type = P_STRING,
4174 .p_class = P_LOCAL,
4175 .ptr = &sDefault.szRootPreExec,
4176 .special = NULL,
4177 .enum_list = NULL,
4178 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4181 .label = "root preexec close",
4182 .type = P_BOOL,
4183 .p_class = P_LOCAL,
4184 .ptr = &sDefault.bRootpreexecClose,
4185 .special = NULL,
4186 .enum_list = NULL,
4187 .flags = FLAG_ADVANCED | FLAG_SHARE,
4190 .label = "root postexec",
4191 .type = P_STRING,
4192 .p_class = P_LOCAL,
4193 .ptr = &sDefault.szRootPostExec,
4194 .special = NULL,
4195 .enum_list = NULL,
4196 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4199 .label = "available",
4200 .type = P_BOOL,
4201 .p_class = P_LOCAL,
4202 .ptr = &sDefault.bAvailable,
4203 .special = NULL,
4204 .enum_list = NULL,
4205 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4208 .label = "registry shares",
4209 .type = P_BOOL,
4210 .p_class = P_GLOBAL,
4211 .ptr = &Globals.bRegistryShares,
4212 .special = NULL,
4213 .enum_list = NULL,
4214 .flags = FLAG_ADVANCED,
4217 .label = "usershare allow guests",
4218 .type = P_BOOL,
4219 .p_class = P_GLOBAL,
4220 .ptr = &Globals.bUsershareAllowGuests,
4221 .special = NULL,
4222 .enum_list = NULL,
4223 .flags = FLAG_ADVANCED,
4226 .label = "usershare max shares",
4227 .type = P_INTEGER,
4228 .p_class = P_GLOBAL,
4229 .ptr = &Globals.iUsershareMaxShares,
4230 .special = NULL,
4231 .enum_list = NULL,
4232 .flags = FLAG_ADVANCED,
4235 .label = "usershare owner only",
4236 .type = P_BOOL,
4237 .p_class = P_GLOBAL,
4238 .ptr = &Globals.bUsershareOwnerOnly,
4239 .special = NULL,
4240 .enum_list = NULL,
4241 .flags = FLAG_ADVANCED,
4244 .label = "usershare path",
4245 .type = P_STRING,
4246 .p_class = P_GLOBAL,
4247 .ptr = &Globals.szUsersharePath,
4248 .special = NULL,
4249 .enum_list = NULL,
4250 .flags = FLAG_ADVANCED,
4253 .label = "usershare prefix allow list",
4254 .type = P_LIST,
4255 .p_class = P_GLOBAL,
4256 .ptr = &Globals.szUsersharePrefixAllowList,
4257 .special = NULL,
4258 .enum_list = NULL,
4259 .flags = FLAG_ADVANCED,
4262 .label = "usershare prefix deny list",
4263 .type = P_LIST,
4264 .p_class = P_GLOBAL,
4265 .ptr = &Globals.szUsersharePrefixDenyList,
4266 .special = NULL,
4267 .enum_list = NULL,
4268 .flags = FLAG_ADVANCED,
4271 .label = "usershare template share",
4272 .type = P_STRING,
4273 .p_class = P_GLOBAL,
4274 .ptr = &Globals.szUsershareTemplateShare,
4275 .special = NULL,
4276 .enum_list = NULL,
4277 .flags = FLAG_ADVANCED,
4280 .label = "volume",
4281 .type = P_STRING,
4282 .p_class = P_LOCAL,
4283 .ptr = &sDefault.volume,
4284 .special = NULL,
4285 .enum_list = NULL,
4286 .flags = FLAG_ADVANCED | FLAG_SHARE,
4289 .label = "fstype",
4290 .type = P_STRING,
4291 .p_class = P_LOCAL,
4292 .ptr = &sDefault.fstype,
4293 .special = NULL,
4294 .enum_list = NULL,
4295 .flags = FLAG_ADVANCED | FLAG_SHARE,
4298 .label = "set directory",
4299 .type = P_BOOLREV,
4300 .p_class = P_LOCAL,
4301 .ptr = &sDefault.bNo_set_dir,
4302 .special = NULL,
4303 .enum_list = NULL,
4304 .flags = FLAG_ADVANCED | FLAG_SHARE,
4307 .label = "wide links",
4308 .type = P_BOOL,
4309 .p_class = P_LOCAL,
4310 .ptr = &sDefault.bWidelinks,
4311 .special = NULL,
4312 .enum_list = NULL,
4313 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4316 .label = "follow symlinks",
4317 .type = P_BOOL,
4318 .p_class = P_LOCAL,
4319 .ptr = &sDefault.bSymlinks,
4320 .special = NULL,
4321 .enum_list = NULL,
4322 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4325 .label = "dont descend",
4326 .type = P_STRING,
4327 .p_class = P_LOCAL,
4328 .ptr = &sDefault.szDontdescend,
4329 .special = NULL,
4330 .enum_list = NULL,
4331 .flags = FLAG_ADVANCED | FLAG_SHARE,
4334 .label = "magic script",
4335 .type = P_STRING,
4336 .p_class = P_LOCAL,
4337 .ptr = &sDefault.szMagicScript,
4338 .special = NULL,
4339 .enum_list = NULL,
4340 .flags = FLAG_ADVANCED | FLAG_SHARE,
4343 .label = "magic output",
4344 .type = P_STRING,
4345 .p_class = P_LOCAL,
4346 .ptr = &sDefault.szMagicOutput,
4347 .special = NULL,
4348 .enum_list = NULL,
4349 .flags = FLAG_ADVANCED | FLAG_SHARE,
4352 .label = "delete readonly",
4353 .type = P_BOOL,
4354 .p_class = P_LOCAL,
4355 .ptr = &sDefault.bDeleteReadonly,
4356 .special = NULL,
4357 .enum_list = NULL,
4358 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4361 .label = "dos filemode",
4362 .type = P_BOOL,
4363 .p_class = P_LOCAL,
4364 .ptr = &sDefault.bDosFilemode,
4365 .special = NULL,
4366 .enum_list = NULL,
4367 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4370 .label = "dos filetimes",
4371 .type = P_BOOL,
4372 .p_class = P_LOCAL,
4373 .ptr = &sDefault.bDosFiletimes,
4374 .special = NULL,
4375 .enum_list = NULL,
4376 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4379 .label = "dos filetime resolution",
4380 .type = P_BOOL,
4381 .p_class = P_LOCAL,
4382 .ptr = &sDefault.bDosFiletimeResolution,
4383 .special = NULL,
4384 .enum_list = NULL,
4385 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4388 .label = "fake directory create times",
4389 .type = P_BOOL,
4390 .p_class = P_LOCAL,
4391 .ptr = &sDefault.bFakeDirCreateTimes,
4392 .special = NULL,
4393 .enum_list = NULL,
4394 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4397 .label = "async smb echo handler",
4398 .type = P_BOOL,
4399 .p_class = P_GLOBAL,
4400 .ptr = &Globals.bAsyncSMBEchoHandler,
4401 .special = NULL,
4402 .enum_list = NULL,
4403 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4406 .label = "panic action",
4407 .type = P_STRING,
4408 .p_class = P_GLOBAL,
4409 .ptr = &Globals.szPanicAction,
4410 .special = NULL,
4411 .enum_list = NULL,
4412 .flags = FLAG_ADVANCED,
4415 .label = "perfcount module",
4416 .type = P_STRING,
4417 .p_class = P_GLOBAL,
4418 .ptr = &Globals.szSMBPerfcountModule,
4419 .special = NULL,
4420 .enum_list = NULL,
4421 .flags = FLAG_ADVANCED,
4424 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4427 .label = "vfs objects",
4428 .type = P_LIST,
4429 .p_class = P_LOCAL,
4430 .ptr = &sDefault.szVfsObjects,
4431 .special = NULL,
4432 .enum_list = NULL,
4433 .flags = FLAG_ADVANCED | FLAG_SHARE,
4436 .label = "vfs object",
4437 .type = P_LIST,
4438 .p_class = P_LOCAL,
4439 .ptr = &sDefault.szVfsObjects,
4440 .special = NULL,
4441 .enum_list = NULL,
4442 .flags = FLAG_HIDE,
4446 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4449 .label = "msdfs root",
4450 .type = P_BOOL,
4451 .p_class = P_LOCAL,
4452 .ptr = &sDefault.bMSDfsRoot,
4453 .special = NULL,
4454 .enum_list = NULL,
4455 .flags = FLAG_ADVANCED | FLAG_SHARE,
4458 .label = "msdfs proxy",
4459 .type = P_STRING,
4460 .p_class = P_LOCAL,
4461 .ptr = &sDefault.szMSDfsProxy,
4462 .special = NULL,
4463 .enum_list = NULL,
4464 .flags = FLAG_ADVANCED | FLAG_SHARE,
4467 .label = "host msdfs",
4468 .type = P_BOOL,
4469 .p_class = P_GLOBAL,
4470 .ptr = &Globals.bHostMSDfs,
4471 .special = NULL,
4472 .enum_list = NULL,
4473 .flags = FLAG_ADVANCED,
4476 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4479 .label = "passdb expand explicit",
4480 .type = P_BOOL,
4481 .p_class = P_GLOBAL,
4482 .ptr = &Globals.bPassdbExpandExplicit,
4483 .special = NULL,
4484 .enum_list = NULL,
4485 .flags = FLAG_ADVANCED,
4488 .label = "idmap backend",
4489 .type = P_STRING,
4490 .p_class = P_GLOBAL,
4491 .ptr = &Globals.szIdmapBackend,
4492 .special = NULL,
4493 .enum_list = NULL,
4494 .flags = FLAG_ADVANCED,
4497 .label = "idmap alloc backend",
4498 .type = P_STRING,
4499 .p_class = P_GLOBAL,
4500 .ptr = &Globals.szIdmapAllocBackend,
4501 .special = NULL,
4502 .enum_list = NULL,
4503 .flags = FLAG_ADVANCED,
4506 .label = "idmap cache time",
4507 .type = P_INTEGER,
4508 .p_class = P_GLOBAL,
4509 .ptr = &Globals.iIdmapCacheTime,
4510 .special = NULL,
4511 .enum_list = NULL,
4512 .flags = FLAG_ADVANCED,
4515 .label = "idmap negative cache time",
4516 .type = P_INTEGER,
4517 .p_class = P_GLOBAL,
4518 .ptr = &Globals.iIdmapNegativeCacheTime,
4519 .special = NULL,
4520 .enum_list = NULL,
4521 .flags = FLAG_ADVANCED,
4524 .label = "idmap uid",
4525 .type = P_STRING,
4526 .p_class = P_GLOBAL,
4527 .ptr = &Globals.szIdmapUID,
4528 .special = handle_idmap_uid,
4529 .enum_list = NULL,
4530 .flags = FLAG_ADVANCED,
4533 .label = "winbind uid",
4534 .type = P_STRING,
4535 .p_class = P_GLOBAL,
4536 .ptr = &Globals.szIdmapUID,
4537 .special = handle_idmap_uid,
4538 .enum_list = NULL,
4539 .flags = FLAG_HIDE,
4542 .label = "idmap gid",
4543 .type = P_STRING,
4544 .p_class = P_GLOBAL,
4545 .ptr = &Globals.szIdmapGID,
4546 .special = handle_idmap_gid,
4547 .enum_list = NULL,
4548 .flags = FLAG_ADVANCED,
4551 .label = "winbind gid",
4552 .type = P_STRING,
4553 .p_class = P_GLOBAL,
4554 .ptr = &Globals.szIdmapGID,
4555 .special = handle_idmap_gid,
4556 .enum_list = NULL,
4557 .flags = FLAG_HIDE,
4560 .label = "template homedir",
4561 .type = P_STRING,
4562 .p_class = P_GLOBAL,
4563 .ptr = &Globals.szTemplateHomedir,
4564 .special = NULL,
4565 .enum_list = NULL,
4566 .flags = FLAG_ADVANCED,
4569 .label = "template shell",
4570 .type = P_STRING,
4571 .p_class = P_GLOBAL,
4572 .ptr = &Globals.szTemplateShell,
4573 .special = NULL,
4574 .enum_list = NULL,
4575 .flags = FLAG_ADVANCED,
4578 .label = "winbind separator",
4579 .type = P_STRING,
4580 .p_class = P_GLOBAL,
4581 .ptr = &Globals.szWinbindSeparator,
4582 .special = NULL,
4583 .enum_list = NULL,
4584 .flags = FLAG_ADVANCED,
4587 .label = "winbind cache time",
4588 .type = P_INTEGER,
4589 .p_class = P_GLOBAL,
4590 .ptr = &Globals.winbind_cache_time,
4591 .special = NULL,
4592 .enum_list = NULL,
4593 .flags = FLAG_ADVANCED,
4596 .label = "winbind reconnect delay",
4597 .type = P_INTEGER,
4598 .p_class = P_GLOBAL,
4599 .ptr = &Globals.winbind_reconnect_delay,
4600 .special = NULL,
4601 .enum_list = NULL,
4602 .flags = FLAG_ADVANCED,
4605 .label = "winbind enum users",
4606 .type = P_BOOL,
4607 .p_class = P_GLOBAL,
4608 .ptr = &Globals.bWinbindEnumUsers,
4609 .special = NULL,
4610 .enum_list = NULL,
4611 .flags = FLAG_ADVANCED,
4614 .label = "winbind enum groups",
4615 .type = P_BOOL,
4616 .p_class = P_GLOBAL,
4617 .ptr = &Globals.bWinbindEnumGroups,
4618 .special = NULL,
4619 .enum_list = NULL,
4620 .flags = FLAG_ADVANCED,
4623 .label = "winbind use default domain",
4624 .type = P_BOOL,
4625 .p_class = P_GLOBAL,
4626 .ptr = &Globals.bWinbindUseDefaultDomain,
4627 .special = NULL,
4628 .enum_list = NULL,
4629 .flags = FLAG_ADVANCED,
4632 .label = "winbind trusted domains only",
4633 .type = P_BOOL,
4634 .p_class = P_GLOBAL,
4635 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4636 .special = NULL,
4637 .enum_list = NULL,
4638 .flags = FLAG_ADVANCED,
4641 .label = "winbind nested groups",
4642 .type = P_BOOL,
4643 .p_class = P_GLOBAL,
4644 .ptr = &Globals.bWinbindNestedGroups,
4645 .special = NULL,
4646 .enum_list = NULL,
4647 .flags = FLAG_ADVANCED,
4650 .label = "winbind expand groups",
4651 .type = P_INTEGER,
4652 .p_class = P_GLOBAL,
4653 .ptr = &Globals.winbind_expand_groups,
4654 .special = NULL,
4655 .enum_list = NULL,
4656 .flags = FLAG_ADVANCED,
4659 .label = "winbind nss info",
4660 .type = P_LIST,
4661 .p_class = P_GLOBAL,
4662 .ptr = &Globals.szWinbindNssInfo,
4663 .special = NULL,
4664 .enum_list = NULL,
4665 .flags = FLAG_ADVANCED,
4668 .label = "winbind refresh tickets",
4669 .type = P_BOOL,
4670 .p_class = P_GLOBAL,
4671 .ptr = &Globals.bWinbindRefreshTickets,
4672 .special = NULL,
4673 .enum_list = NULL,
4674 .flags = FLAG_ADVANCED,
4677 .label = "winbind offline logon",
4678 .type = P_BOOL,
4679 .p_class = P_GLOBAL,
4680 .ptr = &Globals.bWinbindOfflineLogon,
4681 .special = NULL,
4682 .enum_list = NULL,
4683 .flags = FLAG_ADVANCED,
4686 .label = "winbind normalize names",
4687 .type = P_BOOL,
4688 .p_class = P_GLOBAL,
4689 .ptr = &Globals.bWinbindNormalizeNames,
4690 .special = NULL,
4691 .enum_list = NULL,
4692 .flags = FLAG_ADVANCED,
4695 .label = "winbind rpc only",
4696 .type = P_BOOL,
4697 .p_class = P_GLOBAL,
4698 .ptr = &Globals.bWinbindRpcOnly,
4699 .special = NULL,
4700 .enum_list = NULL,
4701 .flags = FLAG_ADVANCED,
4704 .label = "create krb5 conf",
4705 .type = P_BOOL,
4706 .p_class = P_GLOBAL,
4707 .ptr = &Globals.bCreateKrb5Conf,
4708 .special = NULL,
4709 .enum_list = NULL,
4710 .flags = FLAG_ADVANCED,
4713 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4716 /***************************************************************************
4717 Initialise the sDefault parameter structure for the printer values.
4718 ***************************************************************************/
4720 static void init_printer_values(struct service *pService)
4722 /* choose defaults depending on the type of printing */
4723 switch (pService->iPrinting) {
4724 case PRINT_BSD:
4725 case PRINT_AIX:
4726 case PRINT_LPRNT:
4727 case PRINT_LPROS2:
4728 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4729 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4730 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4731 break;
4733 case PRINT_LPRNG:
4734 case PRINT_PLP:
4735 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4736 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4737 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4738 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4739 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4740 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4741 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4742 break;
4744 case PRINT_CUPS:
4745 case PRINT_IPRINT:
4746 #ifdef HAVE_CUPS
4747 /* set the lpq command to contain the destination printer
4748 name only. This is used by cups_queue_get() */
4749 string_set(&pService->szLpqcommand, "%p");
4750 string_set(&pService->szLprmcommand, "");
4751 string_set(&pService->szPrintcommand, "");
4752 string_set(&pService->szLppausecommand, "");
4753 string_set(&pService->szLpresumecommand, "");
4754 string_set(&pService->szQueuepausecommand, "");
4755 string_set(&pService->szQueueresumecommand, "");
4756 #else
4757 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4758 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4759 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4760 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4761 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4762 string_set(&pService->szQueuepausecommand, "disable '%p'");
4763 string_set(&pService->szQueueresumecommand, "enable '%p'");
4764 #endif /* HAVE_CUPS */
4765 break;
4767 case PRINT_SYSV:
4768 case PRINT_HPUX:
4769 string_set(&pService->szLpqcommand, "lpstat -o%p");
4770 string_set(&pService->szLprmcommand, "cancel %p-%j");
4771 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4772 string_set(&pService->szQueuepausecommand, "disable %p");
4773 string_set(&pService->szQueueresumecommand, "enable %p");
4774 #ifndef HPUX
4775 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4776 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4777 #endif /* HPUX */
4778 break;
4780 case PRINT_QNX:
4781 string_set(&pService->szLpqcommand, "lpq -P%p");
4782 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4783 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4784 break;
4786 #ifdef DEVELOPER
4787 case PRINT_TEST:
4788 case PRINT_VLP:
4789 string_set(&pService->szPrintcommand, "vlp print %p %s");
4790 string_set(&pService->szLpqcommand, "vlp lpq %p");
4791 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4792 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4793 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4794 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4795 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4796 break;
4797 #endif /* DEVELOPER */
4802 * Function to return the default value for the maximum number of open
4803 * file descriptors permitted. This function tries to consult the
4804 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4805 * the smaller of those.
4807 static int max_open_files(void)
4809 int sysctl_max = MAX_OPEN_FILES;
4810 int rlimit_max = MAX_OPEN_FILES;
4812 #ifdef HAVE_SYSCTLBYNAME
4814 size_t size = sizeof(sysctl_max);
4815 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4818 #endif
4820 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4822 struct rlimit rl;
4824 ZERO_STRUCT(rl);
4826 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4827 rlimit_max = rl.rlim_cur;
4829 #if defined(RLIM_INFINITY)
4830 if(rl.rlim_cur == RLIM_INFINITY)
4831 rlimit_max = MAX_OPEN_FILES;
4833 #endif
4834 #endif
4836 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4837 DEBUG(2,("max_open_files: sysctl_max (%d) below "
4838 "minimum Windows limit (%d)\n",
4839 sysctl_max,
4840 MIN_OPEN_FILES_WINDOWS));
4841 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4844 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4845 DEBUG(2,("rlimit_max: rlimit_max (%d) below "
4846 "minimum Windows limit (%d)\n",
4847 rlimit_max,
4848 MIN_OPEN_FILES_WINDOWS));
4849 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4852 return MIN(sysctl_max, rlimit_max);
4856 * Common part of freeing allocated data for one parameter.
4858 static void free_one_parameter_common(void *parm_ptr,
4859 struct parm_struct parm)
4861 if ((parm.type == P_STRING) ||
4862 (parm.type == P_USTRING))
4864 string_free((char**)parm_ptr);
4865 } else if (parm.type == P_LIST) {
4866 TALLOC_FREE(*((char***)parm_ptr));
4871 * Free the allocated data for one parameter for a share
4872 * given as a service struct.
4874 static void free_one_parameter(struct service *service,
4875 struct parm_struct parm)
4877 void *parm_ptr;
4879 if (parm.p_class != P_LOCAL) {
4880 return;
4883 parm_ptr = lp_local_ptr(service, parm.ptr);
4885 free_one_parameter_common(parm_ptr, parm);
4889 * Free the allocated parameter data of a share given
4890 * as a service struct.
4892 static void free_parameters(struct service *service)
4894 uint32_t i;
4896 for (i=0; parm_table[i].label; i++) {
4897 free_one_parameter(service, parm_table[i]);
4902 * Free the allocated data for one parameter for a given share
4903 * specified by an snum.
4905 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4907 void *parm_ptr;
4909 if (parm.ptr == NULL) {
4910 return;
4913 if (snum < 0) {
4914 parm_ptr = parm.ptr;
4915 } else if (parm.p_class != P_LOCAL) {
4916 return;
4917 } else {
4918 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4921 free_one_parameter_common(parm_ptr, parm);
4925 * Free the allocated parameter data for a share specified
4926 * by an snum.
4928 static void free_parameters_by_snum(int snum)
4930 uint32_t i;
4932 for (i=0; parm_table[i].label; i++) {
4933 free_one_parameter_by_snum(snum, parm_table[i]);
4938 * Free the allocated global parameters.
4940 static void free_global_parameters(void)
4942 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4945 /***************************************************************************
4946 Initialise the global parameter structure.
4947 ***************************************************************************/
4949 static void init_globals(bool first_time_only)
4951 static bool done_init = False;
4952 char *s = NULL;
4953 int i;
4955 /* If requested to initialize only once and we've already done it... */
4956 if (first_time_only && done_init) {
4957 /* ... then we have nothing more to do */
4958 return;
4961 if (!done_init) {
4962 /* The logfile can be set before this is invoked. Free it if so. */
4963 if (Globals.szLogFile != NULL) {
4964 string_free(&Globals.szLogFile);
4965 Globals.szLogFile = NULL;
4967 done_init = True;
4968 } else {
4969 free_global_parameters();
4972 memset((void *)&Globals, '\0', sizeof(Globals));
4974 for (i = 0; parm_table[i].label; i++) {
4975 if ((parm_table[i].type == P_STRING ||
4976 parm_table[i].type == P_USTRING) &&
4977 parm_table[i].ptr)
4979 string_set((char **)parm_table[i].ptr, "");
4983 string_set(&sDefault.fstype, FSTYPE_STRING);
4984 string_set(&sDefault.szPrintjobUsername, "%U");
4986 init_printer_values(&sDefault);
4989 DEBUG(3, ("Initialising global parameters\n"));
4991 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4992 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4994 /* use the new 'hash2' method by default, with a prefix of 1 */
4995 string_set(&Globals.szManglingMethod, "hash2");
4996 Globals.mangle_prefix = 1;
4998 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
5000 /* using UTF8 by default allows us to support all chars */
5001 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5003 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
5004 /* If the system supports nl_langinfo(), try to grab the value
5005 from the user's locale */
5006 string_set(&Globals.display_charset, "LOCALE");
5007 #else
5008 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
5009 #endif
5011 /* Use codepage 850 as a default for the dos character set */
5012 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5015 * Allow the default PASSWD_CHAT to be overridden in local.h.
5017 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5019 set_global_myname(myhostname());
5020 string_set(&Globals.szNetbiosName,global_myname());
5022 set_global_myworkgroup(WORKGROUP);
5023 string_set(&Globals.szWorkgroup, lp_workgroup());
5025 string_set(&Globals.szPasswdProgram, "");
5026 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5027 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5028 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5029 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5030 string_set(&Globals.szSocketAddress, "0.0.0.0");
5032 * By default support explicit binding to broadcast
5033 * addresses.
5035 Globals.bNmbdBindExplicitBroadcast = true;
5037 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5038 smb_panic("init_globals: ENOMEM");
5040 string_set(&Globals.szServerString, s);
5041 SAFE_FREE(s);
5042 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
5043 DEFAULT_MINOR_VERSION) < 0) {
5044 smb_panic("init_globals: ENOMEM");
5046 string_set(&Globals.szAnnounceVersion, s);
5047 SAFE_FREE(s);
5048 #ifdef DEVELOPER
5049 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5050 #endif
5052 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5054 string_set(&Globals.szLogonDrive, "");
5055 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5056 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5057 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5059 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5060 string_set(&Globals.szPasswordServer, "*");
5062 Globals.AlgorithmicRidBase = BASE_RID;
5064 Globals.bLoadPrinters = True;
5065 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
5067 Globals.ConfigBackend = config_backend;
5069 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5070 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5071 Globals.max_xmit = 0x4104;
5072 Globals.max_mux = 50; /* This is *needed* for profile support. */
5073 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
5074 Globals.bDisableSpoolss = False;
5075 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5076 Globals.pwordlevel = 0;
5077 Globals.unamelevel = 0;
5078 Globals.deadtime = 0;
5079 Globals.getwd_cache = true;
5080 Globals.bLargeReadwrite = True;
5081 Globals.max_log_size = 5000;
5082 Globals.max_open_files = max_open_files();
5083 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5084 Globals.maxprotocol = PROTOCOL_NT1;
5085 Globals.minprotocol = PROTOCOL_CORE;
5086 Globals.security = SEC_USER;
5087 Globals.paranoid_server_security = True;
5088 Globals.bEncryptPasswords = True;
5089 Globals.bUpdateEncrypt = False;
5090 Globals.clientSchannel = Auto;
5091 Globals.serverSchannel = Auto;
5092 Globals.bReadRaw = True;
5093 Globals.bWriteRaw = True;
5094 Globals.bNullPasswords = False;
5095 Globals.bObeyPamRestrictions = False;
5096 Globals.syslog = 1;
5097 Globals.bSyslogOnly = False;
5098 Globals.bTimestampLogs = True;
5099 string_set(&Globals.szLogLevel, "0");
5100 Globals.bDebugPrefixTimestamp = False;
5101 Globals.bDebugHiresTimestamp = true;
5102 Globals.bDebugPid = False;
5103 Globals.bDebugUid = False;
5104 Globals.bDebugClass = False;
5105 Globals.bEnableCoreFiles = True;
5106 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
5107 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
5108 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
5109 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
5110 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
5111 Globals.lm_interval = 60;
5112 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5113 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5114 Globals.bNISHomeMap = False;
5115 #ifdef WITH_NISPLUS_HOME
5116 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5117 #else
5118 string_set(&Globals.szNISHomeMapName, "auto.home");
5119 #endif
5120 #endif
5121 Globals.bTimeServer = False;
5122 Globals.bBindInterfacesOnly = False;
5123 Globals.bUnixPasswdSync = False;
5124 Globals.bPamPasswordChange = False;
5125 Globals.bPasswdChatDebug = False;
5126 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5127 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
5128 Globals.bNTStatusSupport = True; /* Use NT status by default. */
5129 Globals.bStatCache = True; /* use stat cache by default */
5130 Globals.iMaxStatCacheSize = 256; /* 256k by default */
5131 Globals.restrict_anonymous = 0;
5132 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
5133 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
5134 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
5135 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5136 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
5137 /* Note, that we will use NTLM2 session security (which is different), if it is available */
5139 Globals.map_to_guest = 0; /* By Default, "Never" */
5140 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
5141 Globals.enhanced_browsing = true;
5142 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5143 #ifdef MMAP_BLACKLIST
5144 Globals.bUseMmap = False;
5145 #else
5146 Globals.bUseMmap = True;
5147 #endif
5148 Globals.bUnixExtensions = True;
5149 Globals.bResetOnZeroVC = False;
5150 Globals.bLogWriteableFilesOnExit = False;
5151 Globals.bCreateKrb5Conf = true;
5153 /* hostname lookups can be very expensive and are broken on
5154 a large number of sites (tridge) */
5155 Globals.bHostnameLookups = False;
5157 string_set(&Globals.szPassdbBackend, "tdbsam");
5158 string_set(&Globals.szLdapSuffix, "");
5159 string_set(&Globals.szLdapMachineSuffix, "");
5160 string_set(&Globals.szLdapUserSuffix, "");
5161 string_set(&Globals.szLdapGroupSuffix, "");
5162 string_set(&Globals.szLdapIdmapSuffix, "");
5164 string_set(&Globals.szLdapAdminDn, "");
5165 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5166 Globals.ldap_ssl_ads = False;
5167 Globals.ldap_deref = -1;
5168 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5169 Globals.ldap_delete_dn = False;
5170 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5171 Globals.ldap_follow_referral = Auto;
5172 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5173 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5174 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5176 Globals.ldap_debug_level = 0;
5177 Globals.ldap_debug_threshold = 10;
5179 /* This is what we tell the afs client. in reality we set the token
5180 * to never expire, though, when this runs out the afs client will
5181 * forget the token. Set to 0 to get NEVERDATE.*/
5182 Globals.iAfsTokenLifetime = 604800;
5183 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5185 /* these parameters are set to defaults that are more appropriate
5186 for the increasing samba install base:
5188 as a member of the workgroup, that will possibly become a
5189 _local_ master browser (lm = True). this is opposed to a forced
5190 local master browser startup (pm = True).
5192 doesn't provide WINS server service by default (wsupp = False),
5193 and doesn't provide domain master browser services by default, either.
5197 Globals.bMsAddPrinterWizard = True;
5198 Globals.os_level = 20;
5199 Globals.bLocalMaster = True;
5200 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5201 Globals.bDomainLogons = False;
5202 Globals.bBrowseList = True;
5203 Globals.bWINSsupport = False;
5204 Globals.bWINSproxy = False;
5206 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5207 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5209 Globals.bDNSproxy = True;
5211 /* this just means to use them if they exist */
5212 Globals.bKernelOplocks = True;
5214 Globals.bAllowTrustedDomains = True;
5215 string_set(&Globals.szIdmapBackend, "tdb");
5217 string_set(&Globals.szTemplateShell, "/bin/false");
5218 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5219 string_set(&Globals.szWinbindSeparator, "\\");
5221 string_set(&Globals.szCupsServer, "");
5222 string_set(&Globals.szIPrintServer, "");
5224 string_set(&Globals.ctdbdSocket, "");
5225 Globals.szClusterAddresses = NULL;
5226 Globals.clustering = False;
5227 Globals.ctdb_timeout = 0;
5228 Globals.ctdb_locktime_warn_threshold = 0;
5230 Globals.winbind_cache_time = 300; /* 5 minutes */
5231 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5232 Globals.bWinbindEnumUsers = False;
5233 Globals.bWinbindEnumGroups = False;
5234 Globals.bWinbindUseDefaultDomain = False;
5235 Globals.bWinbindTrustedDomainsOnly = False;
5236 Globals.bWinbindNestedGroups = True;
5237 Globals.winbind_expand_groups = 1;
5238 Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5239 Globals.bWinbindRefreshTickets = False;
5240 Globals.bWinbindOfflineLogon = False;
5242 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5243 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5245 Globals.bPassdbExpandExplicit = False;
5247 Globals.name_cache_timeout = 660; /* In seconds */
5249 Globals.bUseSpnego = True;
5250 Globals.bClientUseSpnego = True;
5252 Globals.client_signing = Auto;
5253 Globals.server_signing = False;
5255 Globals.bDeferSharingViolations = True;
5256 string_set(&Globals.smb_ports, SMB_PORTS);
5258 Globals.bEnablePrivileges = True;
5259 Globals.bHostMSDfs = True;
5260 Globals.bASUSupport = False;
5262 /* User defined shares. */
5263 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5264 smb_panic("init_globals: ENOMEM");
5266 string_set(&Globals.szUsersharePath, s);
5267 SAFE_FREE(s);
5268 string_set(&Globals.szUsershareTemplateShare, "");
5269 Globals.iUsershareMaxShares = 0;
5270 /* By default disallow sharing of directories not owned by the sharer. */
5271 Globals.bUsershareOwnerOnly = True;
5272 /* By default disallow guest access to usershares. */
5273 Globals.bUsershareAllowGuests = False;
5275 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5277 /* By default no shares out of the registry */
5278 Globals.bRegistryShares = False;
5280 Globals.iminreceivefile = 0;
5282 Globals.bMapUntrustedToDomain = false;
5284 Globals.ismb2_max_read = 64*1024;
5285 Globals.ismb2_max_write = 64*1024;
5286 Globals.ismb2_max_trans = 64*1024;
5289 /*******************************************************************
5290 Convenience routine to grab string parameters into temporary memory
5291 and run standard_sub_basic on them. The buffers can be written to by
5292 callers without affecting the source string.
5293 ********************************************************************/
5295 static char *lp_string(const char *s)
5297 char *ret;
5298 TALLOC_CTX *ctx = talloc_tos();
5300 /* The follow debug is useful for tracking down memory problems
5301 especially if you have an inner loop that is calling a lp_*()
5302 function that returns a string. Perhaps this debug should be
5303 present all the time? */
5305 #if 0
5306 DEBUG(10, ("lp_string(%s)\n", s));
5307 #endif
5308 if (!s) {
5309 return NULL;
5312 ret = talloc_sub_basic(ctx,
5313 get_current_username(),
5314 current_user_info.domain,
5316 if (trim_char(ret, '\"', '\"')) {
5317 if (strchr(ret,'\"') != NULL) {
5318 TALLOC_FREE(ret);
5319 ret = talloc_sub_basic(ctx,
5320 get_current_username(),
5321 current_user_info.domain,
5325 return ret;
5329 In this section all the functions that are used to access the
5330 parameters from the rest of the program are defined
5333 #define FN_GLOBAL_STRING(fn_name,ptr) \
5334 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5335 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5336 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5337 #define FN_GLOBAL_LIST(fn_name,ptr) \
5338 const char **fn_name(void) {return(*(const char ***)(ptr));}
5339 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5340 bool fn_name(void) {return(*(bool *)(ptr));}
5341 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5342 char fn_name(void) {return(*(char *)(ptr));}
5343 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5344 int fn_name(void) {return(*(int *)(ptr));}
5346 #define FN_LOCAL_STRING(fn_name,val) \
5347 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5348 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5349 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5350 #define FN_LOCAL_LIST(fn_name,val) \
5351 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5352 #define FN_LOCAL_BOOL(fn_name,val) \
5353 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5354 #define FN_LOCAL_INTEGER(fn_name,val) \
5355 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5357 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5358 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5359 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5360 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5361 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5362 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));}
5363 #define FN_LOCAL_CHAR(fn_name,val) \
5364 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5366 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5367 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5368 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5369 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5370 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5371 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5372 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5373 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5374 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5375 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5376 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5377 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5378 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5379 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5380 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5381 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5382 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5383 * build process or in smb.conf, we use that value. Otherwise they
5384 * default to the value of lp_lockdir(). */
5385 char *lp_statedir(void) {
5386 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5387 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5388 return(lp_string(*(char **)(&Globals.szStateDir) ?
5389 *(char **)(&Globals.szStateDir) : ""));
5390 else
5391 return(lp_string(*(char **)(&Globals.szLockDir) ?
5392 *(char **)(&Globals.szLockDir) : ""));
5394 char *lp_cachedir(void) {
5395 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5396 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5397 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5398 *(char **)(&Globals.szCacheDir) : ""));
5399 else
5400 return(lp_string(*(char **)(&Globals.szLockDir) ?
5401 *(char **)(&Globals.szLockDir) : ""));
5403 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5404 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5405 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5406 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5407 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5408 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5409 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5410 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5411 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5412 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5413 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5414 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5415 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5416 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5417 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5418 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5419 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5420 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5421 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5422 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5423 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5424 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5425 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5426 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5427 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5428 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5429 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5430 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5431 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, &Globals.bNmbdBindExplicitBroadcast)
5432 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5433 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5434 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5435 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5436 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5437 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5438 * lp_passdb_backend() should be replace by the this macro again after
5439 * some releases.
5440 * */
5441 const char *lp_passdb_backend(void)
5443 char *delim, *quote;
5445 delim = strchr( Globals.szPassdbBackend, ' ');
5446 /* no space at all */
5447 if (delim == NULL) {
5448 goto out;
5451 quote = strchr(Globals.szPassdbBackend, '"');
5452 /* no quote char or non in the first part */
5453 if (quote == NULL || quote > delim) {
5454 *delim = '\0';
5455 goto warn;
5458 quote = strchr(quote+1, '"');
5459 if (quote == NULL) {
5460 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5461 goto out;
5462 } else if (*(quote+1) == '\0') {
5463 /* space, fitting quote char, and one backend only */
5464 goto out;
5465 } else {
5466 /* terminate string after the fitting quote char */
5467 *(quote+1) = '\0';
5470 warn:
5471 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5472 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5473 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5474 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5476 out:
5477 return Globals.szPassdbBackend;
5479 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5480 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5481 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5482 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5483 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5485 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5486 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5487 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5488 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5489 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5490 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5492 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5494 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5495 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5496 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5498 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5500 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5501 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5502 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5503 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5504 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5505 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5506 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5507 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5508 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5509 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5510 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5511 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5512 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5513 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5514 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5515 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5517 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5518 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5519 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5520 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5521 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5522 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5524 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5525 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5526 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5527 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5528 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5529 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5530 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5531 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5532 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5533 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5534 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5535 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5536 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5537 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5538 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5539 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5540 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5541 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5542 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5543 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5545 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5547 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5548 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5549 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5550 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5551 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5552 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5553 &Globals.bLogWriteableFilesOnExit)
5554 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5555 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5556 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5557 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5558 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5559 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5560 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5561 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5562 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5563 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5564 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5565 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5566 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5567 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5568 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5569 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5570 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5571 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5572 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5573 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5574 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5575 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5576 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5577 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5578 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5579 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5580 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5581 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5582 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5583 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5584 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5585 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5586 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5587 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5588 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5589 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5590 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5591 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5592 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5593 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5594 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5595 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5596 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5597 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5598 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5599 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5600 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5601 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5602 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5603 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5604 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5605 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5606 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5607 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5608 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5609 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5610 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5611 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5612 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5613 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5614 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5615 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5616 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5617 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5618 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5619 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5620 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5621 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5622 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5623 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5624 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5625 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5626 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5627 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5628 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5629 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5630 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5631 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5632 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5633 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5634 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5635 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5636 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5637 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5638 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5639 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5640 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5641 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5642 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5643 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5644 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5645 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5646 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5647 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5648 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5649 FN_GLOBAL_INTEGER(lp_smb2_max_read, &Globals.ismb2_max_read)
5650 FN_GLOBAL_INTEGER(lp_smb2_max_write, &Globals.ismb2_max_write)
5651 FN_GLOBAL_INTEGER(lp_smb2_max_trans, &Globals.ismb2_max_trans)
5653 FN_LOCAL_STRING(lp_preexec, szPreExec)
5654 FN_LOCAL_STRING(lp_postexec, szPostExec)
5655 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5656 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5657 FN_LOCAL_STRING(lp_servicename, szService)
5658 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5659 FN_LOCAL_STRING(lp_pathname, szPath)
5660 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5661 FN_LOCAL_STRING(lp_username, szUsername)
5662 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5663 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5664 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5665 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5666 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5667 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5668 int lp_cups_encrypt(void)
5670 #ifdef HAVE_HTTPCONNECTENCRYPT
5671 switch (Globals.CupsEncrypt) {
5672 case Auto:
5673 Globals.CupsEncrypt = HTTP_ENCRYPT_REQUIRED;
5674 break;
5675 case True:
5676 Globals.CupsEncrypt = HTTP_ENCRYPT_ALWAYS;
5677 break;
5678 case False:
5679 Globals.CupsEncrypt = HTTP_ENCRYPT_NEVER;
5680 break;
5682 #endif
5683 return Globals.CupsEncrypt;
5685 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5686 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5687 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5688 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5689 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5690 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5691 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, &Globals.ctdb_locktime_warn_threshold)
5692 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5693 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5694 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5695 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5696 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5697 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5698 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5699 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5700 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5701 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5702 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5703 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5704 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5705 FN_LOCAL_STRING(lp_comment, comment)
5706 FN_LOCAL_STRING(lp_force_user, force_user)
5707 FN_LOCAL_STRING(lp_force_group, force_group)
5708 FN_LOCAL_LIST(lp_readlist, readlist)
5709 FN_LOCAL_LIST(lp_writelist, writelist)
5710 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5711 FN_LOCAL_STRING(lp_fstype, fstype)
5712 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5713 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5714 static FN_LOCAL_STRING(lp_volume, volume)
5715 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5716 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5717 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5718 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5719 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5720 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5721 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5722 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5723 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5724 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5725 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5726 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5727 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5728 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5729 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5730 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5731 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5732 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5733 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5734 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5735 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5736 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5737 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5738 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5739 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5740 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5741 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5742 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5743 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5744 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5745 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5746 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5747 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5748 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5749 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5750 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5751 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5752 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5753 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5754 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5755 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5756 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5757 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5758 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5759 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5760 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5761 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5762 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5763 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
5764 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5765 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5766 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5767 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5768 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5769 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5770 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5771 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5772 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5773 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5774 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5775 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5776 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5777 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5778 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5779 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5780 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5781 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5782 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5783 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5784 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5785 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5786 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5787 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5788 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5789 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5790 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5791 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5792 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5793 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5794 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5795 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5796 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5797 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5798 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5799 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5800 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5801 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5802 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5803 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5804 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5805 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5806 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5807 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5808 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5809 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5810 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5811 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5812 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5813 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5815 /* local prototypes */
5817 static int map_parameter(const char *pszParmName);
5818 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5819 static const char *get_boolean(bool bool_value);
5820 static int getservicebyname(const char *pszServiceName,
5821 struct service *pserviceDest);
5822 static void copy_service(struct service *pserviceDest,
5823 struct service *pserviceSource,
5824 struct bitmap *pcopymapDest);
5825 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5826 void *userdata);
5827 static bool do_section(const char *pszSectionName, void *userdata);
5828 static void init_copymap(struct service *pservice);
5829 static bool hash_a_service(const char *name, int number);
5830 static void free_service_byindex(int iService);
5831 static void free_param_opts(struct param_opt_struct **popts);
5832 static void show_parameter(int parmIndex);
5833 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5836 * This is a helper function for parametrical options support. It returns a
5837 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5838 * parametrical functions are quite simple
5840 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5841 const char *option)
5843 bool global_section = False;
5844 char* param_key;
5845 struct param_opt_struct *data;
5847 if (snum >= iNumServices) return NULL;
5849 if (snum < 0) {
5850 data = Globals.param_opt;
5851 global_section = True;
5852 } else {
5853 data = ServicePtrs[snum]->param_opt;
5856 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5857 DEBUG(0,("asprintf failed!\n"));
5858 return NULL;
5861 while (data) {
5862 if (strwicmp(data->key, param_key) == 0) {
5863 string_free(&param_key);
5864 return data;
5866 data = data->next;
5869 if (!global_section) {
5870 /* Try to fetch the same option but from globals */
5871 /* but only if we are not already working with Globals */
5872 data = Globals.param_opt;
5873 while (data) {
5874 if (strwicmp(data->key, param_key) == 0) {
5875 string_free(&param_key);
5876 return data;
5878 data = data->next;
5882 string_free(&param_key);
5884 return NULL;
5888 #define MISSING_PARAMETER(name) \
5889 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5891 /*******************************************************************
5892 convenience routine to return int parameters.
5893 ********************************************************************/
5894 static int lp_int(const char *s)
5897 if (!s || !*s) {
5898 MISSING_PARAMETER(lp_int);
5899 return (-1);
5902 return (int)strtol(s, NULL, 0);
5905 /*******************************************************************
5906 convenience routine to return unsigned long parameters.
5907 ********************************************************************/
5908 static unsigned long lp_ulong(const char *s)
5911 if (!s || !*s) {
5912 MISSING_PARAMETER(lp_ulong);
5913 return (0);
5916 return strtoul(s, NULL, 0);
5919 /*******************************************************************
5920 convenience routine to return boolean parameters.
5921 ********************************************************************/
5922 static bool lp_bool(const char *s)
5924 bool ret = False;
5926 if (!s || !*s) {
5927 MISSING_PARAMETER(lp_bool);
5928 return False;
5931 if (!set_boolean(s, &ret)) {
5932 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5933 return False;
5936 return ret;
5939 /*******************************************************************
5940 convenience routine to return enum parameters.
5941 ********************************************************************/
5942 static int lp_enum(const char *s,const struct enum_list *_enum)
5944 int i;
5946 if (!s || !*s || !_enum) {
5947 MISSING_PARAMETER(lp_enum);
5948 return (-1);
5951 for (i=0; _enum[i].name; i++) {
5952 if (strequal(_enum[i].name,s))
5953 return _enum[i].value;
5956 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5957 return (-1);
5960 #undef MISSING_PARAMETER
5962 /* DO NOT USE lp_parm_string ANYMORE!!!!
5963 * use lp_parm_const_string or lp_parm_talloc_string
5965 * lp_parm_string is only used to let old modules find this symbol
5967 #undef lp_parm_string
5968 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5969 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5971 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5974 /* Return parametric option from a given service. Type is a part of option before ':' */
5975 /* Parametric option has following syntax: 'Type: option = value' */
5976 /* the returned value is talloced on the talloc_tos() */
5977 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5979 struct param_opt_struct *data = get_parametrics(snum, type, option);
5981 if (data == NULL||data->value==NULL) {
5982 if (def) {
5983 return lp_string(def);
5984 } else {
5985 return NULL;
5989 return lp_string(data->value);
5992 /* Return parametric option from a given service. Type is a part of option before ':' */
5993 /* Parametric option has following syntax: 'Type: option = value' */
5994 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5996 struct param_opt_struct *data = get_parametrics(snum, type, option);
5998 if (data == NULL||data->value==NULL)
5999 return def;
6001 return data->value;
6004 /* Return parametric option from a given service. Type is a part of option before ':' */
6005 /* Parametric option has following syntax: 'Type: option = value' */
6007 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6009 struct param_opt_struct *data = get_parametrics(snum, type, option);
6011 if (data == NULL||data->value==NULL)
6012 return (const char **)def;
6014 if (data->list==NULL) {
6015 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
6018 return (const char **)data->list;
6021 /* Return parametric option from a given service. Type is a part of option before ':' */
6022 /* Parametric option has following syntax: 'Type: option = value' */
6024 int lp_parm_int(int snum, const char *type, const char *option, int def)
6026 struct param_opt_struct *data = get_parametrics(snum, type, option);
6028 if (data && data->value && *data->value)
6029 return lp_int(data->value);
6031 return def;
6034 /* Return parametric option from a given service. Type is a part of option before ':' */
6035 /* Parametric option has following syntax: 'Type: option = value' */
6037 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6039 struct param_opt_struct *data = get_parametrics(snum, type, option);
6041 if (data && data->value && *data->value)
6042 return lp_ulong(data->value);
6044 return def;
6047 /* Return parametric option from a given service. Type is a part of option before ':' */
6048 /* Parametric option has following syntax: 'Type: option = value' */
6050 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6052 struct param_opt_struct *data = get_parametrics(snum, type, option);
6054 if (data && data->value && *data->value)
6055 return lp_bool(data->value);
6057 return def;
6060 /* Return parametric option from a given service. Type is a part of option before ':' */
6061 /* Parametric option has following syntax: 'Type: option = value' */
6063 int lp_parm_enum(int snum, const char *type, const char *option,
6064 const struct enum_list *_enum, int def)
6066 struct param_opt_struct *data = get_parametrics(snum, type, option);
6068 if (data && data->value && *data->value && _enum)
6069 return lp_enum(data->value, _enum);
6071 return def;
6075 /***************************************************************************
6076 Initialise a service to the defaults.
6077 ***************************************************************************/
6079 static void init_service(struct service *pservice)
6081 memset((char *)pservice, '\0', sizeof(struct service));
6082 copy_service(pservice, &sDefault, NULL);
6087 * free a param_opts structure.
6088 * param_opts handling should be moved to talloc;
6089 * then this whole functions reduces to a TALLOC_FREE().
6092 static void free_param_opts(struct param_opt_struct **popts)
6094 struct param_opt_struct *opt, *next_opt;
6096 if (popts == NULL) {
6097 return;
6100 if (*popts != NULL) {
6101 DEBUG(5, ("Freeing parametrics:\n"));
6103 opt = *popts;
6104 while (opt != NULL) {
6105 string_free(&opt->key);
6106 string_free(&opt->value);
6107 TALLOC_FREE(opt->list);
6108 next_opt = opt->next;
6109 SAFE_FREE(opt);
6110 opt = next_opt;
6112 *popts = NULL;
6115 /***************************************************************************
6116 Free the dynamically allocated parts of a service struct.
6117 ***************************************************************************/
6119 static void free_service(struct service *pservice)
6121 if (!pservice)
6122 return;
6124 if (pservice->szService)
6125 DEBUG(5, ("free_service: Freeing service %s\n",
6126 pservice->szService));
6128 free_parameters(pservice);
6130 string_free(&pservice->szService);
6131 TALLOC_FREE(pservice->copymap);
6133 free_param_opts(&pservice->param_opt);
6135 ZERO_STRUCTP(pservice);
6139 /***************************************************************************
6140 remove a service indexed in the ServicePtrs array from the ServiceHash
6141 and free the dynamically allocated parts
6142 ***************************************************************************/
6144 static void free_service_byindex(int idx)
6146 if ( !LP_SNUM_OK(idx) )
6147 return;
6149 ServicePtrs[idx]->valid = False;
6150 invalid_services[num_invalid_services++] = idx;
6152 /* we have to cleanup the hash record */
6154 if (ServicePtrs[idx]->szService) {
6155 char *canon_name = canonicalize_servicename(
6156 talloc_tos(),
6157 ServicePtrs[idx]->szService );
6159 dbwrap_delete_bystring(ServiceHash, canon_name );
6160 TALLOC_FREE(canon_name);
6163 free_service(ServicePtrs[idx]);
6166 /***************************************************************************
6167 Add a new service to the services array initialising it with the given
6168 service.
6169 ***************************************************************************/
6171 static int add_a_service(const struct service *pservice, const char *name)
6173 int i;
6174 struct service tservice;
6175 int num_to_alloc = iNumServices + 1;
6177 tservice = *pservice;
6179 /* it might already exist */
6180 if (name) {
6181 i = getservicebyname(name, NULL);
6182 if (i >= 0) {
6183 /* Clean all parametric options for service */
6184 /* They will be added during parsing again */
6185 free_param_opts(&ServicePtrs[i]->param_opt);
6186 return (i);
6190 /* find an invalid one */
6191 i = iNumServices;
6192 if (num_invalid_services > 0) {
6193 i = invalid_services[--num_invalid_services];
6196 /* if not, then create one */
6197 if (i == iNumServices) {
6198 struct service **tsp;
6199 int *tinvalid;
6201 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6202 if (tsp == NULL) {
6203 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6204 return (-1);
6206 ServicePtrs = tsp;
6207 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6208 if (!ServicePtrs[iNumServices]) {
6209 DEBUG(0,("add_a_service: out of memory!\n"));
6210 return (-1);
6212 iNumServices++;
6214 /* enlarge invalid_services here for now... */
6215 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6216 num_to_alloc);
6217 if (tinvalid == NULL) {
6218 DEBUG(0,("add_a_service: failed to enlarge "
6219 "invalid_services!\n"));
6220 return (-1);
6222 invalid_services = tinvalid;
6223 } else {
6224 free_service_byindex(i);
6227 ServicePtrs[i]->valid = True;
6229 init_service(ServicePtrs[i]);
6230 copy_service(ServicePtrs[i], &tservice, NULL);
6231 if (name)
6232 string_set(&ServicePtrs[i]->szService, name);
6234 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6235 i, ServicePtrs[i]->szService));
6237 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6238 return (-1);
6241 return (i);
6244 /***************************************************************************
6245 Convert a string to uppercase and remove whitespaces.
6246 ***************************************************************************/
6248 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6250 char *result;
6252 if ( !src ) {
6253 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6254 return NULL;
6257 result = talloc_strdup(ctx, src);
6258 SMB_ASSERT(result != NULL);
6260 strlower_m(result);
6261 return result;
6264 /***************************************************************************
6265 Add a name/index pair for the services array to the hash table.
6266 ***************************************************************************/
6268 static bool hash_a_service(const char *name, int idx)
6270 char *canon_name;
6272 if ( !ServiceHash ) {
6273 DEBUG(10,("hash_a_service: creating servicehash\n"));
6274 ServiceHash = db_open_rbt(NULL);
6275 if ( !ServiceHash ) {
6276 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6277 return False;
6281 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6282 idx, name));
6284 canon_name = canonicalize_servicename(talloc_tos(), name );
6286 dbwrap_store_bystring(ServiceHash, canon_name,
6287 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6288 TDB_REPLACE);
6290 TALLOC_FREE(canon_name);
6292 return True;
6295 /***************************************************************************
6296 Add a new home service, with the specified home directory, defaults coming
6297 from service ifrom.
6298 ***************************************************************************/
6300 bool lp_add_home(const char *pszHomename, int iDefaultService,
6301 const char *user, const char *pszHomedir)
6303 int i;
6305 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6306 pszHomedir[0] == '\0') {
6307 return false;
6310 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6312 if (i < 0)
6313 return (False);
6315 if (!(*(ServicePtrs[iDefaultService]->szPath))
6316 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6317 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6320 if (!(*(ServicePtrs[i]->comment))) {
6321 char *comment = NULL;
6322 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6323 return false;
6325 string_set(&ServicePtrs[i]->comment, comment);
6326 SAFE_FREE(comment);
6329 /* set the browseable flag from the global default */
6331 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6332 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6334 ServicePtrs[i]->autoloaded = True;
6336 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6337 user, ServicePtrs[i]->szPath ));
6339 return (True);
6342 /***************************************************************************
6343 Add a new service, based on an old one.
6344 ***************************************************************************/
6346 int lp_add_service(const char *pszService, int iDefaultService)
6348 if (iDefaultService < 0) {
6349 return add_a_service(&sDefault, pszService);
6352 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6355 /***************************************************************************
6356 Add the IPC service.
6357 ***************************************************************************/
6359 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6361 char *comment = NULL;
6362 int i = add_a_service(&sDefault, ipc_name);
6364 if (i < 0)
6365 return (False);
6367 if (asprintf(&comment, "IPC Service (%s)",
6368 Globals.szServerString) < 0) {
6369 return (False);
6372 string_set(&ServicePtrs[i]->szPath, tmpdir());
6373 string_set(&ServicePtrs[i]->szUsername, "");
6374 string_set(&ServicePtrs[i]->comment, comment);
6375 string_set(&ServicePtrs[i]->fstype, "IPC");
6376 ServicePtrs[i]->iMaxConnections = 0;
6377 ServicePtrs[i]->bAvailable = True;
6378 ServicePtrs[i]->bRead_only = True;
6379 ServicePtrs[i]->bGuest_only = False;
6380 ServicePtrs[i]->bAdministrative_share = True;
6381 ServicePtrs[i]->bGuest_ok = guest_ok;
6382 ServicePtrs[i]->bPrint_ok = False;
6383 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6385 DEBUG(3, ("adding IPC service\n"));
6387 SAFE_FREE(comment);
6388 return (True);
6391 /***************************************************************************
6392 Add a new printer service, with defaults coming from service iFrom.
6393 ***************************************************************************/
6395 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6397 const char *comment = "From Printcap";
6398 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6400 if (i < 0)
6401 return (False);
6403 /* note that we do NOT default the availability flag to True - */
6404 /* we take it from the default service passed. This allows all */
6405 /* dynamic printers to be disabled by disabling the [printers] */
6406 /* entry (if/when the 'available' keyword is implemented!). */
6408 /* the printer name is set to the service name. */
6409 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6410 string_set(&ServicePtrs[i]->comment, comment);
6412 /* set the browseable flag from the gloabl default */
6413 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6415 /* Printers cannot be read_only. */
6416 ServicePtrs[i]->bRead_only = False;
6417 /* No share modes on printer services. */
6418 ServicePtrs[i]->bShareModes = False;
6419 /* No oplocks on printer services. */
6420 ServicePtrs[i]->bOpLocks = False;
6421 /* Printer services must be printable. */
6422 ServicePtrs[i]->bPrint_ok = True;
6424 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6426 return (True);
6430 /***************************************************************************
6431 Check whether the given parameter name is valid.
6432 Parametric options (names containing a colon) are considered valid.
6433 ***************************************************************************/
6435 bool lp_parameter_is_valid(const char *pszParmName)
6437 return ((map_parameter(pszParmName) != -1) ||
6438 (strchr(pszParmName, ':') != NULL));
6441 /***************************************************************************
6442 Check whether the given name is the name of a global parameter.
6443 Returns True for strings belonging to parameters of class
6444 P_GLOBAL, False for all other strings, also for parametric options
6445 and strings not belonging to any option.
6446 ***************************************************************************/
6448 bool lp_parameter_is_global(const char *pszParmName)
6450 int num = map_parameter(pszParmName);
6452 if (num >= 0) {
6453 return (parm_table[num].p_class == P_GLOBAL);
6456 return False;
6459 /**************************************************************************
6460 Check whether the given name is the canonical name of a parameter.
6461 Returns False if it is not a valid parameter Name.
6462 For parametric options, True is returned.
6463 **************************************************************************/
6465 bool lp_parameter_is_canonical(const char *parm_name)
6467 if (!lp_parameter_is_valid(parm_name)) {
6468 return False;
6471 return (map_parameter(parm_name) ==
6472 map_parameter_canonical(parm_name, NULL));
6475 /**************************************************************************
6476 Determine the canonical name for a parameter.
6477 Indicate when it is an inverse (boolean) synonym instead of a
6478 "usual" synonym.
6479 **************************************************************************/
6481 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6482 bool *inverse)
6484 int num;
6486 if (!lp_parameter_is_valid(parm_name)) {
6487 *canon_parm = NULL;
6488 return False;
6491 num = map_parameter_canonical(parm_name, inverse);
6492 if (num < 0) {
6493 /* parametric option */
6494 *canon_parm = parm_name;
6495 } else {
6496 *canon_parm = parm_table[num].label;
6499 return True;
6503 /**************************************************************************
6504 Determine the canonical name for a parameter.
6505 Turn the value given into the inverse boolean expression when
6506 the synonym is an invers boolean synonym.
6508 Return True if parm_name is a valid parameter name and
6509 in case it is an invers boolean synonym, if the val string could
6510 successfully be converted to the reverse bool.
6511 Return false in all other cases.
6512 **************************************************************************/
6514 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6515 const char *val,
6516 const char **canon_parm,
6517 const char **canon_val)
6519 int num;
6520 bool inverse;
6522 if (!lp_parameter_is_valid(parm_name)) {
6523 *canon_parm = NULL;
6524 *canon_val = NULL;
6525 return False;
6528 num = map_parameter_canonical(parm_name, &inverse);
6529 if (num < 0) {
6530 /* parametric option */
6531 *canon_parm = parm_name;
6532 *canon_val = val;
6533 } else {
6534 *canon_parm = parm_table[num].label;
6535 if (inverse) {
6536 if (!lp_invert_boolean(val, canon_val)) {
6537 *canon_val = NULL;
6538 return False;
6540 } else {
6541 *canon_val = val;
6545 return True;
6548 /***************************************************************************
6549 Map a parameter's string representation to something we can use.
6550 Returns False if the parameter string is not recognised, else TRUE.
6551 ***************************************************************************/
6553 static int map_parameter(const char *pszParmName)
6555 int iIndex;
6557 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6558 return (-1);
6560 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6561 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6562 return (iIndex);
6564 /* Warn only if it isn't parametric option */
6565 if (strchr(pszParmName, ':') == NULL)
6566 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6567 /* We do return 'fail' for parametric options as well because they are
6568 stored in different storage
6570 return (-1);
6573 /***************************************************************************
6574 Map a parameter's string representation to the index of the canonical
6575 form of the parameter (it might be a synonym).
6576 Returns -1 if the parameter string is not recognised.
6577 ***************************************************************************/
6579 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6581 int parm_num, canon_num;
6582 bool loc_inverse = False;
6584 parm_num = map_parameter(pszParmName);
6585 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6586 /* invalid, parametric or no canidate for synonyms ... */
6587 goto done;
6590 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6591 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6592 parm_num = canon_num;
6593 goto done;
6597 done:
6598 if (inverse != NULL) {
6599 *inverse = loc_inverse;
6601 return parm_num;
6604 /***************************************************************************
6605 return true if parameter number parm1 is a synonym of parameter
6606 number parm2 (parm2 being the principal name).
6607 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6608 False otherwise.
6609 ***************************************************************************/
6611 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6613 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6614 (parm_table[parm1].flags & FLAG_HIDE) &&
6615 !(parm_table[parm2].flags & FLAG_HIDE))
6617 if (inverse != NULL) {
6618 if ((parm_table[parm1].type == P_BOOLREV) &&
6619 (parm_table[parm2].type == P_BOOL))
6621 *inverse = True;
6622 } else {
6623 *inverse = False;
6626 return True;
6628 return False;
6631 /***************************************************************************
6632 Show one parameter's name, type, [values,] and flags.
6633 (helper functions for show_parameter_list)
6634 ***************************************************************************/
6636 static void show_parameter(int parmIndex)
6638 int enumIndex, flagIndex;
6639 int parmIndex2;
6640 bool hadFlag;
6641 bool hadSyn;
6642 bool inverse;
6643 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6644 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6645 "P_ENUM", "P_SEP"};
6646 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6647 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6648 FLAG_HIDE, FLAG_DOS_STRING};
6649 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6650 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6651 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6653 printf("%s=%s", parm_table[parmIndex].label,
6654 type[parm_table[parmIndex].type]);
6655 if (parm_table[parmIndex].type == P_ENUM) {
6656 printf(",");
6657 for (enumIndex=0;
6658 parm_table[parmIndex].enum_list[enumIndex].name;
6659 enumIndex++)
6661 printf("%s%s",
6662 enumIndex ? "|" : "",
6663 parm_table[parmIndex].enum_list[enumIndex].name);
6666 printf(",");
6667 hadFlag = False;
6668 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6669 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6670 printf("%s%s",
6671 hadFlag ? "|" : "",
6672 flag_names[flagIndex]);
6673 hadFlag = True;
6677 /* output synonyms */
6678 hadSyn = False;
6679 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6680 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6681 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6682 parm_table[parmIndex2].label);
6683 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6684 if (!hadSyn) {
6685 printf(" (synonyms: ");
6686 hadSyn = True;
6687 } else {
6688 printf(", ");
6690 printf("%s%s", parm_table[parmIndex2].label,
6691 inverse ? "[i]" : "");
6694 if (hadSyn) {
6695 printf(")");
6698 printf("\n");
6701 /***************************************************************************
6702 Show all parameter's name, type, [values,] and flags.
6703 ***************************************************************************/
6705 void show_parameter_list(void)
6707 int classIndex, parmIndex;
6708 const char *section_names[] = { "local", "global", NULL};
6710 for (classIndex=0; section_names[classIndex]; classIndex++) {
6711 printf("[%s]\n", section_names[classIndex]);
6712 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6713 if (parm_table[parmIndex].p_class == classIndex) {
6714 show_parameter(parmIndex);
6720 /***************************************************************************
6721 Check if a given string correctly represents a boolean value.
6722 ***************************************************************************/
6724 bool lp_string_is_valid_boolean(const char *parm_value)
6726 return set_boolean(parm_value, NULL);
6729 /***************************************************************************
6730 Get the standard string representation of a boolean value ("yes" or "no")
6731 ***************************************************************************/
6733 static const char *get_boolean(bool bool_value)
6735 static const char *yes_str = "yes";
6736 static const char *no_str = "no";
6738 return (bool_value ? yes_str : no_str);
6741 /***************************************************************************
6742 Provide the string of the negated boolean value associated to the boolean
6743 given as a string. Returns False if the passed string does not correctly
6744 represent a boolean.
6745 ***************************************************************************/
6747 bool lp_invert_boolean(const char *str, const char **inverse_str)
6749 bool val;
6751 if (!set_boolean(str, &val)) {
6752 return False;
6755 *inverse_str = get_boolean(!val);
6756 return True;
6759 /***************************************************************************
6760 Provide the canonical string representation of a boolean value given
6761 as a string. Return True on success, False if the string given does
6762 not correctly represent a boolean.
6763 ***************************************************************************/
6765 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6767 bool val;
6769 if (!set_boolean(str, &val)) {
6770 return False;
6773 *canon_str = get_boolean(val);
6774 return True;
6777 /***************************************************************************
6778 Find a service by name. Otherwise works like get_service.
6779 ***************************************************************************/
6781 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6783 int iService = -1;
6784 char *canon_name;
6785 TDB_DATA data;
6787 if (ServiceHash == NULL) {
6788 return -1;
6791 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6793 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6795 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6796 iService = *(int *)data.dptr;
6799 TALLOC_FREE(canon_name);
6801 if ((iService != -1) && (LP_SNUM_OK(iService))
6802 && (pserviceDest != NULL)) {
6803 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6806 return (iService);
6809 /***************************************************************************
6810 Copy a service structure to another.
6811 If pcopymapDest is NULL then copy all fields
6812 ***************************************************************************/
6815 * Add a parametric option to a param_opt_struct,
6816 * replacing old value, if already present.
6818 static void set_param_opt(struct param_opt_struct **opt_list,
6819 const char *opt_name,
6820 const char *opt_value)
6822 struct param_opt_struct *new_opt, *opt;
6823 bool not_added;
6825 if (opt_list == NULL) {
6826 return;
6829 opt = *opt_list;
6830 not_added = true;
6832 /* Traverse destination */
6833 while (opt) {
6834 /* If we already have same option, override it */
6835 if (strwicmp(opt->key, opt_name) == 0) {
6836 string_free(&opt->value);
6837 TALLOC_FREE(opt->list);
6838 opt->value = SMB_STRDUP(opt_value);
6839 not_added = false;
6840 break;
6842 opt = opt->next;
6844 if (not_added) {
6845 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6846 new_opt->key = SMB_STRDUP(opt_name);
6847 new_opt->value = SMB_STRDUP(opt_value);
6848 new_opt->list = NULL;
6849 DLIST_ADD(*opt_list, new_opt);
6853 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6854 struct bitmap *pcopymapDest)
6856 int i;
6857 bool bcopyall = (pcopymapDest == NULL);
6858 struct param_opt_struct *data;
6860 for (i = 0; parm_table[i].label; i++)
6861 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6862 (bcopyall || bitmap_query(pcopymapDest,i))) {
6863 void *def_ptr = parm_table[i].ptr;
6864 void *src_ptr =
6865 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6866 &sDefault);
6867 void *dest_ptr =
6868 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6869 &sDefault);
6871 switch (parm_table[i].type) {
6872 case P_BOOL:
6873 case P_BOOLREV:
6874 *(bool *)dest_ptr = *(bool *)src_ptr;
6875 break;
6877 case P_INTEGER:
6878 case P_ENUM:
6879 case P_OCTAL:
6880 *(int *)dest_ptr = *(int *)src_ptr;
6881 break;
6883 case P_CHAR:
6884 *(char *)dest_ptr = *(char *)src_ptr;
6885 break;
6887 case P_STRING:
6888 string_set((char **)dest_ptr,
6889 *(char **)src_ptr);
6890 break;
6892 case P_USTRING:
6893 string_set((char **)dest_ptr,
6894 *(char **)src_ptr);
6895 strupper_m(*(char **)dest_ptr);
6896 break;
6897 case P_LIST:
6898 TALLOC_FREE(*((char ***)dest_ptr));
6899 *((char ***)dest_ptr) = str_list_copy(NULL,
6900 *(const char ***)src_ptr);
6901 break;
6902 default:
6903 break;
6907 if (bcopyall) {
6908 init_copymap(pserviceDest);
6909 if (pserviceSource->copymap)
6910 bitmap_copy(pserviceDest->copymap,
6911 pserviceSource->copymap);
6914 data = pserviceSource->param_opt;
6915 while (data) {
6916 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6917 data = data->next;
6921 /***************************************************************************
6922 Check a service for consistency. Return False if the service is in any way
6923 incomplete or faulty, else True.
6924 ***************************************************************************/
6926 bool service_ok(int iService)
6928 bool bRetval;
6930 bRetval = True;
6931 if (ServicePtrs[iService]->szService[0] == '\0') {
6932 DEBUG(0, ("The following message indicates an internal error:\n"));
6933 DEBUG(0, ("No service name in service entry.\n"));
6934 bRetval = False;
6937 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6938 /* I can't see why you'd want a non-printable printer service... */
6939 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6940 if (!ServicePtrs[iService]->bPrint_ok) {
6941 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6942 ServicePtrs[iService]->szService));
6943 ServicePtrs[iService]->bPrint_ok = True;
6945 /* [printers] service must also be non-browsable. */
6946 if (ServicePtrs[iService]->bBrowseable)
6947 ServicePtrs[iService]->bBrowseable = False;
6950 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6951 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6952 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6954 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6955 ServicePtrs[iService]->szService));
6956 ServicePtrs[iService]->bAvailable = False;
6959 /* If a service is flagged unavailable, log the fact at level 1. */
6960 if (!ServicePtrs[iService]->bAvailable)
6961 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6962 ServicePtrs[iService]->szService));
6964 return (bRetval);
6967 static struct smbconf_ctx *lp_smbconf_ctx(void)
6969 WERROR werr;
6970 static struct smbconf_ctx *conf_ctx = NULL;
6972 if (conf_ctx == NULL) {
6973 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6974 if (!W_ERROR_IS_OK(werr)) {
6975 DEBUG(1, ("error initializing registry configuration: "
6976 "%s\n", win_errstr(werr)));
6977 conf_ctx = NULL;
6981 return conf_ctx;
6984 static bool process_smbconf_service(struct smbconf_service *service)
6986 uint32_t count;
6987 bool ret;
6989 if (service == NULL) {
6990 return false;
6993 ret = do_section(service->name, NULL);
6994 if (ret != true) {
6995 return false;
6997 for (count = 0; count < service->num_params; count++) {
6998 ret = do_parameter(service->param_names[count],
6999 service->param_values[count],
7000 NULL);
7001 if (ret != true) {
7002 return false;
7005 if (iServiceIndex >= 0) {
7006 return service_ok(iServiceIndex);
7008 return true;
7012 * load a service from registry and activate it
7014 bool process_registry_service(const char *service_name)
7016 WERROR werr;
7017 struct smbconf_service *service = NULL;
7018 TALLOC_CTX *mem_ctx = talloc_stackframe();
7019 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7020 bool ret = false;
7022 if (conf_ctx == NULL) {
7023 goto done;
7026 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7028 if (!smbconf_share_exists(conf_ctx, service_name)) {
7030 * Registry does not contain data for this service (yet),
7031 * but make sure lp_load doesn't return false.
7033 ret = true;
7034 goto done;
7037 werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7038 if (!W_ERROR_IS_OK(werr)) {
7039 goto done;
7042 ret = process_smbconf_service(service);
7043 if (!ret) {
7044 goto done;
7047 /* store the csn */
7048 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7050 done:
7051 TALLOC_FREE(mem_ctx);
7052 return ret;
7056 * process_registry_globals
7058 static bool process_registry_globals(void)
7060 bool ret;
7062 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7064 ret = do_parameter("registry shares", "yes", NULL);
7065 if (!ret) {
7066 return ret;
7069 return process_registry_service(GLOBAL_NAME);
7072 bool process_registry_shares(void)
7074 WERROR werr;
7075 uint32_t count;
7076 struct smbconf_service **service = NULL;
7077 uint32_t num_shares = 0;
7078 TALLOC_CTX *mem_ctx = talloc_stackframe();
7079 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7080 bool ret = false;
7082 if (conf_ctx == NULL) {
7083 goto done;
7086 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7087 if (!W_ERROR_IS_OK(werr)) {
7088 goto done;
7091 ret = true;
7093 for (count = 0; count < num_shares; count++) {
7094 if (strequal(service[count]->name, GLOBAL_NAME)) {
7095 continue;
7097 ret = process_smbconf_service(service[count]);
7098 if (!ret) {
7099 goto done;
7103 /* store the csn */
7104 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7106 done:
7107 TALLOC_FREE(mem_ctx);
7108 return ret;
7111 #define MAX_INCLUDE_DEPTH 100
7113 static uint8_t include_depth;
7115 static struct file_lists {
7116 struct file_lists *next;
7117 char *name;
7118 char *subfname;
7119 time_t modtime;
7120 } *file_lists = NULL;
7122 /*******************************************************************
7123 Keep a linked list of all config files so we know when one has changed
7124 it's date and needs to be reloaded.
7125 ********************************************************************/
7127 static void add_to_file_list(const char *fname, const char *subfname)
7129 struct file_lists *f = file_lists;
7131 while (f) {
7132 if (f->name && !strcmp(f->name, fname))
7133 break;
7134 f = f->next;
7137 if (!f) {
7138 f = SMB_MALLOC_P(struct file_lists);
7139 if (!f)
7140 return;
7141 f->next = file_lists;
7142 f->name = SMB_STRDUP(fname);
7143 if (!f->name) {
7144 SAFE_FREE(f);
7145 return;
7147 f->subfname = SMB_STRDUP(subfname);
7148 if (!f->subfname) {
7149 SAFE_FREE(f->name);
7150 SAFE_FREE(f);
7151 return;
7153 file_lists = f;
7154 f->modtime = file_modtime(subfname);
7155 } else {
7156 time_t t = file_modtime(subfname);
7157 if (t)
7158 f->modtime = t;
7160 return;
7164 * Free the file lists
7166 static void free_file_list(void)
7168 struct file_lists *f;
7169 struct file_lists *next;
7171 f = file_lists;
7172 while( f ) {
7173 next = f->next;
7174 SAFE_FREE( f->name );
7175 SAFE_FREE( f->subfname );
7176 SAFE_FREE( f );
7177 f = next;
7179 file_lists = NULL;
7184 * Utility function for outsiders to check if we're running on registry.
7186 bool lp_config_backend_is_registry(void)
7188 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7192 * Utility function to check if the config backend is FILE.
7194 bool lp_config_backend_is_file(void)
7196 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7199 /*******************************************************************
7200 Check if a config file has changed date.
7201 ********************************************************************/
7203 bool lp_file_list_changed(void)
7205 struct file_lists *f = file_lists;
7207 DEBUG(6, ("lp_file_list_changed()\n"));
7209 while (f) {
7210 time_t mod_time;
7212 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7213 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7215 if (conf_ctx == NULL) {
7216 return false;
7218 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7219 NULL))
7221 DEBUGADD(6, ("registry config changed\n"));
7222 return true;
7224 } else {
7225 char *n2 = NULL;
7226 n2 = talloc_sub_basic(talloc_tos(),
7227 get_current_username(),
7228 current_user_info.domain,
7229 f->name);
7230 if (!n2) {
7231 return false;
7233 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7234 f->name, n2, ctime(&f->modtime)));
7236 mod_time = file_modtime(n2);
7238 if (mod_time &&
7239 ((f->modtime != mod_time) ||
7240 (f->subfname == NULL) ||
7241 (strcmp(n2, f->subfname) != 0)))
7243 DEBUGADD(6,
7244 ("file %s modified: %s\n", n2,
7245 ctime(&mod_time)));
7246 f->modtime = mod_time;
7247 SAFE_FREE(f->subfname);
7248 f->subfname = SMB_STRDUP(n2);
7249 TALLOC_FREE(n2);
7250 return true;
7252 TALLOC_FREE(n2);
7254 f = f->next;
7256 return (False);
7260 /***************************************************************************
7261 Run standard_sub_basic on netbios name... needed because global_myname
7262 is not accessed through any lp_ macro.
7263 Note: We must *NOT* use string_set() here as ptr points to global_myname.
7264 ***************************************************************************/
7266 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7268 bool ret;
7269 char *netbios_name = talloc_sub_basic(
7270 talloc_tos(), get_current_username(), current_user_info.domain,
7271 pszParmValue);
7273 ret = set_global_myname(netbios_name);
7274 TALLOC_FREE(netbios_name);
7275 string_set(&Globals.szNetbiosName,global_myname());
7277 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7278 global_myname()));
7280 return ret;
7283 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7285 if (strcmp(*ptr, pszParmValue) != 0) {
7286 string_set(ptr, pszParmValue);
7287 init_iconv();
7289 return True;
7294 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7296 bool ret;
7298 ret = set_global_myworkgroup(pszParmValue);
7299 string_set(&Globals.szWorkgroup,lp_workgroup());
7301 return ret;
7304 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7306 bool ret;
7308 ret = set_global_scope(pszParmValue);
7309 string_set(&Globals.szNetbiosScope,global_scope());
7311 return ret;
7314 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7316 TALLOC_FREE(Globals.szNetbiosAliases);
7317 Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7318 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7321 /***************************************************************************
7322 Handle the include operation.
7323 ***************************************************************************/
7324 static bool bAllowIncludeRegistry = true;
7326 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7328 char *fname;
7330 if (include_depth >= MAX_INCLUDE_DEPTH) {
7331 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7332 include_depth));
7333 return false;
7336 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7337 if (!bAllowIncludeRegistry) {
7338 return true;
7340 if (bInGlobalSection) {
7341 bool ret;
7342 include_depth++;
7343 ret = process_registry_globals();
7344 include_depth--;
7345 return ret;
7346 } else {
7347 DEBUG(1, ("\"include = registry\" only effective "
7348 "in %s section\n", GLOBAL_NAME));
7349 return false;
7353 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7354 current_user_info.domain,
7355 pszParmValue);
7357 add_to_file_list(pszParmValue, fname);
7359 string_set(ptr, fname);
7361 if (file_exist(fname)) {
7362 bool ret;
7363 include_depth++;
7364 ret = pm_process(fname, do_section, do_parameter, NULL);
7365 include_depth--;
7366 TALLOC_FREE(fname);
7367 return ret;
7370 DEBUG(2, ("Can't find include file %s\n", fname));
7371 TALLOC_FREE(fname);
7372 return true;
7375 /***************************************************************************
7376 Handle the interpretation of the copy parameter.
7377 ***************************************************************************/
7379 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7381 bool bRetval;
7382 int iTemp;
7383 struct service serviceTemp;
7385 string_set(ptr, pszParmValue);
7387 init_service(&serviceTemp);
7389 bRetval = False;
7391 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7393 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7394 if (iTemp == iServiceIndex) {
7395 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7396 } else {
7397 copy_service(ServicePtrs[iServiceIndex],
7398 &serviceTemp,
7399 ServicePtrs[iServiceIndex]->copymap);
7400 bRetval = True;
7402 } else {
7403 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7404 bRetval = False;
7407 free_service(&serviceTemp);
7408 return (bRetval);
7411 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7413 Globals.ldap_debug_level = lp_int(pszParmValue);
7414 init_ldap_debugging();
7415 return true;
7418 /***************************************************************************
7419 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7420 parameters is:
7422 [global]
7424 idmap uid = 1000-1999
7425 idmap gid = 700-899
7427 We only do simple parsing checks here. The strings are parsed into useful
7428 structures in the idmap daemon code.
7430 ***************************************************************************/
7432 /* Some lp_ routines to return idmap [ug]id information */
7434 static uid_t idmap_uid_low, idmap_uid_high;
7435 static gid_t idmap_gid_low, idmap_gid_high;
7437 bool lp_idmap_uid(uid_t *low, uid_t *high)
7439 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7440 return False;
7442 if (low)
7443 *low = idmap_uid_low;
7445 if (high)
7446 *high = idmap_uid_high;
7448 return True;
7451 bool lp_idmap_gid(gid_t *low, gid_t *high)
7453 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7454 return False;
7456 if (low)
7457 *low = idmap_gid_low;
7459 if (high)
7460 *high = idmap_gid_high;
7462 return True;
7465 /* Do some simple checks on "idmap [ug]id" parameter values */
7467 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7469 uint32 low, high;
7471 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7472 return False;
7474 /* Parse OK */
7476 string_set(ptr, pszParmValue);
7478 idmap_uid_low = low;
7479 idmap_uid_high = high;
7481 return True;
7484 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7486 uint32 low, high;
7488 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7489 return False;
7491 /* Parse OK */
7493 string_set(ptr, pszParmValue);
7495 idmap_gid_low = low;
7496 idmap_gid_high = high;
7498 return True;
7501 /***************************************************************************
7502 Handle the DEBUG level list.
7503 ***************************************************************************/
7505 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7507 string_set(ptr, pszParmValueIn);
7508 return debug_parse_levels(pszParmValueIn);
7511 /***************************************************************************
7512 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7513 ***************************************************************************/
7515 static const char *append_ldap_suffix( const char *str )
7517 const char *suffix_string;
7520 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7521 Globals.szLdapSuffix );
7522 if ( !suffix_string ) {
7523 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7524 return "";
7527 return suffix_string;
7530 const char *lp_ldap_machine_suffix(void)
7532 if (Globals.szLdapMachineSuffix[0])
7533 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7535 return lp_string(Globals.szLdapSuffix);
7538 const char *lp_ldap_user_suffix(void)
7540 if (Globals.szLdapUserSuffix[0])
7541 return append_ldap_suffix(Globals.szLdapUserSuffix);
7543 return lp_string(Globals.szLdapSuffix);
7546 const char *lp_ldap_group_suffix(void)
7548 if (Globals.szLdapGroupSuffix[0])
7549 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7551 return lp_string(Globals.szLdapSuffix);
7554 const char *lp_ldap_idmap_suffix(void)
7556 if (Globals.szLdapIdmapSuffix[0])
7557 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7559 return lp_string(Globals.szLdapSuffix);
7562 /****************************************************************************
7563 set the value for a P_ENUM
7564 ***************************************************************************/
7566 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7567 int *ptr )
7569 int i;
7571 for (i = 0; parm->enum_list[i].name; i++) {
7572 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7573 *ptr = parm->enum_list[i].value;
7574 return;
7577 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7578 pszParmValue, parm->label));
7581 /***************************************************************************
7582 ***************************************************************************/
7584 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7586 static int parm_num = -1;
7587 struct service *s;
7589 if ( parm_num == -1 )
7590 parm_num = map_parameter( "printing" );
7592 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7594 if ( snum < 0 )
7595 s = &sDefault;
7596 else
7597 s = ServicePtrs[snum];
7599 init_printer_values( s );
7601 return True;
7605 /***************************************************************************
7606 Initialise a copymap.
7607 ***************************************************************************/
7609 static void init_copymap(struct service *pservice)
7611 int i;
7613 TALLOC_FREE(pservice->copymap);
7615 pservice->copymap = bitmap_talloc(talloc_autofree_context(),
7616 NUMPARAMETERS);
7617 if (!pservice->copymap)
7618 DEBUG(0,
7619 ("Couldn't allocate copymap!! (size %d)\n",
7620 (int)NUMPARAMETERS));
7621 else
7622 for (i = 0; i < NUMPARAMETERS; i++)
7623 bitmap_set(pservice->copymap, i);
7626 /***************************************************************************
7627 Return the local pointer to a parameter given a service struct and the
7628 pointer into the default structure.
7629 ***************************************************************************/
7631 static void *lp_local_ptr(struct service *service, void *ptr)
7633 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7636 /***************************************************************************
7637 Return the local pointer to a parameter given the service number and the
7638 pointer into the default structure.
7639 ***************************************************************************/
7641 void *lp_local_ptr_by_snum(int snum, void *ptr)
7643 return lp_local_ptr(ServicePtrs[snum], ptr);
7646 /***************************************************************************
7647 Process a parameter for a particular service number. If snum < 0
7648 then assume we are in the globals.
7649 ***************************************************************************/
7651 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7653 int parmnum, i;
7654 void *parm_ptr = NULL; /* where we are going to store the result */
7655 void *def_ptr = NULL;
7656 struct param_opt_struct **opt_list;
7658 parmnum = map_parameter(pszParmName);
7660 if (parmnum < 0) {
7661 if (strchr(pszParmName, ':') == NULL) {
7662 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7663 pszParmName));
7664 return (True);
7668 * We've got a parametric option
7671 opt_list = (snum < 0)
7672 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7673 set_param_opt(opt_list, pszParmName, pszParmValue);
7675 return (True);
7678 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7679 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7680 pszParmName));
7683 def_ptr = parm_table[parmnum].ptr;
7685 /* we might point at a service, the default service or a global */
7686 if (snum < 0) {
7687 parm_ptr = def_ptr;
7688 } else {
7689 if (parm_table[parmnum].p_class == P_GLOBAL) {
7690 DEBUG(0,
7691 ("Global parameter %s found in service section!\n",
7692 pszParmName));
7693 return (True);
7695 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7698 if (snum >= 0) {
7699 if (!ServicePtrs[snum]->copymap)
7700 init_copymap(ServicePtrs[snum]);
7702 /* this handles the aliases - set the copymap for other entries with
7703 the same data pointer */
7704 for (i = 0; parm_table[i].label; i++)
7705 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7706 bitmap_clear(ServicePtrs[snum]->copymap, i);
7709 /* if it is a special case then go ahead */
7710 if (parm_table[parmnum].special) {
7711 return parm_table[parmnum].special(snum, pszParmValue,
7712 (char **)parm_ptr);
7715 /* now switch on the type of variable it is */
7716 switch (parm_table[parmnum].type)
7718 case P_BOOL:
7719 *(bool *)parm_ptr = lp_bool(pszParmValue);
7720 break;
7722 case P_BOOLREV:
7723 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7724 break;
7726 case P_INTEGER:
7727 *(int *)parm_ptr = lp_int(pszParmValue);
7728 break;
7730 case P_CHAR:
7731 *(char *)parm_ptr = *pszParmValue;
7732 break;
7734 case P_OCTAL:
7735 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7736 if ( i != 1 ) {
7737 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7739 break;
7741 case P_LIST:
7742 TALLOC_FREE(*((char ***)parm_ptr));
7743 *(char ***)parm_ptr = str_list_make_v3(
7744 talloc_autofree_context(), pszParmValue, NULL);
7745 break;
7747 case P_STRING:
7748 string_set((char **)parm_ptr, pszParmValue);
7749 break;
7751 case P_USTRING:
7752 string_set((char **)parm_ptr, pszParmValue);
7753 strupper_m(*(char **)parm_ptr);
7754 break;
7756 case P_ENUM:
7757 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7758 break;
7759 case P_SEP:
7760 break;
7763 return (True);
7766 /***************************************************************************
7767 Process a parameter.
7768 ***************************************************************************/
7770 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7771 void *userdata)
7773 if (!bInGlobalSection && bGlobalOnly)
7774 return (True);
7776 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7778 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7779 pszParmName, pszParmValue));
7782 /***************************************************************************
7783 Print a parameter of the specified type.
7784 ***************************************************************************/
7786 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7788 int i;
7789 switch (p->type)
7791 case P_ENUM:
7792 for (i = 0; p->enum_list[i].name; i++) {
7793 if (*(int *)ptr == p->enum_list[i].value) {
7794 fprintf(f, "%s",
7795 p->enum_list[i].name);
7796 break;
7799 break;
7801 case P_BOOL:
7802 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7803 break;
7805 case P_BOOLREV:
7806 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7807 break;
7809 case P_INTEGER:
7810 fprintf(f, "%d", *(int *)ptr);
7811 break;
7813 case P_CHAR:
7814 fprintf(f, "%c", *(char *)ptr);
7815 break;
7817 case P_OCTAL: {
7818 char *o = octal_string(*(int *)ptr);
7819 fprintf(f, "%s", o);
7820 TALLOC_FREE(o);
7821 break;
7824 case P_LIST:
7825 if ((char ***)ptr && *(char ***)ptr) {
7826 char **list = *(char ***)ptr;
7827 for (; *list; list++) {
7828 /* surround strings with whitespace in double quotes */
7829 if ( strchr_m( *list, ' ' ) )
7830 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7831 else
7832 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7835 break;
7837 case P_STRING:
7838 case P_USTRING:
7839 if (*(char **)ptr) {
7840 fprintf(f, "%s", *(char **)ptr);
7842 break;
7843 case P_SEP:
7844 break;
7848 /***************************************************************************
7849 Check if two parameters are equal.
7850 ***************************************************************************/
7852 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7854 switch (type) {
7855 case P_BOOL:
7856 case P_BOOLREV:
7857 return (*((bool *)ptr1) == *((bool *)ptr2));
7859 case P_INTEGER:
7860 case P_ENUM:
7861 case P_OCTAL:
7862 return (*((int *)ptr1) == *((int *)ptr2));
7864 case P_CHAR:
7865 return (*((char *)ptr1) == *((char *)ptr2));
7867 case P_LIST:
7868 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7870 case P_STRING:
7871 case P_USTRING:
7873 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7874 if (p1 && !*p1)
7875 p1 = NULL;
7876 if (p2 && !*p2)
7877 p2 = NULL;
7878 return (p1 == p2 || strequal(p1, p2));
7880 case P_SEP:
7881 break;
7883 return (False);
7886 /***************************************************************************
7887 Initialize any local varients in the sDefault table.
7888 ***************************************************************************/
7890 void init_locals(void)
7892 /* None as yet. */
7895 /***************************************************************************
7896 Process a new section (service). At this stage all sections are services.
7897 Later we'll have special sections that permit server parameters to be set.
7898 Returns True on success, False on failure.
7899 ***************************************************************************/
7901 static bool do_section(const char *pszSectionName, void *userdata)
7903 bool bRetval;
7904 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7905 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7906 bRetval = False;
7908 /* if we were in a global section then do the local inits */
7909 if (bInGlobalSection && !isglobal)
7910 init_locals();
7912 /* if we've just struck a global section, note the fact. */
7913 bInGlobalSection = isglobal;
7915 /* check for multiple global sections */
7916 if (bInGlobalSection) {
7917 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7918 return (True);
7921 if (!bInGlobalSection && bGlobalOnly)
7922 return (True);
7924 /* if we have a current service, tidy it up before moving on */
7925 bRetval = True;
7927 if (iServiceIndex >= 0)
7928 bRetval = service_ok(iServiceIndex);
7930 /* if all is still well, move to the next record in the services array */
7931 if (bRetval) {
7932 /* We put this here to avoid an odd message order if messages are */
7933 /* issued by the post-processing of a previous section. */
7934 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7936 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7937 < 0) {
7938 DEBUG(0, ("Failed to add a new service\n"));
7939 return (False);
7943 return (bRetval);
7947 /***************************************************************************
7948 Determine if a partcular base parameter is currentl set to the default value.
7949 ***************************************************************************/
7951 static bool is_default(int i)
7953 if (!defaults_saved)
7954 return False;
7955 switch (parm_table[i].type) {
7956 case P_LIST:
7957 return str_list_equal((const char **)parm_table[i].def.lvalue,
7958 *(const char ***)parm_table[i].ptr);
7959 case P_STRING:
7960 case P_USTRING:
7961 return strequal(parm_table[i].def.svalue,
7962 *(char **)parm_table[i].ptr);
7963 case P_BOOL:
7964 case P_BOOLREV:
7965 return parm_table[i].def.bvalue ==
7966 *(bool *)parm_table[i].ptr;
7967 case P_CHAR:
7968 return parm_table[i].def.cvalue ==
7969 *(char *)parm_table[i].ptr;
7970 case P_INTEGER:
7971 case P_OCTAL:
7972 case P_ENUM:
7973 return parm_table[i].def.ivalue ==
7974 *(int *)parm_table[i].ptr;
7975 case P_SEP:
7976 break;
7978 return False;
7981 /***************************************************************************
7982 Display the contents of the global structure.
7983 ***************************************************************************/
7985 static void dump_globals(FILE *f)
7987 int i;
7988 struct param_opt_struct *data;
7990 fprintf(f, "[global]\n");
7992 for (i = 0; parm_table[i].label; i++)
7993 if (parm_table[i].p_class == P_GLOBAL &&
7994 !(parm_table[i].flags & FLAG_META) &&
7995 parm_table[i].ptr &&
7996 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7997 if (defaults_saved && is_default(i))
7998 continue;
7999 fprintf(f, "\t%s = ", parm_table[i].label);
8000 print_parameter(&parm_table[i], parm_table[i].ptr, f);
8001 fprintf(f, "\n");
8003 if (Globals.param_opt != NULL) {
8004 data = Globals.param_opt;
8005 while(data) {
8006 fprintf(f, "\t%s = %s\n", data->key, data->value);
8007 data = data->next;
8013 /***************************************************************************
8014 Return True if a local parameter is currently set to the global default.
8015 ***************************************************************************/
8017 bool lp_is_default(int snum, struct parm_struct *parm)
8019 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
8021 return equal_parameter(parm->type,
8022 ((char *)ServicePtrs[snum]) + pdiff,
8023 ((char *)&sDefault) + pdiff);
8026 /***************************************************************************
8027 Display the contents of a single services record.
8028 ***************************************************************************/
8030 static void dump_a_service(struct service *pService, FILE * f)
8032 int i;
8033 struct param_opt_struct *data;
8035 if (pService != &sDefault)
8036 fprintf(f, "[%s]\n", pService->szService);
8038 for (i = 0; parm_table[i].label; i++) {
8040 if (parm_table[i].p_class == P_LOCAL &&
8041 !(parm_table[i].flags & FLAG_META) &&
8042 parm_table[i].ptr &&
8043 (*parm_table[i].label != '-') &&
8044 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8046 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
8048 if (pService == &sDefault) {
8049 if (defaults_saved && is_default(i))
8050 continue;
8051 } else {
8052 if (equal_parameter(parm_table[i].type,
8053 ((char *)pService) +
8054 pdiff,
8055 ((char *)&sDefault) +
8056 pdiff))
8057 continue;
8060 fprintf(f, "\t%s = ", parm_table[i].label);
8061 print_parameter(&parm_table[i],
8062 ((char *)pService) + pdiff, f);
8063 fprintf(f, "\n");
8067 if (pService->param_opt != NULL) {
8068 data = pService->param_opt;
8069 while(data) {
8070 fprintf(f, "\t%s = %s\n", data->key, data->value);
8071 data = data->next;
8076 /***************************************************************************
8077 Display the contents of a parameter of a single services record.
8078 ***************************************************************************/
8080 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8082 int i;
8083 bool result = False;
8084 parm_class p_class;
8085 unsigned flag = 0;
8086 fstring local_parm_name;
8087 char *parm_opt;
8088 const char *parm_opt_value;
8090 /* check for parametrical option */
8091 fstrcpy( local_parm_name, parm_name);
8092 parm_opt = strchr( local_parm_name, ':');
8094 if (parm_opt) {
8095 *parm_opt = '\0';
8096 parm_opt++;
8097 if (strlen(parm_opt)) {
8098 parm_opt_value = lp_parm_const_string( snum,
8099 local_parm_name, parm_opt, NULL);
8100 if (parm_opt_value) {
8101 printf( "%s\n", parm_opt_value);
8102 result = True;
8105 return result;
8108 /* check for a key and print the value */
8109 if (isGlobal) {
8110 p_class = P_GLOBAL;
8111 flag = FLAG_GLOBAL;
8112 } else
8113 p_class = P_LOCAL;
8115 for (i = 0; parm_table[i].label; i++) {
8116 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8117 !(parm_table[i].flags & FLAG_META) &&
8118 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8119 parm_table[i].ptr &&
8120 (*parm_table[i].label != '-') &&
8121 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8123 void *ptr;
8125 if (isGlobal) {
8126 ptr = parm_table[i].ptr;
8127 } else {
8128 struct service *pService = ServicePtrs[snum];
8129 ptr = ((char *)pService) +
8130 PTR_DIFF(parm_table[i].ptr, &sDefault);
8133 print_parameter(&parm_table[i],
8134 ptr, f);
8135 fprintf(f, "\n");
8136 result = True;
8137 break;
8141 return result;
8144 /***************************************************************************
8145 Return info about the requested parameter (given as a string).
8146 Return NULL when the string is not a valid parameter name.
8147 ***************************************************************************/
8149 struct parm_struct *lp_get_parameter(const char *param_name)
8151 int num = map_parameter(param_name);
8153 if (num < 0) {
8154 return NULL;
8157 return &parm_table[num];
8160 /***************************************************************************
8161 Return info about the next parameter in a service.
8162 snum==GLOBAL_SECTION_SNUM gives the globals.
8163 Return NULL when out of parameters.
8164 ***************************************************************************/
8166 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8168 if (snum < 0) {
8169 /* do the globals */
8170 for (; parm_table[*i].label; (*i)++) {
8171 if (parm_table[*i].p_class == P_SEPARATOR)
8172 return &parm_table[(*i)++];
8174 if (!parm_table[*i].ptr
8175 || (*parm_table[*i].label == '-'))
8176 continue;
8178 if ((*i) > 0
8179 && (parm_table[*i].ptr ==
8180 parm_table[(*i) - 1].ptr))
8181 continue;
8183 if (is_default(*i) && !allparameters)
8184 continue;
8186 return &parm_table[(*i)++];
8188 } else {
8189 struct service *pService = ServicePtrs[snum];
8191 for (; parm_table[*i].label; (*i)++) {
8192 if (parm_table[*i].p_class == P_SEPARATOR)
8193 return &parm_table[(*i)++];
8195 if (parm_table[*i].p_class == P_LOCAL &&
8196 parm_table[*i].ptr &&
8197 (*parm_table[*i].label != '-') &&
8198 ((*i) == 0 ||
8199 (parm_table[*i].ptr !=
8200 parm_table[(*i) - 1].ptr)))
8202 int pdiff =
8203 PTR_DIFF(parm_table[*i].ptr,
8204 &sDefault);
8206 if (allparameters ||
8207 !equal_parameter(parm_table[*i].type,
8208 ((char *)pService) +
8209 pdiff,
8210 ((char *)&sDefault) +
8211 pdiff))
8213 return &parm_table[(*i)++];
8219 return NULL;
8223 #if 0
8224 /***************************************************************************
8225 Display the contents of a single copy structure.
8226 ***************************************************************************/
8227 static void dump_copy_map(bool *pcopymap)
8229 int i;
8230 if (!pcopymap)
8231 return;
8233 printf("\n\tNon-Copied parameters:\n");
8235 for (i = 0; parm_table[i].label; i++)
8236 if (parm_table[i].p_class == P_LOCAL &&
8237 parm_table[i].ptr && !pcopymap[i] &&
8238 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8240 printf("\t\t%s\n", parm_table[i].label);
8243 #endif
8245 /***************************************************************************
8246 Return TRUE if the passed service number is within range.
8247 ***************************************************************************/
8249 bool lp_snum_ok(int iService)
8251 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8254 /***************************************************************************
8255 Auto-load some home services.
8256 ***************************************************************************/
8258 static void lp_add_auto_services(char *str)
8260 char *s;
8261 char *p;
8262 int homes;
8263 char *saveptr;
8265 if (!str)
8266 return;
8268 s = SMB_STRDUP(str);
8269 if (!s)
8270 return;
8272 homes = lp_servicenumber(HOMES_NAME);
8274 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8275 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8276 char *home;
8278 if (lp_servicenumber(p) >= 0)
8279 continue;
8281 home = get_user_home_dir(talloc_tos(), p);
8283 if (home && home[0] && homes >= 0)
8284 lp_add_home(p, homes, p, home);
8286 TALLOC_FREE(home);
8288 SAFE_FREE(s);
8291 /***************************************************************************
8292 Auto-load one printer.
8293 ***************************************************************************/
8295 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8297 int printers = lp_servicenumber(PRINTERS_NAME);
8298 int i;
8300 if (lp_servicenumber(name) < 0) {
8301 lp_add_printer(name, printers);
8302 if ((i = lp_servicenumber(name)) >= 0) {
8303 string_set(&ServicePtrs[i]->comment, comment);
8304 ServicePtrs[i]->autoloaded = True;
8309 /***************************************************************************
8310 Have we loaded a services file yet?
8311 ***************************************************************************/
8313 bool lp_loaded(void)
8315 return (bLoaded);
8318 /***************************************************************************
8319 Unload unused services.
8320 ***************************************************************************/
8322 void lp_killunused(bool (*snumused) (int))
8324 int i;
8325 for (i = 0; i < iNumServices; i++) {
8326 if (!VALID(i))
8327 continue;
8329 /* don't kill autoloaded or usershare services */
8330 if ( ServicePtrs[i]->autoloaded ||
8331 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8332 continue;
8335 if (!snumused || !snumused(i)) {
8336 free_service_byindex(i);
8342 * Kill all except autoloaded and usershare services - convenience wrapper
8344 void lp_kill_all_services(void)
8346 lp_killunused(NULL);
8349 /***************************************************************************
8350 Unload a service.
8351 ***************************************************************************/
8353 void lp_killservice(int iServiceIn)
8355 if (VALID(iServiceIn)) {
8356 free_service_byindex(iServiceIn);
8360 /***************************************************************************
8361 Save the curent values of all global and sDefault parameters into the
8362 defaults union. This allows swat and testparm to show only the
8363 changed (ie. non-default) parameters.
8364 ***************************************************************************/
8366 static void lp_save_defaults(void)
8368 int i;
8369 for (i = 0; parm_table[i].label; i++) {
8370 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8371 continue;
8372 switch (parm_table[i].type) {
8373 case P_LIST:
8374 parm_table[i].def.lvalue = str_list_copy(
8375 NULL, *(const char ***)parm_table[i].ptr);
8376 break;
8377 case P_STRING:
8378 case P_USTRING:
8379 if (parm_table[i].ptr) {
8380 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8381 } else {
8382 parm_table[i].def.svalue = NULL;
8384 break;
8385 case P_BOOL:
8386 case P_BOOLREV:
8387 parm_table[i].def.bvalue =
8388 *(bool *)parm_table[i].ptr;
8389 break;
8390 case P_CHAR:
8391 parm_table[i].def.cvalue =
8392 *(char *)parm_table[i].ptr;
8393 break;
8394 case P_INTEGER:
8395 case P_OCTAL:
8396 case P_ENUM:
8397 parm_table[i].def.ivalue =
8398 *(int *)parm_table[i].ptr;
8399 break;
8400 case P_SEP:
8401 break;
8404 defaults_saved = True;
8407 /*******************************************************************
8408 Set the server type we will announce as via nmbd.
8409 ********************************************************************/
8411 static const struct srv_role_tab {
8412 uint32 role;
8413 const char *role_str;
8414 } srv_role_tab [] = {
8415 { ROLE_STANDALONE, "ROLE_STANDALONE" },
8416 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8417 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8418 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8419 { 0, NULL }
8422 const char* server_role_str(uint32 role)
8424 int i = 0;
8425 for (i=0; srv_role_tab[i].role_str; i++) {
8426 if (role == srv_role_tab[i].role) {
8427 return srv_role_tab[i].role_str;
8430 return NULL;
8433 static void set_server_role(void)
8435 server_role = ROLE_STANDALONE;
8437 switch (lp_security()) {
8438 case SEC_SHARE:
8439 if (lp_domain_logons())
8440 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8441 break;
8442 case SEC_SERVER:
8443 if (lp_domain_logons())
8444 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8445 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8446 server_role = ROLE_STANDALONE;
8447 break;
8448 case SEC_DOMAIN:
8449 if (lp_domain_logons()) {
8450 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8451 server_role = ROLE_DOMAIN_BDC;
8452 break;
8454 server_role = ROLE_DOMAIN_MEMBER;
8455 break;
8456 case SEC_ADS:
8457 if (lp_domain_logons()) {
8458 server_role = ROLE_DOMAIN_PDC;
8459 break;
8461 server_role = ROLE_DOMAIN_MEMBER;
8462 break;
8463 case SEC_USER:
8464 if (lp_domain_logons()) {
8466 if (Globals.iDomainMaster) /* auto or yes */
8467 server_role = ROLE_DOMAIN_PDC;
8468 else
8469 server_role = ROLE_DOMAIN_BDC;
8471 break;
8472 default:
8473 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8474 break;
8477 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8480 /***********************************************************
8481 If we should send plaintext/LANMAN passwords in the clinet
8482 ************************************************************/
8484 static void set_allowed_client_auth(void)
8486 if (Globals.bClientNTLMv2Auth) {
8487 Globals.bClientLanManAuth = False;
8489 if (!Globals.bClientLanManAuth) {
8490 Globals.bClientPlaintextAuth = False;
8494 /***************************************************************************
8495 JRA.
8496 The following code allows smbd to read a user defined share file.
8497 Yes, this is my intent. Yes, I'm comfortable with that...
8499 THE FOLLOWING IS SECURITY CRITICAL CODE.
8501 It washes your clothes, it cleans your house, it guards you while you sleep...
8502 Do not f%^k with it....
8503 ***************************************************************************/
8505 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8507 /***************************************************************************
8508 Check allowed stat state of a usershare file.
8509 Ensure we print out who is dicking with us so the admin can
8510 get their sorry ass fired.
8511 ***************************************************************************/
8513 static bool check_usershare_stat(const char *fname,
8514 const SMB_STRUCT_STAT *psbuf)
8516 if (!S_ISREG(psbuf->st_ex_mode)) {
8517 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8518 "not a regular file\n",
8519 fname, (unsigned int)psbuf->st_ex_uid ));
8520 return False;
8523 /* Ensure this doesn't have the other write bit set. */
8524 if (psbuf->st_ex_mode & S_IWOTH) {
8525 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8526 "public write. Refusing to allow as a usershare file.\n",
8527 fname, (unsigned int)psbuf->st_ex_uid ));
8528 return False;
8531 /* Should be 10k or less. */
8532 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8533 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8534 "too large (%u) to be a user share file.\n",
8535 fname, (unsigned int)psbuf->st_ex_uid,
8536 (unsigned int)psbuf->st_ex_size ));
8537 return False;
8540 return True;
8543 /***************************************************************************
8544 Parse the contents of a usershare file.
8545 ***************************************************************************/
8547 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8548 SMB_STRUCT_STAT *psbuf,
8549 const char *servicename,
8550 int snum,
8551 char **lines,
8552 int numlines,
8553 char **pp_sharepath,
8554 char **pp_comment,
8555 char **pp_cp_servicename,
8556 SEC_DESC **ppsd,
8557 bool *pallow_guest)
8559 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8560 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8561 int us_vers;
8562 SMB_STRUCT_DIR *dp;
8563 SMB_STRUCT_STAT sbuf;
8564 char *sharepath = NULL;
8565 char *comment = NULL;
8567 *pp_sharepath = NULL;
8568 *pp_comment = NULL;
8570 *pallow_guest = False;
8572 if (numlines < 4) {
8573 return USERSHARE_MALFORMED_FILE;
8576 if (strcmp(lines[0], "#VERSION 1") == 0) {
8577 us_vers = 1;
8578 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8579 us_vers = 2;
8580 if (numlines < 5) {
8581 return USERSHARE_MALFORMED_FILE;
8583 } else {
8584 return USERSHARE_BAD_VERSION;
8587 if (strncmp(lines[1], "path=", 5) != 0) {
8588 return USERSHARE_MALFORMED_PATH;
8591 sharepath = talloc_strdup(ctx, &lines[1][5]);
8592 if (!sharepath) {
8593 return USERSHARE_POSIX_ERR;
8595 trim_string(sharepath, " ", " ");
8597 if (strncmp(lines[2], "comment=", 8) != 0) {
8598 return USERSHARE_MALFORMED_COMMENT_DEF;
8601 comment = talloc_strdup(ctx, &lines[2][8]);
8602 if (!comment) {
8603 return USERSHARE_POSIX_ERR;
8605 trim_string(comment, " ", " ");
8606 trim_char(comment, '"', '"');
8608 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8609 return USERSHARE_MALFORMED_ACL_DEF;
8612 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8613 return USERSHARE_ACL_ERR;
8616 if (us_vers == 2) {
8617 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8618 return USERSHARE_MALFORMED_ACL_DEF;
8620 if (lines[4][9] == 'y') {
8621 *pallow_guest = True;
8624 /* Backwards compatible extension to file version #2. */
8625 if (numlines > 5) {
8626 if (strncmp(lines[5], "sharename=", 10) != 0) {
8627 return USERSHARE_MALFORMED_SHARENAME_DEF;
8629 if (!strequal(&lines[5][10], servicename)) {
8630 return USERSHARE_BAD_SHARENAME;
8632 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8633 if (!*pp_cp_servicename) {
8634 return USERSHARE_POSIX_ERR;
8639 if (*pp_cp_servicename == NULL) {
8640 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8641 if (!*pp_cp_servicename) {
8642 return USERSHARE_POSIX_ERR;
8646 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8647 /* Path didn't change, no checks needed. */
8648 *pp_sharepath = sharepath;
8649 *pp_comment = comment;
8650 return USERSHARE_OK;
8653 /* The path *must* be absolute. */
8654 if (sharepath[0] != '/') {
8655 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8656 servicename, sharepath));
8657 return USERSHARE_PATH_NOT_ABSOLUTE;
8660 /* If there is a usershare prefix deny list ensure one of these paths
8661 doesn't match the start of the user given path. */
8662 if (prefixdenylist) {
8663 int i;
8664 for ( i=0; prefixdenylist[i]; i++ ) {
8665 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8666 servicename, i, prefixdenylist[i], sharepath ));
8667 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8668 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8669 "usershare prefix deny list entries.\n",
8670 servicename, sharepath));
8671 return USERSHARE_PATH_IS_DENIED;
8676 /* If there is a usershare prefix allow list ensure one of these paths
8677 does match the start of the user given path. */
8679 if (prefixallowlist) {
8680 int i;
8681 for ( i=0; prefixallowlist[i]; i++ ) {
8682 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8683 servicename, i, prefixallowlist[i], sharepath ));
8684 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8685 break;
8688 if (prefixallowlist[i] == NULL) {
8689 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8690 "usershare prefix allow list entries.\n",
8691 servicename, sharepath));
8692 return USERSHARE_PATH_NOT_ALLOWED;
8696 /* Ensure this is pointing to a directory. */
8697 dp = sys_opendir(sharepath);
8699 if (!dp) {
8700 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8701 servicename, sharepath));
8702 return USERSHARE_PATH_NOT_DIRECTORY;
8705 /* Ensure the owner of the usershare file has permission to share
8706 this directory. */
8708 if (sys_stat(sharepath, &sbuf, false) == -1) {
8709 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8710 servicename, sharepath, strerror(errno) ));
8711 sys_closedir(dp);
8712 return USERSHARE_POSIX_ERR;
8715 sys_closedir(dp);
8717 if (!S_ISDIR(sbuf.st_ex_mode)) {
8718 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8719 servicename, sharepath ));
8720 return USERSHARE_PATH_NOT_DIRECTORY;
8723 /* Check if sharing is restricted to owner-only. */
8724 /* psbuf is the stat of the usershare definition file,
8725 sbuf is the stat of the target directory to be shared. */
8727 if (lp_usershare_owner_only()) {
8728 /* root can share anything. */
8729 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8730 return USERSHARE_PATH_NOT_ALLOWED;
8734 *pp_sharepath = sharepath;
8735 *pp_comment = comment;
8736 return USERSHARE_OK;
8739 /***************************************************************************
8740 Deal with a usershare file.
8741 Returns:
8742 >= 0 - snum
8743 -1 - Bad name, invalid contents.
8744 - service name already existed and not a usershare, problem
8745 with permissions to share directory etc.
8746 ***************************************************************************/
8748 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8750 SMB_STRUCT_STAT sbuf;
8751 SMB_STRUCT_STAT lsbuf;
8752 char *fname = NULL;
8753 char *sharepath = NULL;
8754 char *comment = NULL;
8755 char *cp_service_name = NULL;
8756 char **lines = NULL;
8757 int numlines = 0;
8758 int fd = -1;
8759 int iService = -1;
8760 TALLOC_CTX *ctx = talloc_stackframe();
8761 SEC_DESC *psd = NULL;
8762 bool guest_ok = False;
8763 char *canon_name = NULL;
8764 bool added_service = false;
8765 int ret = -1;
8767 /* Ensure share name doesn't contain invalid characters. */
8768 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8769 DEBUG(0,("process_usershare_file: share name %s contains "
8770 "invalid characters (any of %s)\n",
8771 file_name, INVALID_SHARENAME_CHARS ));
8772 goto out;
8775 canon_name = canonicalize_servicename(ctx, file_name);
8776 if (!canon_name) {
8777 goto out;
8780 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8781 if (!fname) {
8782 goto out;
8785 /* Minimize the race condition by doing an lstat before we
8786 open and fstat. Ensure this isn't a symlink link. */
8788 if (sys_lstat(fname, &lsbuf, false) != 0) {
8789 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8790 fname, strerror(errno) ));
8791 goto out;
8794 /* This must be a regular file, not a symlink, directory or
8795 other strange filetype. */
8796 if (!check_usershare_stat(fname, &lsbuf)) {
8797 goto out;
8801 TDB_DATA data = dbwrap_fetch_bystring(
8802 ServiceHash, canon_name, canon_name);
8804 iService = -1;
8806 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8807 iService = *(int *)data.dptr;
8811 if (iService != -1 &&
8812 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8813 &lsbuf.st_ex_mtime) == 0) {
8814 /* Nothing changed - Mark valid and return. */
8815 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8816 canon_name ));
8817 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8818 ret = iService;
8819 goto out;
8822 /* Try and open the file read only - no symlinks allowed. */
8823 #ifdef O_NOFOLLOW
8824 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8825 #else
8826 fd = sys_open(fname, O_RDONLY, 0);
8827 #endif
8829 if (fd == -1) {
8830 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8831 fname, strerror(errno) ));
8832 goto out;
8835 /* Now fstat to be *SURE* it's a regular file. */
8836 if (sys_fstat(fd, &sbuf, false) != 0) {
8837 close(fd);
8838 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8839 fname, strerror(errno) ));
8840 goto out;
8843 /* Is it the same dev/inode as was lstated ? */
8844 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8845 close(fd);
8846 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8847 "Symlink spoofing going on ?\n", fname ));
8848 goto out;
8851 /* This must be a regular file, not a symlink, directory or
8852 other strange filetype. */
8853 if (!check_usershare_stat(fname, &sbuf)) {
8854 goto out;
8857 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8859 close(fd);
8860 if (lines == NULL) {
8861 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8862 fname, (unsigned int)sbuf.st_ex_uid ));
8863 goto out;
8866 if (parse_usershare_file(ctx, &sbuf, file_name,
8867 iService, lines, numlines, &sharepath,
8868 &comment, &cp_service_name,
8869 &psd, &guest_ok) != USERSHARE_OK) {
8870 goto out;
8873 /* Everything ok - add the service possibly using a template. */
8874 if (iService < 0) {
8875 const struct service *sp = &sDefault;
8876 if (snum_template != -1) {
8877 sp = ServicePtrs[snum_template];
8880 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
8881 DEBUG(0, ("process_usershare_file: Failed to add "
8882 "new service %s\n", cp_service_name));
8883 goto out;
8886 added_service = true;
8888 /* Read only is controlled by usershare ACL below. */
8889 ServicePtrs[iService]->bRead_only = False;
8892 /* Write the ACL of the new/modified share. */
8893 if (!set_share_security(canon_name, psd)) {
8894 DEBUG(0, ("process_usershare_file: Failed to set share "
8895 "security for user share %s\n",
8896 canon_name ));
8897 goto out;
8900 /* If from a template it may be marked invalid. */
8901 ServicePtrs[iService]->valid = True;
8903 /* Set the service as a valid usershare. */
8904 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8906 /* Set guest access. */
8907 if (lp_usershare_allow_guests()) {
8908 ServicePtrs[iService]->bGuest_ok = guest_ok;
8911 /* And note when it was loaded. */
8912 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8913 string_set(&ServicePtrs[iService]->szPath, sharepath);
8914 string_set(&ServicePtrs[iService]->comment, comment);
8916 ret = iService;
8918 out:
8920 if (ret == -1 && iService != -1 && added_service) {
8921 lp_remove_service(iService);
8924 TALLOC_FREE(lines);
8925 TALLOC_FREE(ctx);
8926 return ret;
8929 /***************************************************************************
8930 Checks if a usershare entry has been modified since last load.
8931 ***************************************************************************/
8933 static bool usershare_exists(int iService, struct timespec *last_mod)
8935 SMB_STRUCT_STAT lsbuf;
8936 const char *usersharepath = Globals.szUsersharePath;
8937 char *fname;
8939 if (asprintf(&fname, "%s/%s",
8940 usersharepath,
8941 ServicePtrs[iService]->szService) < 0) {
8942 return false;
8945 if (sys_lstat(fname, &lsbuf, false) != 0) {
8946 SAFE_FREE(fname);
8947 return false;
8950 if (!S_ISREG(lsbuf.st_ex_mode)) {
8951 SAFE_FREE(fname);
8952 return false;
8955 SAFE_FREE(fname);
8956 *last_mod = lsbuf.st_ex_mtime;
8957 return true;
8960 /***************************************************************************
8961 Load a usershare service by name. Returns a valid servicenumber or -1.
8962 ***************************************************************************/
8964 int load_usershare_service(const char *servicename)
8966 SMB_STRUCT_STAT sbuf;
8967 const char *usersharepath = Globals.szUsersharePath;
8968 int max_user_shares = Globals.iUsershareMaxShares;
8969 int snum_template = -1;
8971 if (*usersharepath == 0 || max_user_shares == 0) {
8972 return -1;
8975 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8976 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8977 usersharepath, strerror(errno) ));
8978 return -1;
8981 if (!S_ISDIR(sbuf.st_ex_mode)) {
8982 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8983 usersharepath ));
8984 return -1;
8988 * This directory must be owned by root, and have the 't' bit set.
8989 * It also must not be writable by "other".
8992 #ifdef S_ISVTX
8993 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8994 #else
8995 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8996 #endif
8997 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8998 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8999 usersharepath ));
9000 return -1;
9003 /* Ensure the template share exists if it's set. */
9004 if (Globals.szUsershareTemplateShare[0]) {
9005 /* We can't use lp_servicenumber here as we are recommending that
9006 template shares have -valid=False set. */
9007 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9008 if (ServicePtrs[snum_template]->szService &&
9009 strequal(ServicePtrs[snum_template]->szService,
9010 Globals.szUsershareTemplateShare)) {
9011 break;
9015 if (snum_template == -1) {
9016 DEBUG(0,("load_usershare_service: usershare template share %s "
9017 "does not exist.\n",
9018 Globals.szUsershareTemplateShare ));
9019 return -1;
9023 return process_usershare_file(usersharepath, servicename, snum_template);
9026 /***************************************************************************
9027 Load all user defined shares from the user share directory.
9028 We only do this if we're enumerating the share list.
9029 This is the function that can delete usershares that have
9030 been removed.
9031 ***************************************************************************/
9033 int load_usershare_shares(void)
9035 SMB_STRUCT_DIR *dp;
9036 SMB_STRUCT_STAT sbuf;
9037 SMB_STRUCT_DIRENT *de;
9038 int num_usershares = 0;
9039 int max_user_shares = Globals.iUsershareMaxShares;
9040 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
9041 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
9042 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
9043 int iService;
9044 int snum_template = -1;
9045 const char *usersharepath = Globals.szUsersharePath;
9046 int ret = lp_numservices();
9048 if (max_user_shares == 0 || *usersharepath == '\0') {
9049 return lp_numservices();
9052 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9053 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
9054 usersharepath, strerror(errno) ));
9055 return ret;
9059 * This directory must be owned by root, and have the 't' bit set.
9060 * It also must not be writable by "other".
9063 #ifdef S_ISVTX
9064 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9065 #else
9066 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9067 #endif
9068 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9069 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9070 usersharepath ));
9071 return ret;
9074 /* Ensure the template share exists if it's set. */
9075 if (Globals.szUsershareTemplateShare[0]) {
9076 /* We can't use lp_servicenumber here as we are recommending that
9077 template shares have -valid=False set. */
9078 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9079 if (ServicePtrs[snum_template]->szService &&
9080 strequal(ServicePtrs[snum_template]->szService,
9081 Globals.szUsershareTemplateShare)) {
9082 break;
9086 if (snum_template == -1) {
9087 DEBUG(0,("load_usershare_shares: usershare template share %s "
9088 "does not exist.\n",
9089 Globals.szUsershareTemplateShare ));
9090 return ret;
9094 /* Mark all existing usershares as pending delete. */
9095 for (iService = iNumServices - 1; iService >= 0; iService--) {
9096 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9097 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9101 dp = sys_opendir(usersharepath);
9102 if (!dp) {
9103 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9104 usersharepath, strerror(errno) ));
9105 return ret;
9108 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9109 (de = sys_readdir(dp));
9110 num_dir_entries++ ) {
9111 int r;
9112 const char *n = de->d_name;
9114 /* Ignore . and .. */
9115 if (*n == '.') {
9116 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9117 continue;
9121 if (n[0] == ':') {
9122 /* Temporary file used when creating a share. */
9123 num_tmp_dir_entries++;
9126 /* Allow 20% tmp entries. */
9127 if (num_tmp_dir_entries > allowed_tmp_entries) {
9128 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9129 "in directory %s\n",
9130 num_tmp_dir_entries, usersharepath));
9131 break;
9134 r = process_usershare_file(usersharepath, n, snum_template);
9135 if (r == 0) {
9136 /* Update the services count. */
9137 num_usershares++;
9138 if (num_usershares >= max_user_shares) {
9139 DEBUG(0,("load_usershare_shares: max user shares reached "
9140 "on file %s in directory %s\n",
9141 n, usersharepath ));
9142 break;
9144 } else if (r == -1) {
9145 num_bad_dir_entries++;
9148 /* Allow 20% bad entries. */
9149 if (num_bad_dir_entries > allowed_bad_entries) {
9150 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9151 "in directory %s\n",
9152 num_bad_dir_entries, usersharepath));
9153 break;
9156 /* Allow 20% bad entries. */
9157 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9158 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9159 "in directory %s\n",
9160 num_dir_entries, usersharepath));
9161 break;
9165 sys_closedir(dp);
9167 /* Sweep through and delete any non-refreshed usershares that are
9168 not currently in use. */
9169 for (iService = iNumServices - 1; iService >= 0; iService--) {
9170 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9171 if (conn_snum_used(iService)) {
9172 continue;
9174 /* Remove from the share ACL db. */
9175 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9176 lp_servicename(iService) ));
9177 delete_share_security(lp_servicename(iService));
9178 free_service_byindex(iService);
9182 return lp_numservices();
9185 /********************************************************
9186 Destroy global resources allocated in this file
9187 ********************************************************/
9189 void gfree_loadparm(void)
9191 int i;
9193 free_file_list();
9195 /* Free resources allocated to services */
9197 for ( i = 0; i < iNumServices; i++ ) {
9198 if ( VALID(i) ) {
9199 free_service_byindex(i);
9203 SAFE_FREE( ServicePtrs );
9204 iNumServices = 0;
9206 /* Now release all resources allocated to global
9207 parameters and the default service */
9209 free_global_parameters();
9213 /***************************************************************************
9214 Allow client apps to specify that they are a client
9215 ***************************************************************************/
9216 void lp_set_in_client(bool b)
9218 in_client = b;
9222 /***************************************************************************
9223 Determine if we're running in a client app
9224 ***************************************************************************/
9225 bool lp_is_in_client(void)
9227 return in_client;
9230 /***************************************************************************
9231 Load the services array from the services file. Return True on success,
9232 False on failure.
9233 ***************************************************************************/
9235 bool lp_load_ex(const char *pszFname,
9236 bool global_only,
9237 bool save_defaults,
9238 bool add_ipc,
9239 bool initialize_globals,
9240 bool allow_include_registry,
9241 bool allow_registry_shares)
9243 char *n2 = NULL;
9244 bool bRetval;
9246 bRetval = False;
9248 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9250 bInGlobalSection = True;
9251 bGlobalOnly = global_only;
9252 bAllowIncludeRegistry = allow_include_registry;
9254 init_globals(! initialize_globals);
9255 debug_init();
9257 free_file_list();
9259 if (save_defaults) {
9260 init_locals();
9261 lp_save_defaults();
9264 free_param_opts(&Globals.param_opt);
9266 /* We get sections first, so have to start 'behind' to make up */
9267 iServiceIndex = -1;
9269 if (lp_config_backend_is_file()) {
9270 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9271 current_user_info.domain,
9272 pszFname);
9273 if (!n2) {
9274 smb_panic("lp_load_ex: out of memory");
9277 add_to_file_list(pszFname, n2);
9279 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9280 TALLOC_FREE(n2);
9282 /* finish up the last section */
9283 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9284 if (bRetval) {
9285 if (iServiceIndex >= 0) {
9286 bRetval = service_ok(iServiceIndex);
9290 if (lp_config_backend_is_registry()) {
9291 /* config backend changed to registry in config file */
9293 * We need to use this extra global variable here to
9294 * survive restart: init_globals uses this as a default
9295 * for ConfigBackend. Otherwise, init_globals would
9296 * send us into an endless loop here.
9298 config_backend = CONFIG_BACKEND_REGISTRY;
9299 /* start over */
9300 DEBUG(1, ("lp_load_ex: changing to config backend "
9301 "registry\n"));
9302 init_globals(false);
9303 lp_kill_all_services();
9304 return lp_load_ex(pszFname, global_only, save_defaults,
9305 add_ipc, initialize_globals,
9306 allow_include_registry,
9307 allow_registry_shares);
9309 } else if (lp_config_backend_is_registry()) {
9310 bRetval = process_registry_globals();
9311 } else {
9312 DEBUG(0, ("Illegal config backend given: %d\n",
9313 lp_config_backend()));
9314 bRetval = false;
9317 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9318 bRetval = process_registry_shares();
9321 lp_add_auto_services(lp_auto_services());
9323 if (add_ipc) {
9324 /* When 'restrict anonymous = 2' guest connections to ipc$
9325 are denied */
9326 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9327 if ( lp_enable_asu_support() ) {
9328 lp_add_ipc("ADMIN$", false);
9332 set_server_role();
9333 set_default_server_announce_type();
9334 set_allowed_client_auth();
9336 bLoaded = True;
9338 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9339 /* if bWINSsupport is true and we are in the client */
9340 if (lp_is_in_client() && Globals.bWINSsupport) {
9341 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9344 init_iconv();
9346 bAllowIncludeRegistry = true;
9348 return (bRetval);
9351 bool lp_load(const char *pszFname,
9352 bool global_only,
9353 bool save_defaults,
9354 bool add_ipc,
9355 bool initialize_globals)
9357 return lp_load_ex(pszFname,
9358 global_only,
9359 save_defaults,
9360 add_ipc,
9361 initialize_globals,
9362 true, false);
9365 bool lp_load_initial_only(const char *pszFname)
9367 return lp_load_ex(pszFname,
9368 true,
9369 false,
9370 false,
9371 true,
9372 false,
9373 false);
9376 bool lp_load_with_registry_shares(const char *pszFname,
9377 bool global_only,
9378 bool save_defaults,
9379 bool add_ipc,
9380 bool initialize_globals)
9382 return lp_load_ex(pszFname,
9383 global_only,
9384 save_defaults,
9385 add_ipc,
9386 initialize_globals,
9387 true,
9388 true);
9391 /***************************************************************************
9392 Return the max number of services.
9393 ***************************************************************************/
9395 int lp_numservices(void)
9397 return (iNumServices);
9400 /***************************************************************************
9401 Display the contents of the services array in human-readable form.
9402 ***************************************************************************/
9404 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9406 int iService;
9408 if (show_defaults)
9409 defaults_saved = False;
9411 dump_globals(f);
9413 dump_a_service(&sDefault, f);
9415 for (iService = 0; iService < maxtoprint; iService++) {
9416 fprintf(f,"\n");
9417 lp_dump_one(f, show_defaults, iService);
9421 /***************************************************************************
9422 Display the contents of one service in human-readable form.
9423 ***************************************************************************/
9425 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9427 if (VALID(snum)) {
9428 if (ServicePtrs[snum]->szService[0] == '\0')
9429 return;
9430 dump_a_service(ServicePtrs[snum], f);
9434 /***************************************************************************
9435 Return the number of the service with the given name, or -1 if it doesn't
9436 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9437 getservicebyname()! This works ONLY if all services have been loaded, and
9438 does not copy the found service.
9439 ***************************************************************************/
9441 int lp_servicenumber(const char *pszServiceName)
9443 int iService;
9444 fstring serviceName;
9446 if (!pszServiceName) {
9447 return GLOBAL_SECTION_SNUM;
9450 for (iService = iNumServices - 1; iService >= 0; iService--) {
9451 if (VALID(iService) && ServicePtrs[iService]->szService) {
9453 * The substitution here is used to support %U is
9454 * service names
9456 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9457 standard_sub_basic(get_current_username(),
9458 current_user_info.domain,
9459 serviceName,sizeof(serviceName));
9460 if (strequal(serviceName, pszServiceName)) {
9461 break;
9466 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9467 struct timespec last_mod;
9469 if (!usershare_exists(iService, &last_mod)) {
9470 /* Remove the share security tdb entry for it. */
9471 delete_share_security(lp_servicename(iService));
9472 /* Remove it from the array. */
9473 free_service_byindex(iService);
9474 /* Doesn't exist anymore. */
9475 return GLOBAL_SECTION_SNUM;
9478 /* Has it been modified ? If so delete and reload. */
9479 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9480 &last_mod) < 0) {
9481 /* Remove it from the array. */
9482 free_service_byindex(iService);
9483 /* and now reload it. */
9484 iService = load_usershare_service(pszServiceName);
9488 if (iService < 0) {
9489 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9490 return GLOBAL_SECTION_SNUM;
9493 return (iService);
9496 bool share_defined(const char *service_name)
9498 return (lp_servicenumber(service_name) != -1);
9501 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9502 const char *sharename)
9504 struct share_params *result;
9505 char *sname;
9506 int snum;
9508 if (!(sname = SMB_STRDUP(sharename))) {
9509 return NULL;
9512 snum = find_service(sname);
9513 SAFE_FREE(sname);
9515 if (snum < 0) {
9516 return NULL;
9519 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9520 DEBUG(0, ("talloc failed\n"));
9521 return NULL;
9524 result->service = snum;
9525 return result;
9528 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9530 struct share_iterator *result;
9532 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9533 DEBUG(0, ("talloc failed\n"));
9534 return NULL;
9537 result->next_id = 0;
9538 return result;
9541 struct share_params *next_share(struct share_iterator *list)
9543 struct share_params *result;
9545 while (!lp_snum_ok(list->next_id) &&
9546 (list->next_id < lp_numservices())) {
9547 list->next_id += 1;
9550 if (list->next_id >= lp_numservices()) {
9551 return NULL;
9554 if (!(result = TALLOC_P(list, struct share_params))) {
9555 DEBUG(0, ("talloc failed\n"));
9556 return NULL;
9559 result->service = list->next_id;
9560 list->next_id += 1;
9561 return result;
9564 struct share_params *next_printer(struct share_iterator *list)
9566 struct share_params *result;
9568 while ((result = next_share(list)) != NULL) {
9569 if (lp_print_ok(result->service)) {
9570 break;
9573 return result;
9577 * This is a hack for a transition period until we transformed all code from
9578 * service numbers to struct share_params.
9581 struct share_params *snum2params_static(int snum)
9583 static struct share_params result;
9584 result.service = snum;
9585 return &result;
9588 /*******************************************************************
9589 A useful volume label function.
9590 ********************************************************************/
9592 const char *volume_label(int snum)
9594 char *ret;
9595 const char *label = lp_volume(snum);
9596 if (!*label) {
9597 label = lp_servicename(snum);
9600 /* This returns a 33 byte guarenteed null terminated string. */
9601 ret = talloc_strndup(talloc_tos(), label, 32);
9602 if (!ret) {
9603 return "";
9605 return ret;
9608 /*******************************************************************
9609 Set the server type we will announce as via nmbd.
9610 ********************************************************************/
9612 static void set_default_server_announce_type(void)
9614 default_server_announce = 0;
9615 default_server_announce |= SV_TYPE_WORKSTATION;
9616 default_server_announce |= SV_TYPE_SERVER;
9617 default_server_announce |= SV_TYPE_SERVER_UNIX;
9619 /* note that the flag should be set only if we have a
9620 printer service but nmbd doesn't actually load the
9621 services so we can't tell --jerry */
9623 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9625 switch (lp_announce_as()) {
9626 case ANNOUNCE_AS_NT_SERVER:
9627 default_server_announce |= SV_TYPE_SERVER_NT;
9628 /* fall through... */
9629 case ANNOUNCE_AS_NT_WORKSTATION:
9630 default_server_announce |= SV_TYPE_NT;
9631 break;
9632 case ANNOUNCE_AS_WIN95:
9633 default_server_announce |= SV_TYPE_WIN95_PLUS;
9634 break;
9635 case ANNOUNCE_AS_WFW:
9636 default_server_announce |= SV_TYPE_WFW;
9637 break;
9638 default:
9639 break;
9642 switch (lp_server_role()) {
9643 case ROLE_DOMAIN_MEMBER:
9644 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9645 break;
9646 case ROLE_DOMAIN_PDC:
9647 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9648 break;
9649 case ROLE_DOMAIN_BDC:
9650 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9651 break;
9652 case ROLE_STANDALONE:
9653 default:
9654 break;
9656 if (lp_time_server())
9657 default_server_announce |= SV_TYPE_TIME_SOURCE;
9659 if (lp_host_msdfs())
9660 default_server_announce |= SV_TYPE_DFS_SERVER;
9663 /***********************************************************
9664 returns role of Samba server
9665 ************************************************************/
9667 int lp_server_role(void)
9669 return server_role;
9672 /***********************************************************
9673 If we are PDC then prefer us as DMB
9674 ************************************************************/
9676 bool lp_domain_master(void)
9678 if (Globals.iDomainMaster == Auto)
9679 return (lp_server_role() == ROLE_DOMAIN_PDC);
9681 return (bool)Globals.iDomainMaster;
9684 /***********************************************************
9685 If we are DMB then prefer us as LMB
9686 ************************************************************/
9688 bool lp_preferred_master(void)
9690 if (Globals.iPreferredMaster == Auto)
9691 return (lp_local_master() && lp_domain_master());
9693 return (bool)Globals.iPreferredMaster;
9696 /*******************************************************************
9697 Remove a service.
9698 ********************************************************************/
9700 void lp_remove_service(int snum)
9702 ServicePtrs[snum]->valid = False;
9703 invalid_services[num_invalid_services++] = snum;
9706 /*******************************************************************
9707 Copy a service.
9708 ********************************************************************/
9710 void lp_copy_service(int snum, const char *new_name)
9712 do_section(new_name, NULL);
9713 if (snum >= 0) {
9714 snum = lp_servicenumber(new_name);
9715 if (snum >= 0)
9716 lp_do_parameter(snum, "copy", lp_servicename(snum));
9721 /*******************************************************************
9722 Get the default server type we will announce as via nmbd.
9723 ********************************************************************/
9725 int lp_default_server_announce(void)
9727 return default_server_announce;
9730 /*******************************************************************
9731 Split the announce version into major and minor numbers.
9732 ********************************************************************/
9734 int lp_major_announce_version(void)
9736 static bool got_major = False;
9737 static int major_version = DEFAULT_MAJOR_VERSION;
9738 char *vers;
9739 char *p;
9741 if (got_major)
9742 return major_version;
9744 got_major = True;
9745 if ((vers = lp_announce_version()) == NULL)
9746 return major_version;
9748 if ((p = strchr_m(vers, '.')) == 0)
9749 return major_version;
9751 *p = '\0';
9752 major_version = atoi(vers);
9753 return major_version;
9756 int lp_minor_announce_version(void)
9758 static bool got_minor = False;
9759 static int minor_version = DEFAULT_MINOR_VERSION;
9760 char *vers;
9761 char *p;
9763 if (got_minor)
9764 return minor_version;
9766 got_minor = True;
9767 if ((vers = lp_announce_version()) == NULL)
9768 return minor_version;
9770 if ((p = strchr_m(vers, '.')) == 0)
9771 return minor_version;
9773 p++;
9774 minor_version = atoi(p);
9775 return minor_version;
9778 /***********************************************************
9779 Set the global name resolution order (used in smbclient).
9780 ************************************************************/
9782 void lp_set_name_resolve_order(const char *new_order)
9784 string_set(&Globals.szNameResolveOrder, new_order);
9787 const char *lp_printername(int snum)
9789 const char *ret = _lp_printername(snum);
9790 if (ret == NULL || (ret != NULL && *ret == '\0'))
9791 ret = lp_const_servicename(snum);
9793 return ret;
9797 /***********************************************************
9798 Allow daemons such as winbindd to fix their logfile name.
9799 ************************************************************/
9801 void lp_set_logfile(const char *name)
9803 string_set(&Globals.szLogFile, name);
9804 debug_set_logfile(name);
9807 /*******************************************************************
9808 Return the max print jobs per queue.
9809 ********************************************************************/
9811 int lp_maxprintjobs(int snum)
9813 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9814 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9815 maxjobs = PRINT_MAX_JOBID - 1;
9817 return maxjobs;
9820 const char *lp_printcapname(void)
9822 if ((Globals.szPrintcapname != NULL) &&
9823 (Globals.szPrintcapname[0] != '\0'))
9824 return Globals.szPrintcapname;
9826 if (sDefault.iPrinting == PRINT_CUPS) {
9827 #ifdef HAVE_CUPS
9828 return "cups";
9829 #else
9830 return "lpstat";
9831 #endif
9834 if (sDefault.iPrinting == PRINT_BSD)
9835 return "/etc/printcap";
9837 return PRINTCAP_NAME;
9840 static uint32 spoolss_state;
9842 bool lp_disable_spoolss( void )
9844 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9845 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9847 return spoolss_state == SVCCTL_STOPPED ? True : False;
9850 void lp_set_spoolss_state( uint32 state )
9852 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9854 spoolss_state = state;
9857 uint32 lp_get_spoolss_state( void )
9859 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9862 /*******************************************************************
9863 Ensure we don't use sendfile if server smb signing is active.
9864 ********************************************************************/
9866 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9868 bool sign_active = false;
9870 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9871 if (get_Protocol() < PROTOCOL_NT1) {
9872 return false;
9874 if (signing_state) {
9875 sign_active = smb_signing_is_active(signing_state);
9877 return (_lp_use_sendfile(snum) &&
9878 (get_remote_arch() != RA_WIN95) &&
9879 !sign_active);
9882 /*******************************************************************
9883 Turn off sendfile if we find the underlying OS doesn't support it.
9884 ********************************************************************/
9886 void set_use_sendfile(int snum, bool val)
9888 if (LP_SNUM_OK(snum))
9889 ServicePtrs[snum]->bUseSendfile = val;
9890 else
9891 sDefault.bUseSendfile = val;
9894 /*******************************************************************
9895 Turn off storing DOS attributes if this share doesn't support it.
9896 ********************************************************************/
9898 void set_store_dos_attributes(int snum, bool val)
9900 if (!LP_SNUM_OK(snum))
9901 return;
9902 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9905 void lp_set_mangling_method(const char *new_method)
9907 string_set(&Globals.szManglingMethod, new_method);
9910 /*******************************************************************
9911 Global state for POSIX pathname processing.
9912 ********************************************************************/
9914 static bool posix_pathnames;
9916 bool lp_posix_pathnames(void)
9918 return posix_pathnames;
9921 /*******************************************************************
9922 Change everything needed to ensure POSIX pathname processing (currently
9923 not much).
9924 ********************************************************************/
9926 void lp_set_posix_pathnames(void)
9928 posix_pathnames = True;
9931 /*******************************************************************
9932 Global state for POSIX lock processing - CIFS unix extensions.
9933 ********************************************************************/
9935 bool posix_default_lock_was_set;
9936 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9938 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9940 if (posix_default_lock_was_set) {
9941 return posix_cifsx_locktype;
9942 } else {
9943 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9947 /*******************************************************************
9948 ********************************************************************/
9950 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9952 posix_default_lock_was_set = True;
9953 posix_cifsx_locktype = val;
9956 int lp_min_receive_file_size(void)
9958 if (Globals.iminreceivefile < 0) {
9959 return 0;
9961 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9964 /*******************************************************************
9965 If socket address is an empty character string, it is necessary to
9966 define it as "0.0.0.0".
9967 ********************************************************************/
9969 const char *lp_socket_address(void)
9971 char *sock_addr = Globals.szSocketAddress;
9973 if (sock_addr[0] == '\0'){
9974 string_set(&Globals.szSocketAddress, "0.0.0.0");
9976 return Globals.szSocketAddress;
9979 void lp_set_passdb_backend(const char *backend)
9981 string_set(&Globals.szPassdbBackend, backend);
9984 /*******************************************************************
9985 Safe wide links checks.
9986 This helper function always verify the validity of wide links,
9987 even after a configuration file reload.
9988 ********************************************************************/
9990 static bool lp_widelinks_internal(int snum)
9992 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
9993 sDefault.bWidelinks);
9996 void widelinks_warning(int snum)
9998 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
9999 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
10000 "These parameters are incompatible. "
10001 "Wide links will be disabled for this share.\n",
10002 lp_servicename(snum) ));
10006 bool lp_widelinks(int snum)
10008 /* wide links is always incompatible with unix extensions */
10009 if (lp_unix_extensions()) {
10010 return false;
10013 return lp_widelinks_internal(snum);