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