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