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