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