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