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