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