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