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