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