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