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