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