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