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