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