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