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