syncing LDAP schema changes with Samba_3_0
[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         char **list;
91 };
92
93 /* 
94  * This structure describes global (ie., server-wide) parameters.
95  */
96 typedef struct
97 {
98         char *smb_ports;
99         char *dos_charset;
100         char *unix_charset;
101         char *display_charset;
102         char *szPrintcapname;
103         char *szEnumPortsCommand;
104         char *szAddPrinterCommand;
105         char *szDeletePrinterCommand;
106         char *szOs2DriverMap;
107         char *szLockDir;
108         char *szPidDir;
109         char *szRootdir;
110         char *szDefaultService;
111         char *szDfree;
112         char *szMsgCommand;
113         char *szHostsEquiv;
114         char *szServerString;
115         char *szAutoServices;
116         char *szPasswdProgram;
117         char *szPasswdChat;
118         char *szLogFile;
119         char *szConfigFile;
120         char *szSMBPasswdFile;
121         char *szPrivateDir;
122         char **szPassdbBackend;
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         BOOL *bIdmapOnly;
168         char *szNonUnixAccountRange;
169         int AlgorithmicRidBase;
170         char *szTemplateHomedir;
171         char *szTemplateShell;
172         char *szWinbindSeparator;
173         BOOL bWinbindEnumUsers;
174         BOOL bWinbindEnumGroups;
175         BOOL bWinbindUseDefaultDomain;
176         char *szWinbindBackend;
177         char *szIdmapBackend;
178         char *szAddShareCommand;
179         char *szChangeShareCommand;
180         char *szDeleteShareCommand;
181         char *szGuestaccount;
182         char *szManglingMethod;
183         int mangle_prefix;
184         int max_log_size;
185         char *szLogLevel;
186         int mangled_stack;
187         int max_xmit;
188         int max_mux;
189         int max_open_files;
190         int pwordlevel;
191         int unamelevel;
192         int deadtime;
193         int maxprotocol;
194         int minprotocol;
195         int security;
196         char **AuthMethods;
197         BOOL paranoid_server_security;
198         int maxdisksize;
199         int lpqcachetime;
200         int iMaxSmbdProcesses;
201         BOOL bDisableSpoolss;
202         int iTotalPrintJobs;
203         int syslog;
204         int os_level;
205         int enhanced_browsing;
206         int max_ttl;
207         int max_wins_ttl;
208         int min_wins_ttl;
209         int ReadSize;
210         int lm_announce;
211         int lm_interval;
212         int announce_as;        /* This is initialised in init_globals */
213         int machine_password_timeout;
214         int change_notify_timeout;
215         int stat_cache_size;
216         int map_to_guest;
217         int min_passwd_length;
218         int oplock_break_wait_time;
219         int winbind_cache_time;
220         int iLockSpinCount;
221         int iLockSpinTime;
222         char *szLdapMachineSuffix;
223         char *szLdapUserSuffix;
224 #ifdef WITH_LDAP_SAMCONFIG
225         int ldap_port;
226         char *szLdapServer;
227 #endif
228         int ldap_ssl;
229         char *szLdapSuffix;
230         char *szLdapFilter;
231         char *szLdapAdminDn;
232         BOOL ldap_trust_ids;
233         char *szAclCompat;
234         int ldap_passwd_sync; 
235         BOOL ldap_delete_dn;
236         BOOL bMsAddPrinterWizard;
237         BOOL bDNSproxy;
238         BOOL bWINSsupport;
239         BOOL bWINSproxy;
240         BOOL bLocalMaster;
241         BOOL bPreferredMaster;
242         BOOL bDomainMaster;
243         BOOL bDomainLogons;
244         BOOL bEncryptPasswords;
245         BOOL bUpdateEncrypt;
246         int  clientSchannel;
247         int  serverSchannel;
248         BOOL bStripDot;
249         BOOL bNullPasswords;
250         BOOL bObeyPamRestrictions;
251         BOOL bLoadPrinters;
252         BOOL bLargeReadwrite;
253         BOOL bReadRaw;
254         BOOL bWriteRaw;
255         BOOL bReadPrediction;
256         BOOL bReadbmpx;
257         BOOL bSyslogOnly;
258         BOOL bBrowseList;
259         BOOL bNISHomeMap;
260         BOOL bTimeServer;
261         BOOL bBindInterfacesOnly;
262         BOOL bPamPasswordChange;
263         BOOL bUnixPasswdSync;
264         BOOL bPasswdChatDebug;
265         BOOL bTimestampLogs;
266         BOOL bNTSmbSupport;
267         BOOL bNTPipeSupport;
268         BOOL bNTStatusSupport;
269         BOOL bStatCache;
270         BOOL bKernelOplocks;
271         BOOL bAllowTrustedDomains;
272         BOOL bLanmanAuth;
273         BOOL bNTLMAuth;
274         BOOL bUseSpnego;
275         BOOL bClientLanManAuth;
276         BOOL bClientNTLMv2Auth;
277         BOOL bClientUseSpnego;
278         BOOL bDebugHiresTimestamp;
279         BOOL bDebugPid;
280         BOOL bDebugUid;
281         BOOL bHostMSDfs;
282         BOOL bHideLocalUsers;
283         BOOL bUnicode;
284         BOOL bUseMmap;
285         BOOL bHostnameLookups;
286         BOOL bUnixExtensions;
287         BOOL bDisableNetbios;
288         BOOL bKernelChangeNotify;
289         int restrict_anonymous;
290         int name_cache_timeout;
291         BOOL client_signing;
292         param_opt_struct *param_opt;
293 }
294 global;
295
296 static global Globals;
297
298 /* 
299  * This structure describes a single service. 
300  */
301 typedef struct
302 {
303         BOOL valid;
304         BOOL autoloaded;
305         char *szService;
306         char *szPath;
307         char *szUsername;
308         char **szInvalidUsers;
309         char **szValidUsers;
310         char **szAdminUsers;
311         char *szCopy;
312         char *szInclude;
313         char *szPreExec;
314         char *szPostExec;
315         char *szRootPreExec;
316         char *szRootPostExec;
317         char *szPrintcommand;
318         char *szLpqcommand;
319         char *szLprmcommand;
320         char *szLppausecommand;
321         char *szLpresumecommand;
322         char *szQueuepausecommand;
323         char *szQueueresumecommand;
324         char *szPrintername;
325         char *szDontdescend;
326         char **szHostsallow;
327         char **szHostsdeny;
328         char *szMagicScript;
329         char *szMagicOutput;
330         char *szMangledMap;
331         char *szVetoFiles;
332         char *szHideFiles;
333         char *szVetoOplockFiles;
334         char *comment;
335         char *force_user;
336         char *force_group;
337         char **readlist;
338         char **writelist;
339         char **printer_admin;
340         char *volume;
341         char *fstype;
342         char *szVfsObjectFile;
343         char *szVfsOptions;
344         char *szVfsPath;
345         char *szMSDfsProxy;
346         int iMinPrintSpace;
347         int iMaxPrintJobs;
348         int iMaxReportedPrintJobs;
349         int iWriteCacheSize;
350         int iCreate_mask;
351         int iCreate_force_mode;
352         int iSecurity_mask;
353         int iSecurity_force_mode;
354         int iDir_mask;
355         int iDir_force_mode;
356         int iDir_Security_mask;
357         int iDir_Security_force_mode;
358         int iMaxConnections;
359         int iDefaultCase;
360         int iPrinting;
361         int iOplockContentionLimit;
362         int iCSCPolicy;
363         int iBlock_size;
364         BOOL bPreexecClose;
365         BOOL bRootpreexecClose;
366         BOOL bCaseSensitive;
367         BOOL bCasePreserve;
368         BOOL bShortCasePreserve;
369         BOOL bCaseMangle;
370         BOOL bHideDotFiles;
371         BOOL bHideSpecialFiles;
372         BOOL bHideUnReadable;
373         BOOL bHideUnWriteableFiles;
374         BOOL bBrowseable;
375         BOOL bAvailable;
376         BOOL bRead_only;
377         BOOL bNo_set_dir;
378         BOOL bGuest_only;
379         BOOL bGuest_ok;
380         BOOL bPrint_ok;
381         BOOL bMap_system;
382         BOOL bMap_hidden;
383         BOOL bMap_archive;
384         BOOL bLocking;
385         BOOL bStrictLocking;
386         BOOL bPosixLocking;
387         BOOL bShareModes;
388         BOOL bOpLocks;
389         BOOL bLevel2OpLocks;
390         BOOL bOnlyUser;
391         BOOL bMangledNames;
392         BOOL bWidelinks;
393         BOOL bSymlinks;
394         BOOL bSyncAlways;
395         BOOL bStrictAllocate;
396         BOOL bStrictSync;
397         char magic_char;
398         BOOL *copymap;
399         BOOL bDeleteReadonly;
400         BOOL bFakeOplocks;
401         BOOL bDeleteVetoFiles;
402         BOOL bDosFilemode;
403         BOOL bDosFiletimes;
404         BOOL bDosFiletimeResolution;
405         BOOL bFakeDirCreateTimes;
406         BOOL bBlockingLocks;
407         BOOL bInheritPerms;
408         BOOL bInheritACLS;
409         BOOL bMSDfsRoot;
410         BOOL bUseClientDriver;
411         BOOL bDefaultDevmode;
412         BOOL bNTAclSupport;
413         BOOL bUseSendfile;
414         BOOL bProfileAcls;
415         param_opt_struct *param_opt;
416
417         char dummy[3];          /* for alignment */
418 }
419 service;
420
421
422 /* This is a default service used to prime a services structure */
423 static service sDefault = {
424         True,                   /* valid */
425         False,                  /* not autoloaded */
426         NULL,                   /* szService */
427         NULL,                   /* szPath */
428         NULL,                   /* szUsername */
429         NULL,                   /* szInvalidUsers */
430         NULL,                   /* szValidUsers */
431         NULL,                   /* szAdminUsers */
432         NULL,                   /* szCopy */
433         NULL,                   /* szInclude */
434         NULL,                   /* szPreExec */
435         NULL,                   /* szPostExec */
436         NULL,                   /* szRootPreExec */
437         NULL,                   /* szRootPostExec */
438         NULL,                   /* szPrintcommand */
439         NULL,                   /* szLpqcommand */
440         NULL,                   /* szLprmcommand */
441         NULL,                   /* szLppausecommand */
442         NULL,                   /* szLpresumecommand */
443         NULL,                   /* szQueuepausecommand */
444         NULL,                   /* szQueueresumecommand */
445         NULL,                   /* szPrintername */
446         NULL,                   /* szDontdescend */
447         NULL,                   /* szHostsallow */
448         NULL,                   /* szHostsdeny */
449         NULL,                   /* szMagicScript */
450         NULL,                   /* szMagicOutput */
451         NULL,                   /* szMangledMap */
452         NULL,                   /* szVetoFiles */
453         NULL,                   /* szHideFiles */
454         NULL,                   /* szVetoOplockFiles */
455         NULL,                   /* comment */
456         NULL,                   /* force user */
457         NULL,                   /* force group */
458         NULL,                   /* readlist */
459         NULL,                   /* writelist */
460         NULL,                   /* printer admin */
461         NULL,                   /* volume */
462         NULL,                   /* fstype */
463         NULL,                   /* vfs object */
464         NULL,                   /* vfs options */
465         NULL,                   /* vfs path */
466         NULL,                   /* szMSDfsProxy */
467         0,                      /* iMinPrintSpace */
468         1000,                   /* iMaxPrintJobs */
469         0,                      /* iMaxReportedPrintJobs */
470         0,                      /* iWriteCacheSize */
471         0744,                   /* iCreate_mask */
472         0000,                   /* iCreate_force_mode */
473         0777,                   /* iSecurity_mask */
474         0,                      /* iSecurity_force_mode */
475         0755,                   /* iDir_mask */
476         0000,                   /* iDir_force_mode */
477         0777,                   /* iDir_Security_mask */
478         0,                      /* iDir_Security_force_mode */
479         0,                      /* iMaxConnections */
480         CASE_LOWER,             /* iDefaultCase */
481         DEFAULT_PRINTING,       /* iPrinting */
482         2,                      /* iOplockContentionLimit */
483         0,                      /* iCSCPolicy */
484         1024,           /* iBlock_size */
485         False,                  /* bPreexecClose */
486         False,                  /* bRootpreexecClose */
487         False,                  /* case sensitive */
488         True,                   /* case preserve */
489         True,                   /* short case preserve */
490         False,                  /* case mangle */
491         True,                   /* bHideDotFiles */
492         False,                  /* bHideSpecialFiles */
493         False,                  /* bHideUnReadable */
494         False,                  /* bHideUnWriteableFiles */
495         True,                   /* bBrowseable */
496         True,                   /* bAvailable */
497         True,                   /* bRead_only */
498         True,                   /* bNo_set_dir */
499         False,                  /* bGuest_only */
500         False,                  /* bGuest_ok */
501         False,                  /* bPrint_ok */
502         False,                  /* bMap_system */
503         False,                  /* bMap_hidden */
504         True,                   /* bMap_archive */
505         True,                   /* bLocking */
506         True,                   /* bStrictLocking */
507         True,                   /* bPosixLocking */
508         True,                   /* bShareModes */
509         True,                   /* bOpLocks */
510         True,                   /* bLevel2OpLocks */
511         False,                  /* bOnlyUser */
512         True,                   /* bMangledNames */
513         True,                   /* bWidelinks */
514         True,                   /* bSymlinks */
515         False,                  /* bSyncAlways */
516         False,                  /* bStrictAllocate */
517         False,                  /* bStrictSync */
518         '~',                    /* magic char */
519         NULL,                   /* copymap */
520         False,                  /* bDeleteReadonly */
521         False,                  /* bFakeOplocks */
522         False,                  /* bDeleteVetoFiles */
523         False,                  /* bDosFilemode */
524         False,                  /* bDosFiletimes */
525         False,                  /* bDosFiletimeResolution */
526         False,                  /* bFakeDirCreateTimes */
527         True,                   /* bBlockingLocks */
528         False,                  /* bInheritPerms */
529         False,                  /* bInheritACLS */
530         False,                  /* bMSDfsRoot */
531         False,                  /* bUseClientDriver */
532         False,                  /* bDefaultDevmode */
533         True,                   /* bNTAclSupport */
534         False,                  /* bUseSendfile */
535         False,                  /* bProfileAcls */
536         
537         NULL,                   /* Parametric options */
538
539         ""                      /* dummy */
540 };
541
542 /* local variables */
543 static service **ServicePtrs = NULL;
544 static int iNumServices = 0;
545 static int iServiceIndex = 0;
546 static BOOL bInGlobalSection = True;
547 static BOOL bGlobalOnly = False;
548 static int server_role;
549 static int default_server_announce;
550
551 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
552
553 /* prototypes for the special type handlers */
554 static BOOL handle_include(const char *pszParmValue, char **ptr);
555 static BOOL handle_copy(const char *pszParmValue, char **ptr);
556 static BOOL handle_source_env(const char *pszParmValue, char **ptr);
557 static BOOL handle_netbios_name(const char *pszParmValue, char **ptr);
558 static BOOL handle_idmap_uid(const char *pszParmValue, char **ptr);
559 static BOOL handle_idmap_gid(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_CUPS, "cups"},
604         {PRINT_LPRNT, "nt"},
605         {PRINT_LPROS2, "os2"},
606 #ifdef DEVELOPER
607         {PRINT_TEST, "test"},
608         {PRINT_VLP, "vlp"},
609 #endif /* DEVELOPER */
610         {-1, NULL}
611 };
612
613 static const struct enum_list enum_ldap_ssl[] = {
614 #ifdef WITH_LDAP_SAMCONFIG
615         {LDAP_SSL_ON, "Yes"},
616         {LDAP_SSL_ON, "yes"},
617         {LDAP_SSL_ON, "on"},
618         {LDAP_SSL_ON, "On"},
619 #endif
620         {LDAP_SSL_OFF, "no"},
621         {LDAP_SSL_OFF, "No"},
622         {LDAP_SSL_OFF, "off"},
623         {LDAP_SSL_OFF, "Off"},
624         {LDAP_SSL_START_TLS, "start tls"},
625         {LDAP_SSL_START_TLS, "Start_tls"},
626         {-1, NULL}
627 };
628
629 static const struct enum_list enum_ldap_passwd_sync[] = {
630         {LDAP_PASSWD_SYNC_ON, "Yes"},
631         {LDAP_PASSWD_SYNC_ON, "yes"},
632         {LDAP_PASSWD_SYNC_ON, "on"},
633         {LDAP_PASSWD_SYNC_ON, "On"},
634         {LDAP_PASSWD_SYNC_OFF, "no"},
635         {LDAP_PASSWD_SYNC_OFF, "No"},
636         {LDAP_PASSWD_SYNC_OFF, "off"},
637         {LDAP_PASSWD_SYNC_OFF, "Off"},
638 #ifdef LDAP_EXOP_X_MODIFY_PASSWD        
639         {LDAP_PASSWD_SYNC_ONLY, "Only"},
640         {LDAP_PASSWD_SYNC_ONLY, "only"},
641 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */  
642         {-1, NULL}
643 };
644
645 /* Types of machine we can announce as. */
646 #define ANNOUNCE_AS_NT_SERVER 1
647 #define ANNOUNCE_AS_WIN95 2
648 #define ANNOUNCE_AS_WFW 3
649 #define ANNOUNCE_AS_NT_WORKSTATION 4
650
651 static const struct enum_list enum_announce_as[] = {
652         {ANNOUNCE_AS_NT_SERVER, "NT"},
653         {ANNOUNCE_AS_NT_SERVER, "NT Server"},
654         {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
655         {ANNOUNCE_AS_WIN95, "win95"},
656         {ANNOUNCE_AS_WFW, "WfW"},
657         {-1, NULL}
658 };
659
660 static const struct enum_list enum_case[] = {
661         {CASE_LOWER, "lower"},
662         {CASE_UPPER, "upper"},
663         {-1, NULL}
664 };
665
666 static const struct enum_list enum_bool_auto[] = {
667         {False, "No"},
668         {False, "False"},
669         {False, "0"},
670         {True, "Yes"},
671         {True, "True"},
672         {True, "1"},
673         {Auto, "Auto"},
674         {-1, NULL}
675 };
676
677 /* Client-side offline caching policy types */
678 #define CSC_POLICY_MANUAL 0
679 #define CSC_POLICY_DOCUMENTS 1
680 #define CSC_POLICY_PROGRAMS 2
681 #define CSC_POLICY_DISABLE 3
682
683 static const struct enum_list enum_csc_policy[] = {
684         {CSC_POLICY_MANUAL, "manual"},
685         {CSC_POLICY_DOCUMENTS, "documents"},
686         {CSC_POLICY_PROGRAMS, "programs"},
687         {CSC_POLICY_DISABLE, "disable"},
688         {-1, NULL}
689 };
690
691 /* 
692    Do you want session setups at user level security with a invalid
693    password to be rejected or allowed in as guest? WinNT rejects them
694    but it can be a pain as it means "net view" needs to use a password
695
696    You have 3 choices in the setting of map_to_guest:
697
698    "Never" means session setups with an invalid password
699    are rejected. This is the default.
700
701    "Bad User" means session setups with an invalid password
702    are rejected, unless the username does not exist, in which case it
703    is treated as a guest login
704
705    "Bad Password" means session setups with an invalid password
706    are treated as a guest login
707
708    Note that map_to_guest only has an effect in user or server
709    level security.
710 */
711
712 static const struct enum_list enum_map_to_guest[] = {
713         {NEVER_MAP_TO_GUEST, "Never"},
714         {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
715         {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
716         {-1, NULL}
717 };
718
719 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
720  *
721  * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
722  * is implied in current control logic. This may change at some later time. A
723  * flag value of 0 means - show as development option only.
724  *
725  * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
726  * screen in SWAT. This is used to exclude parameters as well as to squash all
727  * parameters that have been duplicated by pseudonyms.
728  */
729 static struct parm_struct parm_table[] = {
730         {"Base Options", P_SEP, P_SEPARATOR},
731
732         {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
733         {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
734         {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
735         {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
736         {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
737         {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
738         {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
739         {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
740         {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
741         {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
742         {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
743         {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
744         {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED  | FLAG_DEVELOPER},
745         {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
746         {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
747
748         {"Security Options", P_SEP, P_SEPARATOR},
749         
750         {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
751         {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
752         {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
753         {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
754         {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC},
755         {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC},
756         {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
757         {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
758         {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
759         {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
760         {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED | FLAG_DEVELOPER},
761         {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
762         {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
763         {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
764         {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765         {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
766         {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767         {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
768         {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769         {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770         {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
771         {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
772         
773         {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
774         {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
775         {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
776         {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
777         {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
778         {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
779         {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
780         {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
781         {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
782         {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
783         {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
784         {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
785         {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
786         
787         {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
788         {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
789         {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
790         
791         {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
792         {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
793         {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
794         {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
795         {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
796         {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_GLOBAL | FLAG_PRINT},
797         {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE},
798         {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE},
799         {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
800         
801         {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
802         {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
803         {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
804         {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
805         
806         {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
807         {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
808         {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
809         {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
810         {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
811         {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
812         {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
813         {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
814         {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
815         {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
816         {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE},
817         {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_SHARE},
818         {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
819         {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
820
821         {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
822         {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
823         
824         {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
825         {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
826         {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
827         {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
828         {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
829         {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
830
831         {"Logging Options", P_SEP, P_SEPARATOR},
832
833         {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
834         {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
835         {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
836         {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
837         {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
838         
839         {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
840         {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
841         {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_DEVELOPER},
842         {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_DEVELOPER},
843         {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_DEVELOPER},
844         {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_DEVELOPER},
845         
846         {"Protocol Options", P_SEP, P_SEPARATOR},
847         
848         {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
849         {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED | FLAG_DEVELOPER},
850         {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
851         {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
852         {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
853         {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
854         {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_DEVELOPER},
855         {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
856         {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
857         {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
858         
859         {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_ADVANCED},
860         {"nt acl support", P_BOOL,  P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED | FLAG_WIZARD},
861         {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
862         {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
863         {"profile acls", P_BOOL,  P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE  | FLAG_ADVANCED | FLAG_WIZARD},
864         
865         {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
866         {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
867         {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
868         {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
869         
870         {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
871         {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, 
872         {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
873         {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
874         {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
875         {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
876         {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
877         {"client signing", P_BOOL, P_GLOBAL, &Globals.client_signing, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
878         {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_DEVELOPER},
879
880         {"Tuning Options", P_SEP, P_SEPARATOR},
881         
882         {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
883         {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_DEVELOPER},
884         {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_DEVELOPER},
885         {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_DEVELOPER},
886         {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
887         {"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_DEVELOPER},
888         
889         {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
890         {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_DEVELOPER},
891         {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
892         {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
893         {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_DEVELOPER},
894         {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
895         {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
896         {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, FLAG_DEVELOPER},
897         
898         {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_DEVELOPER},
899         {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, FLAG_DEVELOPER},
900         {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_SHARE},
901         {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE},
902         {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE},
903         {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
904         {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_SHARE},
905         {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
906         {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE},
907
908         {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
909
910         {"Printing Options", P_SEP, P_SEPARATOR},
911         
912         {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_PRINT},
913         {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
914         {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
915         {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
916         {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
917         {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
918         {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
919         {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
920         {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
921         {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
922         {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
923         {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
924         {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
925         {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
926         {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
927         {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
928
929         {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
930         {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
931         {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
932         {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
933         {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
934         
935         {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
936         {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
937         {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_PRINT},
938         {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_PRINT},
939
940         {"Filename Handling", P_SEP, P_SEPARATOR},
941         {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
942         {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
943         {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
944         
945         {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
946         {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE},
947         {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
948         {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_HIDE},
949         {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
950         {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
951         {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
952         {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
953         {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
954         {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
955         {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
956         {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
957         {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
958         {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
959         {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
960         {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
961         {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
962         {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
963         {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
964         {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
965         {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
966         {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_DEVELOPER},
967
968         {"Domain Options", P_SEP, P_SEPARATOR},
969         
970         {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
971
972         {"Logon Options", P_SEP, P_SEPARATOR},
973
974         {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
975         {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
976         {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
977         {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
978         {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
979         {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
980         {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
981         {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
982         {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
983         {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
984
985         {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
986         {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
987         {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
988         {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
989         {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
990
991         {"Browse Options", P_SEP, P_SEPARATOR},
992         
993         {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
994         {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
995         {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
996         {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
997         {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
998         {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
999         {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
1000         {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1001         {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
1002         {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1003         {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
1004
1005         {"WINS Options", P_SEP, P_SEPARATOR},
1006         {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1007         {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1008         
1009         {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
1010         {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
1011         {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1012         {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
1013
1014         {"Locking Options", P_SEP, P_SEPARATOR},
1015         
1016         {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1017         {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
1018         {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE},
1019         {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
1020         {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1021         {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
1022         {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
1023         
1024         {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1025         {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1026         {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_GLOBAL},
1027         {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1028         {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1029         {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1030         {"share modes", P_BOOL, P_LOCAL,  &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
1031
1032         {"Ldap Options", P_SEP, P_SEPARATOR},
1033         
1034 #ifdef WITH_LDAP_SAMCONFIG
1035         {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
1036         {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0}, 
1037 #endif
1038         {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1039         {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_machine_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1040         {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1041         {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1042         {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1043         {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED | FLAG_DEVELOPER},
1044         {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED | FLAG_DEVELOPER},
1045         {"ldap trust ids", P_BOOL, P_GLOBAL, &Globals.ldap_trust_ids, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1046         {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1047
1048         {"Miscellaneous Options", P_SEP, P_SEPARATOR},
1049         {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1050         {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1051         {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1052         
1053         {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1054         {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1055         {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1056         {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE}, 
1057         {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1058         {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, 
1059 #ifdef WITH_UTMP
1060         {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1061         {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1062         {"utmp",          P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1063 #endif
1064         
1065         {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1066         {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL,  FLAG_DEVELOPER},
1067         {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1068         {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1069         {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1070         {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1071         {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
1072         {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1073         {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1074         {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1075         {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1076         
1077         {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1078         {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1079         {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1080         {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1081         
1082         {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_SHARE},
1083         {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1084         {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1085         {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_SHARE},
1086         {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1087         {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1088         {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
1089         {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
1090         {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE},
1091         {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1092         {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1093         {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1094         {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE},
1095         {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE},
1096         {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE},
1097         {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1098         {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1099         {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1100         {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1101
1102         {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1103         {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1104         {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1105
1106         {"VFS module options", P_SEP, P_SEPARATOR},
1107         
1108         {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjectFile, NULL, NULL, FLAG_SHARE},
1109         {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, FLAG_SHARE},
1110         {"vfs path", P_STRING, P_LOCAL, &sDefault.szVfsPath, NULL, NULL, FLAG_SHARE},
1111
1112         
1113         {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
1114         {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
1115         {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1116
1117         {"Winbind options", P_SEP, P_SEPARATOR},
1118
1119         {"idmap only", P_BOOL, P_GLOBAL, &Globals.bIdmapOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1120         {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1121         {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1122         {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_HIDE},
1123         {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1124         {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_HIDE},
1125         {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1126         {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1127         {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1128         {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1129         {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1130         {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1131         {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1132
1133         {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
1134 };
1135
1136 /***************************************************************************
1137  Initialise the sDefault parameter structure for the printer values.
1138 ***************************************************************************/
1139
1140 static void init_printer_values(void)
1141 {
1142         /* choose defaults depending on the type of printing */
1143         switch (sDefault.iPrinting) {
1144                 case PRINT_BSD:
1145                 case PRINT_AIX:
1146                 case PRINT_LPRNT:
1147                 case PRINT_LPROS2:
1148                         string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
1149                         string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
1150                         string_set(&sDefault.szPrintcommand,
1151                                    "lpr -r -P'%p' %s");
1152                         break;
1153
1154                 case PRINT_LPRNG:
1155                 case PRINT_PLP:
1156                         string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
1157                         string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
1158                         string_set(&sDefault.szPrintcommand,
1159                                    "lpr -r -P'%p' %s");
1160                         string_set(&sDefault.szQueuepausecommand,
1161                                    "lpc stop '%p'");
1162                         string_set(&sDefault.szQueueresumecommand,
1163                                    "lpc start '%p'");
1164                         string_set(&sDefault.szLppausecommand,
1165                                    "lpc hold '%p' %j");
1166                         string_set(&sDefault.szLpresumecommand,
1167                                    "lpc release '%p' %j");
1168                         break;
1169
1170                 case PRINT_CUPS:
1171 #ifdef HAVE_CUPS
1172                         string_set(&sDefault.szLpqcommand, "");
1173                         string_set(&sDefault.szLprmcommand, "");
1174                         string_set(&sDefault.szPrintcommand, "");
1175                         string_set(&sDefault.szLppausecommand, "");
1176                         string_set(&sDefault.szLpresumecommand, "");
1177                         string_set(&sDefault.szQueuepausecommand, "");
1178                         string_set(&sDefault.szQueueresumecommand, "");
1179
1180                         string_set(&Globals.szPrintcapname, "cups");
1181 #else
1182                         string_set(&sDefault.szLpqcommand,
1183                                    "/usr/bin/lpstat -o '%p'");
1184                         string_set(&sDefault.szLprmcommand,
1185                                    "/usr/bin/cancel '%p-%j'");
1186                         string_set(&sDefault.szPrintcommand,
1187                                    "/usr/bin/lp -d '%p' %s; rm %s");
1188                         string_set(&sDefault.szLppausecommand,
1189                                    "lp -i '%p-%j' -H hold");
1190                         string_set(&sDefault.szLpresumecommand,
1191                                    "lp -i '%p-%j' -H resume");
1192                         string_set(&sDefault.szQueuepausecommand,
1193                                    "/usr/bin/disable '%p'");
1194                         string_set(&sDefault.szQueueresumecommand,
1195                                    "/usr/bin/enable '%p'");
1196                         string_set(&Globals.szPrintcapname, "lpstat");
1197 #endif /* HAVE_CUPS */
1198                         break;
1199
1200                 case PRINT_SYSV:
1201                 case PRINT_HPUX:
1202                         string_set(&sDefault.szLpqcommand, "lpstat -o%p");
1203                         string_set(&sDefault.szLprmcommand, "cancel %p-%j");
1204                         string_set(&sDefault.szPrintcommand,
1205                                    "lp -c -d%p %s; rm %s");
1206                         string_set(&sDefault.szQueuepausecommand,
1207                                    "disable %p");
1208                         string_set(&sDefault.szQueueresumecommand,
1209                                    "enable %p");
1210 #ifndef HPUX
1211                         string_set(&sDefault.szLppausecommand,
1212                                    "lp -i %p-%j -H hold");
1213                         string_set(&sDefault.szLpresumecommand,
1214                                    "lp -i %p-%j -H resume");
1215 #endif /* HPUX */
1216                         break;
1217
1218                 case PRINT_QNX:
1219                         string_set(&sDefault.szLpqcommand, "lpq -P%p");
1220                         string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
1221                         string_set(&sDefault.szPrintcommand, "lp -r -P%p %s");
1222                         break;
1223
1224 #ifdef DEVELOPER
1225         case PRINT_TEST:
1226         case PRINT_VLP:
1227                 string_set(&sDefault.szPrintcommand, "vlp print %p %s");
1228                 string_set(&sDefault.szLpqcommand, "vlp lpq %p");
1229                 string_set(&sDefault.szLprmcommand, "vlp lprm %p %j");
1230                 string_set(&sDefault.szLppausecommand, "vlp lppause %p %j");
1231                 string_set(&sDefault.szLpresumecommand, "vlp lpresum %p %j");
1232                 string_set(&sDefault.szQueuepausecommand, "vlp queuepause %p");
1233                 string_set(&sDefault.szQueueresumecommand, "vlp queueresume %p");
1234                 break;
1235 #endif /* DEVELOPER */
1236
1237         }
1238 }
1239
1240 /***************************************************************************
1241  Initialise the global parameter structure.
1242 ***************************************************************************/
1243
1244 static void init_globals(void)
1245 {
1246         static BOOL done_init = False;
1247         pstring s;
1248
1249         if (!done_init) {
1250                 int i;
1251                 memset((void *)&Globals, '\0', sizeof(Globals));
1252
1253                 for (i = 0; parm_table[i].label; i++)
1254                         if ((parm_table[i].type == P_STRING ||
1255                              parm_table[i].type == P_USTRING) &&
1256                             parm_table[i].ptr)
1257                                 string_set(parm_table[i].ptr, "");
1258
1259                 string_set(&sDefault.fstype, FSTYPE_STRING);
1260
1261                 init_printer_values();
1262
1263                 done_init = True;
1264         }
1265
1266
1267         DEBUG(3, ("Initialising global parameters\n"));
1268
1269         string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1270         string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1271
1272         /* use the new 'hash2' method by default, with a prefix of 1 */
1273         string_set(&Globals.szManglingMethod, "hash2");
1274         Globals.mangle_prefix = 1;
1275
1276         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1277
1278         /* using UTF8 by default allows us to support all chars */
1279         string_set(&Globals.unix_charset, "UTF8");
1280
1281         /* using UTF8 by default allows us to support all chars */
1282         string_set(&Globals.display_charset, "ASCII");
1283
1284         /* Use codepage 850 as a default for the dos character set */
1285         string_set(&Globals.dos_charset, "CP850");
1286
1287         /*
1288          * Allow the default PASSWD_CHAT to be overridden in local.h.
1289          */
1290         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1291         
1292         set_global_myname(myhostname());
1293         string_set(&Globals.szNetbiosName,global_myname());
1294
1295         set_global_myworkgroup(WORKGROUP);
1296         string_set(&Globals.szWorkgroup, lp_workgroup());
1297         
1298         string_set(&Globals.szPasswdProgram, "");
1299         string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
1300         string_set(&Globals.szPidDir, dyn_PIDDIR);
1301         string_set(&Globals.szLockDir, dyn_LOCKDIR);
1302         string_set(&Globals.szSocketAddress, "0.0.0.0");
1303         pstrcpy(s, "Samba ");
1304         pstrcat(s, VERSION);
1305         string_set(&Globals.szServerString, s);
1306         slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1307                  DEFAULT_MINOR_VERSION);
1308         string_set(&Globals.szAnnounceVersion, s);
1309
1310         pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1311
1312         string_set(&Globals.szLogonDrive, "");
1313         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1314         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1315         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1316
1317         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1318         string_set(&Globals.szPasswordServer, "*");
1319
1320         Globals.AlgorithmicRidBase = BASE_RID;
1321
1322         Globals.bLoadPrinters = True;
1323         Globals.mangled_stack = 50;
1324         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1325         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1326         Globals.max_xmit = 0x4104;
1327         Globals.max_mux = 50;   /* This is *needed* for profile support. */
1328         Globals.lpqcachetime = 10;
1329         Globals.bDisableSpoolss = False;
1330         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1331         Globals.iTotalPrintJobs = 0;  /* no limit specified */
1332         Globals.pwordlevel = 0;
1333         Globals.unamelevel = 0;
1334         Globals.deadtime = 0;
1335         Globals.bLargeReadwrite = True;
1336         Globals.max_log_size = 5000;
1337         Globals.max_open_files = MAX_OPEN_FILES;
1338         Globals.maxprotocol = PROTOCOL_NT1;
1339         Globals.minprotocol = PROTOCOL_CORE;
1340         Globals.security = SEC_USER;
1341         Globals.paranoid_server_security = True;
1342         Globals.bEncryptPasswords = True;
1343         Globals.bUpdateEncrypt = False;
1344         Globals.clientSchannel = False;
1345         Globals.serverSchannel = False;
1346         Globals.bReadRaw = True;
1347         Globals.bWriteRaw = True;
1348         Globals.bReadPrediction = False;
1349         Globals.bReadbmpx = False;
1350         Globals.bNullPasswords = False;
1351         Globals.bObeyPamRestrictions = False;
1352         Globals.bStripDot = False;
1353         Globals.syslog = 1;
1354         Globals.bSyslogOnly = False;
1355         Globals.bTimestampLogs = True;
1356         string_set(&Globals.szLogLevel, "0");
1357         Globals.bDebugHiresTimestamp = False;
1358         Globals.bDebugPid = False;
1359         Globals.bDebugUid = False;
1360         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
1361         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
1362         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
1363         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
1364         Globals.change_notify_timeout = 60;     /* 1 minute default. */
1365         Globals.bKernelChangeNotify = True;     /* On if we have it. */
1366         Globals.ReadSize = 16 * 1024;
1367         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
1368         Globals.lm_interval = 60;
1369         Globals.stat_cache_size = 50;   /* Number of stat translations we'll keep */
1370         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1371 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1372         Globals.bNISHomeMap = False;
1373 #ifdef WITH_NISPLUS_HOME
1374         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1375 #else
1376         string_set(&Globals.szNISHomeMapName, "auto.home");
1377 #endif
1378 #endif
1379         Globals.bTimeServer = False;
1380         Globals.bBindInterfacesOnly = False;
1381         Globals.bUnixPasswdSync = False;
1382         Globals.bPamPasswordChange = False;
1383         Globals.bPasswdChatDebug = False;
1384         Globals.bUnicode = True;        /* Do unicode on the wire by default */
1385         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
1386         Globals.bNTStatusSupport = True; /* Use NT status by default. */
1387         Globals.bStatCache = True;      /* use stat cache by default */
1388         Globals.restrict_anonymous = 0;
1389         Globals.bClientLanManAuth = True;       /* Do use the LanMan hash if it is available */
1390         Globals.bLanmanAuth = True;     /* Do use the LanMan hash if it is available */
1391         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1392         
1393         Globals.map_to_guest = 0;       /* By Default, "Never" */
1394         Globals.min_passwd_length = MINPASSWDLENGTH;    /* By Default, 5. */
1395         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
1396         Globals.enhanced_browsing = True; 
1397         Globals.iLockSpinCount = 3; /* Try 2 times. */
1398         Globals.iLockSpinTime = 10; /* usec. */
1399 #ifdef MMAP_BLACKLIST
1400         Globals.bUseMmap = False;
1401 #else
1402         Globals.bUseMmap = True;
1403 #endif
1404         Globals.bUnixExtensions = False;
1405
1406         /* hostname lookups can be very expensive and are broken on
1407            a large number of sites (tridge) */
1408         Globals.bHostnameLookups = False;
1409
1410 #ifdef WITH_LDAP_SAMCONFIG
1411         string_set(&Globals.szLdapServer, "localhost");
1412         Globals.ldap_port = 636;
1413         Globals.szPassdbBackend = str_list_make("ldapsam guest", NULL);
1414 #else
1415         Globals.szPassdbBackend = str_list_make("smbpasswd guest", NULL);
1416 #endif /* WITH_LDAP_SAMCONFIG */
1417
1418         string_set(&Globals.szLdapSuffix, "");
1419         string_set(&Globals.szLdapFilter, "(uid=%u)");
1420         string_set(&Globals.szLdapMachineSuffix, "");
1421         string_set(&Globals.szLdapUserSuffix, "");
1422
1423         string_set(&Globals.szLdapAdminDn, "");
1424         Globals.ldap_ssl = LDAP_SSL_ON;
1425         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1426         Globals.ldap_delete_dn = False;
1427
1428 /* these parameters are set to defaults that are more appropriate
1429    for the increasing samba install base:
1430
1431    as a member of the workgroup, that will possibly become a
1432    _local_ master browser (lm = True).  this is opposed to a forced
1433    local master browser startup (pm = True).
1434
1435    doesn't provide WINS server service by default (wsupp = False),
1436    and doesn't provide domain master browser services by default, either.
1437
1438 */
1439
1440         Globals.bMsAddPrinterWizard = True;
1441         Globals.bPreferredMaster = Auto;        /* depending on bDomainMaster */
1442         Globals.os_level = 20;
1443         Globals.bLocalMaster = True;
1444         Globals.bDomainMaster = Auto;   /* depending on bDomainLogons */
1445         Globals.bDomainLogons = False;
1446         Globals.bBrowseList = True;
1447         Globals.bWINSsupport = False;
1448         Globals.bWINSproxy = False;
1449
1450         Globals.bDNSproxy = True;
1451
1452         /* this just means to use them if they exist */
1453         Globals.bKernelOplocks = True;
1454
1455         Globals.bAllowTrustedDomains = True;
1456
1457         string_set(&Globals.szTemplateShell, "/bin/false");
1458         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1459         string_set(&Globals.szWinbindSeparator, "\\");
1460         string_set(&Globals.szAclCompat, "");
1461
1462         Globals.winbind_cache_time = 15;
1463         Globals.bWinbindEnumUsers = True;
1464         Globals.bWinbindEnumGroups = True;
1465         Globals.bWinbindUseDefaultDomain = False;
1466
1467         Globals.bIdmapOnly = False;
1468
1469         Globals.name_cache_timeout = 660; /* In seconds */
1470
1471         Globals.bUseSpnego = True;
1472         Globals.bClientUseSpnego = True;
1473
1474         string_set(&Globals.smb_ports, SMB_PORTS);
1475 }
1476
1477 static TALLOC_CTX *lp_talloc;
1478
1479 /******************************************************************* a
1480  Free up temporary memory - called from the main loop.
1481 ********************************************************************/
1482
1483 void lp_talloc_free(void)
1484 {
1485         if (!lp_talloc)
1486                 return;
1487         talloc_destroy(lp_talloc);
1488         lp_talloc = NULL;
1489 }
1490
1491 /*******************************************************************
1492  Convenience routine to grab string parameters into temporary memory
1493  and run standard_sub_basic on them. The buffers can be written to by
1494  callers without affecting the source string.
1495 ********************************************************************/
1496
1497 static char *lp_string(const char *s)
1498 {
1499         size_t len = s ? strlen(s) : 0;
1500         char *ret;
1501
1502         /* The follow debug is useful for tracking down memory problems
1503            especially if you have an inner loop that is calling a lp_*()
1504            function that returns a string.  Perhaps this debug should be
1505            present all the time? */
1506
1507 #if 0
1508         DEBUG(10, ("lp_string(%s)\n", s));
1509 #endif
1510
1511         if (!lp_talloc)
1512                 lp_talloc = talloc_init("lp_talloc");
1513
1514         ret = (char *)talloc(lp_talloc, len + 100);     /* leave room for substitution */
1515
1516         if (!ret)
1517                 return NULL;
1518
1519         /* Note: StrnCpy touches len+1 bytes, but we allocate 100
1520          * extra bytes so we're OK. */
1521
1522         if (!s)
1523                 *ret = 0;
1524         else
1525                 StrnCpy(ret, s, len);
1526
1527         if (trim_string(ret, "\"", "\"")) {
1528                 if (strchr(ret,'"') != NULL)
1529                         StrnCpy(ret, s, len);
1530         }
1531
1532         standard_sub_basic(current_user_info.smb_name,ret,len+100);
1533         return (ret);
1534 }
1535
1536 /*
1537    In this section all the functions that are used to access the 
1538    parameters from the rest of the program are defined 
1539 */
1540
1541 #define FN_GLOBAL_STRING(fn_name,ptr) \
1542  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1543 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1544  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1545 #define FN_GLOBAL_LIST(fn_name,ptr) \
1546  const char **fn_name(void) {return(*(const char ***)(ptr));}
1547 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1548  BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1549 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1550  char fn_name(void) {return(*(char *)(ptr));}
1551 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1552  int fn_name(void) {return(*(int *)(ptr));}
1553
1554 #define FN_LOCAL_STRING(fn_name,val) \
1555  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1556 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1557  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1558 #define FN_LOCAL_LIST(fn_name,val) \
1559  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1560 #define FN_LOCAL_BOOL(fn_name,val) \
1561  BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1562 #define FN_LOCAL_CHAR(fn_name,val) \
1563  char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1564 #define FN_LOCAL_INTEGER(fn_name,val) \
1565  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1566
1567 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1568 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1569 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1570 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1571 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1572 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1573 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1574 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1575 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1576 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1577 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1578 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1579 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1580 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1581 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1582 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1583 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1584 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1585 #ifdef WITH_UTMP
1586 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1587 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1588 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1589 #endif
1590 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1591 FN_GLOBAL_STRING(lp_source_environment, &Globals.szSourceEnv)
1592 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1593 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1594 FN_GLOBAL_STRING(lp_dfree_command, &Globals.szDfree)
1595 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1596 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1597 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1598 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1599 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1600 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1601 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1602 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1603 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1604 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1605 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1606 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1607 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1608 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1609 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1610 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1611 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1612 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1613 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1614 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1615 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1616 FN_GLOBAL_LIST(lp_passdb_backend, &Globals.szPassdbBackend)
1617 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1618 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1619 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1620 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1621
1622 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1623 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1624 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1625 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1626 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1627 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1628
1629 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1630
1631 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1632 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1633
1634 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1635 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1636 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1637 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1638 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1639 FN_GLOBAL_STRING(lp_acl_compatibility, &Globals.szAclCompat)
1640 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1641 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1642 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1643
1644 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
1645 FN_GLOBAL_BOOL(lp_idmap_only, &Globals.bIdmapOnly)
1646
1647 #ifdef WITH_LDAP_SAMCONFIG
1648 FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
1649 FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
1650 #endif
1651 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1652 FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix)
1653 FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix)
1654 FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
1655 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1656 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1657 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1658 FN_GLOBAL_BOOL(lp_ldap_trust_ids, &Globals.ldap_trust_ids)
1659 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1660 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1661 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1662 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1663
1664 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1665 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1666 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1667 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1668 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1669 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1670 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1671 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1672 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1673 FN_GLOBAL_BOOL(lp_readprediction, &Globals.bReadPrediction)
1674 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1675 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1676 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1677 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1678 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1679 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1680 FN_GLOBAL_BOOL(lp_strip_dot, &Globals.bStripDot)
1681 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1682 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1683 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1684 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1685 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1686 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1687 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1688 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1689 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1690 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1691 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1692 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1693 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1694 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1695 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1696 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1697 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1698 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1699 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1700 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1701 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1702 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1703 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1704 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1705 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1706 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1707 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1708 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1709 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1710 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1711 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1712 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1713 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1714 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1715 FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
1716 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1717 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1718 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1719 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1720 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
1721 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
1722 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
1723 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1724 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1725 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1726 FN_GLOBAL_INTEGER(lp_readsize, &Globals.ReadSize)
1727 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
1728 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1729 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1730 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1731 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1732 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1733 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
1734 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1735 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
1736 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1737 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
1738 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1739 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1740 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1741 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1742 FN_GLOBAL_INTEGER(lp_change_notify_timeout, &Globals.change_notify_timeout)
1743 FN_GLOBAL_INTEGER(lp_stat_cache_size, &Globals.stat_cache_size)
1744 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
1745 FN_GLOBAL_INTEGER(lp_min_passwd_length, &Globals.min_passwd_length)
1746 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
1747 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1748 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1749 FN_LOCAL_STRING(lp_preexec, szPreExec)
1750 FN_LOCAL_STRING(lp_postexec, szPostExec)
1751 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
1752 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
1753 FN_LOCAL_STRING(lp_servicename, szService)
1754 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1755 FN_LOCAL_STRING(lp_pathname, szPath)
1756 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
1757 FN_LOCAL_STRING(lp_username, szUsername)
1758 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1759 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1760 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1761 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1762 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1763 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1764 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1765 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1766 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1767 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1768 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1769 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1770 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1771 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
1772 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
1773 FN_LOCAL_STRING(lp_comment, comment)
1774 FN_LOCAL_STRING(lp_force_user, force_user)
1775 FN_LOCAL_STRING(lp_force_group, force_group)
1776 FN_LOCAL_LIST(lp_readlist, readlist)
1777 FN_LOCAL_LIST(lp_writelist, writelist)
1778 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
1779 FN_LOCAL_STRING(lp_fstype, fstype)
1780 FN_LOCAL_LIST(lp_vfsobj, szVfsObjectFile)
1781 FN_LOCAL_STRING(lp_vfs_options, szVfsOptions)
1782 FN_LOCAL_STRING(lp_vfs_path, szVfsPath)
1783 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1784 static FN_LOCAL_STRING(lp_volume, volume)
1785 FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
1786 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
1787 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
1788 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
1789 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1790 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1791 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
1792 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
1793 FN_LOCAL_BOOL(lp_casesensitive, bCaseSensitive)
1794 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
1795 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
1796 FN_LOCAL_BOOL(lp_casemangle, bCaseMangle)
1797 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
1798 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
1799 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
1800 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
1801 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1802 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1803 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
1804 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1805 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1806 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1807 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1808 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1809 FN_LOCAL_BOOL(lp_locking, bLocking)
1810 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1811 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1812 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1813 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1814 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1815 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1816 FN_LOCAL_BOOL(lp_manglednames, bMangledNames)
1817 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
1818 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
1819 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
1820 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
1821 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1822 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1823 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
1824 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
1825 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
1826 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
1827 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
1828 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
1829 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
1830 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
1831 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
1832 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
1833 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
1834 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
1835 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
1836 FN_LOCAL_BOOL(lp_use_sendfile, bUseSendfile)
1837 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
1838 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
1839 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
1840 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
1841 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
1842 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
1843 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
1844 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
1845 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
1846 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1847 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
1848 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1849 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1850 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
1851 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
1852 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1853 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
1854 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
1855 FN_LOCAL_CHAR(lp_magicchar, magic_char)
1856 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1857 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1858 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
1859 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1860 FN_GLOBAL_BOOL(lp_client_signing, &Globals.client_signing)
1861
1862 /* local prototypes */
1863
1864 static int map_parameter(const char *pszParmName);
1865 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1866 static int getservicebyname(const char *pszServiceName,
1867                             service * pserviceDest);
1868 static void copy_service(service * pserviceDest,
1869                          service * pserviceSource, BOOL *pcopymapDest);
1870 static BOOL service_ok(int iService);
1871 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
1872 static BOOL do_section(const char *pszSectionName);
1873 static void init_copymap(service * pservice);
1874
1875 /* This is a helper function for parametrical options support. */
1876 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1877 /* Actual parametrical functions are quite simple */
1878 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
1879 {
1880         BOOL global_section = False;
1881         char* param_key;
1882         param_opt_struct *data;
1883         
1884         if (snum >= iNumServices) return NULL;
1885         
1886         if (snum < 0) { 
1887                 data = Globals.param_opt;
1888                 global_section = True;
1889         } else {
1890                 data = ServicePtrs[snum]->param_opt;
1891         }
1892     
1893         asprintf(&param_key, "%s:%s", type, option);
1894         if (!param_key) {
1895                 DEBUG(0,("asprintf failed!\n"));
1896                 return NULL;
1897         }
1898
1899         while (data) {
1900                 if (strcmp(data->key, param_key) == 0) {
1901                         string_free(&param_key);
1902                         return data;
1903                 }
1904                 data = data->next;
1905         }
1906
1907         if (!global_section) {
1908                 /* Try to fetch the same option but from globals */
1909                 /* but only if we are not already working with Globals */
1910                 data = Globals.param_opt;
1911                 while (data) {
1912                         if (strcmp(data->key, param_key) == 0) {
1913                                 string_free(&param_key);
1914                                 return data;
1915                         }
1916                         data = data->next;
1917                 }
1918         }
1919
1920         string_free(&param_key);
1921         
1922         return NULL;
1923 }
1924
1925
1926 /*******************************************************************
1927 convenience routine to return int parameters.
1928 ********************************************************************/
1929 static int lp_int(const char *s)
1930 {
1931
1932         if (!s) {
1933                 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1934                 return (-1);
1935         }
1936
1937         return atoi(s); 
1938 }
1939
1940 /*******************************************************************
1941 convenience routine to return unsigned long parameters.
1942 ********************************************************************/
1943 static int lp_ulong(const char *s)
1944 {
1945
1946         if (!s) {
1947                 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1948                 return (-1);
1949         }
1950
1951         return strtoul(s, NULL, 10);
1952 }
1953
1954 /*******************************************************************
1955 convenience routine to return boolean parameters.
1956 ********************************************************************/
1957 static BOOL lp_bool(const char *s)
1958 {
1959         BOOL ret = False;
1960
1961         if (!s) {
1962                 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1963                 return False;
1964         }
1965         
1966         if (!set_boolean(&ret,s)) {
1967                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1968                 return False;
1969         }
1970
1971         return ret;
1972 }
1973
1974 /*******************************************************************
1975 convenience routine to return enum parameters.
1976 ********************************************************************/
1977 static int lp_enum(const char *s,const struct enum_list *_enum)
1978 {
1979         int i;
1980
1981         if (!s || !_enum) {
1982                 DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
1983                 return (-1);
1984         }
1985         
1986         for (i=0; _enum[i].name; i++) {
1987                 if (strcasecmp(_enum[i].name,s)==0)
1988                         return _enum[i].value;
1989         }
1990
1991         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1992         return (-1);
1993 }
1994
1995
1996 /* DO NOT USE lp_parm_string ANYMORE!!!!
1997  * use lp_parm_const_string or lp_parm_talloc_string
1998  *
1999  * lp_parm_string is only used to let old modules find this symbol
2000  */
2001 #undef lp_parm_string
2002  char *lp_parm_string(const char *servicename, const char *type, const char *option)
2003 {
2004         return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2005 }
2006
2007 /* Return parametric option from a given service. Type is a part of option before ':' */
2008 /* Parametric option has following syntax: 'Type: option = value' */
2009 /* the returned value is talloced in lp_talloc */
2010 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2011 {
2012         param_opt_struct *data = get_parametrics(snum, type, option);
2013         
2014         if (data == NULL||data->value==NULL) {
2015                 if (def) {
2016                         return lp_string(def);
2017                 } else {
2018                         return NULL;
2019                 }
2020         }
2021
2022         return lp_string(data->value);
2023 }
2024
2025 /* Return parametric option from a given service. Type is a part of option before ':' */
2026 /* Parametric option has following syntax: 'Type: option = value' */
2027 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2028 {
2029         param_opt_struct *data = get_parametrics(snum, type, option);
2030         
2031         if (data == NULL||data->value==NULL)
2032                 return def;
2033                 
2034         return data->value;
2035 }
2036
2037 /* Return parametric option from a given service. Type is a part of option before ':' */
2038 /* Parametric option has following syntax: 'Type: option = value' */
2039
2040 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2041 {
2042         param_opt_struct *data = get_parametrics(snum, type, option);
2043
2044         if (data == NULL||data->value==NULL)
2045                 return (const char **)def;
2046                 
2047         if (data->list==NULL) {
2048                 data->list = str_list_make(data->value, NULL);
2049         }
2050
2051         return (const char **)data->list;
2052 }
2053
2054 /* Return parametric option from a given service. Type is a part of option before ':' */
2055 /* Parametric option has following syntax: 'Type: option = value' */
2056
2057 int lp_parm_int(int snum, const char *type, const char *option, int def)
2058 {
2059         param_opt_struct *data = get_parametrics(snum, type, option);
2060         
2061         if (data && data->value && *data->value)
2062                 return lp_int(data->value);
2063
2064         return def;
2065 }
2066
2067 /* Return parametric option from a given service. Type is a part of option before ':' */
2068 /* Parametric option has following syntax: 'Type: option = value' */
2069
2070 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2071 {
2072         param_opt_struct *data = get_parametrics(snum, type, option);
2073         
2074         if (data && data->value && *data->value)
2075                 return lp_ulong(data->value);
2076
2077         return def;
2078 }
2079
2080 /* Return parametric option from a given service. Type is a part of option before ':' */
2081 /* Parametric option has following syntax: 'Type: option = value' */
2082
2083 BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
2084 {
2085         param_opt_struct *data = get_parametrics(snum, type, option);
2086         
2087         if (data && data->value && *data->value)
2088                 return lp_bool(data->value);
2089
2090         return def;
2091 }
2092
2093 /* Return parametric option from a given service. Type is a part of option before ':' */
2094 /* Parametric option has following syntax: 'Type: option = value' */
2095
2096 int lp_parm_enum(int snum, const char *type, const char *option,
2097                  const struct enum_list *_enum, int def)
2098 {
2099         param_opt_struct *data = get_parametrics(snum, type, option);
2100         
2101         if (data && data->value && *data->value && _enum)
2102                 return lp_enum(data->value, _enum);
2103
2104         return def;
2105 }
2106
2107
2108 /***************************************************************************
2109  Initialise a service to the defaults.
2110 ***************************************************************************/
2111
2112 static void init_service(service * pservice)
2113 {
2114         memset((char *)pservice, '\0', sizeof(service));
2115         copy_service(pservice, &sDefault, NULL);
2116 }
2117
2118 /***************************************************************************
2119  Free the dynamically allocated parts of a service struct.
2120 ***************************************************************************/
2121
2122 static void free_service(service *pservice)
2123 {
2124         int i;
2125         param_opt_struct *data, *pdata;
2126         if (!pservice)
2127                 return;
2128
2129         if (pservice->szService)
2130                 DEBUG(5, ("free_service: Freeing service %s\n",
2131                        pservice->szService));
2132
2133         string_free(&pservice->szService);
2134         SAFE_FREE(pservice->copymap);
2135
2136         for (i = 0; parm_table[i].label; i++) {
2137                 if ((parm_table[i].type == P_STRING ||
2138                      parm_table[i].type == P_USTRING) &&
2139                     parm_table[i].class == P_LOCAL)
2140                         string_free((char **)
2141                                     (((char *)pservice) +
2142                                      PTR_DIFF(parm_table[i].ptr, &sDefault)));
2143                 else if (parm_table[i].type == P_LIST &&
2144                          parm_table[i].class == P_LOCAL)
2145                              str_list_free((char ***)
2146                                             (((char *)pservice) +
2147                                              PTR_DIFF(parm_table[i].ptr, &sDefault)));
2148         }
2149
2150         data = pservice->param_opt;
2151         if (data)
2152                 DEBUG(5,("Freeing parametrics:\n"));
2153         while (data) {
2154                 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2155                 string_free(&data->key);
2156                 string_free(&data->value);
2157                 str_list_free(&data->list);
2158                 pdata = data->next;
2159                 SAFE_FREE(data);
2160                 data = pdata;
2161         }
2162
2163         ZERO_STRUCTP(pservice);
2164 }
2165
2166 /***************************************************************************
2167  Add a new service to the services array initialising it with the given 
2168  service. 
2169 ***************************************************************************/
2170
2171 static int add_a_service(const service *pservice, const char *name)
2172 {
2173         int i;
2174         service tservice;
2175         int num_to_alloc = iNumServices + 1;
2176         param_opt_struct *data, *pdata;
2177
2178         tservice = *pservice;
2179
2180         /* it might already exist */
2181         if (name) {
2182                 i = getservicebyname(name, NULL);
2183                 if (i >= 0) {
2184                         /* Clean all parametric options for service */
2185                         /* They will be added during parsing again */
2186                         data = ServicePtrs[i]->param_opt;
2187                         while (data) {
2188                                 string_free(&data->key);
2189                                 string_free(&data->value);
2190                                 str_list_free(&data->list);
2191                                 pdata = data->next;
2192                                 SAFE_FREE(data);
2193                                 data = pdata;
2194                         }
2195                         ServicePtrs[i]->param_opt = NULL;
2196                         return (i);
2197                 }
2198         }
2199
2200         /* find an invalid one */
2201         for (i = 0; i < iNumServices; i++)
2202                 if (!ServicePtrs[i]->valid)
2203                         break;
2204
2205         /* if not, then create one */
2206         if (i == iNumServices) {
2207                 service **tsp;
2208                 
2209                 tsp = (service **) Realloc(ServicePtrs,
2210                                            sizeof(service *) *
2211                                            num_to_alloc);
2212                                            
2213                 if (!tsp) {
2214                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2215                         return (-1);
2216                 }
2217                 else {
2218                         ServicePtrs = tsp;
2219                         ServicePtrs[iNumServices] =
2220                                 (service *) malloc(sizeof(service));
2221                 }
2222                 if (!ServicePtrs[iNumServices]) {
2223                         DEBUG(0,("add_a_service: out of memory!\n"));
2224                         return (-1);
2225                 }
2226
2227                 iNumServices++;
2228         } else
2229                 free_service(ServicePtrs[i]);
2230
2231         ServicePtrs[i]->valid = True;
2232
2233         init_service(ServicePtrs[i]);
2234         copy_service(ServicePtrs[i], &tservice, NULL);
2235         if (name)
2236                 string_set(&ServicePtrs[i]->szService, name);
2237         return (i);
2238 }
2239
2240 /***************************************************************************
2241  Add a new home service, with the specified home directory, defaults coming 
2242  from service ifrom.
2243 ***************************************************************************/
2244
2245 BOOL lp_add_home(const char *pszHomename, int iDefaultService, 
2246                  const char *user, const char *pszHomedir)
2247 {
2248         int i;
2249         pstring newHomedir;
2250
2251         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2252
2253         if (i < 0)
2254                 return (False);
2255
2256         if (!(*(ServicePtrs[iDefaultService]->szPath))
2257             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2258                 pstrcpy(newHomedir, pszHomedir);
2259         } else {
2260                 pstrcpy(newHomedir, lp_pathname(iDefaultService));
2261                 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir)); 
2262         }
2263
2264         string_set(&ServicePtrs[i]->szPath, newHomedir);
2265
2266         if (!(*(ServicePtrs[i]->comment))) {
2267                 pstring comment;
2268                 slprintf(comment, sizeof(comment) - 1,
2269                          "Home directory of %s", user);
2270                 string_set(&ServicePtrs[i]->comment, comment);
2271         }
2272         ServicePtrs[i]->bAvailable = sDefault.bAvailable;
2273         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2274
2275         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
2276                user, newHomedir));
2277         
2278         return (True);
2279 }
2280
2281 /***************************************************************************
2282  Add a new service, based on an old one.
2283 ***************************************************************************/
2284
2285 int lp_add_service(const char *pszService, int iDefaultService)
2286 {
2287         return (add_a_service(ServicePtrs[iDefaultService], pszService));
2288 }
2289
2290 /***************************************************************************
2291  Add the IPC service.
2292 ***************************************************************************/
2293
2294 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2295 {
2296         pstring comment;
2297         int i = add_a_service(&sDefault, ipc_name);
2298
2299         if (i < 0)
2300                 return (False);
2301
2302         slprintf(comment, sizeof(comment) - 1,
2303                  "IPC Service (%s)", Globals.szServerString);
2304
2305         string_set(&ServicePtrs[i]->szPath, tmpdir());
2306         string_set(&ServicePtrs[i]->szUsername, "");
2307         string_set(&ServicePtrs[i]->comment, comment);
2308         string_set(&ServicePtrs[i]->fstype, "IPC");
2309         ServicePtrs[i]->iMaxConnections = 0;
2310         ServicePtrs[i]->bAvailable = True;
2311         ServicePtrs[i]->bRead_only = True;
2312         ServicePtrs[i]->bGuest_only = False;
2313         ServicePtrs[i]->bGuest_ok = guest_ok;
2314         ServicePtrs[i]->bPrint_ok = False;
2315         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2316
2317         DEBUG(3, ("adding IPC service\n"));
2318
2319         return (True);
2320 }
2321
2322 /***************************************************************************
2323  Add a new printer service, with defaults coming from service iFrom.
2324 ***************************************************************************/
2325
2326 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2327 {
2328         const char *comment = "From Printcap";
2329         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2330
2331         if (i < 0)
2332                 return (False);
2333
2334         /* note that we do NOT default the availability flag to True - */
2335         /* we take it from the default service passed. This allows all */
2336         /* dynamic printers to be disabled by disabling the [printers] */
2337         /* entry (if/when the 'available' keyword is implemented!).    */
2338
2339         /* the printer name is set to the service name. */
2340         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2341         string_set(&ServicePtrs[i]->comment, comment);
2342         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2343         /* Printers cannot be read_only. */
2344         ServicePtrs[i]->bRead_only = False;
2345         /* No share modes on printer services. */
2346         ServicePtrs[i]->bShareModes = False;
2347         /* No oplocks on printer services. */
2348         ServicePtrs[i]->bOpLocks = False;
2349         /* Printer services must be printable. */
2350         ServicePtrs[i]->bPrint_ok = True;
2351
2352         DEBUG(3, ("adding printer service %s\n", pszPrintername));
2353
2354         update_server_announce_as_printserver();
2355
2356         return (True);
2357 }
2358
2359 /***************************************************************************
2360  Map a parameter's string representation to something we can use. 
2361  Returns False if the parameter string is not recognised, else TRUE.
2362 ***************************************************************************/
2363
2364 static int map_parameter(const char *pszParmName)
2365 {
2366         int iIndex;
2367
2368         if (*pszParmName == '-')
2369                 return (-1);
2370
2371         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2372                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2373                         return (iIndex);
2374
2375         /* Warn only if it isn't parametric option */
2376         if (strchr(pszParmName, ':') == NULL)
2377                 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2378         /* We do return 'fail' for parametric options as well because they are
2379            stored in different storage
2380          */
2381         return (-1);
2382 }
2383
2384 /***************************************************************************
2385  Set a boolean variable from the text value stored in the passed string.
2386  Returns True in success, False if the passed string does not correctly 
2387  represent a boolean.
2388 ***************************************************************************/
2389
2390 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2391 {
2392         BOOL bRetval;
2393
2394         bRetval = True;
2395         if (strwicmp(pszParmValue, "yes") == 0 ||
2396             strwicmp(pszParmValue, "true") == 0 ||
2397             strwicmp(pszParmValue, "1") == 0)
2398                 *pb = True;
2399         else if (strwicmp(pszParmValue, "no") == 0 ||
2400                     strwicmp(pszParmValue, "False") == 0 ||
2401                     strwicmp(pszParmValue, "0") == 0)
2402                 *pb = False;
2403         else {
2404                 DEBUG(0,
2405                       ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2406                        pszParmValue));
2407                 bRetval = False;
2408         }
2409         return (bRetval);
2410 }
2411
2412 /***************************************************************************
2413 Find a service by name. Otherwise works like get_service.
2414 ***************************************************************************/
2415
2416 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2417 {
2418         int iService;
2419
2420         for (iService = iNumServices - 1; iService >= 0; iService--)
2421                 if (VALID(iService) &&
2422                     strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
2423                         if (pserviceDest != NULL)
2424                                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2425                         break;
2426                 }
2427
2428         return (iService);
2429 }
2430
2431 /***************************************************************************
2432  Copy a service structure to another.
2433  If pcopymapDest is NULL then copy all fields
2434 ***************************************************************************/
2435
2436 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2437 {
2438         int i;
2439         BOOL bcopyall = (pcopymapDest == NULL);
2440         param_opt_struct *data, *pdata, *paramo;
2441         BOOL not_added;
2442
2443         for (i = 0; parm_table[i].label; i++)
2444                 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
2445                     (bcopyall || pcopymapDest[i])) {
2446                         void *def_ptr = parm_table[i].ptr;
2447                         void *src_ptr =
2448                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2449                                                                     &sDefault);
2450                         void *dest_ptr =
2451                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2452                                                                   &sDefault);
2453
2454                         switch (parm_table[i].type) {
2455                                 case P_BOOL:
2456                                 case P_BOOLREV:
2457                                         *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2458                                         break;
2459
2460                                 case P_INTEGER:
2461                                 case P_ENUM:
2462                                 case P_OCTAL:
2463                                         *(int *)dest_ptr = *(int *)src_ptr;
2464                                         break;
2465
2466                                 case P_CHAR:
2467                                         *(char *)dest_ptr = *(char *)src_ptr;
2468                                         break;
2469
2470                                 case P_STRING:
2471                                         string_set(dest_ptr,
2472                                                    *(char **)src_ptr);
2473                                         break;
2474
2475                                 case P_USTRING:
2476                                         string_set(dest_ptr,
2477                                                    *(char **)src_ptr);
2478                                         strupper(*(char **)dest_ptr);
2479                                         break;
2480                                 case P_LIST:
2481                                         str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2482                                         break;
2483                                 default:
2484                                         break;
2485                         }
2486                 }
2487
2488         if (bcopyall) {
2489                 init_copymap(pserviceDest);
2490                 if (pserviceSource->copymap)
2491                         memcpy((void *)pserviceDest->copymap,
2492                                (void *)pserviceSource->copymap,
2493                                sizeof(BOOL) * NUMPARAMETERS);
2494         }
2495         
2496         data = pserviceSource->param_opt;
2497         while (data) {
2498                 not_added = True;
2499                 pdata = pserviceDest->param_opt;
2500                 /* Traverse destination */
2501                 while (pdata) {
2502                         /* If we already have same option, override it */
2503                         if (strcmp(pdata->key, data->key) == 0) {
2504                                 string_free(&pdata->value);
2505                                 str_list_free(&data->list);
2506                                 pdata->value = strdup(data->value);
2507                                 not_added = False;
2508                                 break;
2509                         }
2510                         pdata = pdata->next;
2511                 }
2512                 if (not_added) {
2513                     paramo = smb_xmalloc(sizeof(param_opt_struct));
2514                     paramo->key = strdup(data->key);
2515                     paramo->value = strdup(data->value);
2516                     paramo->list = NULL;
2517                     DLIST_ADD(pserviceDest->param_opt, paramo);
2518                 }
2519                 data = data->next;
2520         }
2521 }
2522
2523 /***************************************************************************
2524 Check a service for consistency. Return False if the service is in any way
2525 incomplete or faulty, else True.
2526 ***************************************************************************/
2527
2528 static BOOL service_ok(int iService)
2529 {
2530         BOOL bRetval;
2531
2532         bRetval = True;
2533         if (ServicePtrs[iService]->szService[0] == '\0') {
2534                 DEBUG(0, ("The following message indicates an internal error:\n"));
2535                 DEBUG(0, ("No service name in service entry.\n"));
2536                 bRetval = False;
2537         }
2538
2539         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2540         /* I can't see why you'd want a non-printable printer service...        */
2541         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2542                 if (!ServicePtrs[iService]->bPrint_ok) {
2543                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2544                                ServicePtrs[iService]->szService));
2545                         ServicePtrs[iService]->bPrint_ok = True;
2546                 }
2547                 /* [printers] service must also be non-browsable. */
2548                 if (ServicePtrs[iService]->bBrowseable)
2549                         ServicePtrs[iService]->bBrowseable = False;
2550         }
2551
2552         if (ServicePtrs[iService]->szPath[0] == '\0' &&
2553             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0) {
2554                 DEBUG(0, ("No path in service %s - using %s\n",
2555                        ServicePtrs[iService]->szService, tmpdir()));
2556                 string_set(&ServicePtrs[iService]->szPath, tmpdir());
2557         }
2558
2559         /* If a service is flagged unavailable, log the fact at level 0. */
2560         if (!ServicePtrs[iService]->bAvailable)
2561                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2562                           ServicePtrs[iService]->szService));
2563
2564         return (bRetval);
2565 }
2566
2567 static struct file_lists {
2568         struct file_lists *next;
2569         char *name;
2570         char *subfname;
2571         time_t modtime;
2572 } *file_lists = NULL;
2573
2574 /*******************************************************************
2575  Keep a linked list of all config files so we know when one has changed 
2576  it's date and needs to be reloaded.
2577 ********************************************************************/
2578
2579 static void add_to_file_list(const char *fname, const char *subfname)
2580 {
2581         struct file_lists *f = file_lists;
2582
2583         while (f) {
2584                 if (f->name && !strcmp(f->name, fname))
2585                         break;
2586                 f = f->next;
2587         }
2588
2589         if (!f) {
2590                 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
2591                 if (!f)
2592                         return;
2593                 f->next = file_lists;
2594                 f->name = strdup(fname);
2595                 if (!f->name) {
2596                         SAFE_FREE(f);
2597                         return;
2598                 }
2599                 f->subfname = strdup(subfname);
2600                 if (!f->subfname) {
2601                         SAFE_FREE(f);
2602                         return;
2603                 }
2604                 file_lists = f;
2605                 f->modtime = file_modtime(subfname);
2606         } else {
2607                 time_t t = file_modtime(subfname);
2608                 if (t)
2609                         f->modtime = t;
2610         }
2611 }
2612
2613 /*******************************************************************
2614  Check if a config file has changed date.
2615 ********************************************************************/
2616
2617 BOOL lp_file_list_changed(void)
2618 {
2619         struct file_lists *f = file_lists;
2620         DEBUG(6, ("lp_file_list_changed()\n"));
2621
2622         while (f) {
2623                 pstring n2;
2624                 time_t mod_time;
2625
2626                 pstrcpy(n2, f->name);
2627                 standard_sub_basic(current_user_info.smb_name, n2,sizeof(n2));
2628
2629                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
2630                              f->name, n2, ctime(&f->modtime)));
2631
2632                 mod_time = file_modtime(n2);
2633
2634                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2635                         DEBUGADD(6,
2636                                  ("file %s modified: %s\n", n2,
2637                                   ctime(&mod_time)));
2638                         f->modtime = mod_time;
2639                         SAFE_FREE(f->subfname);
2640                         f->subfname = strdup(n2);
2641                         return (True);
2642                 }
2643                 f = f->next;
2644         }
2645         return (False);
2646 }
2647
2648 /***************************************************************************
2649  Run standard_sub_basic on netbios name... needed because global_myname
2650  is not accessed through any lp_ macro.
2651  Note: We must *NOT* use string_set() here as ptr points to global_myname.
2652 ***************************************************************************/
2653
2654 static BOOL handle_netbios_name(const char *pszParmValue, char **ptr)
2655 {
2656         BOOL ret;
2657         pstring netbios_name;
2658
2659         pstrcpy(netbios_name, pszParmValue);
2660
2661         standard_sub_basic(current_user_info.smb_name, netbios_name,sizeof(netbios_name));
2662
2663
2664         ret = set_global_myname(netbios_name);
2665         string_set(&Globals.szNetbiosName,global_myname());
2666         
2667         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
2668                global_myname()));
2669
2670         return ret;
2671 }
2672
2673 static BOOL handle_workgroup(const char *pszParmValue, char **ptr)
2674 {
2675         BOOL ret;
2676         
2677         ret = set_global_myworkgroup(pszParmValue);
2678         string_set(&Globals.szWorkgroup,lp_workgroup());
2679         
2680         return ret;
2681 }
2682
2683 static BOOL handle_netbios_scope(const char *pszParmValue, char **ptr)
2684 {
2685         BOOL ret;
2686         
2687         ret = set_global_scope(pszParmValue);
2688         string_set(&Globals.szNetbiosScope,global_scope());
2689
2690         return ret;
2691 }
2692
2693 static BOOL handle_netbios_aliases(const char *pszParmValue, char **ptr)
2694 {
2695         Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
2696         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
2697 }
2698
2699 /***************************************************************************
2700  Do the work of sourcing in environment variable/value pairs.
2701 ***************************************************************************/
2702
2703 static BOOL source_env(char **lines)
2704 {
2705         char *varval;
2706         size_t len;
2707         int i;
2708         char *p;
2709
2710         for (i = 0; lines[i]; i++) {
2711                 char *line = lines[i];
2712
2713                 if ((len = strlen(line)) == 0)
2714                         continue;
2715
2716                 if (line[len - 1] == '\n')
2717                         line[--len] = '\0';
2718
2719                 if ((varval = malloc(len + 1)) == NULL) {
2720                         DEBUG(0, ("source_env: Not enough memory!\n"));
2721                         return (False);
2722                 }
2723
2724                 DEBUG(4, ("source_env: Adding to environment: %s\n", line));
2725                 strncpy(varval, line, len);
2726                 varval[len] = '\0';
2727
2728                 p = strchr_m(line, (int)'=');
2729                 if (p == NULL) {
2730                         DEBUG(4, ("source_env: missing '=': %s\n", line));
2731                         continue;
2732                 }
2733
2734                 if (putenv(varval)) {
2735                         DEBUG(0, ("source_env: Failed to put environment variable %s\n",
2736                                varval));
2737                         continue;
2738                 }
2739
2740                 *p = '\0';
2741                 p++;
2742                 DEBUG(4, ("source_env: getting var %s = %s\n", line, getenv(line)));
2743         }
2744
2745         DEBUG(4, ("source_env: returning successfully\n"));
2746         return (True);
2747 }
2748
2749 /***************************************************************************
2750  Handle the source environment operation.
2751 ***************************************************************************/
2752
2753 static BOOL handle_source_env(const char *pszParmValue, char **ptr)
2754 {
2755         pstring fname;
2756         char *p = fname;
2757         BOOL result;
2758         char **lines;
2759
2760         pstrcpy(fname, pszParmValue);
2761
2762         standard_sub_basic(current_user_info.smb_name, fname,sizeof(fname));
2763
2764         string_set(ptr, pszParmValue);
2765
2766         DEBUG(4, ("handle_source_env: checking env type\n"));
2767
2768         /*
2769          * Filename starting with '|' means popen and read from stdin.
2770          */
2771
2772         if (*p == '|')
2773                 lines = file_lines_pload(p + 1, NULL);
2774         else
2775                 lines = file_lines_load(fname, NULL);
2776
2777         if (!lines) {
2778                 DEBUG(0, ("handle_source_env: Failed to open file %s, Error was %s\n",
2779                        fname, strerror(errno)));
2780                 return (False);
2781         }
2782
2783         result = source_env(lines);
2784         file_lines_free(lines);
2785
2786         return (result);
2787 }
2788
2789 /***************************************************************************
2790  Handle the include operation.
2791 ***************************************************************************/
2792
2793 static BOOL handle_include(const char *pszParmValue, char **ptr)
2794 {
2795         pstring fname;
2796         pstrcpy(fname, pszParmValue);
2797
2798         standard_sub_basic(current_user_info.smb_name, fname,sizeof(fname));
2799
2800         add_to_file_list(pszParmValue, fname);
2801
2802         string_set(ptr, fname);
2803
2804         if (file_exist(fname, NULL))
2805                 return (pm_process(fname, do_section, do_parameter));
2806
2807         DEBUG(2, ("Can't find include file %s\n", fname));
2808
2809         return (False);
2810 }
2811
2812 /***************************************************************************
2813  Handle the interpretation of the copy parameter.
2814 ***************************************************************************/
2815
2816 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2817 {
2818         BOOL bRetval;
2819         int iTemp;
2820         service serviceTemp;
2821
2822         string_set(ptr, pszParmValue);
2823
2824         init_service(&serviceTemp);
2825
2826         bRetval = False;
2827
2828         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2829
2830         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2831                 if (iTemp == iServiceIndex) {
2832                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2833                 } else {
2834                         copy_service(ServicePtrs[iServiceIndex],
2835                                      &serviceTemp,
2836                                      ServicePtrs[iServiceIndex]->copymap);
2837                         bRetval = True;
2838                 }
2839         } else {
2840                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2841                 bRetval = False;
2842         }
2843
2844         free_service(&serviceTemp);
2845         return (bRetval);
2846 }
2847
2848 /***************************************************************************
2849  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
2850  parameters is:
2851
2852  [global]
2853
2854         idmap uid = 1000-1999
2855         idmap gid = 700-899
2856
2857  We only do simple parsing checks here.  The strings are parsed into useful
2858  structures in the idmap daemon code.
2859
2860 ***************************************************************************/
2861
2862 /* Some lp_ routines to return idmap [ug]id information */
2863
2864 static uid_t idmap_uid_low, idmap_uid_high;
2865 static gid_t idmap_gid_low, idmap_gid_high;
2866
2867 BOOL lp_idmap_uid(uid_t *low, uid_t *high)
2868 {
2869         if (idmap_uid_low == 0 || idmap_uid_high == 0)
2870                 return False;
2871
2872         if (low)
2873                 *low = idmap_uid_low;
2874
2875         if (high)
2876                 *high = idmap_uid_high;
2877
2878         return True;
2879 }
2880
2881 BOOL lp_idmap_gid(gid_t *low, gid_t *high)
2882 {
2883         if (idmap_gid_low == 0 || idmap_gid_high == 0)
2884                 return False;
2885
2886         if (low)
2887                 *low = idmap_gid_low;
2888
2889         if (high)
2890                 *high = idmap_gid_high;
2891
2892         return True;
2893 }
2894
2895 /* Do some simple checks on "idmap [ug]id" parameter values */
2896
2897 static BOOL handle_idmap_uid(const char *pszParmValue, char **ptr)
2898 {
2899         uint32 low, high;
2900
2901         if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2902                 return False;
2903
2904         /* Parse OK */
2905
2906         string_set(ptr, pszParmValue);
2907
2908         idmap_uid_low = low;
2909         idmap_uid_high = high;
2910
2911         return True;
2912 }
2913
2914 static BOOL handle_idmap_gid(const char *pszParmValue, char **ptr)
2915 {
2916         uint32 low, high;
2917
2918         if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2919                 return False;
2920
2921         /* Parse OK */
2922
2923         string_set(ptr, pszParmValue);
2924
2925         idmap_gid_low = low;
2926         idmap_gid_high = high;
2927
2928         return True;
2929 }
2930
2931 /***************************************************************************
2932  Handle the DEBUG level list.
2933 ***************************************************************************/
2934
2935 static BOOL handle_debug_list( const char *pszParmValueIn, char **ptr )
2936 {
2937         pstring pszParmValue;
2938
2939         pstrcpy(pszParmValue, pszParmValueIn);
2940         string_set(ptr, pszParmValueIn);
2941         return debug_parse_levels( pszParmValue );
2942 }
2943
2944 /***************************************************************************
2945  Handle the ldap machine suffix option.
2946 ***************************************************************************/
2947
2948 static BOOL handle_ldap_machine_suffix( const char *pszParmValue, char **ptr)
2949 {
2950        pstring suffix;
2951        
2952        pstrcpy(suffix, pszParmValue);
2953
2954        if (! *Globals.szLdapSuffix ) {
2955                string_set( ptr, suffix );
2956                return True;
2957        }
2958
2959        if (! strstr(suffix, Globals.szLdapSuffix) ) {
2960                if ( *pszParmValue )
2961                        pstrcat(suffix, ",");
2962                pstrcat(suffix, Globals.szLdapSuffix);
2963        }
2964        string_set( ptr, suffix );
2965        return True;
2966 }
2967
2968 /***************************************************************************
2969  Handle the ldap user suffix option.
2970 ***************************************************************************/
2971
2972 static BOOL handle_ldap_user_suffix( const char *pszParmValue, char **ptr)
2973 {
2974        pstring suffix;
2975        
2976        pstrcpy(suffix, pszParmValue);
2977
2978        if (! *Globals.szLdapSuffix ) {
2979                string_set( ptr, suffix );
2980                return True;
2981        }
2982        
2983        if (! strstr(suffix, Globals.szLdapSuffix) ) {
2984                if ( *pszParmValue )
2985                        pstrcat(suffix, ",");
2986                pstrcat(suffix, Globals.szLdapSuffix);
2987        }
2988        string_set( ptr, suffix );
2989        return True;
2990 }
2991
2992 /***************************************************************************
2993  Handle setting ldap suffix and determines whether ldap machine suffix needs
2994  to be set as well.
2995 ***************************************************************************/
2996
2997 static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr)
2998 {
2999        pstring suffix;
3000        pstring user_suffix;
3001        pstring machine_suffix;
3002                
3003        pstrcpy(suffix, pszParmValue);
3004
3005        if (! *Globals.szLdapMachineSuffix )
3006                string_set(&Globals.szLdapMachineSuffix, suffix);
3007        if (! *Globals.szLdapUserSuffix ) 
3008                string_set(&Globals.szLdapUserSuffix, suffix);
3009        
3010        if (! strstr(Globals.szLdapMachineSuffix, suffix)) {
3011                pstrcpy(machine_suffix, Globals.szLdapMachineSuffix);
3012                if ( *Globals.szLdapMachineSuffix )
3013                        pstrcat(machine_suffix, ",");
3014                pstrcat(machine_suffix, suffix);
3015                string_set(&Globals.szLdapMachineSuffix, machine_suffix);       
3016        }
3017
3018        if (! strstr(Globals.szLdapUserSuffix, suffix)) {
3019                pstrcpy(user_suffix, Globals.szLdapUserSuffix);
3020                if ( *Globals.szLdapUserSuffix )
3021                        pstrcat(user_suffix, ",");
3022                pstrcat(user_suffix, suffix);   
3023                string_set(&Globals.szLdapUserSuffix, user_suffix);
3024        } 
3025
3026        string_set(ptr, suffix); 
3027        return True;
3028 }
3029
3030 static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr)
3031 {
3032         if (strequal(pszParmValue, "auto"))
3033                 string_set(ptr, "");
3034         else if (strequal(pszParmValue, "winnt"))
3035                 string_set(ptr, "winnt");
3036         else if (strequal(pszParmValue, "win2k"))
3037                 string_set(ptr, "win2k");
3038         else
3039                 return False;
3040
3041         return True;
3042 }
3043 /***************************************************************************
3044  Initialise a copymap.
3045 ***************************************************************************/
3046
3047 static void init_copymap(service * pservice)
3048 {
3049         int i;
3050         SAFE_FREE(pservice->copymap);
3051         pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
3052         if (!pservice->copymap)
3053                 DEBUG(0,
3054                       ("Couldn't allocate copymap!! (size %d)\n",
3055                        (int)NUMPARAMETERS));
3056         else
3057                 for (i = 0; i < NUMPARAMETERS; i++)
3058                         pservice->copymap[i] = True;
3059 }
3060
3061 /***************************************************************************
3062  Return the local pointer to a parameter given the service number and the 
3063  pointer into the default structure.
3064 ***************************************************************************/
3065
3066 void *lp_local_ptr(int snum, void *ptr)
3067 {
3068         return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3069 }
3070
3071 /***************************************************************************
3072  Process a parameter for a particular service number. If snum < 0
3073  then assume we are in the globals.
3074 ***************************************************************************/
3075
3076 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3077 {
3078         int parmnum, i, slen;
3079         void *parm_ptr = NULL;  /* where we are going to store the result */
3080         void *def_ptr = NULL;
3081         pstring param_key;
3082         char *sep;
3083         param_opt_struct *paramo, *data;
3084         BOOL not_added;
3085
3086         parmnum = map_parameter(pszParmName);
3087
3088         if (parmnum < 0) {
3089                 if ((sep=strchr(pszParmName, ':')) != NULL) {
3090                         *sep = '\0';
3091                         ZERO_STRUCT(param_key);
3092                         pstr_sprintf(param_key, "%s:", pszParmName);
3093                         slen = strlen(param_key);
3094                         pstrcat(param_key, sep+1);
3095                         trim_string(param_key+slen, " ", " ");
3096                         not_added = True;
3097                         data = (snum < 0) ? Globals.param_opt : 
3098                                 ServicePtrs[snum]->param_opt;
3099                         /* Traverse destination */
3100                         while (data) {
3101                                 /* If we already have same option, override it */
3102                                 if (strcmp(data->key, param_key) == 0) {
3103                                         string_free(&data->value);
3104                                         str_list_free(&data->list);
3105                                         data->value = strdup(pszParmValue);
3106                                         not_added = False;
3107                                         break;
3108                                 }
3109                                 data = data->next;
3110                         }
3111                         if (not_added) {
3112                                 paramo = smb_xmalloc(sizeof(param_opt_struct));
3113                                 paramo->key = strdup(param_key);
3114                                 paramo->value = strdup(pszParmValue);
3115                                 paramo->list = NULL;
3116                                 if (snum < 0) {
3117                                         DLIST_ADD(Globals.param_opt, paramo);
3118                                 } else {
3119                                         DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3120                                 }
3121                         }
3122
3123                         *sep = ':';
3124                         return (True);
3125                 }
3126                 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3127                 return (True);
3128         }
3129
3130         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3131                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3132                           pszParmName));
3133         }
3134
3135         def_ptr = parm_table[parmnum].ptr;
3136
3137         /* we might point at a service, the default service or a global */
3138         if (snum < 0) {
3139                 parm_ptr = def_ptr;
3140         } else {
3141                 if (parm_table[parmnum].class == P_GLOBAL) {
3142                         DEBUG(0,
3143                               ("Global parameter %s found in service section!\n",
3144                                pszParmName));
3145                         return (True);
3146                 }
3147                 parm_ptr =
3148                         ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3149                                                             &sDefault);
3150         }
3151
3152         if (snum >= 0) {
3153                 if (!ServicePtrs[snum]->copymap)
3154                         init_copymap(ServicePtrs[snum]);
3155
3156                 /* this handles the aliases - set the copymap for other entries with
3157                    the same data pointer */
3158                 for (i = 0; parm_table[i].label; i++)
3159                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
3160                                 ServicePtrs[snum]->copymap[i] = False;
3161         }
3162
3163         /* if it is a special case then go ahead */
3164         if (parm_table[parmnum].special) {
3165                 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
3166                 return (True);
3167         }
3168
3169         /* now switch on the type of variable it is */
3170         switch (parm_table[parmnum].type)
3171         {
3172                 case P_BOOL:
3173                         set_boolean(parm_ptr, pszParmValue);
3174                         break;
3175
3176                 case P_BOOLREV:
3177                         set_boolean(parm_ptr, pszParmValue);
3178                         *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
3179                         break;
3180
3181                 case P_INTEGER:
3182                         *(int *)parm_ptr = atoi(pszParmValue);
3183                         break;
3184
3185                 case P_CHAR:
3186                         *(char *)parm_ptr = *pszParmValue;
3187                         break;
3188
3189                 case P_OCTAL:
3190                         sscanf(pszParmValue, "%o", (int *)parm_ptr);
3191                         break;
3192
3193                 case P_LIST:
3194                         str_list_free(parm_ptr);
3195                         *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3196                         break;
3197
3198                 case P_STRING:
3199                         string_set(parm_ptr, pszParmValue);
3200                         break;
3201
3202                 case P_USTRING:
3203                         string_set(parm_ptr, pszParmValue);
3204                         strupper(*(char **)parm_ptr);
3205                         break;
3206
3207                 case P_GSTRING:
3208                         pstrcpy((char *)parm_ptr, pszParmValue);
3209                         break;
3210
3211                 case P_UGSTRING:
3212                         pstrcpy((char *)parm_ptr, pszParmValue);
3213                         strupper((char *)parm_ptr);
3214                         break;
3215
3216                 case P_ENUM:
3217                         for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
3218                                 if (strequal
3219                                     (pszParmValue,
3220                                      parm_table[parmnum].enum_list[i].name)) {
3221                                         *(int *)parm_ptr =
3222                                                 parm_table[parmnum].
3223                                                 enum_list[i].value;
3224                                         break;
3225                                 }
3226                         }
3227                         break;
3228                 case P_SEP:
3229                         break;
3230         }
3231
3232         return (True);
3233 }
3234
3235 /***************************************************************************
3236  Process a parameter.
3237 ***************************************************************************/
3238
3239 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3240 {
3241         if (!bInGlobalSection && bGlobalOnly)
3242                 return (True);
3243
3244         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3245
3246         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3247                                 pszParmName, pszParmValue));
3248 }
3249
3250 /***************************************************************************
3251  Print a parameter of the specified type.
3252 ***************************************************************************/
3253
3254 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3255 {
3256         int i;
3257         switch (p->type)
3258         {
3259                 case P_ENUM:
3260                         for (i = 0; p->enum_list[i].name; i++) {
3261                                 if (*(int *)ptr == p->enum_list[i].value) {
3262                                         fprintf(f, "%s",
3263                                                 p->enum_list[i].name);
3264                                         break;
3265                                 }
3266                         }
3267                         break;
3268
3269                 case P_BOOL:
3270                         fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3271                         break;
3272
3273                 case P_BOOLREV:
3274                         fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3275                         break;
3276
3277                 case P_INTEGER:
3278                         fprintf(f, "%d", *(int *)ptr);
3279                         break;
3280
3281                 case P_CHAR:
3282                         fprintf(f, "%c", *(char *)ptr);
3283                         break;
3284
3285                 case P_OCTAL:
3286                         fprintf(f, "%s", octal_string(*(int *)ptr));
3287                         break;
3288
3289                 case P_LIST:
3290                         if ((char ***)ptr && *(char ***)ptr) {
3291                                 char **list = *(char ***)ptr;
3292                                 
3293                                 for (; *list; list++)
3294                                         fprintf(f, "%s%s", *list,
3295                                                 ((*(list+1))?", ":""));
3296                         }
3297                         break;
3298
3299                 case P_GSTRING:
3300                 case P_UGSTRING:
3301                         if ((char *)ptr) {
3302                                 fprintf(f, "%s", (char *)ptr);
3303                         }
3304                         break;
3305
3306                 case P_STRING:
3307                 case P_USTRING:
3308                         if (*(char **)ptr) {
3309                                 fprintf(f, "%s", *(char **)ptr);
3310                         }
3311                         break;
3312                 case P_SEP:
3313                         break;
3314         }
3315 }
3316
3317 /***************************************************************************
3318  Check if two parameters are equal.
3319 ***************************************************************************/
3320
3321 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3322 {
3323         switch (type) {
3324                 case P_BOOL:
3325                 case P_BOOLREV:
3326                         return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3327
3328                 case P_INTEGER:
3329                 case P_ENUM:
3330                 case P_OCTAL:
3331                         return (*((int *)ptr1) == *((int *)ptr2));
3332
3333                 case P_CHAR:
3334                         return (*((char *)ptr1) == *((char *)ptr2));
3335                 
3336                 case P_LIST:
3337                         return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3338
3339                 case P_GSTRING:
3340                 case P_UGSTRING:
3341                 {
3342                         char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3343                         if (p1 && !*p1)
3344                                 p1 = NULL;
3345                         if (p2 && !*p2)
3346                                 p2 = NULL;
3347                         return (p1 == p2 || strequal(p1, p2));
3348                 }
3349                 case P_STRING:
3350                 case P_USTRING:
3351                 {
3352                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3353                         if (p1 && !*p1)
3354                                 p1 = NULL;
3355                         if (p2 && !*p2)
3356                                 p2 = NULL;
3357                         return (p1 == p2 || strequal(p1, p2));
3358                 }
3359                 case P_SEP:
3360                         break;
3361         }
3362         return (False);
3363 }
3364
3365 /***************************************************************************
3366  Initialize any local varients in the sDefault table.
3367 ***************************************************************************/
3368
3369 void init_locals(void)
3370 {
3371         /* None as yet. */
3372 }
3373
3374 /***************************************************************************
3375  Process a new section (service). At this stage all sections are services.
3376  Later we'll have special sections that permit server parameters to be set.
3377  Returns True on success, False on failure. 
3378 ***************************************************************************/
3379
3380 static BOOL do_section(const char *pszSectionName)
3381 {
3382         BOOL bRetval;
3383         BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3384                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3385         bRetval = False;
3386
3387         /* if we were in a global section then do the local inits */
3388         if (bInGlobalSection && !isglobal)
3389                 init_locals();
3390
3391         /* if we've just struck a global section, note the fact. */
3392         bInGlobalSection = isglobal;
3393
3394         /* check for multiple global sections */
3395         if (bInGlobalSection) {
3396                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3397                 return (True);
3398         }
3399
3400         if (!bInGlobalSection && bGlobalOnly)
3401                 return (True);
3402
3403         /* if we have a current service, tidy it up before moving on */
3404         bRetval = True;
3405
3406         if (iServiceIndex >= 0)
3407                 bRetval = service_ok(iServiceIndex);
3408
3409         /* if all is still well, move to the next record in the services array */
3410         if (bRetval) {
3411                 /* We put this here to avoid an odd message order if messages are */
3412                 /* issued by the post-processing of a previous section. */
3413                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3414
3415                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3416                     < 0) {
3417                         DEBUG(0, ("Failed to add a new service\n"));
3418                         return (False);
3419                 }
3420         }
3421
3422         return (bRetval);
3423 }
3424
3425
3426 /***************************************************************************
3427  Determine if a partcular base parameter is currentl set to the default value.
3428 ***************************************************************************/
3429
3430 static BOOL is_default(int i)
3431 {
3432         if (!defaults_saved)
3433                 return False;
3434         switch (parm_table[i].type) {
3435                 case P_LIST:
3436                         return str_list_compare (parm_table[i].def.lvalue, 
3437                                                 *(char ***)parm_table[i].ptr);
3438                 case P_STRING:
3439                 case P_USTRING:
3440                         return strequal(parm_table[i].def.svalue,
3441                                         *(char **)parm_table[i].ptr);
3442                 case P_GSTRING:
3443                 case P_UGSTRING:
3444                         return strequal(parm_table[i].def.svalue,
3445                                         (char *)parm_table[i].ptr);
3446                 case P_BOOL:
3447                 case P_BOOLREV:
3448                         return parm_table[i].def.bvalue ==
3449                                 *(BOOL *)parm_table[i].ptr;
3450                 case P_CHAR:
3451                         return parm_table[i].def.cvalue ==
3452                                 *(char *)parm_table[i].ptr;
3453                 case P_INTEGER:
3454                 case P_OCTAL:
3455                 case P_ENUM:
3456                         return parm_table[i].def.ivalue ==
3457                                 *(int *)parm_table[i].ptr;
3458                 case P_SEP:
3459                         break;
3460         }
3461         return False;
3462 }
3463
3464 /***************************************************************************
3465 Display the contents of the global structure.
3466 ***************************************************************************/
3467
3468 static void dump_globals(FILE *f)
3469 {
3470         int i;
3471         param_opt_struct *data;
3472         
3473         fprintf(f, "# Global parameters\n[global]\n");
3474
3475         for (i = 0; parm_table[i].label; i++)
3476                 if (parm_table[i].class == P_GLOBAL &&
3477                     parm_table[i].ptr &&
3478                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3479                         if (defaults_saved && is_default(i))
3480                                 continue;
3481                         fprintf(f, "\t%s = ", parm_table[i].label);
3482                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
3483                         fprintf(f, "\n");
3484         }
3485         if (Globals.param_opt != NULL) {
3486                 data = Globals.param_opt;
3487                 while(data) {
3488                         fprintf(f, "\t%s = %s\n", data->key, data->value);
3489                         data = data->next;
3490                 }
3491         }
3492
3493 }
3494
3495 /***************************************************************************
3496  Return True if a local parameter is currently set to the global default.
3497 ***************************************************************************/
3498
3499 BOOL lp_is_default(int snum, struct parm_struct *parm)
3500 {
3501         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3502
3503         return equal_parameter(parm->type,
3504                                ((char *)ServicePtrs[snum]) + pdiff,
3505                                ((char *)&sDefault) + pdiff);
3506 }
3507
3508 /***************************************************************************
3509  Display the contents of a single services record.
3510 ***************************************************************************/
3511
3512 static void dump_a_service(service * pService, FILE * f)
3513 {
3514         int i;
3515         param_opt_struct *data;
3516         
3517         if (pService != &sDefault)
3518                 fprintf(f, "\n[%s]\n", pService->szService);
3519
3520         for (i = 0; parm_table[i].label; i++)
3521                 if (parm_table[i].class == P_LOCAL &&
3522                     parm_table[i].ptr &&
3523                     (*parm_table[i].label != '-') &&
3524                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3525                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3526
3527                         if (pService == &sDefault) {
3528                                 if (defaults_saved && is_default(i))
3529                                         continue;
3530                         } else {
3531                                 if (equal_parameter(parm_table[i].type,
3532                                                     ((char *)pService) +
3533                                                     pdiff,
3534                                                     ((char *)&sDefault) +
3535                                                     pdiff))
3536                                         continue;
3537                         }
3538
3539                         fprintf(f, "\t%s = ", parm_table[i].label);
3540                         print_parameter(&parm_table[i],
3541                                         ((char *)pService) + pdiff, f);
3542                         fprintf(f, "\n");
3543         }
3544         if (pService->param_opt != NULL) {
3545                 data = pService->param_opt;
3546                 while(data) {
3547                         fprintf(f, "\t%s = %s\n", data->key, data->value);
3548                         data = data->next;
3549                 }
3550         }
3551 }
3552
3553
3554 /***************************************************************************
3555  Return info about the next service  in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
3556  Return NULL when out of parameters.
3557 ***************************************************************************/
3558
3559 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
3560 {
3561         if (snum < 0) {
3562                 /* do the globals */
3563                 for (; parm_table[*i].label; (*i)++) {
3564                         if (parm_table[*i].class == P_SEPARATOR)
3565                                 return &parm_table[(*i)++];
3566
3567                         if (!parm_table[*i].ptr
3568                             || (*parm_table[*i].label == '-'))
3569                                 continue;
3570
3571                         if ((*i) > 0
3572                             && (parm_table[*i].ptr ==
3573                                 parm_table[(*i) - 1].ptr))
3574                                 continue;
3575
3576                         return &parm_table[(*i)++];
3577                 }
3578         } else {
3579                 service *pService = ServicePtrs[snum];
3580
3581                 for (; parm_table[*i].label; (*i)++) {
3582                         if (parm_table[*i].class == P_SEPARATOR)
3583                                 return &parm_table[(*i)++];
3584
3585                         if (parm_table[*i].class == P_LOCAL &&
3586                             parm_table[*i].ptr &&
3587                             (*parm_table[*i].label != '-') &&
3588                             ((*i) == 0 ||
3589                              (parm_table[*i].ptr !=
3590                               parm_table[(*i) - 1].ptr)))
3591                         {
3592                                 int pdiff =
3593                                         PTR_DIFF(parm_table[*i].ptr,
3594                                                  &sDefault);
3595
3596                                 if (allparameters ||
3597                                     !equal_parameter(parm_table[*i].type,
3598                                                      ((char *)pService) +
3599                                                      pdiff,
3600                                                      ((char *)&sDefault) +
3601                                                      pdiff))
3602                                 {
3603                                         return &parm_table[(*i)++];
3604                                 }
3605                         }
3606                 }
3607         }
3608
3609         return NULL;
3610 }
3611
3612
3613 #if 0
3614 /***************************************************************************
3615  Display the contents of a single copy structure.
3616 ***************************************************************************/
3617 static void dump_copy_map(BOOL *pcopymap)
3618 {
3619         int i;
3620         if (!pcopymap)
3621                 return;
3622
3623         printf("\n\tNon-Copied parameters:\n");
3624
3625         for (i = 0; parm_table[i].label; i++)
3626                 if (parm_table[i].class == P_LOCAL &&
3627                     parm_table[i].ptr && !pcopymap[i] &&
3628                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3629                 {
3630                         printf("\t\t%s\n", parm_table[i].label);
3631                 }
3632 }
3633 #endif
3634
3635 /***************************************************************************
3636  Return TRUE if the passed service number is within range.
3637 ***************************************************************************/
3638
3639 BOOL lp_snum_ok(int iService)
3640 {
3641         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3642 }
3643
3644 /***************************************************************************
3645  Auto-load some home services.
3646 ***************************************************************************/
3647
3648 static void lp_add_auto_services(char *str)
3649 {
3650         char *s;
3651         char *p;
3652         int homes;
3653
3654         if (!str)
3655                 return;
3656
3657         s = strdup(str);
3658         if (!s)
3659                 return;
3660
3661         homes = lp_servicenumber(HOMES_NAME);
3662
3663         for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
3664                 char *home = get_user_home_dir(p);
3665
3666                 if (lp_servicenumber(p) >= 0)
3667                         continue;
3668
3669                 if (home && homes >= 0)
3670                         lp_add_home(p, homes, p, home);
3671         }
3672         SAFE_FREE(s);
3673 }
3674
3675 /***************************************************************************
3676  Auto-load one printer.
3677 ***************************************************************************/
3678
3679 void lp_add_one_printer(char *name, char *comment)
3680 {
3681         int printers = lp_servicenumber(PRINTERS_NAME);
3682         int i;
3683
3684         if (lp_servicenumber(name) < 0) {
3685                 lp_add_printer(name, printers);
3686                 if ((i = lp_servicenumber(name)) >= 0) {
3687                         string_set(&ServicePtrs[i]->comment, comment);
3688                         ServicePtrs[i]->autoloaded = True;
3689                 }
3690         }
3691 }
3692
3693 /***************************************************************************
3694  Announce ourselves as a print server.
3695 ***************************************************************************/
3696
3697 void update_server_announce_as_printserver(void)
3698 {
3699         default_server_announce |= SV_TYPE_PRINTQ_SERVER;       
3700 }
3701
3702 /***************************************************************************
3703  Have we loaded a services file yet?
3704 ***************************************************************************/
3705
3706 BOOL lp_loaded(void)
3707 {
3708         return (bLoaded);
3709 }
3710
3711 /***************************************************************************
3712  Unload unused services.
3713 ***************************************************************************/
3714
3715 void lp_killunused(BOOL (*snumused) (int))
3716 {
3717         int i;
3718         for (i = 0; i < iNumServices; i++) {
3719                 if (!VALID(i))
3720                         continue;
3721
3722                 if (!snumused || !snumused(i)) {
3723                         ServicePtrs[i]->valid = False;
3724                         free_service(ServicePtrs[i]);
3725                 }
3726         }
3727 }
3728
3729 /***************************************************************************
3730  Unload a service.
3731 ***************************************************************************/
3732
3733 void lp_killservice(int iServiceIn)
3734 {
3735         if (VALID(iServiceIn)) {
3736                 ServicePtrs[iServiceIn]->valid = False;
3737                 free_service(ServicePtrs[iServiceIn]);
3738         }
3739 }
3740
3741 /***************************************************************************
3742  Save the curent values of all global and sDefault parameters into the 
3743  defaults union. This allows swat and testparm to show only the
3744  changed (ie. non-default) parameters.
3745 ***************************************************************************/
3746
3747 static void lp_save_defaults(void)
3748 {
3749         int i;
3750         for (i = 0; parm_table[i].label; i++) {
3751                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
3752                         continue;
3753                 switch (parm_table[i].type) {
3754                         case P_LIST:
3755                                 str_list_copy(&(parm_table[i].def.lvalue),
3756                                             *(const char ***)parm_table[i].ptr);
3757                                 break;
3758                         case P_STRING:
3759                         case P_USTRING:
3760                                 if (parm_table[i].ptr) {
3761                                         parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
3762                                 } else {
3763                                         parm_table[i].def.svalue = NULL;
3764                                 }
3765                                 break;
3766                         case P_GSTRING:
3767                         case P_UGSTRING:
3768                                 if (parm_table[i].ptr) {
3769                                         parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
3770                                 } else {
3771                                         parm_table[i].def.svalue = NULL;
3772                                 }
3773                                 break;
3774                         case P_BOOL:
3775                         case P_BOOLREV:
3776                                 parm_table[i].def.bvalue =
3777                                         *(BOOL *)parm_table[i].ptr;
3778                                 break;
3779                         case P_CHAR:
3780                                 parm_table[i].def.cvalue =
3781                                         *(char *)parm_table[i].ptr;
3782                                 break;
3783                         case P_INTEGER:
3784                         case P_OCTAL:
3785                         case P_ENUM:
3786                                 parm_table[i].def.ivalue =
3787                                         *(int *)parm_table[i].ptr;
3788                                 break;
3789                         case P_SEP:
3790                                 break;
3791                 }
3792         }
3793         defaults_saved = True;
3794 }
3795
3796 /*******************************************************************
3797  Set the server type we will announce as via nmbd.
3798 ********************************************************************/
3799
3800 static void set_server_role(void)
3801 {
3802         server_role = ROLE_STANDALONE;
3803
3804         switch (lp_security()) {
3805                 case SEC_SHARE:
3806                         if (lp_domain_logons())
3807                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
3808                         break;
3809                 case SEC_SERVER:
3810                         if (lp_domain_logons())
3811                                 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
3812                         server_role = ROLE_DOMAIN_MEMBER;
3813                         break;
3814                 case SEC_DOMAIN:
3815                         if (lp_domain_logons()) {
3816                                 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
3817                                 server_role = ROLE_DOMAIN_BDC;
3818                                 break;
3819                         }
3820                         server_role = ROLE_DOMAIN_MEMBER;
3821                         break;
3822                 case SEC_ADS:
3823                         if (lp_domain_logons()) {
3824                                 server_role = ROLE_DOMAIN_PDC;
3825                                 break;
3826                         }
3827                         server_role = ROLE_DOMAIN_MEMBER;
3828                         break;
3829                 case SEC_USER:
3830                         if (lp_domain_logons()) {
3831
3832                                 if (Globals.bDomainMaster) /* auto or yes */ 
3833                                         server_role = ROLE_DOMAIN_PDC;
3834                                 else
3835                                         server_role = ROLE_DOMAIN_BDC;
3836                         }
3837                         break;
3838                 default:
3839                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3840                         break;
3841         }
3842
3843         DEBUG(10, ("set_server_role: role = "));
3844
3845         switch(server_role) {
3846         case ROLE_STANDALONE:
3847                 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3848                 break;
3849         case ROLE_DOMAIN_MEMBER:
3850                 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3851                 break;
3852         case ROLE_DOMAIN_BDC:
3853                 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3854                 break;
3855         case ROLE_DOMAIN_PDC:
3856                 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3857                 break;
3858         }
3859 }
3860
3861 /***************************************************************************
3862  Load the services array from the services file. Return True on success, 
3863  False on failure.
3864 ***************************************************************************/
3865
3866 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3867              BOOL add_ipc)
3868 {
3869         pstring n2;
3870         BOOL bRetval;
3871         param_opt_struct *data, *pdata;
3872
3873         pstrcpy(n2, pszFname);
3874         standard_sub_basic(current_user_info.smb_name, n2,sizeof(n2));
3875
3876         add_to_file_list(pszFname, n2);
3877
3878         bRetval = False;
3879
3880         DEBUG(3, ("lp_load: refreshing parameters\n"));
3881         
3882         bInGlobalSection = True;
3883         bGlobalOnly = global_only;
3884
3885         init_globals();
3886         debug_init();
3887
3888         if (save_defaults)
3889         {
3890                 init_locals();
3891                 lp_save_defaults();
3892         }
3893
3894         if (Globals.param_opt != NULL) {
3895                 data = Globals.param_opt;
3896                 while (data) {
3897                         string_free(&data->key);
3898                         string_free(&data->value);
3899                         str_list_free(&data->list);
3900                         pdata = data->next;
3901                         SAFE_FREE(data);
3902                         data = pdata;
3903                 }
3904                 Globals.param_opt = NULL;
3905         }
3906         
3907         /* We get sections first, so have to start 'behind' to make up */
3908         iServiceIndex = -1;
3909         bRetval = pm_process(n2, do_section, do_parameter);
3910
3911         /* finish up the last section */
3912         DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3913         if (bRetval)
3914                 if (iServiceIndex >= 0)
3915                         bRetval = service_ok(iServiceIndex);
3916
3917         lp_add_auto_services(lp_auto_services());
3918
3919         if (add_ipc) {
3920                 /* When 'restrict anonymous = 2' guest connections to ipc$
3921                    are denied */
3922                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3923                 lp_add_ipc("ADMIN$", False);
3924         }
3925
3926         set_server_role();
3927         set_default_server_announce_type();
3928
3929         bLoaded = True;
3930
3931         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3932         /* if bWINSsupport is true and we are in the client            */
3933         if (in_client && Globals.bWINSsupport) {
3934                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
3935         }
3936
3937         init_iconv();
3938
3939         return (bRetval);
3940 }
3941
3942 /***************************************************************************
3943  Reset the max number of services.
3944 ***************************************************************************/
3945
3946 void lp_resetnumservices(void)
3947 {
3948         iNumServices = 0;
3949 }
3950
3951 /***************************************************************************
3952  Return the max number of services.
3953 ***************************************************************************/
3954
3955 int lp_numservices(void)
3956 {
3957         return (iNumServices);
3958 }
3959
3960 /***************************************************************************
3961 Display the contents of the services array in human-readable form.
3962 ***************************************************************************/
3963
3964 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3965 {
3966         int iService;
3967
3968         if (show_defaults)
3969                 defaults_saved = False;
3970
3971         dump_globals(f);
3972
3973         dump_a_service(&sDefault, f);
3974
3975         for (iService = 0; iService < maxtoprint; iService++)
3976                 lp_dump_one(f, show_defaults, iService);
3977 }
3978
3979 /***************************************************************************
3980 Display the contents of one service in human-readable form.
3981 ***************************************************************************/
3982
3983 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3984 {
3985         if (VALID(snum)) {
3986                 if (ServicePtrs[snum]->szService[0] == '\0')
3987                         return;
3988                 dump_a_service(ServicePtrs[snum], f);
3989         }
3990 }
3991
3992 /***************************************************************************
3993 Return the number of the service with the given name, or -1 if it doesn't
3994 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3995 getservicebyname()! This works ONLY if all services have been loaded, and
3996 does not copy the found service.
3997 ***************************************************************************/
3998
3999 int lp_servicenumber(const char *pszServiceName)
4000 {
4001         int iService;
4002         fstring serviceName;
4003         
4004         if (!pszServiceName)
4005                 return GLOBAL_SECTION_SNUM;
4006         
4007         for (iService = iNumServices - 1; iService >= 0; iService--) {
4008                 if (VALID(iService) && ServicePtrs[iService]->szService) {
4009                         /*
4010                          * The substitution here is used to support %U is
4011                          * service names
4012                          */
4013                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
4014                         standard_sub_basic(current_user_info.smb_name, serviceName,sizeof(serviceName));
4015                         if (strequal(serviceName, pszServiceName))
4016                                 break;
4017                 }
4018         }
4019
4020         if (iService < 0) {
4021                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4022                 return GLOBAL_SECTION_SNUM;
4023         }
4024
4025         return (iService);
4026 }
4027
4028 /*******************************************************************
4029  A useful volume label function. 
4030 ********************************************************************/
4031
4032 char *volume_label(int snum)
4033 {
4034         char *ret = lp_volume(snum);
4035         if (!*ret)
4036                 return lp_servicename(snum);
4037         return (ret);
4038 }
4039
4040
4041 /*******************************************************************
4042  Set the server type we will announce as via nmbd.
4043 ********************************************************************/
4044
4045 static void set_default_server_announce_type(void)
4046 {
4047         default_server_announce = 0;
4048         default_server_announce |= SV_TYPE_WORKSTATION;
4049         default_server_announce |= SV_TYPE_SERVER;
4050         default_server_announce |= SV_TYPE_SERVER_UNIX;
4051
4052         switch (lp_announce_as()) {
4053                 case ANNOUNCE_AS_NT_SERVER:
4054                         default_server_announce |= SV_TYPE_SERVER_NT;
4055                         /* fall through... */
4056                 case ANNOUNCE_AS_NT_WORKSTATION:
4057                         default_server_announce |= SV_TYPE_NT;
4058                         break;
4059                 case ANNOUNCE_AS_WIN95:
4060                         default_server_announce |= SV_TYPE_WIN95_PLUS;
4061                         break;
4062                 case ANNOUNCE_AS_WFW:
4063                         default_server_announce |= SV_TYPE_WFW;
4064                         break;
4065                 default:
4066                         break;
4067         }
4068
4069         switch (lp_server_role()) {
4070                 case ROLE_DOMAIN_MEMBER:
4071                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4072                         break;
4073                 case ROLE_DOMAIN_PDC:
4074                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4075                         break;
4076                 case ROLE_DOMAIN_BDC:
4077                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4078                         break;
4079                 case ROLE_STANDALONE:
4080                 default:
4081                         break;
4082         }
4083         if (lp_time_server())
4084                 default_server_announce |= SV_TYPE_TIME_SOURCE;
4085
4086         if (lp_host_msdfs())
4087                 default_server_announce |= SV_TYPE_DFS_SERVER;
4088 }
4089
4090 /***********************************************************
4091  returns role of Samba server
4092 ************************************************************/
4093
4094 int lp_server_role(void)
4095 {
4096         return server_role;
4097 }
4098
4099 /***********************************************************
4100  If we are PDC then prefer us as DMB
4101 ************************************************************/
4102
4103 BOOL lp_domain_master(void)
4104 {
4105         if (Globals.bDomainMaster == Auto)
4106                 return (lp_server_role() == ROLE_DOMAIN_PDC);
4107
4108         return Globals.bDomainMaster;
4109 }
4110
4111 /***********************************************************
4112  If we are DMB then prefer us as LMB
4113 ************************************************************/
4114
4115 BOOL lp_preferred_master(void)
4116 {
4117         if (Globals.bPreferredMaster == Auto)
4118                 return (lp_local_master() && lp_domain_master());
4119
4120         return Globals.bPreferredMaster;
4121 }
4122
4123 /*******************************************************************
4124  Remove a service.
4125 ********************************************************************/
4126
4127 void lp_remove_service(int snum)
4128 {
4129         ServicePtrs[snum]->valid = False;
4130 }
4131
4132 /*******************************************************************
4133  Copy a service.
4134 ********************************************************************/
4135
4136 void lp_copy_service(int snum, const char *new_name)
4137 {
4138         char *oldname = lp_servicename(snum);
4139         do_section(new_name);
4140         if (snum >= 0) {
4141                 snum = lp_servicenumber(new_name);
4142                 if (snum >= 0)
4143                         lp_do_parameter(snum, "copy", oldname);
4144         }
4145 }
4146
4147
4148 /*******************************************************************
4149  Get the default server type we will announce as via nmbd.
4150 ********************************************************************/
4151
4152 int lp_default_server_announce(void)
4153 {
4154         return default_server_announce;
4155 }
4156
4157 /*******************************************************************
4158  Split the announce version into major and minor numbers.
4159 ********************************************************************/
4160
4161 int lp_major_announce_version(void)
4162 {
4163         static BOOL got_major = False;
4164         static int major_version = DEFAULT_MAJOR_VERSION;
4165         char *vers;
4166         char *p;
4167
4168         if (got_major)
4169                 return major_version;
4170
4171         got_major = True;
4172         if ((vers = lp_announce_version()) == NULL)
4173                 return major_version;
4174
4175         if ((p = strchr_m(vers, '.')) == 0)
4176                 return major_version;
4177
4178         *p = '\0';
4179         major_version = atoi(vers);
4180         return major_version;
4181 }
4182
4183 int lp_minor_announce_version(void)
4184 {
4185         static BOOL got_minor = False;
4186         static int minor_version = DEFAULT_MINOR_VERSION;
4187         char *vers;
4188         char *p;
4189
4190         if (got_minor)
4191                 return minor_version;
4192
4193         got_minor = True;
4194         if ((vers = lp_announce_version()) == NULL)
4195                 return minor_version;
4196
4197         if ((p = strchr_m(vers, '.')) == 0)
4198                 return minor_version;
4199
4200         p++;
4201         minor_version = atoi(p);
4202         return minor_version;
4203 }
4204
4205 /***********************************************************
4206  Set the global name resolution order (used in smbclient).
4207 ************************************************************/
4208
4209 void lp_set_name_resolve_order(char *new_order)
4210 {
4211         Globals.szNameResolveOrder = new_order;
4212 }
4213
4214 const char *lp_printername(int snum)
4215 {
4216         const char *ret = _lp_printername(snum);
4217         if (ret == NULL || (ret != NULL && *ret == '\0'))
4218                 ret = lp_const_servicename(snum);
4219
4220         return ret;
4221 }
4222
4223
4224 /****************************************************************
4225  Compatibility fn. for 2.2.2 code.....
4226 *****************************************************************/
4227
4228 void get_private_directory(pstring privdir)
4229 {
4230         pstrcpy (privdir, lp_private_dir());
4231 }
4232
4233 /***********************************************************
4234  Allow daemons such as winbindd to fix their logfile name.
4235 ************************************************************/
4236
4237 void lp_set_logfile(const char *name)
4238 {
4239         extern pstring debugf;
4240         string_set(&Globals.szLogFile, name);
4241         pstrcpy(debugf, name);
4242 }
4243
4244 /*******************************************************************
4245  Return the NetBIOS called name.
4246 ********************************************************************/
4247
4248 const char *get_called_name(void)
4249 {
4250         extern fstring local_machine;
4251         static fstring called_name;
4252
4253         if (! *local_machine)
4254                 return global_myname();
4255
4256         /*
4257          * Windows NT/2k uses "*SMBSERVER" and XP uses "*SMBSERV"
4258          * arrggg!!! but we've already rewritten the client's
4259          * netbios name at this point...
4260          */
4261
4262         if (*local_machine) {
4263                 if (!StrCaseCmp(local_machine, "_SMBSERVER") || !StrCaseCmp(local_machine, "_SMBSERV")) {
4264                         fstrcpy(called_name, get_my_primary_ip());
4265                         DEBUG(8,("get_called_name: assuming that client used IP address [%s] as called name.\n",
4266                                 called_name));
4267                         return called_name;
4268                 }
4269         }
4270
4271         return local_machine;
4272 }
4273
4274 /*******************************************************************
4275  Return the max print jobs per queue.
4276 ********************************************************************/
4277
4278 int lp_maxprintjobs(int snum)
4279 {
4280         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4281         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4282                 maxjobs = PRINT_MAX_JOBID - 1;
4283
4284         return maxjobs;
4285 }