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