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