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