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