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