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