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