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