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