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