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