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