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