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