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