This is the netlogon schannel client code. Try a
[sfrench/samba-autobuild/.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) Anthony Liguori 2003
12    
13    This program is free software; you can redistribute it and/or modify
14    it under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2 of the License, or
16    (at your option) any later version.
17    
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License for more details.
22    
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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
56 BOOL in_client = False;         /* Not in the client by default */
57 BOOL bLoaded = False;
58
59 extern userdom_struct current_user_info;
60 extern pstring user_socket_options;
61
62 #ifndef GLOBAL_NAME
63 #define GLOBAL_NAME "global"
64 #endif
65
66 #ifndef PRINTERS_NAME
67 #define PRINTERS_NAME "printers"
68 #endif
69
70 #ifndef HOMES_NAME
71 #define HOMES_NAME "homes"
72 #endif
73
74 /* some helpful bits */
75 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
76 #define VALID(i) ServicePtrs[i]->valid
77
78 int keepalive = DEFAULT_KEEPALIVE;
79 BOOL use_getwd_cache = True;
80
81 extern int extra_time_offset;
82
83 static BOOL defaults_saved = False;
84
85 typedef struct _param_opt_struct param_opt_struct;
86 struct _param_opt_struct {
87         param_opt_struct *prev, *next;
88         char *key;
89         char *value;
90 };
91
92 /* 
93  * This structure describes global (ie., server-wide) parameters.
94  */
95 typedef struct
96 {
97         char *smb_ports;
98         char *dos_charset;
99         char *unix_charset;
100         char *display_charset;
101         char *szPrintcapname;
102         char *szEnumPortsCommand;
103         char *szAddPrinterCommand;
104         char *szDeletePrinterCommand;
105         char *szOs2DriverMap;
106         char *szLockDir;
107         char *szPidDir;
108         char *szRootdir;
109         char *szDefaultService;
110         char *szDfree;
111         char *szMsgCommand;
112         char *szHostsEquiv;
113         char *szServerString;
114         char *szAutoServices;
115         char *szPasswdProgram;
116         char *szPasswdChat;
117         char *szLogFile;
118         char *szConfigFile;
119         char *szSMBPasswdFile;
120         char *szPrivateDir;
121         char **szPassdbBackend;
122         char **szSamBackend;
123         char **szPreloadModules;
124         char *szPasswordServer;
125         char *szSocketOptions;
126         char *szRealm;
127         char *szADSserver;
128         char *szUsernameMap;
129         char *szLogonScript;
130         char *szLogonPath;
131         char *szLogonDrive;
132         char *szLogonHome;
133         char **szWINSservers;
134         char **szInterfaces;
135         char *szRemoteAnnounce;
136         char *szRemoteBrowseSync;
137         char *szSocketAddress;
138         char *szNISHomeMapName;
139         char *szAnnounceVersion;        /* This is initialised in init_globals */
140         char *szWorkgroup;
141         char *szNetbiosName;
142         char **szNetbiosAliases;
143         char *szNetbiosScope;
144         char *szDomainOtherSIDs;
145         char *szNameResolveOrder;
146         char *szPanicAction;
147         char *szAddUserScript;
148         char *szDelUserScript;
149         char *szAddGroupScript;
150         char *szDelGroupScript;
151         char *szAddUserToGroupScript;
152         char *szDelUserFromGroupScript;
153         char *szSetPrimaryGroupScript;
154         char *szAddMachineScript;
155         char *szShutdownScript;
156         char *szAbortShutdownScript;
157         char *szWINSHook;
158         char *szWINSPartners;
159 #ifdef WITH_UTMP
160         char *szUtmpDir;
161         char *szWtmpDir;
162         BOOL bUtmp;
163 #endif
164         char *szSourceEnv;
165         char *szIdmapUID;
166         char *szIdmapGID;
167         char *szNonUnixAccountRange;
168         int AlgorithmicRidBase;
169         char *szTemplateHomedir;
170         char *szTemplateShell;
171         char *szWinbindSeparator;
172         BOOL bWinbindEnumUsers;
173         BOOL bWinbindEnumGroups;
174         BOOL bWinbindUseDefaultDomain;
175         char *szWinbindBackend;
176         char *szIdmapBackend;
177         char *szAddShareCommand;
178         char *szChangeShareCommand;
179         char *szDeleteShareCommand;
180         char *szGuestaccount;
181         char *szManglingMethod;
182         int mangle_prefix;
183         int max_log_size;
184         char *szLogLevel;
185         int mangled_stack;
186         int max_xmit;
187         int max_mux;
188         int max_open_files;
189         int pwordlevel;
190         int unamelevel;
191         int deadtime;
192         int maxprotocol;
193         int minprotocol;
194         int security;
195         char **AuthMethods;
196         BOOL paranoid_server_security;
197         int maxdisksize;
198         int lpqcachetime;
199         int iMaxSmbdProcesses;
200         BOOL bDisableSpoolss;
201         int iTotalPrintJobs;
202         int syslog;
203         int os_level;
204         int enhanced_browsing;
205         int max_ttl;
206         int max_wins_ttl;
207         int min_wins_ttl;
208         int ReadSize;
209         int lm_announce;
210         int lm_interval;
211         int announce_as;        /* This is initialised in init_globals */
212         int machine_password_timeout;
213         int change_notify_timeout;
214         int stat_cache_size;
215         int map_to_guest;
216         int min_passwd_length;
217         int oplock_break_wait_time;
218         int winbind_cache_time;
219         int iLockSpinCount;
220         int iLockSpinTime;
221         char *szLdapMachineSuffix;
222         char *szLdapUserSuffix;
223 #ifdef WITH_LDAP_SAMCONFIG
224         int ldap_port;
225         char *szLdapServer;
226 #endif
227         int ldap_ssl;
228         char *szLdapSuffix;
229         char *szLdapFilter;
230         char *szLdapAdminDn;
231         BOOL ldap_trust_ids;
232         char *szAclCompat;
233         int ldap_passwd_sync; 
234         BOOL ldap_delete_dn;
235         BOOL bMsAddPrinterWizard;
236         BOOL bDNSproxy;
237         BOOL bWINSsupport;
238         BOOL bWINSproxy;
239         BOOL bLocalMaster;
240         BOOL bPreferredMaster;
241         BOOL bDomainMaster;
242         BOOL bDomainLogons;
243         BOOL bEncryptPasswords;
244         BOOL bUpdateEncrypt;
245         int  clientSchannel;
246         int  serverSchannel;
247         BOOL bStripDot;
248         BOOL bNullPasswords;
249         BOOL bObeyPamRestrictions;
250         BOOL bLoadPrinters;
251         BOOL bLargeReadwrite;
252         BOOL bReadRaw;
253         BOOL bWriteRaw;
254         BOOL bReadPrediction;
255         BOOL bReadbmpx;
256         BOOL bSyslogOnly;
257         BOOL bBrowseList;
258         BOOL bNISHomeMap;
259         BOOL bTimeServer;
260         BOOL bBindInterfacesOnly;
261         BOOL bPamPasswordChange;
262         BOOL bUnixPasswdSync;
263         BOOL bPasswdChatDebug;
264         BOOL bTimestampLogs;
265         BOOL bNTSmbSupport;
266         BOOL bNTPipeSupport;
267         BOOL bNTStatusSupport;
268         BOOL bStatCache;
269         BOOL bKernelOplocks;
270         BOOL bAllowTrustedDomains;
271         BOOL bLanmanAuth;
272         BOOL bNTLMAuth;
273         BOOL bUseSpnego;
274         BOOL bClientLanManAuth;
275         BOOL bClientNTLMv2Auth;
276         BOOL bClientUseSpnego;
277         BOOL bDebugHiresTimestamp;
278         BOOL bDebugPid;
279         BOOL bDebugUid;
280         BOOL bHostMSDfs;
281         BOOL bHideLocalUsers;
282         BOOL bUnicode;
283         BOOL bUseMmap;
284         BOOL bHostnameLookups;
285         BOOL bUnixExtensions;
286         BOOL bDisableNetbios;
287         BOOL bKernelChangeNotify;
288         int restrict_anonymous;
289         int name_cache_timeout;
290         BOOL client_signing;
291         param_opt_struct *param_opt;
292 }
293 global;
294
295 static global Globals;
296
297 /* 
298  * This structure describes a single service. 
299  */
300 typedef struct
301 {
302         BOOL valid;
303         BOOL autoloaded;
304         char *szService;
305         char *szPath;
306         char *szUsername;
307         char **szInvalidUsers;
308         char **szValidUsers;
309         char **szAdminUsers;
310         char *szCopy;
311         char *szInclude;
312         char *szPreExec;
313         char *szPostExec;
314         char *szRootPreExec;
315         char *szRootPostExec;
316         char *szPrintcommand;
317         char *szLpqcommand;
318         char *szLprmcommand;
319         char *szLppausecommand;
320         char *szLpresumecommand;
321         char *szQueuepausecommand;
322         char *szQueueresumecommand;
323         char *szPrintername;
324         char *szDontdescend;
325         char **szHostsallow;
326         char **szHostsdeny;
327         char *szMagicScript;
328         char *szMagicOutput;
329         char *szMangledMap;
330         char *szVetoFiles;
331         char *szHideFiles;
332         char *szVetoOplockFiles;
333         char *comment;
334         char *force_user;
335         char *force_group;
336         char **readlist;
337         char **writelist;
338         char **printer_admin;
339         char *volume;
340         char *fstype;
341         char *szVfsObjectFile;
342         char *szVfsOptions;
343         char *szVfsPath;
344         char *szMSDfsProxy;
345         int iMinPrintSpace;
346         int iMaxPrintJobs;
347         int iMaxReportedPrintJobs;
348         int iWriteCacheSize;
349         int iCreate_mask;
350         int iCreate_force_mode;
351         int iSecurity_mask;
352         int iSecurity_force_mode;
353         int iDir_mask;
354         int iDir_force_mode;
355         int iDir_Security_mask;
356         int iDir_Security_force_mode;
357         int iMaxConnections;
358         int iDefaultCase;
359         int iPrinting;
360         int iOplockContentionLimit;
361         int iCSCPolicy;
362         int iBlock_size;
363         BOOL bPreexecClose;
364         BOOL bRootpreexecClose;
365         BOOL bCaseSensitive;
366         BOOL bCasePreserve;
367         BOOL bShortCasePreserve;
368         BOOL bCaseMangle;
369         BOOL bHideDotFiles;
370         BOOL bHideSpecialFiles;
371         BOOL bHideUnReadable;
372         BOOL bHideUnWriteableFiles;
373         BOOL bBrowseable;
374         BOOL bAvailable;
375         BOOL bRead_only;
376         BOOL bNo_set_dir;
377         BOOL bGuest_only;
378         BOOL bGuest_ok;
379         BOOL bPrint_ok;
380         BOOL bMap_system;
381         BOOL bMap_hidden;
382         BOOL bMap_archive;
383         BOOL bLocking;
384         BOOL bStrictLocking;
385         BOOL bPosixLocking;
386         BOOL bShareModes;
387         BOOL bOpLocks;
388         BOOL bLevel2OpLocks;
389         BOOL bOnlyUser;
390         BOOL bMangledNames;
391         BOOL bWidelinks;
392         BOOL bSymlinks;
393         BOOL bSyncAlways;
394         BOOL bStrictAllocate;
395         BOOL bStrictSync;
396         char magic_char;
397         BOOL *copymap;
398         BOOL bDeleteReadonly;
399         BOOL bFakeOplocks;
400         BOOL bDeleteVetoFiles;
401         BOOL bDosFilemode;
402         BOOL bDosFiletimes;
403         BOOL bDosFiletimeResolution;
404         BOOL bFakeDirCreateTimes;
405         BOOL bBlockingLocks;
406         BOOL bInheritPerms;
407         BOOL bInheritACLS;
408         BOOL bMSDfsRoot;
409         BOOL bUseClientDriver;
410         BOOL bDefaultDevmode;
411         BOOL bNTAclSupport;
412         BOOL bUseSendfile;
413         BOOL bProfileAcls;
414         param_opt_struct *param_opt;
415
416         char dummy[3];          /* for alignment */
417 }
418 service;
419
420
421 /* This is a default service used to prime a services structure */
422 static service sDefault = {
423         True,                   /* valid */
424         False,                  /* not autoloaded */
425         NULL,                   /* szService */
426         NULL,                   /* szPath */
427         NULL,                   /* szUsername */
428         NULL,                   /* szInvalidUsers */
429         NULL,                   /* szValidUsers */
430         NULL,                   /* szAdminUsers */
431         NULL,                   /* szCopy */
432         NULL,                   /* szInclude */
433         NULL,                   /* szPreExec */
434         NULL,                   /* szPostExec */
435         NULL,                   /* szRootPreExec */
436         NULL,                   /* szRootPostExec */
437         NULL,                   /* szPrintcommand */
438         NULL,                   /* szLpqcommand */
439         NULL,                   /* szLprmcommand */
440         NULL,                   /* szLppausecommand */
441         NULL,                   /* szLpresumecommand */
442         NULL,                   /* szQueuepausecommand */
443         NULL,                   /* szQueueresumecommand */
444         NULL,                   /* szPrintername */
445         NULL,                   /* szDontdescend */
446         NULL,                   /* szHostsallow */
447         NULL,                   /* szHostsdeny */
448         NULL,                   /* szMagicScript */
449         NULL,                   /* szMagicOutput */
450         NULL,                   /* szMangledMap */
451         NULL,                   /* szVetoFiles */
452         NULL,                   /* szHideFiles */
453         NULL,                   /* szVetoOplockFiles */
454         NULL,                   /* comment */
455         NULL,                   /* force user */
456         NULL,                   /* force group */
457         NULL,                   /* readlist */
458         NULL,                   /* writelist */
459         NULL,                   /* printer admin */
460         NULL,                   /* volume */
461         NULL,                   /* fstype */
462         NULL,                   /* vfs object */
463         NULL,                   /* vfs options */
464         NULL,                   /* vfs path */
465         NULL,                   /* szMSDfsProxy */
466         0,                      /* iMinPrintSpace */
467         1000,                   /* iMaxPrintJobs */
468         0,                      /* iMaxReportedPrintJobs */
469         0,                      /* iWriteCacheSize */
470         0744,                   /* iCreate_mask */
471         0000,                   /* iCreate_force_mode */
472         0777,                   /* iSecurity_mask */
473         0,                      /* iSecurity_force_mode */
474         0755,                   /* iDir_mask */
475         0000,                   /* iDir_force_mode */
476         0777,                   /* iDir_Security_mask */
477         0,                      /* iDir_Security_force_mode */
478         0,                      /* iMaxConnections */
479         CASE_LOWER,             /* iDefaultCase */
480         DEFAULT_PRINTING,       /* iPrinting */
481         2,                      /* iOplockContentionLimit */
482         0,                      /* iCSCPolicy */
483         1024,           /* iBlock_size */
484         False,                  /* bPreexecClose */
485         False,                  /* bRootpreexecClose */
486         False,                  /* case sensitive */
487         True,                   /* case preserve */
488         True,                   /* short case preserve */
489         False,                  /* case mangle */
490         True,                   /* bHideDotFiles */
491         False,                  /* bHideSpecialFiles */
492         False,                  /* bHideUnReadable */
493         False,                  /* bHideUnWriteableFiles */
494         True,                   /* bBrowseable */
495         True,                   /* bAvailable */
496         True,                   /* bRead_only */
497         True,                   /* bNo_set_dir */
498         False,                  /* bGuest_only */
499         False,                  /* bGuest_ok */
500         False,                  /* bPrint_ok */
501         False,                  /* bMap_system */
502         False,                  /* bMap_hidden */
503         True,                   /* bMap_archive */
504         True,                   /* bLocking */
505         True,                   /* bStrictLocking */
506         True,                   /* bPosixLocking */
507         True,                   /* bShareModes */
508         True,                   /* bOpLocks */
509         True,                   /* bLevel2OpLocks */
510         False,                  /* bOnlyUser */
511         True,                   /* bMangledNames */
512         True,                   /* bWidelinks */
513         True,                   /* bSymlinks */
514         False,                  /* bSyncAlways */
515         False,                  /* bStrictAllocate */
516         False,                  /* bStrictSync */
517         '~',                    /* magic char */
518         NULL,                   /* copymap */
519         False,                  /* bDeleteReadonly */
520         False,                  /* bFakeOplocks */
521         False,                  /* bDeleteVetoFiles */
522         False,                  /* bDosFilemode */
523         False,                  /* bDosFiletimes */
524         False,                  /* bDosFiletimeResolution */
525         False,                  /* bFakeDirCreateTimes */
526         True,                   /* bBlockingLocks */
527         False,                  /* bInheritPerms */
528         False,                  /* bInheritACLS */
529         False,                  /* bMSDfsRoot */
530         False,                  /* bUseClientDriver */
531         False,                  /* bDefaultDevmode */
532         True,                   /* bNTAclSupport */
533         False,                  /* bUseSendfile */
534         False,                  /* bProfileAcls */
535         
536         NULL,                   /* Parametric options */
537
538         ""                      /* dummy */
539 };
540
541 /* local variables */
542 static service **ServicePtrs = NULL;
543 static int iNumServices = 0;
544 static int iServiceIndex = 0;
545 static BOOL bInGlobalSection = True;
546 static BOOL bGlobalOnly = False;
547 static int server_role;
548 static int default_server_announce;
549
550 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
551
552 /* prototypes for the special type handlers */
553 static BOOL handle_include(const char *pszParmValue, char **ptr);
554 static BOOL handle_copy(const char *pszParmValue, char **ptr);
555 static BOOL handle_source_env(const char *pszParmValue, char **ptr);
556 static BOOL handle_netbios_name(const char *pszParmValue, char **ptr);
557 static BOOL handle_idmap_uid(const char *pszParmValue, char **ptr);
558 static BOOL handle_idmap_gid(const char *pszParmValue, char **ptr);
559 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
560 static BOOL handle_debug_list( const char *pszParmValue, char **ptr );
561 static BOOL handle_workgroup( const char *pszParmValue, char **ptr );
562 static BOOL handle_netbios_aliases( const char *pszParmValue, char **ptr );
563 static BOOL handle_netbios_scope( const char *pszParmValue, char **ptr );
564
565 static BOOL handle_ldap_machine_suffix ( const char *pszParmValue, char **ptr );
566 static BOOL handle_ldap_user_suffix ( const char *pszParmValue, char **ptr );
567 static BOOL handle_ldap_suffix ( const char *pszParmValue, char **ptr );
568
569 static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr);
570
571 static void set_server_role(void);
572 static void set_default_server_announce_type(void);
573
574 static const struct enum_list enum_protocol[] = {
575         {PROTOCOL_NT1, "NT1"},
576         {PROTOCOL_LANMAN2, "LANMAN2"},
577         {PROTOCOL_LANMAN1, "LANMAN1"},
578         {PROTOCOL_CORE, "CORE"},
579         {PROTOCOL_COREPLUS, "COREPLUS"},
580         {PROTOCOL_COREPLUS, "CORE+"},
581         {-1, NULL}
582 };
583
584 static const struct enum_list enum_security[] = {
585         {SEC_SHARE, "SHARE"},
586         {SEC_USER, "USER"},
587         {SEC_SERVER, "SERVER"},
588         {SEC_DOMAIN, "DOMAIN"},
589 #ifdef HAVE_ADS
590         {SEC_ADS, "ADS"},
591 #endif
592         {-1, NULL}
593 };
594
595 static const struct enum_list enum_printing[] = {
596         {PRINT_SYSV, "sysv"},
597         {PRINT_AIX, "aix"},
598         {PRINT_HPUX, "hpux"},
599         {PRINT_BSD, "bsd"},
600         {PRINT_QNX, "qnx"},
601         {PRINT_PLP, "plp"},
602         {PRINT_LPRNG, "lprng"},
603         {PRINT_SOFTQ, "softq"},
604         {PRINT_CUPS, "cups"},
605         {PRINT_LPRNT, "nt"},
606         {PRINT_LPROS2, "os2"},
607 #ifdef DEVELOPER
608         {PRINT_TEST, "test"},
609         {PRINT_VLP, "vlp"},
610 #endif /* DEVELOPER */
611         {-1, NULL}
612 };
613
614 static const struct enum_list enum_ldap_ssl[] = {
615 #ifdef WITH_LDAP_SAMCONFIG
616         {LDAP_SSL_ON, "Yes"},
617         {LDAP_SSL_ON, "yes"},
618         {LDAP_SSL_ON, "on"},
619         {LDAP_SSL_ON, "On"},
620 #endif
621         {LDAP_SSL_OFF, "no"},
622         {LDAP_SSL_OFF, "No"},
623         {LDAP_SSL_OFF, "off"},
624         {LDAP_SSL_OFF, "Off"},
625         {LDAP_SSL_START_TLS, "start tls"},
626         {LDAP_SSL_START_TLS, "Start_tls"},
627         {-1, NULL}
628 };
629
630 static const struct enum_list enum_ldap_passwd_sync[] = {
631         {LDAP_PASSWD_SYNC_ON, "Yes"},
632         {LDAP_PASSWD_SYNC_ON, "yes"},
633         {LDAP_PASSWD_SYNC_ON, "on"},
634         {LDAP_PASSWD_SYNC_ON, "On"},
635         {LDAP_PASSWD_SYNC_OFF, "no"},
636         {LDAP_PASSWD_SYNC_OFF, "No"},
637         {LDAP_PASSWD_SYNC_OFF, "off"},
638         {LDAP_PASSWD_SYNC_OFF, "Off"},
639 #ifdef LDAP_EXOP_X_MODIFY_PASSWD        
640         {LDAP_PASSWD_SYNC_ONLY, "Only"},
641         {LDAP_PASSWD_SYNC_ONLY, "only"},
642 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */  
643         {-1, NULL}
644 };
645
646 /* Types of machine we can announce as. */
647 #define ANNOUNCE_AS_NT_SERVER 1
648 #define ANNOUNCE_AS_WIN95 2
649 #define ANNOUNCE_AS_WFW 3
650 #define ANNOUNCE_AS_NT_WORKSTATION 4
651
652 static const struct enum_list enum_announce_as[] = {
653         {ANNOUNCE_AS_NT_SERVER, "NT"},
654         {ANNOUNCE_AS_NT_SERVER, "NT Server"},
655         {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
656         {ANNOUNCE_AS_WIN95, "win95"},
657         {ANNOUNCE_AS_WFW, "WfW"},
658         {-1, NULL}
659 };
660
661 static const struct enum_list enum_case[] = {
662         {CASE_LOWER, "lower"},
663         {CASE_UPPER, "upper"},
664         {-1, NULL}
665 };
666
667 static const struct enum_list enum_bool_auto[] = {
668         {False, "No"},
669         {False, "False"},
670         {False, "0"},
671         {True, "Yes"},
672         {True, "True"},
673         {True, "1"},
674         {Auto, "Auto"},
675         {-1, NULL}
676 };
677
678 /* Client-side offline caching policy types */
679 #define CSC_POLICY_MANUAL 0
680 #define CSC_POLICY_DOCUMENTS 1
681 #define CSC_POLICY_PROGRAMS 2
682 #define CSC_POLICY_DISABLE 3
683
684 static const struct enum_list enum_csc_policy[] = {
685         {CSC_POLICY_MANUAL, "manual"},
686         {CSC_POLICY_DOCUMENTS, "documents"},
687         {CSC_POLICY_PROGRAMS, "programs"},
688         {CSC_POLICY_DISABLE, "disable"},
689         {-1, NULL}
690 };
691
692 /* 
693    Do you want session setups at user level security with a invalid
694    password to be rejected or allowed in as guest? WinNT rejects them
695    but it can be a pain as it means "net view" needs to use a password
696
697    You have 3 choices in the setting of map_to_guest:
698
699    "Never" means session setups with an invalid password
700    are rejected. This is the default.
701
702    "Bad User" means session setups with an invalid password
703    are rejected, unless the username does not exist, in which case it
704    is treated as a guest login
705
706    "Bad Password" means session setups with an invalid password
707    are treated as a guest login
708
709    Note that map_to_guest only has an effect in user or server
710    level security.
711 */
712
713 static const struct enum_list enum_map_to_guest[] = {
714         {NEVER_MAP_TO_GUEST, "Never"},
715         {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
716         {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
717         {-1, NULL}
718 };
719
720 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
721  *
722  * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
723  * is implied in current control logic. This may change at some later time. A
724  * flag value of 0 means - show as development option only.
725  *
726  * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
727  * screen in SWAT. This is used to exclude parameters as well as to squash all
728  * parameters that have been duplicated by pseudonyms.
729  */
730 static struct parm_struct parm_table[] = {
731         {"Base Options", P_SEP, P_SEPARATOR},
732
733         {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
734         {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
735         {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
736         {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
737         {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
738         {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
739         {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
740         {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
741         {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
742         {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
743         {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
744         {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
745         {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED  | FLAG_DEVELOPER},
746         {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
747         {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
748
749         {"Security Options", P_SEP, P_SEPARATOR},
750         
751         {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
752         {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
753         {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
754         {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
755         {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC},
756         {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC},
757         {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
758         {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
759         {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
760         {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
761         {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
762         {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED | FLAG_DEVELOPER},
763         {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
764         {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765         {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
766         {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767         {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
768         {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769         {"sam backend", P_LIST, P_GLOBAL, &Globals.szSamBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770         {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
771         {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
772         {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
773         {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
774         {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
775         {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
776         
777         {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
778         {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
779         {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
780         {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
781         {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
782         {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
783         {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
784         {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
785         {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
786         {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
787         {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
788         {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
789         {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
790         
791         {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
792         {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
793         {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
794         
795         {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
796         {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
797         {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
798         {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
799         {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
800         {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_GLOBAL | FLAG_PRINT},
801         {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE},
802         {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE},
803         {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
804         
805         {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
806         {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
807         {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
808         {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
809         
810         {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
811         {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
812         {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
813         {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
814         {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
815         {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
816         {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
817         {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
818         {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
819         {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
820         {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE},
821         {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_SHARE},
822         {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
823         {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
824
825         {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
826         {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
827         
828         {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
829         {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
830         {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
831         {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
832         {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
833         {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
834
835         {"Logging Options", P_SEP, P_SEPARATOR},
836
837         {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
838         {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
839         {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
840         {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
841         {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
842         
843         {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
844         {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
845         {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_DEVELOPER},
846         {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_DEVELOPER},
847         {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_DEVELOPER},
848         {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_DEVELOPER},
849         
850         {"Protocol Options", P_SEP, P_SEPARATOR},
851         
852         {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
853         {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED | FLAG_DEVELOPER},
854         {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
855         {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
856         {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
857         {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
858         {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_DEVELOPER},
859         {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
860         {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
861         {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
862         
863         {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_ADVANCED},
864         {"nt acl support", P_BOOL,  P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED | FLAG_WIZARD},
865         {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
866         {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
867         {"profile acls", P_BOOL,  P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE  | FLAG_ADVANCED | FLAG_WIZARD},
868         
869         {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
870         {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
871         {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
872         {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
873         
874         {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
875         {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, 
876         {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
877         {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
878         {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
879         {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
880         {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
881         {"client signing", P_BOOL, P_GLOBAL, &Globals.client_signing, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
882         {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_DEVELOPER},
883
884         {"Tuning Options", P_SEP, P_SEPARATOR},
885         
886         {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
887         {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_DEVELOPER},
888         {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_DEVELOPER},
889         {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_DEVELOPER},
890         {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
891         {"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_DEVELOPER},
892         
893         {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
894         {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_DEVELOPER},
895         {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
896         {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
897         {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_DEVELOPER},
898         {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
899         {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
900         {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, FLAG_DEVELOPER},
901         
902         {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_DEVELOPER},
903         {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, FLAG_DEVELOPER},
904         {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_SHARE},
905         {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE},
906         {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE},
907         {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
908         {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_SHARE},
909         {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
910         {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE},
911
912         {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
913
914         {"Printing Options", P_SEP, P_SEPARATOR},
915         
916         {"total print jobs", P_INTEGER, P_GLOBAL, &Globals.iTotalPrintJobs, NULL, NULL, FLAG_PRINT},
917         {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_PRINT},
918         {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
919         {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
920         {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
921         {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
922         {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
923         {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
924         {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
925         {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
926         {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
927         {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
928         {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
929         {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
930         {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
931         {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
932         {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
933
934         {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
935         {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
936         {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
937         {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
938         {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
939         
940         {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
941         {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
942         {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_PRINT},
943         {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_PRINT},
944
945         {"Filename Handling", P_SEP, P_SEPARATOR},
946         {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
947         {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
948         {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
949         
950         {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
951         {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE},
952         {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
953         {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_HIDE},
954         {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
955         {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
956         {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
957         {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
958         {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
959         {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
960         {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
961         {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
962         {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
963         {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
964         {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
965         {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
966         {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
967         {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
968         {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
969         {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
970         {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
971         {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_DEVELOPER},
972
973         {"Domain Options", P_SEP, P_SEPARATOR},
974         
975         {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
976
977         {"Logon Options", P_SEP, P_SEPARATOR},
978
979         {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
980         {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
981         {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
982         {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
983         {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
984         {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
985         {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
986         {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
987         {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
988         {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
989
990         {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
991         {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
992         {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
993         {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
994         {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
995
996         {"Browse Options", P_SEP, P_SEPARATOR},
997         
998         {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
999         {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
1000         {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1001         {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
1002         {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
1003         {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
1004         {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
1005         {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1006         {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
1007         {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1008         {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
1009
1010         {"WINS Options", P_SEP, P_SEPARATOR},
1011         {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1012         {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1013         
1014         {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
1015         {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
1016         {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1017         {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
1018
1019         {"Locking Options", P_SEP, P_SEPARATOR},
1020         
1021         {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1022         {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
1023         {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE},
1024         {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
1025         {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1026         {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
1027         {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
1028         
1029         {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1030         {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1031         {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_GLOBAL},
1032         {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1033         {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1034         {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1035         {"share modes", P_BOOL, P_LOCAL,  &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
1036
1037         {"Ldap Options", P_SEP, P_SEPARATOR},
1038         
1039 #ifdef WITH_LDAP_SAMCONFIG
1040         {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
1041         {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0}, 
1042 #endif
1043         {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1044         {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_machine_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1045         {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1046         {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1047         {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1048         {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED | FLAG_DEVELOPER},
1049         {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED | FLAG_DEVELOPER},
1050         {"ldap trust ids", P_BOOL, P_GLOBAL, &Globals.ldap_trust_ids, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1051         {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1052
1053         {"Miscellaneous Options", P_SEP, P_SEPARATOR},
1054         {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1055         {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1056         {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1057         
1058         {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1059         {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1060         {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1061         {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE}, 
1062         {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1063         {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, 
1064 #ifdef WITH_UTMP
1065         {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1066         {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1067         {"utmp",          P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1068 #endif
1069         
1070         {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1071         {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL,  FLAG_DEVELOPER},
1072         {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1073         {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1074         {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1075         {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1076         {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
1077         {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1078         {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1079         {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1080         {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1081         
1082         {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1083         {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1084         {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1085         {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1086         
1087         {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_SHARE},
1088         {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1089         {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1090         {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_SHARE},
1091         {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1092         {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1093         {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
1094         {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
1095         {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE},
1096         {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1097         {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1098         {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1099         {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE},
1100         {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE},
1101         {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE},
1102         {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1103         {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1104         {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1105         {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1106
1107         {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1108         {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1109         {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1110
1111         {"VFS module options", P_SEP, P_SEPARATOR},
1112         
1113         {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjectFile, NULL, NULL, FLAG_SHARE},
1114         {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, FLAG_SHARE},
1115         {"vfs path", P_STRING, P_LOCAL, &sDefault.szVfsPath, NULL, NULL, FLAG_SHARE},
1116
1117         
1118         {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
1119         {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
1120         {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1121
1122         {"Winbind options", P_SEP, P_SEPARATOR},
1123
1124         {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1125         {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_HIDE},
1126         {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1127         {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_HIDE},
1128         {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1129         {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1130         {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1131         {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1132         {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1133         {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1134         {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1135         {"winbind backend", P_STRING, P_GLOBAL, &Globals.szWinbindBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1136
1137         {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
1138 };
1139
1140 /***************************************************************************
1141  Initialise the sDefault parameter structure for the printer values.
1142 ***************************************************************************/
1143
1144 static void init_printer_values(void)
1145 {
1146         /* choose defaults depending on the type of printing */
1147         switch (sDefault.iPrinting) {
1148                 case PRINT_BSD:
1149                 case PRINT_AIX:
1150                 case PRINT_LPRNT:
1151                 case PRINT_LPROS2:
1152                         string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
1153                         string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
1154                         string_set(&sDefault.szPrintcommand,
1155                                    "lpr -r -P'%p' %s");
1156                         break;
1157
1158                 case PRINT_LPRNG:
1159                 case PRINT_PLP:
1160                         string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
1161                         string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
1162                         string_set(&sDefault.szPrintcommand,
1163                                    "lpr -r -P'%p' %s");
1164                         string_set(&sDefault.szQueuepausecommand,
1165                                    "lpc stop '%p'");
1166                         string_set(&sDefault.szQueueresumecommand,
1167                                    "lpc start '%p'");
1168                         string_set(&sDefault.szLppausecommand,
1169                                    "lpc hold '%p' %j");
1170                         string_set(&sDefault.szLpresumecommand,
1171                                    "lpc release '%p' %j");
1172                         break;
1173
1174                 case PRINT_CUPS:
1175 #ifdef HAVE_CUPS
1176                         string_set(&sDefault.szLpqcommand, "");
1177                         string_set(&sDefault.szLprmcommand, "");
1178                         string_set(&sDefault.szPrintcommand, "");
1179                         string_set(&sDefault.szLppausecommand, "");
1180                         string_set(&sDefault.szLpresumecommand, "");
1181                         string_set(&sDefault.szQueuepausecommand, "");
1182                         string_set(&sDefault.szQueueresumecommand, "");
1183
1184                         string_set(&Globals.szPrintcapname, "cups");
1185 #else
1186                         string_set(&sDefault.szLpqcommand,
1187                                    "/usr/bin/lpstat -o '%p'");
1188                         string_set(&sDefault.szLprmcommand,
1189                                    "/usr/bin/cancel '%p-%j'");
1190                         string_set(&sDefault.szPrintcommand,
1191                                    "/usr/bin/lp -d '%p' %s; rm %s");
1192                         string_set(&sDefault.szLppausecommand,
1193                                    "lp -i '%p-%j' -H hold");
1194                         string_set(&sDefault.szLpresumecommand,
1195                                    "lp -i '%p-%j' -H resume");
1196                         string_set(&sDefault.szQueuepausecommand,
1197                                    "/usr/bin/disable '%p'");
1198                         string_set(&sDefault.szQueueresumecommand,
1199                                    "/usr/bin/enable '%p'");
1200                         string_set(&Globals.szPrintcapname, "lpstat");
1201 #endif /* HAVE_CUPS */
1202                         break;
1203
1204                 case PRINT_SYSV:
1205                 case PRINT_HPUX:
1206                         string_set(&sDefault.szLpqcommand, "lpstat -o%p");
1207                         string_set(&sDefault.szLprmcommand, "cancel %p-%j");
1208                         string_set(&sDefault.szPrintcommand,
1209                                    "lp -c -d%p %s; rm %s");
1210                         string_set(&sDefault.szQueuepausecommand,
1211                                    "disable %p");
1212                         string_set(&sDefault.szQueueresumecommand,
1213                                    "enable %p");
1214 #ifndef HPUX
1215                         string_set(&sDefault.szLppausecommand,
1216                                    "lp -i %p-%j -H hold");
1217                         string_set(&sDefault.szLpresumecommand,
1218                                    "lp -i %p-%j -H resume");
1219 #endif /* HPUX */
1220                         break;
1221
1222                 case PRINT_QNX:
1223                         string_set(&sDefault.szLpqcommand, "lpq -P%p");
1224                         string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
1225                         string_set(&sDefault.szPrintcommand, "lp -r -P%p %s");
1226                         break;
1227
1228                 case PRINT_SOFTQ:
1229                         string_set(&sDefault.szLpqcommand, "qstat -l -d%p");
1230                         string_set(&sDefault.szLprmcommand,
1231                                    "qstat -s -j%j -c");
1232                         string_set(&sDefault.szPrintcommand,
1233                                    "lp -d%p -s %s; rm %s");
1234                         string_set(&sDefault.szLppausecommand,
1235                                    "qstat -s -j%j -h");
1236                         string_set(&sDefault.szLpresumecommand,
1237                                    "qstat -s -j%j -r");
1238                         break;
1239 #ifdef DEVELOPER
1240         case PRINT_TEST:
1241         case PRINT_VLP:
1242                 string_set(&sDefault.szPrintcommand, "vlp print %p %s");
1243                 string_set(&sDefault.szLpqcommand, "vlp lpq %p");
1244                 string_set(&sDefault.szLprmcommand, "vlp lprm %p %j");
1245                 string_set(&sDefault.szLppausecommand, "vlp lppause %p %j");
1246                 string_set(&sDefault.szLpresumecommand, "vlp lpresum %p %j");
1247                 string_set(&sDefault.szQueuepausecommand, "vlp queuepause %p");
1248                 string_set(&sDefault.szQueueresumecommand, "vlp queueresume %p");
1249                 break;
1250 #endif /* DEVELOPER */
1251
1252         }
1253 }
1254
1255 /***************************************************************************
1256  Initialise the global parameter structure.
1257 ***************************************************************************/
1258
1259 static void init_globals(void)
1260 {
1261         static BOOL done_init = False;
1262         pstring s;
1263
1264         if (!done_init) {
1265                 int i;
1266                 memset((void *)&Globals, '\0', sizeof(Globals));
1267
1268                 for (i = 0; parm_table[i].label; i++)
1269                         if ((parm_table[i].type == P_STRING ||
1270                              parm_table[i].type == P_USTRING) &&
1271                             parm_table[i].ptr)
1272                                 string_set(parm_table[i].ptr, "");
1273
1274                 string_set(&sDefault.fstype, FSTYPE_STRING);
1275
1276                 init_printer_values();
1277
1278                 done_init = True;
1279         }
1280
1281
1282         DEBUG(3, ("Initialising global parameters\n"));
1283
1284         string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1285         string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1286
1287         /* use the new 'hash2' method by default, with a prefix of 1 */
1288         string_set(&Globals.szManglingMethod, "hash2");
1289         Globals.mangle_prefix = 1;
1290
1291         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1292
1293         /* using UTF8 by default allows us to support all chars */
1294         string_set(&Globals.unix_charset, "UTF8");
1295
1296         /* using UTF8 by default allows us to support all chars */
1297         string_set(&Globals.display_charset, "ASCII");
1298
1299         /* Use codepage 850 as a default for the dos character set */
1300         string_set(&Globals.dos_charset, "CP850");
1301
1302         /*
1303          * Allow the default PASSWD_CHAT to be overridden in local.h.
1304          */
1305         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1306         
1307         set_global_myname(myhostname());
1308         string_set(&Globals.szNetbiosName,global_myname());
1309
1310         set_global_myworkgroup(WORKGROUP);
1311         string_set(&Globals.szWorkgroup, lp_workgroup());
1312         
1313         string_set(&Globals.szPasswdProgram, "");
1314         string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
1315         string_set(&Globals.szPidDir, dyn_PIDDIR);
1316         string_set(&Globals.szLockDir, dyn_LOCKDIR);
1317         string_set(&Globals.szSocketAddress, "0.0.0.0");
1318         pstrcpy(s, "Samba ");
1319         pstrcat(s, VERSION);
1320         string_set(&Globals.szServerString, s);
1321         slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1322                  DEFAULT_MINOR_VERSION);
1323         string_set(&Globals.szAnnounceVersion, s);
1324
1325         pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1326
1327         string_set(&Globals.szLogonDrive, "");
1328         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1329         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1330         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1331
1332         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1333         string_set(&Globals.szPasswordServer, "*");
1334
1335         Globals.AlgorithmicRidBase = BASE_RID;
1336
1337         Globals.bLoadPrinters = True;
1338         Globals.mangled_stack = 50;
1339         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1340         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1341         Globals.max_xmit = 0x4104;
1342         Globals.max_mux = 50;   /* This is *needed* for profile support. */
1343         Globals.lpqcachetime = 10;
1344         Globals.bDisableSpoolss = False;
1345         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1346         Globals.iTotalPrintJobs = 0;  /* no limit specified */
1347         Globals.pwordlevel = 0;
1348         Globals.unamelevel = 0;
1349         Globals.deadtime = 0;
1350         Globals.bLargeReadwrite = True;
1351         Globals.max_log_size = 5000;
1352         Globals.max_open_files = MAX_OPEN_FILES;
1353         Globals.maxprotocol = PROTOCOL_NT1;
1354         Globals.minprotocol = PROTOCOL_CORE;
1355         Globals.security = SEC_USER;
1356         Globals.paranoid_server_security = True;
1357         Globals.bEncryptPasswords = True;
1358         Globals.bUpdateEncrypt = False;
1359         Globals.clientSchannel = Auto;
1360         Globals.serverSchannel = Auto;
1361         Globals.bReadRaw = True;
1362         Globals.bWriteRaw = True;
1363         Globals.bReadPrediction = False;
1364         Globals.bReadbmpx = False;
1365         Globals.bNullPasswords = False;
1366         Globals.bObeyPamRestrictions = False;
1367         Globals.bStripDot = False;
1368         Globals.syslog = 1;
1369         Globals.bSyslogOnly = False;
1370         Globals.bTimestampLogs = True;
1371         string_set(&Globals.szLogLevel, "0");
1372         Globals.bDebugHiresTimestamp = False;
1373         Globals.bDebugPid = False;
1374         Globals.bDebugUid = False;
1375         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
1376         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
1377         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
1378         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
1379         Globals.change_notify_timeout = 60;     /* 1 minute default. */
1380         Globals.bKernelChangeNotify = True;     /* On if we have it. */
1381         Globals.ReadSize = 16 * 1024;
1382         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
1383         Globals.lm_interval = 60;
1384         Globals.stat_cache_size = 50;   /* Number of stat translations we'll keep */
1385         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1386 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1387         Globals.bNISHomeMap = False;
1388 #ifdef WITH_NISPLUS_HOME
1389         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1390 #else
1391         string_set(&Globals.szNISHomeMapName, "auto.home");
1392 #endif
1393 #endif
1394         Globals.bTimeServer = False;
1395         Globals.bBindInterfacesOnly = False;
1396         Globals.bUnixPasswdSync = False;
1397         Globals.bPamPasswordChange = False;
1398         Globals.bPasswdChatDebug = False;
1399         Globals.bUnicode = True;        /* Do unicode on the wire by default */
1400         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
1401         Globals.bNTStatusSupport = True; /* Use NT status by default. */
1402         Globals.bStatCache = True;      /* use stat cache by default */
1403         Globals.restrict_anonymous = 0;
1404         Globals.bClientLanManAuth = True;       /* Do use the LanMan hash if it is available */
1405         Globals.bLanmanAuth = True;     /* Do use the LanMan hash if it is available */
1406         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1407         
1408         Globals.map_to_guest = 0;       /* By Default, "Never" */
1409         Globals.min_passwd_length = MINPASSWDLENGTH;    /* By Default, 5. */
1410         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
1411         Globals.enhanced_browsing = True; 
1412         Globals.iLockSpinCount = 3; /* Try 2 times. */
1413         Globals.iLockSpinTime = 10; /* usec. */
1414 #ifdef MMAP_BLACKLIST
1415         Globals.bUseMmap = False;
1416 #else
1417         Globals.bUseMmap = True;
1418 #endif
1419         Globals.bUnixExtensions = False;
1420
1421         /* hostname lookups can be very expensive and are broken on
1422            a large number of sites (tridge) */
1423         Globals.bHostnameLookups = False;
1424
1425 #ifdef WITH_LDAP_SAMCONFIG
1426         string_set(&Globals.szLdapServer, "localhost");
1427         Globals.ldap_port = 636;
1428         Globals.szPassdbBackend = str_list_make("ldapsam guest", NULL);
1429 #else
1430         Globals.szPassdbBackend = str_list_make("smbpasswd guest", NULL);
1431 #endif /* WITH_LDAP_SAMCONFIG */
1432
1433         string_set(&Globals.szLdapSuffix, "");
1434         string_set(&Globals.szLdapMachineSuffix, "");
1435         string_set(&Globals.szLdapUserSuffix, "");
1436
1437         string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))");
1438         string_set(&Globals.szLdapAdminDn, "");
1439         Globals.ldap_ssl = LDAP_SSL_ON;
1440         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1441         Globals.ldap_delete_dn = False;
1442
1443 /* these parameters are set to defaults that are more appropriate
1444    for the increasing samba install base:
1445
1446    as a member of the workgroup, that will possibly become a
1447    _local_ master browser (lm = True).  this is opposed to a forced
1448    local master browser startup (pm = True).
1449
1450    doesn't provide WINS server service by default (wsupp = False),
1451    and doesn't provide domain master browser services by default, either.
1452
1453 */
1454
1455         Globals.bMsAddPrinterWizard = True;
1456         Globals.bPreferredMaster = Auto;        /* depending on bDomainMaster */
1457         Globals.os_level = 20;
1458         Globals.bLocalMaster = True;
1459         Globals.bDomainMaster = Auto;   /* depending on bDomainLogons */
1460         Globals.bDomainLogons = False;
1461         Globals.bBrowseList = True;
1462         Globals.bWINSsupport = False;
1463         Globals.bWINSproxy = False;
1464
1465         Globals.bDNSproxy = True;
1466
1467         /* this just means to use them if they exist */
1468         Globals.bKernelOplocks = True;
1469
1470         Globals.bAllowTrustedDomains = True;
1471
1472         string_set(&Globals.szTemplateShell, "/bin/false");
1473         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1474         string_set(&Globals.szWinbindSeparator, "\\");
1475         string_set(&Globals.szAclCompat, "");
1476
1477         Globals.winbind_cache_time = 15;
1478         Globals.bWinbindEnumUsers = True;
1479         Globals.bWinbindEnumGroups = True;
1480         Globals.bWinbindUseDefaultDomain = False;
1481
1482         string_set(&Globals.szWinbindBackend, "tdb");
1483
1484         Globals.name_cache_timeout = 660; /* In seconds */
1485
1486         Globals.bUseSpnego = True;
1487         Globals.bClientUseSpnego = True;
1488
1489         string_set(&Globals.smb_ports, SMB_PORTS);
1490 }
1491
1492 static TALLOC_CTX *lp_talloc;
1493
1494 /******************************************************************* a
1495  Free up temporary memory - called from the main loop.
1496 ********************************************************************/
1497
1498 void lp_talloc_free(void)
1499 {
1500         if (!lp_talloc)
1501                 return;
1502         talloc_destroy(lp_talloc);
1503         lp_talloc = NULL;
1504 }
1505
1506 /*******************************************************************
1507  Convenience routine to grab string parameters into temporary memory
1508  and run standard_sub_basic on them. The buffers can be written to by
1509  callers without affecting the source string.
1510 ********************************************************************/
1511
1512 static char *lp_string(const char *s)
1513 {
1514         size_t len = s ? strlen(s) : 0;
1515         char *ret;
1516
1517         /* The follow debug is useful for tracking down memory problems
1518            especially if you have an inner loop that is calling a lp_*()
1519            function that returns a string.  Perhaps this debug should be
1520            present all the time? */
1521
1522 #if 0
1523         DEBUG(10, ("lp_string(%s)\n", s));
1524 #endif
1525
1526         if (!lp_talloc)
1527                 lp_talloc = talloc_init("lp_talloc");
1528
1529         ret = (char *)talloc(lp_talloc, len + 100);     /* leave room for substitution */
1530
1531         if (!ret)
1532                 return NULL;
1533
1534         /* Note: StrnCpy touches len+1 bytes, but we allocate 100
1535          * extra bytes so we're OK. */
1536
1537         if (!s)
1538                 *ret = 0;
1539         else
1540                 StrnCpy(ret, s, len);
1541
1542         if (trim_string(ret, "\"", "\"")) {
1543                 if (strchr(ret,'"') != NULL)
1544                         StrnCpy(ret, s, len);
1545         }
1546
1547         standard_sub_basic(current_user_info.smb_name,ret,len+100);
1548         return (ret);
1549 }
1550
1551 /*
1552    In this section all the functions that are used to access the 
1553    parameters from the rest of the program are defined 
1554 */
1555
1556 #define FN_GLOBAL_STRING(fn_name,ptr) \
1557  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1558 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1559  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1560 #define FN_GLOBAL_LIST(fn_name,ptr) \
1561  const char **fn_name(void) {return(*(const char ***)(ptr));}
1562 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1563  BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1564 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1565  char fn_name(void) {return(*(char *)(ptr));}
1566 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1567  int fn_name(void) {return(*(int *)(ptr));}
1568
1569 #define FN_LOCAL_STRING(fn_name,val) \
1570  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1571 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1572  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1573 #define FN_LOCAL_LIST(fn_name,val) \
1574  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1575 #define FN_LOCAL_BOOL(fn_name,val) \
1576  BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1577 #define FN_LOCAL_CHAR(fn_name,val) \
1578  char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1579 #define FN_LOCAL_INTEGER(fn_name,val) \
1580  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1581
1582 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1583 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1584 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1585 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1586 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1587 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1588 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1589 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1590 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1591 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1592 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1593 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1594 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1595 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1596 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1597 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1598 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1599 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1600 #ifdef WITH_UTMP
1601 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1602 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1603 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1604 #endif
1605 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1606 FN_GLOBAL_STRING(lp_source_environment, &Globals.szSourceEnv)
1607 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1608 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1609 FN_GLOBAL_STRING(lp_dfree_command, &Globals.szDfree)
1610 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1611 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1612 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1613 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1614 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1615 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1616 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1617 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1618 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1619 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1620 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1621 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1622 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1623 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1624 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1625 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1626 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1627 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1628 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1629 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1630 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1631 FN_GLOBAL_LIST(lp_passdb_backend, &Globals.szPassdbBackend)
1632 FN_GLOBAL_LIST(lp_sam_backend, &Globals.szSamBackend)
1633 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1634 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1635 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1636 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1637
1638 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1639 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1640 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1641 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1642 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1643 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1644
1645 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1646
1647 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1648 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1649
1650 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1651 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1652 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1653 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1654 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1655 FN_GLOBAL_STRING(lp_acl_compatibility, &Globals.szAclCompat)
1656 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1657 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1658 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1659 FN_GLOBAL_STRING(lp_winbind_backend, &Globals.szWinbindBackend)
1660
1661 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
1662
1663 #ifdef WITH_LDAP_SAMCONFIG
1664 FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
1665 FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
1666 #endif
1667 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1668 FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix)
1669 FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix)
1670 FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
1671 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1672 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1673 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1674 FN_GLOBAL_BOOL(lp_ldap_trust_ids, &Globals.ldap_trust_ids)
1675 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1676 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1677 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1678 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1679
1680 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1681 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1682 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1683 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1684 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1685 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1686 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1687 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1688 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1689 FN_GLOBAL_BOOL(lp_readprediction, &Globals.bReadPrediction)
1690 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1691 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1692 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1693 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1694 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1695 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1696 FN_GLOBAL_BOOL(lp_strip_dot, &Globals.bStripDot)
1697 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1698 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1699 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1700 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1701 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1702 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1703 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1704 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1705 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1706 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1707 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1708 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1709 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1710 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1711 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1712 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1713 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1714 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1715 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1716 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1717 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1718 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1719 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1720 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1721 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1722 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1723 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1724 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1725 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1726 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1727 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1728 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1729 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1730 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1731 FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
1732 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1733 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1734 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1735 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1736 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
1737 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
1738 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
1739 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1740 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1741 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1742 FN_GLOBAL_INTEGER(lp_readsize, &Globals.ReadSize)
1743 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
1744 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1745 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1746 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1747 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1748 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1749 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
1750 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1751 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
1752 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1753 FN_GLOBAL_INTEGER(lp_totalprintjobs, &Globals.iTotalPrintJobs)
1754 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
1755 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1756 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1757 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1758 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1759 FN_GLOBAL_INTEGER(lp_change_notify_timeout, &Globals.change_notify_timeout)
1760 FN_GLOBAL_INTEGER(lp_stat_cache_size, &Globals.stat_cache_size)
1761 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
1762 FN_GLOBAL_INTEGER(lp_min_passwd_length, &Globals.min_passwd_length)
1763 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
1764 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1765 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1766 FN_LOCAL_STRING(lp_preexec, szPreExec)
1767 FN_LOCAL_STRING(lp_postexec, szPostExec)
1768 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
1769 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
1770 FN_LOCAL_STRING(lp_servicename, szService)
1771 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1772 FN_LOCAL_STRING(lp_pathname, szPath)
1773 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
1774 FN_LOCAL_STRING(lp_username, szUsername)
1775 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1776 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1777 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1778 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1779 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1780 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1781 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1782 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1783 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1784 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1785 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1786 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1787 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1788 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
1789 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
1790 FN_LOCAL_STRING(lp_comment, comment)
1791 FN_LOCAL_STRING(lp_force_user, force_user)
1792 FN_LOCAL_STRING(lp_force_group, force_group)
1793 FN_LOCAL_LIST(lp_readlist, readlist)
1794 FN_LOCAL_LIST(lp_writelist, writelist)
1795 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
1796 FN_LOCAL_STRING(lp_fstype, fstype)
1797 FN_LOCAL_LIST(lp_vfsobj, szVfsObjectFile)
1798 FN_LOCAL_STRING(lp_vfs_options, szVfsOptions)
1799 FN_LOCAL_STRING(lp_vfs_path, szVfsPath)
1800 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1801 static FN_LOCAL_STRING(lp_volume, volume)
1802 FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
1803 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
1804 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
1805 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
1806 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1807 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1808 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
1809 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
1810 FN_LOCAL_BOOL(lp_casesensitive, bCaseSensitive)
1811 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
1812 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
1813 FN_LOCAL_BOOL(lp_casemangle, bCaseMangle)
1814 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
1815 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
1816 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
1817 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
1818 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1819 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1820 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
1821 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1822 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1823 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1824 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1825 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1826 FN_LOCAL_BOOL(lp_locking, bLocking)
1827 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1828 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1829 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1830 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1831 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1832 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1833 FN_LOCAL_BOOL(lp_manglednames, bMangledNames)
1834 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
1835 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
1836 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
1837 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
1838 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1839 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1840 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
1841 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
1842 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
1843 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
1844 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
1845 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
1846 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
1847 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
1848 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
1849 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
1850 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
1851 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
1852 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
1853 FN_LOCAL_BOOL(lp_use_sendfile, bUseSendfile)
1854 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
1855 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
1856 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
1857 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
1858 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
1859 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
1860 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
1861 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
1862 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
1863 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1864 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
1865 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1866 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1867 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
1868 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
1869 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1870 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
1871 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
1872 FN_LOCAL_CHAR(lp_magicchar, magic_char)
1873 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1874 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1875 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
1876 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1877 FN_GLOBAL_BOOL(lp_client_signing, &Globals.client_signing)
1878
1879 /* local prototypes */
1880
1881 static int map_parameter(const char *pszParmName);
1882 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1883 static int getservicebyname(const char *pszServiceName,
1884                             service * pserviceDest);
1885 static void copy_service(service * pserviceDest,
1886                          service * pserviceSource, BOOL *pcopymapDest);
1887 static BOOL service_ok(int iService);
1888 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
1889 static BOOL do_section(const char *pszSectionName);
1890 static void init_copymap(service * pservice);
1891
1892 /* This is a helper function for parametrical options support. */
1893 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1894 /* Actual parametrical functions are quite simple */
1895 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1896 {
1897         char* vfskey;
1898         param_opt_struct *data;
1899         
1900         if (lookup_service >= iNumServices) return NULL;
1901         
1902         data = (lookup_service < 0) ? 
1903                 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1904     
1905         asprintf(&vfskey, "%s:%s", type, option);
1906         while (data) {
1907                 if (strcmp(data->key, vfskey) == 0) {
1908                         string_free(&vfskey);
1909                         return data->value;
1910                 }
1911                 data = data->next;
1912         }
1913
1914         if (lookup_service >= 0) {
1915                 /* Try to fetch the same option but from globals */
1916                 /* but only if we are not already working with Globals */
1917                 data = Globals.param_opt;
1918                 while (data) {
1919                         if (strcmp(data->key, vfskey) == 0) {
1920                                 string_free(&vfskey);
1921                                 return data->value;
1922                         }
1923                         data = data->next;
1924                 }
1925         }
1926
1927         string_free(&vfskey);
1928         
1929         return NULL;
1930 }
1931
1932
1933 /*******************************************************************
1934 convenience routine to return int parameters.
1935 ********************************************************************/
1936 static int lp_int(const char *s)
1937 {
1938
1939         if (!s) {
1940                 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1941                 return (-1);
1942         }
1943
1944         return atoi(s); 
1945 }
1946
1947 /*******************************************************************
1948 convenience routine to return unsigned long parameters.
1949 ********************************************************************/
1950 static int lp_ulong(const char *s)
1951 {
1952
1953         if (!s) {
1954                 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1955                 return (-1);
1956         }
1957
1958         return strtoul(s, NULL, 10);
1959 }
1960
1961 /*******************************************************************
1962 convenience routine to return boolean parameters.
1963 ********************************************************************/
1964 static BOOL lp_bool(const char *s)
1965 {
1966         BOOL ret = False;
1967
1968         if (!s) {
1969                 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1970                 return False;
1971         }
1972         
1973         if (!set_boolean(&ret,s)) {
1974                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1975                 return False;
1976         }
1977
1978         return ret;
1979 }
1980
1981 /*******************************************************************
1982 convenience routine to return enum parameters.
1983 ********************************************************************/
1984 static int lp_enum(const char *s,const struct enum_list *_enum)
1985 {
1986         int i;
1987
1988         if (!s || !_enum) {
1989                 DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
1990                 return False;
1991         }
1992         
1993         for (i=0; _enum[i].name; i++) {
1994                 if (strcasecmp(_enum[i].name,s)==0)
1995                         return _enum[i].value;
1996         }
1997
1998         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1999         return (-1);
2000 }
2001
2002 /* Return parametric option from a given service. Type is a part of option before ':' */
2003 /* Parametric option has following syntax: 'Type: option = value' */
2004 /* Returned value is allocated in 'lp_talloc' context */
2005
2006 char *lp_parm_string(int lookup_service, const char *type, const char *option)
2007 {
2008         const char *value = get_parametrics(lookup_service, type, option);
2009         
2010         if (value)
2011                 return lp_string(value);
2012
2013         return NULL;
2014 }
2015
2016 /* Return parametric option from a given service. Type is a part of option before ':' */
2017 /* Parametric option has following syntax: 'Type: option = value' */
2018 /* Returned value is allocated in 'lp_talloc' context */
2019
2020 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
2021                            const char *separator)
2022 {
2023         const char *value = get_parametrics(lookup_service, type, option);
2024         
2025         if (value)
2026                 return str_list_make(value, separator);
2027
2028         return NULL;
2029 }
2030
2031 /* Return parametric option from a given service. Type is a part of option before ':' */
2032 /* Parametric option has following syntax: 'Type: option = value' */
2033
2034 int lp_parm_int(int lookup_service, const char *type, const char *option)
2035 {
2036         const char *value = get_parametrics(lookup_service, type, option);
2037         
2038         if (value)
2039                 return lp_int(value);
2040
2041         return (-1);
2042 }
2043
2044 /* Return parametric option from a given service. Type is a part of option before ':' */
2045 /* Parametric option has following syntax: 'Type: option = value' */
2046
2047 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option)
2048 {
2049         const char *value = get_parametrics(lookup_service, type, option);
2050         
2051         if (value)
2052                 return lp_ulong(value);
2053
2054         return (0);
2055 }
2056
2057 /* Return parametric option from a given service. Type is a part of option before ':' */
2058 /* Parametric option has following syntax: 'Type: option = value' */
2059
2060 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option)
2061 {
2062         const char *value = get_parametrics(lookup_service, type, option);
2063         
2064         if (value)
2065                 return lp_bool(value);
2066
2067         return False;
2068 }
2069
2070 /* Return parametric option from a given service. Type is a part of option before ':' */
2071 /* Parametric option has following syntax: 'Type: option = value' */
2072
2073 int lp_parm_enum(int lookup_service, const char *type, const char *option,
2074                  const struct enum_list *_enum)
2075 {
2076         const char *value = get_parametrics(lookup_service, type, option);
2077         
2078         if (value)
2079                 return lp_enum(value, _enum);
2080
2081         return (-1);
2082 }
2083
2084
2085 /***************************************************************************
2086  Initialise a service to the defaults.
2087 ***************************************************************************/
2088
2089 static void init_service(service * pservice)
2090 {
2091         memset((char *)pservice, '\0', sizeof(service));
2092         copy_service(pservice, &sDefault, NULL);
2093 }
2094
2095 /***************************************************************************
2096  Free the dynamically allocated parts of a service struct.
2097 ***************************************************************************/
2098
2099 static void free_service(service *pservice)
2100 {
2101         int i;
2102         param_opt_struct *data, *pdata;
2103         if (!pservice)
2104                 return;
2105
2106         if (pservice->szService)
2107                 DEBUG(5, ("free_service: Freeing service %s\n",
2108                        pservice->szService));
2109
2110         string_free(&pservice->szService);
2111         SAFE_FREE(pservice->copymap);
2112
2113         for (i = 0; parm_table[i].label; i++) {
2114                 if ((parm_table[i].type == P_STRING ||
2115                      parm_table[i].type == P_USTRING) &&
2116                     parm_table[i].class == P_LOCAL)
2117                         string_free((char **)
2118                                     (((char *)pservice) +
2119                                      PTR_DIFF(parm_table[i].ptr, &sDefault)));
2120                 else if (parm_table[i].type == P_LIST &&
2121                          parm_table[i].class == P_LOCAL)
2122                              str_list_free((char ***)
2123                                             (((char *)pservice) +
2124                                              PTR_DIFF(parm_table[i].ptr, &sDefault)));
2125         }
2126                                 
2127         DEBUG(5,("Freeing parametrics:\n"));
2128         data = pservice->param_opt;
2129         while (data) {
2130                 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2131                 string_free(&data->key);
2132                 string_free(&data->value);
2133                 pdata = data->next;
2134                 SAFE_FREE(data);
2135                 data = pdata;
2136         }
2137
2138         ZERO_STRUCTP(pservice);
2139 }
2140
2141 /***************************************************************************
2142  Add a new service to the services array initialising it with the given 
2143  service. 
2144 ***************************************************************************/
2145
2146 static int add_a_service(const service *pservice, const char *name)
2147 {
2148         int i;
2149         service tservice;
2150         int num_to_alloc = iNumServices + 1;
2151         param_opt_struct *data, *pdata;
2152
2153         tservice = *pservice;
2154
2155         /* it might already exist */
2156         if (name) {
2157                 i = getservicebyname(name, NULL);
2158                 if (i >= 0) {
2159                         /* Clean all parametric options for service */
2160                         /* They will be added during parsing again */
2161                         data = ServicePtrs[i]->param_opt;
2162                         while (data) {
2163                                 string_free(&data->key);
2164                                 string_free(&data->value);
2165                                 pdata = data->next;
2166                                 SAFE_FREE(data);
2167                                 data = pdata;
2168                         }
2169                         ServicePtrs[i]->param_opt = NULL;
2170                         return (i);
2171                 }
2172         }
2173
2174         /* find an invalid one */
2175         for (i = 0; i < iNumServices; i++)
2176                 if (!ServicePtrs[i]->valid)
2177                         break;
2178
2179         /* if not, then create one */
2180         if (i == iNumServices) {
2181                 service **tsp;
2182                 
2183                 tsp = (service **) Realloc(ServicePtrs,
2184                                            sizeof(service *) *
2185                                            num_to_alloc);
2186                                            
2187                 if (!tsp) {
2188                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2189                         return (-1);
2190                 }
2191                 else {
2192                         ServicePtrs = tsp;
2193                         ServicePtrs[iNumServices] =
2194                                 (service *) malloc(sizeof(service));
2195                 }
2196                 if (!ServicePtrs[iNumServices]) {
2197                         DEBUG(0,("add_a_service: out of memory!\n"));
2198                         return (-1);
2199                 }
2200
2201                 iNumServices++;
2202         } else
2203                 free_service(ServicePtrs[i]);
2204
2205         ServicePtrs[i]->valid = True;
2206
2207         init_service(ServicePtrs[i]);
2208         copy_service(ServicePtrs[i], &tservice, NULL);
2209         if (name)
2210                 string_set(&ServicePtrs[i]->szService, name);
2211         return (i);
2212 }
2213
2214 /***************************************************************************
2215  Add a new home service, with the specified home directory, defaults coming 
2216  from service ifrom.
2217 ***************************************************************************/
2218
2219 BOOL lp_add_home(const char *pszHomename, int iDefaultService, 
2220                  const char *user, const char *pszHomedir)
2221 {
2222         int i;
2223         pstring newHomedir;
2224
2225         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2226
2227         if (i < 0)
2228                 return (False);
2229
2230         if (!(*(ServicePtrs[iDefaultService]->szPath))
2231             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
2232                 pstrcpy(newHomedir, pszHomedir);
2233         } else {
2234                 pstrcpy(newHomedir, lp_pathname(iDefaultService));
2235                 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir)); 
2236         }
2237
2238         string_set(&ServicePtrs[i]->szPath, newHomedir);
2239
2240         if (!(*(ServicePtrs[i]->comment))) {
2241                 pstring comment;
2242                 slprintf(comment, sizeof(comment) - 1,
2243                          "Home directory of %s", user);
2244                 string_set(&ServicePtrs[i]->comment, comment);
2245         }
2246         ServicePtrs[i]->bAvailable = sDefault.bAvailable;
2247         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2248
2249         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
2250                user, newHomedir));
2251         
2252         return (True);
2253 }
2254
2255 /***************************************************************************
2256  Add a new service, based on an old one.
2257 ***************************************************************************/
2258
2259 int lp_add_service(const char *pszService, int iDefaultService)
2260 {
2261         return (add_a_service(ServicePtrs[iDefaultService], pszService));
2262 }
2263
2264 /***************************************************************************
2265  Add the IPC service.
2266 ***************************************************************************/
2267
2268 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2269 {
2270         pstring comment;
2271         int i = add_a_service(&sDefault, ipc_name);
2272
2273         if (i < 0)
2274                 return (False);
2275
2276         slprintf(comment, sizeof(comment) - 1,
2277                  "IPC Service (%s)", Globals.szServerString);
2278
2279         string_set(&ServicePtrs[i]->szPath, tmpdir());
2280         string_set(&ServicePtrs[i]->szUsername, "");
2281         string_set(&ServicePtrs[i]->comment, comment);
2282         string_set(&ServicePtrs[i]->fstype, "IPC");
2283         ServicePtrs[i]->iMaxConnections = 0;
2284         ServicePtrs[i]->bAvailable = True;
2285         ServicePtrs[i]->bRead_only = True;
2286         ServicePtrs[i]->bGuest_only = False;
2287         ServicePtrs[i]->bGuest_ok = guest_ok;
2288         ServicePtrs[i]->bPrint_ok = False;
2289         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2290
2291         DEBUG(3, ("adding IPC service\n"));
2292
2293         return (True);
2294 }
2295
2296 /***************************************************************************
2297  Add a new printer service, with defaults coming from service iFrom.
2298 ***************************************************************************/
2299
2300 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2301 {
2302         const char *comment = "From Printcap";
2303         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2304
2305         if (i < 0)
2306                 return (False);
2307
2308         /* note that we do NOT default the availability flag to True - */
2309         /* we take it from the default service passed. This allows all */
2310         /* dynamic printers to be disabled by disabling the [printers] */
2311         /* entry (if/when the 'available' keyword is implemented!).    */
2312
2313         /* the printer name is set to the service name. */
2314         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2315         string_set(&ServicePtrs[i]->comment, comment);
2316         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2317         /* Printers cannot be read_only. */
2318         ServicePtrs[i]->bRead_only = False;
2319         /* No share modes on printer services. */
2320         ServicePtrs[i]->bShareModes = False;
2321         /* No oplocks on printer services. */
2322         ServicePtrs[i]->bOpLocks = False;
2323         /* Printer services must be printable. */
2324         ServicePtrs[i]->bPrint_ok = True;
2325
2326         DEBUG(3, ("adding printer service %s\n", pszPrintername));
2327
2328         update_server_announce_as_printserver();
2329
2330         return (True);
2331 }
2332
2333 /***************************************************************************
2334  Map a parameter's string representation to something we can use. 
2335  Returns False if the parameter string is not recognised, else TRUE.
2336 ***************************************************************************/
2337
2338 static int map_parameter(const char *pszParmName)
2339 {
2340         int iIndex;
2341
2342         if (*pszParmName == '-')
2343                 return (-1);
2344
2345         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2346                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2347                         return (iIndex);
2348
2349         /* Warn only if it isn't parametric option */
2350         if (strchr(pszParmName, ':') == NULL)
2351                 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2352         /* We do return 'fail' for parametric options as well because they are
2353            stored in different storage
2354          */
2355         return (-1);
2356 }
2357
2358 /***************************************************************************
2359  Set a boolean variable from the text value stored in the passed string.
2360  Returns True in success, False if the passed string does not correctly 
2361  represent a boolean.
2362 ***************************************************************************/
2363
2364 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2365 {
2366         BOOL bRetval;
2367
2368         bRetval = True;
2369         if (strwicmp(pszParmValue, "yes") == 0 ||
2370             strwicmp(pszParmValue, "true") == 0 ||
2371             strwicmp(pszParmValue, "1") == 0)
2372                 *pb = True;
2373         else if (strwicmp(pszParmValue, "no") == 0 ||
2374                     strwicmp(pszParmValue, "False") == 0 ||
2375                     strwicmp(pszParmValue, "0") == 0)
2376                 *pb = False;
2377         else {
2378                 DEBUG(0,
2379                       ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2380                        pszParmValue));
2381                 bRetval = False;
2382         }
2383         return (bRetval);
2384 }
2385
2386 /***************************************************************************
2387 Find a service by name. Otherwise works like get_service.
2388 ***************************************************************************/
2389
2390 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2391 {
2392         int iService;
2393
2394         for (iService = iNumServices - 1; iService >= 0; iService--)
2395                 if (VALID(iService) &&
2396                     strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
2397                         if (pserviceDest != NULL)
2398                                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2399                         break;
2400                 }
2401
2402         return (iService);
2403 }
2404
2405 /***************************************************************************
2406  Copy a service structure to another.
2407  If pcopymapDest is NULL then copy all fields
2408 ***************************************************************************/
2409
2410 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2411 {
2412         int i;
2413         BOOL bcopyall = (pcopymapDest == NULL);
2414         param_opt_struct *data, *pdata, *paramo;
2415         BOOL not_added;
2416
2417         for (i = 0; parm_table[i].label; i++)
2418                 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
2419                     (bcopyall || pcopymapDest[i])) {
2420                         void *def_ptr = parm_table[i].ptr;
2421                         void *src_ptr =
2422                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2423                                                                     &sDefault);
2424                         void *dest_ptr =
2425                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2426                                                                   &sDefault);
2427
2428                         switch (parm_table[i].type) {
2429                                 case P_BOOL:
2430                                 case P_BOOLREV:
2431                                         *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2432                                         break;
2433
2434                                 case P_INTEGER:
2435                                 case P_ENUM:
2436                                 case P_OCTAL:
2437                                         *(int *)dest_ptr = *(int *)src_ptr;
2438                                         break;
2439
2440                                 case P_CHAR:
2441                                         *(char *)dest_ptr = *(char *)src_ptr;
2442                                         break;
2443
2444                                 case P_STRING:
2445                                         string_set(dest_ptr,
2446                                                    *(char **)src_ptr);
2447                                         break;
2448
2449                                 case P_USTRING:
2450                                         string_set(dest_ptr,
2451                                                    *(char **)src_ptr);
2452                                         strupper(*(char **)dest_ptr);
2453                                         break;
2454                                 case P_LIST:
2455                                         str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2456                                         break;
2457                                 default:
2458                                         break;
2459                         }
2460                 }
2461
2462         if (bcopyall) {
2463                 init_copymap(pserviceDest);
2464                 if (pserviceSource->copymap)
2465                         memcpy((void *)pserviceDest->copymap,
2466                                (void *)pserviceSource->copymap,
2467                                sizeof(BOOL) * NUMPARAMETERS);
2468         }
2469         
2470         data = pserviceSource->param_opt;
2471         while (data) {
2472                 not_added = True;
2473                 pdata = pserviceDest->param_opt;
2474                 /* Traverse destination */
2475                 while (pdata) {
2476                         /* If we already have same option, override it */
2477                         if (strcmp(pdata->key, data->key) == 0) {
2478                                 string_free(&pdata->value);
2479                                 pdata->value = strdup(data->value);
2480                                 not_added = False;
2481                                 break;
2482                         }
2483                         pdata = pdata->next;
2484                 }
2485                 if (not_added) {
2486                     paramo = smb_xmalloc(sizeof(param_opt_struct));
2487                     paramo->key = strdup(data->key);
2488                     paramo->value = strdup(data->value);
2489                     DLIST_ADD(pserviceDest->param_opt, paramo);
2490                 }
2491                 data = data->next;
2492         }
2493 }
2494
2495 /***************************************************************************
2496 Check a service for consistency. Return False if the service is in any way
2497 incomplete or faulty, else True.
2498 ***************************************************************************/
2499
2500 static BOOL service_ok(int iService)
2501 {
2502         BOOL bRetval;
2503
2504         bRetval = True;
2505         if (ServicePtrs[iService]->szService[0] == '\0') {
2506                 DEBUG(0, ("The following message indicates an internal error:\n"));
2507                 DEBUG(0, ("No service name in service entry.\n"));
2508                 bRetval = False;
2509         }
2510
2511         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2512         /* I can't see why you'd want a non-printable printer service...        */
2513         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2514                 if (!ServicePtrs[iService]->bPrint_ok) {
2515                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2516                                ServicePtrs[iService]->szService));
2517                         ServicePtrs[iService]->bPrint_ok = True;
2518                 }
2519                 /* [printers] service must also be non-browsable. */
2520                 if (ServicePtrs[iService]->bBrowseable)
2521                         ServicePtrs[iService]->bBrowseable = False;
2522         }
2523
2524         if (ServicePtrs[iService]->szPath[0] == '\0' &&
2525             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0) {
2526                 DEBUG(0, ("No path in service %s - using %s\n",
2527                        ServicePtrs[iService]->szService, tmpdir()));
2528                 string_set(&ServicePtrs[iService]->szPath, tmpdir());
2529         }
2530
2531         /* If a service is flagged unavailable, log the fact at level 0. */
2532         if (!ServicePtrs[iService]->bAvailable)
2533                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2534                           ServicePtrs[iService]->szService));
2535
2536         return (bRetval);
2537 }
2538
2539 static struct file_lists {
2540         struct file_lists *next;
2541         char *name;
2542         char *subfname;
2543         time_t modtime;
2544 } *file_lists = NULL;
2545
2546 /*******************************************************************
2547  Keep a linked list of all config files so we know when one has changed 
2548  it's date and needs to be reloaded.
2549 ********************************************************************/
2550
2551 static void add_to_file_list(const char *fname, const char *subfname)
2552 {
2553         struct file_lists *f = file_lists;
2554
2555         while (f) {
2556                 if (f->name && !strcmp(f->name, fname))
2557                         break;
2558                 f = f->next;
2559         }
2560
2561         if (!f) {
2562                 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
2563                 if (!f)
2564                         return;
2565                 f->next = file_lists;
2566                 f->name = strdup(fname);
2567                 if (!f->name) {
2568                         SAFE_FREE(f);
2569                         return;
2570                 }
2571                 f->subfname = strdup(subfname);
2572                 if (!f->subfname) {
2573                         SAFE_FREE(f);
2574                         return;
2575                 }
2576                 file_lists = f;
2577                 f->modtime = file_modtime(subfname);
2578         } else {
2579                 time_t t = file_modtime(subfname);
2580                 if (t)
2581                         f->modtime = t;
2582         }
2583 }
2584
2585 /*******************************************************************
2586  Check if a config file has changed date.
2587 ********************************************************************/
2588
2589 BOOL lp_file_list_changed(void)
2590 {
2591         struct file_lists *f = file_lists;
2592         DEBUG(6, ("lp_file_list_changed()\n"));
2593
2594         while (f) {
2595                 pstring n2;
2596                 time_t mod_time;
2597
2598                 pstrcpy(n2, f->name);
2599                 standard_sub_basic(current_user_info.smb_name, n2,sizeof(n2));
2600
2601                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
2602                              f->name, n2, ctime(&f->modtime)));
2603
2604                 mod_time = file_modtime(n2);
2605
2606                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2607                         DEBUGADD(6,
2608                                  ("file %s modified: %s\n", n2,
2609                                   ctime(&mod_time)));
2610                         f->modtime = mod_time;
2611                         SAFE_FREE(f->subfname);
2612                         f->subfname = strdup(n2);
2613                         return (True);
2614                 }
2615                 f = f->next;
2616         }
2617         return (False);
2618 }
2619
2620 /***************************************************************************
2621  Run standard_sub_basic on netbios name... needed because global_myname
2622  is not accessed through any lp_ macro.
2623  Note: We must *NOT* use string_set() here as ptr points to global_myname.
2624 ***************************************************************************/
2625
2626 static BOOL handle_netbios_name(const char *pszParmValue, char **ptr)
2627 {
2628         BOOL ret;
2629         pstring netbios_name;
2630
2631         pstrcpy(netbios_name, pszParmValue);
2632
2633         standard_sub_basic(current_user_info.smb_name, netbios_name,sizeof(netbios_name));
2634
2635
2636         ret = set_global_myname(netbios_name);
2637         string_set(&Globals.szNetbiosName,global_myname());
2638         
2639         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
2640                global_myname()));
2641
2642         return ret;
2643 }
2644
2645 static BOOL handle_workgroup(const char *pszParmValue, char **ptr)
2646 {
2647         BOOL ret;
2648         
2649         ret = set_global_myworkgroup(pszParmValue);
2650         string_set(&Globals.szWorkgroup,lp_workgroup());
2651         
2652         return ret;
2653 }
2654
2655 static BOOL handle_netbios_scope(const char *pszParmValue, char **ptr)
2656 {
2657         BOOL ret;
2658         
2659         ret = set_global_scope(pszParmValue);
2660         string_set(&Globals.szNetbiosScope,global_scope());
2661
2662         return ret;
2663 }
2664
2665 static BOOL handle_netbios_aliases(const char *pszParmValue, char **ptr)
2666 {
2667         Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
2668         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
2669 }
2670
2671 /***************************************************************************
2672  Do the work of sourcing in environment variable/value pairs.
2673 ***************************************************************************/
2674
2675 static BOOL source_env(char **lines)
2676 {
2677         char *varval;
2678         size_t len;
2679         int i;
2680         char *p;
2681
2682         for (i = 0; lines[i]; i++) {
2683                 char *line = lines[i];
2684
2685                 if ((len = strlen(line)) == 0)
2686                         continue;
2687
2688                 if (line[len - 1] == '\n')
2689                         line[--len] = '\0';
2690
2691                 if ((varval = malloc(len + 1)) == NULL) {
2692                         DEBUG(0, ("source_env: Not enough memory!\n"));
2693                         return (False);
2694                 }
2695
2696                 DEBUG(4, ("source_env: Adding to environment: %s\n", line));
2697                 strncpy(varval, line, len);
2698                 varval[len] = '\0';
2699
2700                 p = strchr_m(line, (int)'=');
2701                 if (p == NULL) {
2702                         DEBUG(4, ("source_env: missing '=': %s\n", line));
2703                         continue;
2704                 }
2705
2706                 if (putenv(varval)) {
2707                         DEBUG(0, ("source_env: Failed to put environment variable %s\n",
2708                                varval));
2709                         continue;
2710                 }
2711
2712                 *p = '\0';
2713                 p++;
2714                 DEBUG(4, ("source_env: getting var %s = %s\n", line, getenv(line)));
2715         }
2716
2717         DEBUG(4, ("source_env: returning successfully\n"));
2718         return (True);
2719 }
2720
2721 /***************************************************************************
2722  Handle the source environment operation.
2723 ***************************************************************************/
2724
2725 static BOOL handle_source_env(const char *pszParmValue, char **ptr)
2726 {
2727         pstring fname;
2728         char *p = fname;
2729         BOOL result;
2730         char **lines;
2731
2732         pstrcpy(fname, pszParmValue);
2733
2734         standard_sub_basic(current_user_info.smb_name, fname,sizeof(fname));
2735
2736         string_set(ptr, pszParmValue);
2737
2738         DEBUG(4, ("handle_source_env: checking env type\n"));
2739
2740         /*
2741          * Filename starting with '|' means popen and read from stdin.
2742          */
2743
2744         if (*p == '|')
2745                 lines = file_lines_pload(p + 1, NULL);
2746         else
2747                 lines = file_lines_load(fname, NULL);
2748
2749         if (!lines) {
2750                 DEBUG(0, ("handle_source_env: Failed to open file %s, Error was %s\n",
2751                        fname, strerror(errno)));
2752                 return (False);
2753         }
2754
2755         result = source_env(lines);
2756         file_lines_free(lines);
2757
2758         return (result);
2759 }
2760
2761 /***************************************************************************
2762  Handle the include operation.
2763 ***************************************************************************/
2764
2765 static BOOL handle_include(const char *pszParmValue, char **ptr)
2766 {
2767         pstring fname;
2768         pstrcpy(fname, pszParmValue);
2769
2770         standard_sub_basic(current_user_info.smb_name, fname,sizeof(fname));
2771
2772         add_to_file_list(pszParmValue, fname);
2773
2774         string_set(ptr, fname);
2775
2776         if (file_exist(fname, NULL))
2777                 return (pm_process(fname, do_section, do_parameter));
2778
2779         DEBUG(2, ("Can't find include file %s\n", fname));
2780
2781         return (False);
2782 }
2783
2784 /***************************************************************************
2785  Handle the interpretation of the copy parameter.
2786 ***************************************************************************/
2787
2788 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2789 {
2790         BOOL bRetval;
2791         int iTemp;
2792         service serviceTemp;
2793
2794         string_set(ptr, pszParmValue);
2795
2796         init_service(&serviceTemp);
2797
2798         bRetval = False;
2799
2800         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2801
2802         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2803                 if (iTemp == iServiceIndex) {
2804                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2805                 } else {
2806                         copy_service(ServicePtrs[iServiceIndex],
2807                                      &serviceTemp,
2808                                      ServicePtrs[iServiceIndex]->copymap);
2809                         bRetval = True;
2810                 }
2811         } else {
2812                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2813                 bRetval = False;
2814         }
2815
2816         free_service(&serviceTemp);
2817         return (bRetval);
2818 }
2819
2820 /***************************************************************************
2821  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
2822  parameters is:
2823
2824  [global]
2825
2826         idmap uid = 1000-1999
2827         idmap gid = 700-899
2828
2829  We only do simple parsing checks here.  The strings are parsed into useful
2830  structures in the idmap daemon code.
2831
2832 ***************************************************************************/
2833
2834 /* Some lp_ routines to return idmap [ug]id information */
2835
2836 static uid_t idmap_uid_low, idmap_uid_high;
2837 static gid_t idmap_gid_low, idmap_gid_high;
2838 static uint32 non_unix_account_low, non_unix_account_high;
2839
2840 BOOL lp_idmap_uid(uid_t *low, uid_t *high)
2841 {
2842         if (idmap_uid_low == 0 || idmap_uid_high == 0)
2843                 return False;
2844
2845         if (low)
2846                 *low = idmap_uid_low;
2847
2848         if (high)
2849                 *high = idmap_uid_high;
2850
2851         return True;
2852 }
2853
2854 BOOL lp_idmap_gid(gid_t *low, gid_t *high)
2855 {
2856         if (idmap_gid_low == 0 || idmap_gid_high == 0)
2857                 return False;
2858
2859         if (low)
2860                 *low = idmap_gid_low;
2861
2862         if (high)
2863                 *high = idmap_gid_high;
2864
2865         return True;
2866 }
2867
2868 BOOL lp_non_unix_account_range(uint32 *low, uint32 *high)
2869 {
2870         if (non_unix_account_low == 0 || non_unix_account_high == 0)
2871                 return False;
2872
2873         if (low)
2874                 *low = non_unix_account_low;
2875
2876         if (high)
2877                 *high = non_unix_account_high;
2878
2879         return True;
2880 }
2881
2882 /* Do some simple checks on "idmap [ug]id" parameter values */
2883
2884 static BOOL handle_idmap_uid(const char *pszParmValue, char **ptr)
2885 {
2886         uint32 low, high;
2887
2888         if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2889                 return False;
2890
2891         /* Parse OK */
2892
2893         string_set(ptr, pszParmValue);
2894
2895         idmap_uid_low = low;
2896         idmap_uid_high = high;
2897
2898         return True;
2899 }
2900
2901 static BOOL handle_idmap_gid(const char *pszParmValue, char **ptr)
2902 {
2903         uint32 low, high;
2904
2905         if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2906                 return False;
2907
2908         /* Parse OK */
2909
2910         string_set(ptr, pszParmValue);
2911
2912         idmap_gid_low = low;
2913         idmap_gid_high = high;
2914
2915         return True;
2916 }
2917
2918 /***************************************************************************
2919  Do some simple checks on "non unix account range" parameter values.
2920 ***************************************************************************/
2921
2922 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2923 {
2924         uint32 low, high;
2925
2926         if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2927                 return False;
2928
2929         /* Parse OK */
2930
2931         string_set(ptr, pszParmValue);
2932
2933         non_unix_account_low = low;
2934         non_unix_account_high = high;
2935
2936         return True;
2937 }
2938
2939 /***************************************************************************
2940  Handle the DEBUG level list.
2941 ***************************************************************************/
2942
2943 static BOOL handle_debug_list( const char *pszParmValueIn, char **ptr )
2944 {
2945         pstring pszParmValue;
2946
2947         pstrcpy(pszParmValue, pszParmValueIn);
2948         string_set(ptr, pszParmValueIn);
2949         return debug_parse_levels( pszParmValue );
2950 }
2951
2952 /***************************************************************************
2953  Handle the ldap machine suffix option.
2954 ***************************************************************************/
2955
2956 static BOOL handle_ldap_machine_suffix( const char *pszParmValue, char **ptr)
2957 {
2958        pstring suffix;
2959        
2960        pstrcpy(suffix, pszParmValue);
2961
2962        if (! *Globals.szLdapSuffix ) {
2963                string_set( ptr, suffix );
2964                return True;
2965        }
2966
2967        if (! strstr(suffix, Globals.szLdapSuffix) ) {
2968                if ( *pszParmValue )
2969                        pstrcat(suffix, ",");
2970                pstrcat(suffix, Globals.szLdapSuffix);
2971        }
2972        string_set( ptr, suffix );
2973        return True;
2974 }
2975
2976 /***************************************************************************
2977  Handle the ldap user suffix option.
2978 ***************************************************************************/
2979
2980 static BOOL handle_ldap_user_suffix( const char *pszParmValue, char **ptr)
2981 {
2982        pstring suffix;
2983        
2984        pstrcpy(suffix, pszParmValue);
2985
2986        if (! *Globals.szLdapSuffix ) {
2987                string_set( ptr, suffix );
2988                return True;
2989        }
2990        
2991        if (! strstr(suffix, Globals.szLdapSuffix) ) {
2992                if ( *pszParmValue )
2993                        pstrcat(suffix, ",");
2994                pstrcat(suffix, Globals.szLdapSuffix);
2995        }
2996        string_set( ptr, suffix );
2997        return True;
2998 }
2999
3000 /***************************************************************************
3001  Handle setting ldap suffix and determines whether ldap machine suffix needs
3002  to be set as well.
3003 ***************************************************************************/
3004
3005 static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr)
3006 {
3007        pstring suffix;
3008        pstring user_suffix;
3009        pstring machine_suffix;
3010                
3011        pstrcpy(suffix, pszParmValue);
3012
3013        if (! *Globals.szLdapMachineSuffix )
3014                string_set(&Globals.szLdapMachineSuffix, suffix);
3015        if (! *Globals.szLdapUserSuffix ) 
3016                string_set(&Globals.szLdapUserSuffix, suffix);
3017        
3018        if (! strstr(Globals.szLdapMachineSuffix, suffix)) {
3019                pstrcpy(machine_suffix, Globals.szLdapMachineSuffix);
3020                if ( *Globals.szLdapMachineSuffix )
3021                        pstrcat(machine_suffix, ",");
3022                pstrcat(machine_suffix, suffix);
3023                string_set(&Globals.szLdapMachineSuffix, machine_suffix);       
3024        }
3025
3026        if (! strstr(Globals.szLdapUserSuffix, suffix)) {
3027                pstrcpy(user_suffix, Globals.szLdapUserSuffix);
3028                if ( *Globals.szLdapUserSuffix )
3029                        pstrcat(user_suffix, ",");
3030                pstrcat(user_suffix, suffix);   
3031                string_set(&Globals.szLdapUserSuffix, user_suffix);
3032        } 
3033
3034        string_set(ptr, suffix); 
3035        return True;
3036 }
3037
3038 static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr)
3039 {
3040         if (strequal(pszParmValue, "auto"))
3041                 string_set(ptr, "");
3042         else if (strequal(pszParmValue, "winnt"))
3043                 string_set(ptr, "winnt");
3044         else if (strequal(pszParmValue, "win2k"))
3045                 string_set(ptr, "win2k");
3046         else
3047                 return False;
3048
3049         return True;
3050 }
3051 /***************************************************************************
3052  Initialise a copymap.
3053 ***************************************************************************/
3054
3055 static void init_copymap(service * pservice)
3056 {
3057         int i;
3058         SAFE_FREE(pservice->copymap);
3059         pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
3060         if (!pservice->copymap)
3061                 DEBUG(0,
3062                       ("Couldn't allocate copymap!! (size %d)\n",
3063                        (int)NUMPARAMETERS));
3064         else
3065                 for (i = 0; i < NUMPARAMETERS; i++)
3066                         pservice->copymap[i] = True;
3067 }
3068
3069 /***************************************************************************
3070  Return the local pointer to a parameter given the service number and the 
3071  pointer into the default structure.
3072 ***************************************************************************/
3073
3074 void *lp_local_ptr(int snum, void *ptr)
3075 {
3076         return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3077 }
3078
3079 /***************************************************************************
3080  Process a parameter for a particular service number. If snum < 0
3081  then assume we are in the globals.
3082 ***************************************************************************/
3083
3084 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3085 {
3086         int parmnum, i, slen;
3087         void *parm_ptr = NULL;  /* where we are going to store the result */
3088         void *def_ptr = NULL;
3089         pstring vfskey;
3090         char *sep;
3091         param_opt_struct *paramo, *data;
3092         BOOL not_added;
3093
3094         parmnum = map_parameter(pszParmName);
3095
3096         if (parmnum < 0) {
3097                 if ((sep=strchr(pszParmName, ':')) != NULL) {
3098