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