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