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