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