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