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