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