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