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