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