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