r5174: ensure that we consistently use the current_user_info.smb_name vs. smb_name...
[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|FLAG_DEPRECATED}, 
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(get_current_username(), s);
1588         if (trim_char(tmpstr, '\"', '\"')) {
1589                 if (strchr(tmpstr,'\"') != NULL) {
1590                         SAFE_FREE(tmpstr);
1591                         tmpstr = alloc_sub_basic(get_current_username(),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
2698         DEBUG(6, ("lp_file_list_changed()\n"));
2699
2700         while (f) {
2701                 pstring n2;
2702                 time_t mod_time;
2703
2704                 pstrcpy(n2, f->name);
2705                 standard_sub_basic( get_current_username(), n2, sizeof(n2) );
2706
2707                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
2708                              f->name, n2, ctime(&f->modtime)));
2709
2710                 mod_time = file_modtime(n2);
2711
2712                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2713                         DEBUGADD(6,
2714                                  ("file %s modified: %s\n", n2,
2715                                   ctime(&mod_time)));
2716                         f->modtime = mod_time;
2717                         SAFE_FREE(f->subfname);
2718                         f->subfname = SMB_STRDUP(n2);
2719                         return (True);
2720                 }
2721                 f = f->next;
2722         }
2723         return (False);
2724 }
2725
2726 /***************************************************************************
2727  Run standard_sub_basic on netbios name... needed because global_myname
2728  is not accessed through any lp_ macro.
2729  Note: We must *NOT* use string_set() here as ptr points to global_myname.
2730 ***************************************************************************/
2731
2732 static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
2733 {
2734         BOOL ret;
2735         pstring netbios_name;
2736
2737         pstrcpy(netbios_name, pszParmValue);
2738
2739         standard_sub_basic(get_current_username(), netbios_name,sizeof(netbios_name));
2740
2741         ret = set_global_myname(netbios_name);
2742         string_set(&Globals.szNetbiosName,global_myname());
2743         
2744         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
2745                global_myname()));
2746
2747         return ret;
2748 }
2749
2750 static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
2751 {
2752         if (strcmp(*ptr, pszParmValue) != 0) {
2753                 string_set(ptr, pszParmValue);
2754                 init_iconv();
2755         }
2756         return True;
2757 }
2758
2759 static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
2760 {
2761         BOOL ret;
2762         
2763         ret = set_global_myworkgroup(pszParmValue);
2764         string_set(&Globals.szWorkgroup,lp_workgroup());
2765         
2766         return ret;
2767 }
2768
2769 static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
2770 {
2771         BOOL ret;
2772         
2773         ret = set_global_scope(pszParmValue);
2774         string_set(&Globals.szNetbiosScope,global_scope());
2775
2776         return ret;
2777 }
2778
2779 static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
2780 {
2781         str_list_free(&Globals.szNetbiosAliases);
2782         Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
2783         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
2784 }
2785
2786 /***************************************************************************
2787  Handle the include operation.
2788 ***************************************************************************/
2789
2790 static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
2791 {
2792         pstring fname;
2793         pstrcpy(fname, pszParmValue);
2794
2795         standard_sub_basic(get_current_username(), fname,sizeof(fname));
2796
2797         add_to_file_list(pszParmValue, fname);
2798
2799         string_set(ptr, fname);
2800
2801         if (file_exist(fname, NULL))
2802                 return (pm_process(fname, do_section, do_parameter));
2803
2804         DEBUG(2, ("Can't find include file %s\n", fname));
2805
2806         return (False);
2807 }
2808
2809 /***************************************************************************
2810  Handle the interpretation of the copy parameter.
2811 ***************************************************************************/
2812
2813 static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
2814 {
2815         BOOL bRetval;
2816         int iTemp;
2817         service serviceTemp;
2818
2819         string_set(ptr, pszParmValue);
2820
2821         init_service(&serviceTemp);
2822
2823         bRetval = False;
2824
2825         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2826
2827         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2828                 if (iTemp == iServiceIndex) {
2829                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2830                 } else {
2831                         copy_service(ServicePtrs[iServiceIndex],
2832                                      &serviceTemp,
2833                                      ServicePtrs[iServiceIndex]->copymap);
2834                         bRetval = True;
2835                 }
2836         } else {
2837                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2838                 bRetval = False;
2839         }
2840
2841         free_service(&serviceTemp);
2842         return (bRetval);
2843 }
2844
2845 /***************************************************************************
2846  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
2847  parameters is:
2848
2849  [global]
2850
2851         idmap uid = 1000-1999
2852         idmap gid = 700-899
2853
2854  We only do simple parsing checks here.  The strings are parsed into useful
2855  structures in the idmap daemon code.
2856
2857 ***************************************************************************/
2858
2859 /* Some lp_ routines to return idmap [ug]id information */
2860
2861 static uid_t idmap_uid_low, idmap_uid_high;
2862 static gid_t idmap_gid_low, idmap_gid_high;
2863
2864 BOOL lp_idmap_uid(uid_t *low, uid_t *high)
2865 {
2866         if (idmap_uid_low == 0 || idmap_uid_high == 0)
2867                 return False;
2868
2869         if (low)
2870                 *low = idmap_uid_low;
2871
2872         if (high)
2873                 *high = idmap_uid_high;
2874
2875         return True;
2876 }
2877
2878 BOOL lp_idmap_gid(gid_t *low, gid_t *high)
2879 {
2880         if (idmap_gid_low == 0 || idmap_gid_high == 0)
2881                 return False;
2882
2883         if (low)
2884                 *low = idmap_gid_low;
2885
2886         if (high)
2887                 *high = idmap_gid_high;
2888
2889         return True;
2890 }
2891
2892 /* Do some simple checks on "idmap [ug]id" parameter values */
2893
2894 static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
2895 {
2896         uint32 low, high;
2897
2898         if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2899                 return False;
2900
2901         /* Parse OK */
2902
2903         string_set(ptr, pszParmValue);
2904
2905         idmap_uid_low = low;
2906         idmap_uid_high = high;
2907
2908         return True;
2909 }
2910
2911 static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
2912 {
2913         uint32 low, high;
2914
2915         if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2916                 return False;
2917
2918         /* Parse OK */
2919
2920         string_set(ptr, pszParmValue);
2921
2922         idmap_gid_low = low;
2923         idmap_gid_high = high;
2924
2925         return True;
2926 }
2927
2928 /***************************************************************************
2929  Handle the DEBUG level list.
2930 ***************************************************************************/
2931
2932 static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
2933 {
2934         pstring pszParmValue;
2935
2936         pstrcpy(pszParmValue, pszParmValueIn);
2937         string_set(ptr, pszParmValueIn);
2938         return debug_parse_levels( pszParmValue );
2939 }
2940
2941 /***************************************************************************
2942  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2943 ***************************************************************************/
2944
2945 static char* append_ldap_suffix( const char *str )
2946 {
2947         char *suffix_string;
2948
2949
2950         if (!lp_talloc)
2951                 lp_talloc = talloc_init("lp_talloc");
2952
2953         suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
2954         if ( !suffix_string ) {
2955                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2956                 return NULL;
2957         }
2958
2959         return suffix_string;
2960 }
2961
2962 char *lp_ldap_machine_suffix(void)
2963 {
2964         if (Globals.szLdapMachineSuffix[0])
2965                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
2966
2967         return lp_string(Globals.szLdapSuffix);
2968 }
2969
2970 char *lp_ldap_user_suffix(void)
2971 {
2972         if (Globals.szLdapUserSuffix[0])
2973                 return append_ldap_suffix(Globals.szLdapUserSuffix);
2974
2975         return lp_string(Globals.szLdapSuffix);
2976 }
2977
2978 char *lp_ldap_group_suffix(void)
2979 {
2980         if (Globals.szLdapGroupSuffix[0])
2981                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
2982
2983         return lp_string(Globals.szLdapSuffix);
2984 }
2985
2986 char *lp_ldap_idmap_suffix(void)
2987 {
2988         if (Globals.szLdapIdmapSuffix[0])
2989                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
2990
2991         return lp_string(Globals.szLdapSuffix);
2992 }
2993
2994 /***************************************************************************
2995 ***************************************************************************/
2996
2997 static BOOL handle_acl_compatibility(int snum, const char *pszParmValue, char **ptr)
2998 {
2999         if (strequal(pszParmValue, "auto"))
3000                 string_set(ptr, "");
3001         else if (strequal(pszParmValue, "winnt"))
3002                 string_set(ptr, "winnt");
3003         else if (strequal(pszParmValue, "win2k"))
3004                 string_set(ptr, "win2k");
3005         else
3006                 return False;
3007
3008         return True;
3009 }
3010
3011 /****************************************************************************
3012  set the value for a P_ENUM
3013  ***************************************************************************/
3014
3015 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3016                               int *ptr )
3017 {
3018         int i;
3019
3020         for (i = 0; parm->enum_list[i].name; i++) {
3021                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3022                         *ptr = parm->enum_list[i].value;
3023                         break;
3024                 }
3025         }
3026 }
3027
3028 /***************************************************************************
3029 ***************************************************************************/
3030
3031 static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
3032 {
3033         static int parm_num = -1;
3034         service *s;
3035
3036         if ( parm_num == -1 )
3037                 parm_num = map_parameter( "printing" );
3038
3039         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3040
3041         if ( snum < 0 )
3042                 s = &sDefault;
3043         else
3044                 s = ServicePtrs[snum];
3045
3046         init_printer_values( s );
3047
3048         return True;
3049 }
3050
3051
3052 /***************************************************************************
3053  Initialise a copymap.
3054 ***************************************************************************/
3055
3056 static void init_copymap(service * pservice)
3057 {
3058         int i;
3059         SAFE_FREE(pservice->copymap);
3060         pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
3061         if (!pservice->copymap)
3062                 DEBUG(0,
3063                       ("Couldn't allocate copymap!! (size %d)\n",
3064                        (int)NUMPARAMETERS));
3065         else
3066                 for (i = 0; i < NUMPARAMETERS; i++)
3067                         pservice->copymap[i] = True;
3068 }
3069
3070 /***************************************************************************
3071  Return the local pointer to a parameter given the service number and the 
3072  pointer into the default structure.
3073 ***************************************************************************/
3074
3075 void *lp_local_ptr(int snum, void *ptr)
3076 {
3077         return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3078 }
3079
3080 /***************************************************************************
3081  Process a parameter for a particular service number. If snum < 0
3082  then assume we are in the globals.
3083 ***************************************************************************/
3084
3085 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3086 {
3087         int parmnum, i, slen;
3088         void *parm_ptr = NULL;  /* where we are going to store the result */
3089         void *def_ptr = NULL;
3090         pstring param_key;
3091         char *sep;
3092         param_opt_struct *paramo, *data;
3093         BOOL not_added;
3094
3095         parmnum = map_parameter(pszParmName);
3096
3097         if (parmnum < 0) {
3098                 if ((sep=strchr(pszParmName, ':')) != NULL) {
3099                         *sep = '\0';
3100                         ZERO_STRUCT(param_key);
3101                         pstr_sprintf(param_key, "%s:", pszParmName);
3102                         slen = strlen(param_key);
3103                         pstrcat(param_key, sep+1);
3104                         trim_char(param_key+slen, ' ', ' ');
3105                         not_added = True;
3106                         data = (snum < 0) ? Globals.param_opt : 
3107                                 ServicePtrs[snum]->param_opt;
3108                         /* Traverse destination */
3109                         while (data) {
3110                                 /* If we already have same option, override it */
3111                                 if (strcmp(data->key, param_key) == 0) {
3112                                         string_free(&data->value);
3113                                         str_list_free(&data->list);
3114                                         data->value = SMB_STRDUP(pszParmValue);
3115                                         not_added = False;
3116                                         break;
3117                                 }
3118                                 data = data->next;
3119                         }
3120                         if (not_added) {
3121                                 paramo = SMB_XMALLOC_P(param_opt_struct);
3122                                 paramo->key = SMB_STRDUP(param_key);
3123                                 paramo->value = SMB_STRDUP(pszParmValue);
3124                                 paramo->list = NULL;
3125                                 if (snum < 0) {
3126                                         DLIST_ADD(Globals.param_opt, paramo);
3127                                 } else {
3128                                         DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3129                                 }
3130                         }
3131
3132                         *sep = ':';
3133                         return (True);
3134                 }
3135                 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3136                 return (True);
3137         }
3138
3139         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3140                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3141                           pszParmName));
3142         }
3143
3144         def_ptr = parm_table[parmnum].ptr;
3145
3146         /* we might point at a service, the default service or a global */
3147         if (snum < 0) {
3148                 parm_ptr = def_ptr;
3149         } else {
3150                 if (parm_table[parmnum].class == P_GLOBAL) {
3151                         DEBUG(0,
3152                               ("Global parameter %s found in service section!\n",
3153                                pszParmName));
3154                         return (True);
3155                 }
3156                 parm_ptr =
3157                         ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3158                                                             &sDefault);
3159         }
3160
3161         if (snum >= 0) {
3162                 if (!ServicePtrs[snum]->copymap)
3163                         init_copymap(ServicePtrs[snum]);
3164
3165                 /* this handles the aliases - set the copymap for other entries with
3166                    the same data pointer */
3167                 for (i = 0; parm_table[i].label; i++)
3168                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
3169                                 ServicePtrs[snum]->copymap[i] = False;
3170         }
3171
3172         /* if it is a special case then go ahead */
3173         if (parm_table[parmnum].special) {
3174                 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
3175                 return (True);
3176         }
3177
3178         /* now switch on the type of variable it is */
3179         switch (parm_table[parmnum].type)
3180         {
3181                 case P_BOOL:
3182                         set_boolean(parm_ptr, pszParmValue);
3183                         break;
3184
3185                 case P_BOOLREV:
3186                         set_boolean(parm_ptr, pszParmValue);
3187                         *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
3188                         break;
3189
3190                 case P_INTEGER:
3191                         *(int *)parm_ptr = atoi(pszParmValue);
3192                         break;
3193
3194                 case P_CHAR:
3195                         *(char *)parm_ptr = *pszParmValue;
3196                         break;
3197
3198                 case P_OCTAL:
3199                         sscanf(pszParmValue, "%o", (int *)parm_ptr);
3200                         break;
3201
3202                 case P_LIST:
3203                         str_list_free(parm_ptr);
3204                         *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3205                         break;
3206
3207                 case P_STRING:
3208                         string_set(parm_ptr, pszParmValue);
3209                         break;
3210
3211                 case P_USTRING:
3212                         string_set(parm_ptr, pszParmValue);
3213                         strupper_m(*(char **)parm_ptr);
3214                         break;
3215
3216                 case P_GSTRING:
3217                         pstrcpy((char *)parm_ptr, pszParmValue);
3218                         break;
3219
3220                 case P_UGSTRING:
3221                         pstrcpy((char *)parm_ptr, pszParmValue);
3222                         strupper_m((char *)parm_ptr);
3223                         break;
3224
3225                 case P_ENUM:
3226                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3227                         break;
3228                 case P_SEP:
3229                         break;
3230         }
3231
3232         return (True);
3233 }
3234
3235 /***************************************************************************
3236  Process a parameter.
3237 ***************************************************************************/
3238
3239 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3240 {
3241         if (!bInGlobalSection && bGlobalOnly)
3242                 return (True);
3243
3244         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3245
3246         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3247                                 pszParmName, pszParmValue));
3248 }
3249
3250 /***************************************************************************
3251  Print a parameter of the specified type.
3252 ***************************************************************************/
3253
3254 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3255 {
3256         int i;
3257         switch (p->type)
3258         {
3259                 case P_ENUM:
3260                         for (i = 0; p->enum_list[i].name; i++) {
3261                                 if (*(int *)ptr == p->enum_list[i].value) {
3262                                         fprintf(f, "%s",
3263                                                 p->enum_list[i].name);
3264                                         break;
3265                                 }
3266                         }
3267                         break;
3268
3269                 case P_BOOL:
3270                         fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3271                         break;
3272
3273                 case P_BOOLREV:
3274                         fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3275                         break;
3276
3277                 case P_INTEGER:
3278                         fprintf(f, "%d", *(int *)ptr);
3279                         break;
3280
3281                 case P_CHAR:
3282                         fprintf(f, "%c", *(char *)ptr);
3283                         break;
3284
3285                 case P_OCTAL:
3286                         fprintf(f, "%s", octal_string(*(int *)ptr));
3287                         break;
3288
3289                 case P_LIST:
3290                         if ((char ***)ptr && *(char ***)ptr) {
3291                                 char **list = *(char ***)ptr;
3292                                 
3293                                 for (; *list; list++) {
3294                                         /* surround strings with whitespace in double quotes */
3295                                         if ( strchr_m( *list, ' ' ) )
3296                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
3297                                         else
3298                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
3299                                 }
3300                         }
3301                         break;
3302
3303                 case P_GSTRING:
3304                 case P_UGSTRING:
3305                         if ((char *)ptr) {
3306                                 fprintf(f, "%s", (char *)ptr);
3307                         }
3308                         break;
3309
3310                 case P_STRING:
3311                 case P_USTRING:
3312                         if (*(char **)ptr) {
3313                                 fprintf(f, "%s", *(char **)ptr);
3314                         }
3315                         break;
3316                 case P_SEP:
3317                         break;
3318         }
3319 }
3320
3321 /***************************************************************************
3322  Check if two parameters are equal.
3323 ***************************************************************************/
3324
3325 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3326 {
3327         switch (type) {
3328                 case P_BOOL:
3329                 case P_BOOLREV:
3330                         return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3331
3332                 case P_INTEGER:
3333                 case P_ENUM:
3334                 case P_OCTAL:
3335                         return (*((int *)ptr1) == *((int *)ptr2));
3336
3337                 case P_CHAR:
3338                         return (*((char *)ptr1) == *((char *)ptr2));
3339                 
3340                 case P_LIST:
3341                         return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3342
3343                 case P_GSTRING:
3344                 case P_UGSTRING:
3345                 {
3346                         char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3347                         if (p1 && !*p1)
3348                                 p1 = NULL;
3349                         if (p2 && !*p2)
3350                                 p2 = NULL;
3351                         return (p1 == p2 || strequal(p1, p2));
3352                 }
3353                 case P_STRING:
3354                 case P_USTRING:
3355                 {
3356                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3357                         if (p1 && !*p1)
3358                                 p1 = NULL;
3359                         if (p2 && !*p2)
3360                                 p2 = NULL;
3361                         return (p1 == p2 || strequal(p1, p2));
3362                 }
3363                 case P_SEP:
3364                         break;
3365         }
3366         return (False);
3367 }
3368
3369 /***************************************************************************
3370  Initialize any local varients in the sDefault table.
3371 ***************************************************************************/
3372
3373 void init_locals(void)
3374 {
3375         /* None as yet. */
3376 }
3377
3378 /***************************************************************************
3379  Process a new section (service). At this stage all sections are services.
3380  Later we'll have special sections that permit server parameters to be set.
3381  Returns True on success, False on failure. 
3382 ***************************************************************************/
3383
3384 static BOOL do_section(const char *pszSectionName)
3385 {
3386         BOOL bRetval;
3387         BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3388                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3389         bRetval = False;
3390
3391         /* if we were in a global section then do the local inits */
3392         if (bInGlobalSection && !isglobal)
3393                 init_locals();
3394
3395         /* if we've just struck a global section, note the fact. */
3396         bInGlobalSection = isglobal;
3397
3398         /* check for multiple global sections */
3399         if (bInGlobalSection) {
3400                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3401                 return (True);
3402         }
3403
3404         if (!bInGlobalSection && bGlobalOnly)
3405                 return (True);
3406
3407         /* if we have a current service, tidy it up before moving on */
3408         bRetval = True;
3409
3410         if (iServiceIndex >= 0)
3411                 bRetval = service_ok(iServiceIndex);
3412
3413         /* if all is still well, move to the next record in the services array */
3414         if (bRetval) {
3415                 /* We put this here to avoid an odd message order if messages are */
3416                 /* issued by the post-processing of a previous section. */
3417                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3418
3419                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3420                     < 0) {
3421                         DEBUG(0, ("Failed to add a new service\n"));
3422                         return (False);
3423                 }
3424         }
3425
3426         return (bRetval);
3427 }
3428
3429
3430 /***************************************************************************
3431  Determine if a partcular base parameter is currentl set to the default value.
3432 ***************************************************************************/
3433
3434 static BOOL is_default(int i)
3435 {
3436         if (!defaults_saved)
3437                 return False;
3438         switch (parm_table[i].type) {
3439                 case P_LIST:
3440                         return str_list_compare (parm_table[i].def.lvalue, 
3441                                                 *(char ***)parm_table[i].ptr);
3442                 case P_STRING:
3443                 case P_USTRING:
3444                         return strequal(parm_table[i].def.svalue,
3445                                         *(char **)parm_table[i].ptr);
3446                 case P_GSTRING:
3447                 case P_UGSTRING:
3448                         return strequal(parm_table[i].def.svalue,
3449                                         (char *)parm_table[i].ptr);
3450                 case P_BOOL:
3451                 case P_BOOLREV:
3452                         return parm_table[i].def.bvalue ==
3453                                 *(BOOL *)parm_table[i].ptr;
3454                 case P_CHAR:
3455                         return parm_table[i].def.cvalue ==
3456                                 *(char *)parm_table[i].ptr;
3457                 case P_INTEGER:
3458                 case P_OCTAL:
3459                 case P_ENUM:
3460                         return parm_table[i].def.ivalue ==
3461                                 *(int *)parm_table[i].ptr;
3462                 case P_SEP:
3463                         break;
3464         }
3465         return False;
3466 }
3467
3468 /***************************************************************************
3469 Display the contents of the global structure.
3470 ***************************************************************************/
3471
3472 static void dump_globals(FILE *f)
3473 {
3474         int i;
3475         param_opt_struct *data;
3476         
3477         fprintf(f, "# Global parameters\n[global]\n");
3478
3479         for (i = 0; parm_table[i].label; i++)
3480                 if (parm_table[i].class == P_GLOBAL &&
3481                     parm_table[i].ptr &&
3482                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3483                         if (defaults_saved && is_default(i))
3484                                 continue;
3485                         fprintf(f, "\t%s = ", parm_table[i].label);
3486                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
3487                         fprintf(f, "\n");
3488         }
3489         if (Globals.param_opt != NULL) {
3490                 data = Globals.param_opt;
3491                 while(data) {
3492                         fprintf(f, "\t%s = %s\n", data->key, data->value);
3493                         data = data->next;
3494                 }
3495         }
3496
3497 }
3498
3499 /***************************************************************************
3500  Return True if a local parameter is currently set to the global default.
3501 ***************************************************************************/
3502
3503 BOOL lp_is_default(int snum, struct parm_struct *parm)
3504 {
3505         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3506
3507         return equal_parameter(parm->type,
3508                                ((char *)ServicePtrs[snum]) + pdiff,
3509                                ((char *)&sDefault) + pdiff);
3510 }
3511
3512 /***************************************************************************
3513  Display the contents of a single services record.
3514 ***************************************************************************/
3515
3516 static void dump_a_service(service * pService, FILE * f)
3517 {
3518         int i;
3519         param_opt_struct *data;
3520         
3521         if (pService != &sDefault)
3522                 fprintf(f, "\n[%s]\n", pService->szService);
3523
3524         for (i = 0; parm_table[i].label; i++) {
3525
3526                 if (parm_table[i].class == P_LOCAL &&
3527                     parm_table[i].ptr &&
3528                     (*parm_table[i].label != '-') &&
3529                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
3530                 {
3531                 
3532                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3533
3534                         if (pService == &sDefault) {
3535                                 if (defaults_saved && is_default(i))
3536                                         continue;
3537                         } else {
3538                                 if (equal_parameter(parm_table[i].type,
3539                                                     ((char *)pService) +
3540                                                     pdiff,
3541                                                     ((char *)&sDefault) +
3542                                                     pdiff))
3543                                         continue;
3544                         }
3545
3546                         fprintf(f, "\t%s = ", parm_table[i].label);
3547                         print_parameter(&parm_table[i],
3548                                         ((char *)pService) + pdiff, f);
3549                         fprintf(f, "\n");
3550                 }
3551         }
3552
3553         if (pService->param_opt != NULL) {
3554                 data = pService->param_opt;
3555                 while(data) {
3556                         fprintf(f, "\t%s = %s\n", data->key, data->value);
3557                         data = data->next;
3558                 }
3559         }
3560 }
3561
3562
3563 /***************************************************************************
3564  Return info about the next service  in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
3565  Return NULL when out of parameters.
3566 ***************************************************************************/
3567
3568 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
3569 {
3570         if (snum < 0) {
3571                 /* do the globals */
3572                 for (; parm_table[*i].label; (*i)++) {
3573                         if (parm_table[*i].class == P_SEPARATOR)
3574                                 return &parm_table[(*i)++];
3575
3576                         if (!parm_table[*i].ptr
3577                             || (*parm_table[*i].label == '-'))
3578                                 continue;
3579
3580                         if ((*i) > 0
3581                             && (parm_table[*i].ptr ==
3582                                 parm_table[(*i) - 1].ptr))
3583                                 continue;
3584
3585                         return &parm_table[(*i)++];
3586                 }
3587         } else {
3588                 service *pService = ServicePtrs[snum];
3589
3590                 for (; parm_table[*i].label; (*i)++) {
3591                         if (parm_table[*i].class == P_SEPARATOR)
3592                                 return &parm_table[(*i)++];
3593
3594                         if (parm_table[*i].class == P_LOCAL &&
3595                             parm_table[*i].ptr &&
3596                             (*parm_table[*i].label != '-') &&
3597                             ((*i) == 0 ||
3598                              (parm_table[*i].ptr !=
3599                               parm_table[(*i) - 1].ptr)))
3600                         {
3601                                 int pdiff =
3602                                         PTR_DIFF(parm_table[*i].ptr,
3603                                                  &sDefault);
3604
3605                                 if (allparameters ||
3606                                     !equal_parameter(parm_table[*i].type,
3607                                                      ((char *)pService) +
3608                                                      pdiff,
3609                                                      ((char *)&sDefault) +
3610                                                      pdiff))
3611                                 {
3612                                         return &parm_table[(*i)++];
3613                                 }
3614                         }
3615                 }
3616         }
3617
3618         return NULL;
3619 }
3620
3621
3622 #if 0
3623 /***************************************************************************
3624  Display the contents of a single copy structure.
3625 ***************************************************************************/
3626 static void dump_copy_map(BOOL *pcopymap)
3627 {
3628         int i;
3629         if (!pcopymap)
3630                 return;
3631
3632         printf("\n\tNon-Copied parameters:\n");
3633
3634         for (i = 0; parm_table[i].label; i++)
3635                 if (parm_table[i].class == P_LOCAL &&
3636                     parm_table[i].ptr && !pcopymap[i] &&
3637                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3638                 {
3639                         printf("\t\t%s\n", parm_table[i].label);
3640                 }
3641 }
3642 #endif
3643
3644 /***************************************************************************
3645  Return TRUE if the passed service number is within range.
3646 ***************************************************************************/
3647
3648 BOOL lp_snum_ok(int iService)
3649 {
3650         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3651 }
3652
3653 /***************************************************************************
3654  Auto-load some home services.
3655 ***************************************************************************/
3656
3657 static void lp_add_auto_services(char *str)
3658 {
3659         char *s;
3660         char *p;
3661         int homes;
3662
3663         if (!str)
3664                 return;
3665
3666         s = SMB_STRDUP(str);
3667         if (!s)
3668                 return;
3669
3670         homes = lp_servicenumber(HOMES_NAME);
3671
3672         for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
3673                 char *home = get_user_home_dir(p);
3674
3675                 if (lp_servicenumber(p) >= 0)
3676                         continue;
3677
3678                 if (home && homes >= 0)
3679                         lp_add_home(p, homes, p, home);
3680         }
3681         SAFE_FREE(s);
3682 }
3683
3684 /***************************************************************************
3685  Auto-load one printer.
3686 ***************************************************************************/
3687
3688 void lp_add_one_printer(char *name, char *comment)
3689 {
3690         int printers = lp_servicenumber(PRINTERS_NAME);
3691         int i;
3692
3693         if (lp_servicenumber(name) < 0) {
3694                 lp_add_printer(name, printers);
3695                 if ((i = lp_servicenumber(name)) >= 0) {
3696                         string_set(&ServicePtrs[i]->comment, comment);
3697                         ServicePtrs[i]->autoloaded = True;
3698                 }
3699         }
3700 }
3701
3702 /***************************************************************************
3703  Have we loaded a services file yet?
3704 ***************************************************************************/
3705
3706 BOOL lp_loaded(void)
3707 {
3708         return (bLoaded);
3709 }
3710
3711 /***************************************************************************
3712  Unload unused services.
3713 ***************************************************************************/
3714
3715 void lp_killunused(BOOL (*snumused) (int))
3716 {
3717         int i;
3718         for (i = 0; i < iNumServices; i++) {
3719                 if (!VALID(i))
3720                         continue;
3721
3722                 /* don't kill autoloaded services */
3723                 if ( ServicePtrs[i]->autoloaded )
3724                         continue;
3725
3726                 if (!snumused || !snumused(i)) {
3727                         ServicePtrs[i]->valid = False;
3728                         free_service(ServicePtrs[i]);
3729                 }
3730         }
3731 }
3732
3733 /***************************************************************************
3734  Unload a service.
3735 ***************************************************************************/
3736
3737 void lp_killservice(int iServiceIn)
3738 {
3739         if (VALID(iServiceIn)) {
3740                 ServicePtrs[iServiceIn]->valid = False;
3741                 free_service(ServicePtrs[iServiceIn]);
3742         }
3743 }
3744
3745 /***************************************************************************
3746  Save the curent values of all global and sDefault parameters into the 
3747  defaults union. This allows swat and testparm to show only the
3748  changed (ie. non-default) parameters.
3749 ***************************************************************************/
3750
3751 static void lp_save_defaults(void)
3752 {
3753         int i;
3754         for (i = 0; parm_table[i].label; i++) {
3755                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
3756                         continue;
3757                 switch (parm_table[i].type) {
3758                         case P_LIST:
3759                                 str_list_copy(&(parm_table[i].def.lvalue),
3760                                             *(const char ***)parm_table[i].ptr);
3761                                 break;
3762                         case P_STRING:
3763                         case P_USTRING:
3764                                 if (parm_table[i].ptr) {
3765                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
3766                                 } else {
3767                                         parm_table[i].def.svalue = NULL;
3768                                 }
3769                                 break;
3770                         case P_GSTRING:
3771                         case P_UGSTRING:
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_BOOL:
3779                         case P_BOOLREV:
3780                                 parm_table[i].def.bvalue =
3781                                         *(BOOL *)parm_table[i].ptr;
3782                                 break;
3783                         case P_CHAR:
3784                                 parm_table[i].def.cvalue =
3785                                         *(char *)parm_table[i].ptr;
3786                                 break;
3787                         case P_INTEGER:
3788                         case P_OCTAL:
3789                         case P_ENUM:
3790                                 parm_table[i].def.ivalue =
3791                                         *(int *)parm_table[i].ptr;
3792                                 break;
3793                         case P_SEP:
3794                                 break;
3795                 }
3796         }
3797         defaults_saved = True;
3798 }
3799
3800 /*******************************************************************
3801  Set the server type we will announce as via nmbd.
3802 ********************************************************************/
3803
3804 static void set_server_role(void)
3805 {
3806         server_role = ROLE_STANDALONE;
3807
3808         switch (lp_security()) {
3809                 case SEC_SHARE:
3810                         if (lp_domain_logons())
3811                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
3812                         break;
3813                 case SEC_SERVER:
3814                         if (lp_domain_logons())
3815                                 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
3816                         server_role = ROLE_DOMAIN_MEMBER;
3817                         break;
3818                 case SEC_DOMAIN:
3819                         if (lp_domain_logons()) {
3820                                 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
3821                                 server_role = ROLE_DOMAIN_BDC;
3822                                 break;
3823                         }
3824                         server_role = ROLE_DOMAIN_MEMBER;
3825                         break;
3826                 case SEC_ADS:
3827                         if (lp_domain_logons()) {
3828                                 server_role = ROLE_DOMAIN_PDC;
3829                                 break;
3830                         }
3831                         server_role = ROLE_DOMAIN_MEMBER;
3832                         break;
3833                 case SEC_USER:
3834                         if (lp_domain_logons()) {
3835
3836                                 if (Globals.bDomainMaster) /* auto or yes */ 
3837                                         server_role = ROLE_DOMAIN_PDC;
3838                                 else
3839                                         server_role = ROLE_DOMAIN_BDC;
3840                         }
3841                         break;
3842                 default:
3843                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3844                         break;
3845         }
3846
3847         DEBUG(10, ("set_server_role: role = "));
3848
3849         switch(server_role) {
3850         case ROLE_STANDALONE:
3851                 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3852                 break;
3853         case ROLE_DOMAIN_MEMBER:
3854                 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3855                 break;
3856         case ROLE_DOMAIN_BDC:
3857                 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3858                 break;
3859         case ROLE_DOMAIN_PDC:
3860                 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3861                 break;
3862         }
3863 }
3864
3865 /***********************************************************
3866  If we should send plaintext/LANMAN passwords in the clinet
3867 ************************************************************/
3868 static void set_allowed_client_auth(void)
3869 {
3870         if (Globals.bClientNTLMv2Auth) {
3871                 Globals.bClientLanManAuth = False;
3872         }
3873         if (!Globals.bClientLanManAuth) {
3874                 Globals.bClientPlaintextAuth = False;
3875         }
3876 }
3877
3878 /***************************************************************************
3879  Load the services array from the services file. Return True on success, 
3880  False on failure.
3881 ***************************************************************************/
3882
3883 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3884              BOOL add_ipc)
3885 {
3886         pstring n2;
3887         BOOL bRetval;
3888         param_opt_struct *data, *pdata;
3889
3890         pstrcpy(n2, pszFname);
3891         
3892         standard_sub_basic( get_current_username(), n2,sizeof(n2) );
3893
3894         add_to_file_list(pszFname, n2);
3895
3896         bRetval = False;
3897
3898         DEBUG(3, ("lp_load: refreshing parameters\n"));
3899         
3900         bInGlobalSection = True;
3901         bGlobalOnly = global_only;
3902
3903         init_globals();
3904         debug_init();
3905
3906         if (save_defaults) {
3907                 init_locals();
3908                 lp_save_defaults();
3909         }
3910
3911         if (Globals.param_opt != NULL) {
3912                 data = Globals.param_opt;
3913                 while (data) {
3914                         string_free(&data->key);
3915                         string_free(&data->value);
3916                         str_list_free(&data->list);
3917                         pdata = data->next;
3918                         SAFE_FREE(data);
3919                         data = pdata;
3920                 }
3921                 Globals.param_opt = NULL;
3922         }
3923         
3924         /* We get sections first, so have to start 'behind' to make up */
3925         iServiceIndex = -1;
3926         bRetval = pm_process(n2, do_section, do_parameter);
3927
3928         /* finish up the last section */
3929         DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3930         if (bRetval)
3931                 if (iServiceIndex >= 0)
3932                         bRetval = service_ok(iServiceIndex);
3933
3934         lp_add_auto_services(lp_auto_services());
3935
3936         if (add_ipc) {
3937                 /* When 'restrict anonymous = 2' guest connections to ipc$
3938                    are denied */
3939                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3940                 lp_add_ipc("ADMIN$", False);
3941         }
3942
3943         set_server_role();
3944         set_default_server_announce_type();
3945         set_allowed_client_auth();
3946
3947         bLoaded = True;
3948
3949         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3950         /* if bWINSsupport is true and we are in the client            */
3951         if (in_client && Globals.bWINSsupport) {
3952                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
3953         }
3954
3955         init_iconv();
3956
3957         return (bRetval);
3958 }
3959
3960 /***************************************************************************
3961  Reset the max number of services.
3962 ***************************************************************************/
3963
3964 void lp_resetnumservices(void)
3965 {
3966         iNumServices = 0;
3967 }
3968
3969 /***************************************************************************
3970  Return the max number of services.
3971 ***************************************************************************/
3972
3973 int lp_numservices(void)
3974 {
3975         return (iNumServices);
3976 }
3977
3978 /***************************************************************************
3979 Display the contents of the services array in human-readable form.
3980 ***************************************************************************/
3981
3982 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3983 {
3984         int iService;
3985
3986         if (show_defaults)
3987                 defaults_saved = False;
3988
3989         dump_globals(f);
3990
3991         dump_a_service(&sDefault, f);
3992
3993         for (iService = 0; iService < maxtoprint; iService++)
3994                 lp_dump_one(f, show_defaults, iService);
3995 }
3996
3997 /***************************************************************************
3998 Display the contents of one service in human-readable form.
3999 ***************************************************************************/
4000
4001 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
4002 {
4003         if (VALID(snum)) {
4004                 if (ServicePtrs[snum]->szService[0] == '\0')
4005                         return;
4006                 dump_a_service(ServicePtrs[snum], f);
4007         }
4008 }
4009
4010 /***************************************************************************
4011 Return the number of the service with the given name, or -1 if it doesn't
4012 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4013 getservicebyname()! This works ONLY if all services have been loaded, and
4014 does not copy the found service.
4015 ***************************************************************************/
4016
4017 int lp_servicenumber(const char *pszServiceName)
4018 {
4019         int iService;
4020         fstring serviceName;
4021         
4022         if (!pszServiceName)
4023                 return GLOBAL_SECTION_SNUM;
4024         
4025         for (iService = iNumServices - 1; iService >= 0; iService--) {
4026                 if (VALID(iService) && ServicePtrs[iService]->szService) {
4027                         /*
4028                          * The substitution here is used to support %U is
4029                          * service names
4030                          */
4031                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
4032                         standard_sub_basic(get_current_username(), serviceName,sizeof(serviceName));
4033                         if (strequal(serviceName, pszServiceName))
4034                                 break;
4035                 }
4036         }
4037
4038         if (iService < 0) {
4039                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4040                 return GLOBAL_SECTION_SNUM;
4041         }
4042
4043         return (iService);
4044 }
4045
4046 /*******************************************************************
4047  A useful volume label function. 
4048 ********************************************************************/
4049
4050 char *volume_label(int snum)
4051 {
4052         char *ret = lp_volume(snum);
4053         if (!*ret)
4054                 return lp_servicename(snum);
4055         return (ret);
4056 }
4057
4058
4059 /*******************************************************************
4060  Set the server type we will announce as via nmbd.
4061 ********************************************************************/
4062
4063 static void set_default_server_announce_type(void)
4064 {
4065         default_server_announce = 0;
4066         default_server_announce |= SV_TYPE_WORKSTATION;
4067         default_server_announce |= SV_TYPE_SERVER;
4068         default_server_announce |= SV_TYPE_SERVER_UNIX;
4069
4070         /* note that the flag should be set only if we have a 
4071            printer service but nmbd doesn't actually load the 
4072            services so we can't tell   --jerry */
4073
4074         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4075
4076         switch (lp_announce_as()) {
4077                 case ANNOUNCE_AS_NT_SERVER:
4078                         default_server_announce |= SV_TYPE_SERVER_NT;
4079                         /* fall through... */
4080                 case ANNOUNCE_AS_NT_WORKSTATION:
4081                         default_server_announce |= SV_TYPE_NT;
4082                         break;
4083                 case ANNOUNCE_AS_WIN95:
4084                         default_server_announce |= SV_TYPE_WIN95_PLUS;
4085                         break;
4086                 case ANNOUNCE_AS_WFW:
4087                         default_server_announce |= SV_TYPE_WFW;
4088                         break;
4089                 default:
4090                         break;
4091         }
4092
4093         switch (lp_server_role()) {
4094                 case ROLE_DOMAIN_MEMBER:
4095                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4096                         break;
4097                 case ROLE_DOMAIN_PDC:
4098                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4099                         break;
4100                 case ROLE_DOMAIN_BDC:
4101                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4102                         break;
4103                 case ROLE_STANDALONE:
4104                 default:
4105                         break;
4106         }
4107         if (lp_time_server())
4108                 default_server_announce |= SV_TYPE_TIME_SOURCE;
4109
4110         if (lp_host_msdfs())
4111                 default_server_announce |= SV_TYPE_DFS_SERVER;
4112 }
4113
4114 /***********************************************************
4115  returns role of Samba server
4116 ************************************************************/
4117
4118 int lp_server_role(void)
4119 {
4120         return server_role;
4121 }
4122
4123 /***********************************************************
4124  If we are PDC then prefer us as DMB
4125 ************************************************************/
4126
4127 BOOL lp_domain_master(void)
4128 {
4129         if (Globals.bDomainMaster == Auto)
4130                 return (lp_server_role() == ROLE_DOMAIN_PDC);
4131
4132         return Globals.bDomainMaster;
4133 }
4134
4135 /***********************************************************
4136  If we are DMB then prefer us as LMB
4137 ************************************************************/
4138
4139 BOOL lp_preferred_master(void)
4140 {
4141         if (Globals.bPreferredMaster == Auto)
4142                 return (lp_local_master() && lp_domain_master());
4143
4144         return Globals.bPreferredMaster;
4145 }
4146
4147 /*******************************************************************
4148  Remove a service.
4149 ********************************************************************/
4150
4151 void lp_remove_service(int snum)
4152 {
4153         ServicePtrs[snum]->valid = False;
4154 }
4155
4156 /*******************************************************************
4157  Copy a service.
4158 ********************************************************************/
4159
4160 void lp_copy_service(int snum, const char *new_name)
4161 {
4162         do_section(new_name);
4163         if (snum >= 0) {
4164                 snum = lp_servicenumber(new_name);
4165                 if (snum >= 0)
4166                         lp_do_parameter(snum, "copy", lp_servicename(snum));
4167         }
4168 }
4169
4170
4171 /*******************************************************************
4172  Get the default server type we will announce as via nmbd.
4173 ********************************************************************/
4174
4175 int lp_default_server_announce(void)
4176 {
4177         return default_server_announce;
4178 }
4179
4180 /*******************************************************************
4181  Split the announce version into major and minor numbers.
4182 ********************************************************************/
4183
4184 int lp_major_announce_version(void)
4185 {
4186         static BOOL got_major = False;
4187         static int major_version = DEFAULT_MAJOR_VERSION;
4188         char *vers;
4189         char *p;
4190
4191         if (got_major)
4192                 return major_version;
4193
4194         got_major = True;
4195         if ((vers = lp_announce_version()) == NULL)
4196                 return major_version;
4197
4198         if ((p = strchr_m(vers, '.')) == 0)
4199                 return major_version;
4200
4201         *p = '\0';
4202         major_version = atoi(vers);
4203         return major_version;
4204 }
4205
4206 int lp_minor_announce_version(void)
4207 {
4208         static BOOL got_minor = False;
4209         static int minor_version = DEFAULT_MINOR_VERSION;
4210         char *vers;
4211         char *p;
4212
4213         if (got_minor)
4214                 return minor_version;
4215
4216         got_minor = True;
4217         if ((vers = lp_announce_version()) == NULL)
4218                 return minor_version;
4219
4220         if ((p = strchr_m(vers, '.')) == 0)
4221                 return minor_version;
4222
4223         p++;
4224         minor_version = atoi(p);
4225         return minor_version;
4226 }
4227
4228 /***********************************************************
4229  Set the global name resolution order (used in smbclient).
4230 ************************************************************/
4231
4232 void lp_set_name_resolve_order(const char *new_order)
4233 {
4234         string_set(&Globals.szNameResolveOrder, new_order);
4235 }
4236
4237 const char *lp_printername(int snum)
4238 {
4239         const char *ret = _lp_printername(snum);
4240         if (ret == NULL || (ret != NULL && *ret == '\0'))
4241                 ret = lp_const_servicename(snum);
4242
4243         return ret;
4244 }
4245
4246
4247 /****************************************************************
4248  Compatibility fn. for 2.2.2 code.....
4249 *****************************************************************/
4250
4251 void get_private_directory(pstring privdir)
4252 {
4253         pstrcpy (privdir, lp_private_dir());
4254 }
4255
4256 /***********************************************************
4257  Allow daemons such as winbindd to fix their logfile name.
4258 ************************************************************/
4259
4260 void lp_set_logfile(const char *name)
4261 {
4262         string_set(&Globals.szLogFile, name);
4263         pstrcpy(debugf, name);
4264 }
4265
4266 /*******************************************************************
4267  Return the max print jobs per queue.
4268 ********************************************************************/
4269
4270 int lp_maxprintjobs(int snum)
4271 {
4272         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4273         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4274                 maxjobs = PRINT_MAX_JOBID - 1;
4275
4276         return maxjobs;
4277 }
4278
4279 const char *lp_printcapname(void)
4280 {
4281         if ((Globals.szPrintcapname != NULL) &&
4282             (Globals.szPrintcapname[0] != '\0'))
4283                 return Globals.szPrintcapname;
4284
4285         if (sDefault.iPrinting == PRINT_CUPS) {
4286 #ifdef HAVE_CUPS
4287                 return "cups";
4288 #else
4289                 return "lpstat";
4290 #endif
4291         }
4292
4293         if (sDefault.iPrinting == PRINT_BSD)
4294                 return "/etc/printcap";
4295
4296         return PRINTCAP_NAME;
4297 }
4298
4299 /*******************************************************************
4300  Ensure we don't use sendfile if server smb signing is active.
4301 ********************************************************************/
4302
4303 BOOL lp_use_sendfile(int snum)
4304 {
4305         extern enum protocol_types Protocol;
4306         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4307         if (Protocol < PROTOCOL_NT1) {
4308                 return False;
4309         }
4310         return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
4311 }
4312
4313 /*******************************************************************
4314  Turn off sendfile if we find the underlying OS doesn't support it.
4315 ********************************************************************/
4316
4317 void set_use_sendfile(int snum, BOOL val)
4318 {
4319         if (LP_SNUM_OK(snum))
4320                 ServicePtrs[snum]->bUseSendfile = val;
4321         else
4322                 sDefault.bUseSendfile = val;
4323 }
4324
4325 /*******************************************************************
4326  Turn off storing DOS attributes if this share doesn't support it.
4327 ********************************************************************/
4328
4329 void set_store_dos_attributes(int snum, BOOL val)
4330 {
4331         if (!LP_SNUM_OK(snum))
4332                 return;
4333         ServicePtrs[(snum)]->bStoreDosAttributes = val;
4334 }