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