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