source: branches/samba-3.0/source/param/loadparm.c@ 109

Last change on this file since 109 was 109, checked in by Paul Smedley, 18 years ago

Add support for undocumented 'printing = os2' parameter - patch from HerwigB

File size: 195.3 KB
Line 
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
56BOOL in_client = False; /* Not in the client by default */
57BOOL bLoaded = False;
58
59extern pstring user_socket_options;
60extern enum protocol_types Protocol;
61extern userdom_struct current_user_info;
62
63#ifndef GLOBAL_NAME
64#define GLOBAL_NAME "global"
65#endif
66
67#ifndef PRINTERS_NAME
68#define PRINTERS_NAME "printers"
69#endif
70
71#ifndef HOMES_NAME
72#define HOMES_NAME "homes"
73#endif
74
75/* some helpful bits */
76#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
77#define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
78
79#define USERSHARE_VALID 1
80#define USERSHARE_PENDING_DELETE 2
81
82int keepalive = DEFAULT_KEEPALIVE;
83BOOL use_getwd_cache = True;
84
85extern int extra_time_offset;
86
87static BOOL defaults_saved = False;
88
89typedef struct _param_opt_struct param_opt_struct;
90struct _param_opt_struct {
91 param_opt_struct *prev, *next;
92 char *key;
93 char *value;
94 char **list;
95};
96
97/*
98 * This structure describes global (ie., server-wide) parameters.
99 */
100typedef struct {
101 char *smb_ports;
102 char *dos_charset;
103 char *unix_charset;
104 char *display_charset;
105 char *szPrintcapname;
106 char *szAddPortCommand;
107 char *szEnumPortsCommand;
108 char *szAddPrinterCommand;
109 char *szDeletePrinterCommand;
110 char *szOs2DriverMap;
111 char *szLockDir;
112 char *szPidDir;
113 char *szRootdir;
114 char *szDefaultService;
115 char *szGetQuota;
116 char *szSetQuota;
117 char *szMsgCommand;
118 char *szServerString;
119 char *szAutoServices;
120 char *szPasswdProgram;
121 char *szPasswdChat;
122 char *szLogFile;
123 char *szConfigFile;
124 char *szSMBPasswdFile;
125 char *szPrivateDir;
126 char *szPassdbBackend;
127 char **szPreloadModules;
128 char *szPasswordServer;
129 char *szSocketOptions;
130 char *szRealm;
131 char *szAfsUsernameMap;
132 int iAfsTokenLifetime;
133 char *szLogNtTokenCommand;
134 char *szUsernameMap;
135 char *szLogonScript;
136 char *szLogonPath;
137 char *szLogonDrive;
138 char *szLogonHome;
139 char **szWINSservers;
140 char **szInterfaces;
141 char *szRemoteAnnounce;
142 char *szRemoteBrowseSync;
143 char *szSocketAddress;
144 char *szNISHomeMapName;
145 char *szAnnounceVersion; /* This is initialised in init_globals */
146 char *szWorkgroup;
147 char *szNetbiosName;
148 char **szNetbiosAliases;
149 char *szNetbiosScope;
150 char *szNameResolveOrder;
151 char *szPanicAction;
152 char *szAddUserScript;
153 char *szRenameUserScript;
154 char *szDelUserScript;
155 char *szAddGroupScript;
156 char *szDelGroupScript;
157 char *szAddUserToGroupScript;
158 char *szDelUserFromGroupScript;
159 char *szSetPrimaryGroupScript;
160 char *szAddMachineScript;
161 char *szShutdownScript;
162 char *szAbortShutdownScript;
163 char *szUsernameMapScript;
164 char *szCheckPasswordScript;
165 char *szWINSHook;
166 char *szUtmpDir;
167 char *szWtmpDir;
168 BOOL bUtmp;
169 char *szIdmapUID;
170 char *szIdmapGID;
171 BOOL bPassdbExpandExplicit;
172 int AlgorithmicRidBase;
173 char *szTemplateHomedir;
174 char *szTemplateShell;
175 char *szWinbindSeparator;
176 BOOL bWinbindEnumUsers;
177 BOOL bWinbindEnumGroups;
178 BOOL bWinbindUseDefaultDomain;
179 BOOL bWinbindTrustedDomainsOnly;
180 BOOL bWinbindNestedGroups;
181 BOOL bWinbindRefreshTickets;
182 BOOL bWinbindOfflineLogon;
183 BOOL bWinbindNormalizeNames;
184 char **szIdmapDomains;
185 char **szIdmapBackend; /* deprecated */
186 char *szIdmapAllocBackend;
187 char *szAddShareCommand;
188 char *szChangeShareCommand;
189 char *szDeleteShareCommand;
190 char **szEventLogs;
191 char *szGuestaccount;
192 char *szManglingMethod;
193 char **szServicesList;
194 char *szUsersharePath;
195 char *szUsershareTemplateShare;
196 char **szUsersharePrefixAllowList;
197 char **szUsersharePrefixDenyList;
198 int mangle_prefix;
199 int max_log_size;
200 char *szLogLevel;
201 int max_xmit;
202 int max_mux;
203 int max_open_files;
204 int open_files_db_hash_size;
205 int pwordlevel;
206 int unamelevel;
207 int deadtime;
208 int maxprotocol;
209 int minprotocol;
210 int security;
211 char **AuthMethods;
212 BOOL paranoid_server_security;
213 int maxdisksize;
214 int lpqcachetime;
215 int iMaxSmbdProcesses;
216 BOOL bDisableSpoolss;
217 int syslog;
218 int os_level;
219 int enhanced_browsing;
220 int max_ttl;
221 int max_wins_ttl;
222 int min_wins_ttl;
223 int lm_announce;
224 int lm_interval;
225 int announce_as; /* This is initialised in init_globals */
226 int machine_password_timeout;
227 int map_to_guest;
228 int oplock_break_wait_time;
229 int winbind_cache_time;
230 int winbind_max_idle_children;
231 char **szWinbindNssInfo;
232 int iLockSpinTime;
233 char *szLdapMachineSuffix;
234 char *szLdapUserSuffix;
235 char *szLdapIdmapSuffix;
236 char *szLdapGroupSuffix;
237 int ldap_ssl;
238 char *szLdapSuffix;
239 char *szLdapAdminDn;
240 int iAclCompat;
241 char *szCupsServer;
242 char *szIPrintServer;
243 int ldap_passwd_sync;
244 int ldap_replication_sleep;
245 int ldap_timeout; /* This is initialised in init_globals */
246 int ldap_page_size;
247 BOOL ldap_delete_dn;
248 BOOL bMsAddPrinterWizard;
249 BOOL bDNSproxy;
250 BOOL bWINSsupport;
251 BOOL bWINSproxy;
252 BOOL bLocalMaster;
253 BOOL bPreferredMaster;
254 BOOL bDomainMaster;
255 BOOL bDomainLogons;
256 BOOL bEncryptPasswords;
257 BOOL bUpdateEncrypt;
258 int clientSchannel;
259 int serverSchannel;
260 BOOL bNullPasswords;
261 BOOL bObeyPamRestrictions;
262 BOOL bLoadPrinters;
263 int PrintcapCacheTime;
264 BOOL bLargeReadwrite;
265 BOOL bReadRaw;
266 BOOL bWriteRaw;
267 BOOL bReadbmpx;
268 BOOL bSyslogOnly;
269 BOOL bBrowseList;
270 BOOL bNISHomeMap;
271 BOOL bTimeServer;
272 BOOL bBindInterfacesOnly;
273 BOOL bPamPasswordChange;
274 BOOL bUnixPasswdSync;
275 BOOL bPasswdChatDebug;
276 int iPasswdChatTimeout;
277 BOOL bTimestampLogs;
278 BOOL bNTSmbSupport;
279 BOOL bNTPipeSupport;
280 BOOL bNTStatusSupport;
281 BOOL bStatCache;
282 int iMaxStatCacheSize;
283 BOOL bKernelOplocks;
284 BOOL bAllowTrustedDomains;
285 BOOL bLanmanAuth;
286 BOOL bNTLMAuth;
287 BOOL bUseSpnego;
288 BOOL bClientLanManAuth;
289 BOOL bClientNTLMv2Auth;
290 BOOL bClientPlaintextAuth;
291 BOOL bClientUseSpnego;
292 BOOL bDebugPrefixTimestamp;
293 BOOL bDebugHiresTimestamp;
294 BOOL bDebugPid;
295 BOOL bDebugUid;
296 BOOL bEnableCoreFiles;
297 BOOL bHostMSDfs;
298 BOOL bUseMmap;
299 BOOL bHostnameLookups;
300 BOOL bUnixExtensions;
301 BOOL bDisableNetbios;
302 BOOL bUseKerberosKeytab;
303 BOOL bDeferSharingViolations;
304 BOOL bEnablePrivileges;
305 BOOL bASUSupport;
306 BOOL bUsershareOwnerOnly;
307 BOOL bUsershareAllowGuests;
308 int restrict_anonymous;
309 int name_cache_timeout;
310 int client_signing;
311 int server_signing;
312 int iUsershareMaxShares;
313 int iIdmapCacheTime;
314 int iIdmapNegativeCacheTime;
315
316 BOOL bResetOnZeroVC;
317 param_opt_struct *param_opt;
318} global;
319
320static global Globals;
321
322/*
323 * This structure describes a single service.
324 */
325typedef struct {
326 BOOL valid;
327 BOOL autoloaded;
328 int usershare;
329 time_t usershare_last_mod;
330 char *szService;
331 char *szPath;
332 char *szUsername;
333 char **szInvalidUsers;
334 char **szValidUsers;
335 char **szAdminUsers;
336 char *szCopy;
337 char *szInclude;
338 char *szPreExec;
339 char *szPostExec;
340 char *szRootPreExec;
341 char *szRootPostExec;
342 char *szCupsOptions;
343 char *szPrintcommand;
344 char *szLpqcommand;
345 char *szLprmcommand;
346 char *szLppausecommand;
347 char *szLpresumecommand;
348 char *szQueuepausecommand;
349 char *szQueueresumecommand;
350 char *szPrintername;
351 char *szPrintjobUsername;
352 char *szDontdescend;
353 char **szHostsallow;
354 char **szHostsdeny;
355 char *szMagicScript;
356 char *szMagicOutput;
357 char *szMangledMap;
358 char *szVetoFiles;
359 char *szHideFiles;
360 char *szVetoOplockFiles;
361 char *comment;
362 char *force_user;
363 char *force_group;
364 char **readlist;
365 char **writelist;
366 char **printer_admin;
367 char *volume;
368 char *fstype;
369 char **szVfsObjects;
370 char *szMSDfsProxy;
371 char *szAioWriteBehind;
372 char *szDfree;
373 int iMinPrintSpace;
374 int iMaxPrintJobs;
375 int iMaxReportedPrintJobs;
376 int iWriteCacheSize;
377 int iCreate_mask;
378 int iCreate_force_mode;
379 int iSecurity_mask;
380 int iSecurity_force_mode;
381 int iDir_mask;
382 int iDir_force_mode;
383 int iDir_Security_mask;
384 int iDir_Security_force_mode;
385 int iMaxConnections;
386 int iDefaultCase;
387 int iPrinting;
388 int iOplockContentionLimit;
389 int iCSCPolicy;
390 int iBlock_size;
391 int iDfreeCacheTime;
392 BOOL bPreexecClose;
393 BOOL bRootpreexecClose;
394 int iCaseSensitive;
395 BOOL bCasePreserve;
396 BOOL bShortCasePreserve;
397 BOOL bHideDotFiles;
398 BOOL bHideSpecialFiles;
399 BOOL bHideUnReadable;
400 BOOL bHideUnWriteableFiles;
401 BOOL bBrowseable;
402 BOOL bAvailable;
403 BOOL bRead_only;
404 BOOL bNo_set_dir;
405 BOOL bGuest_only;
406 BOOL bGuest_ok;
407 BOOL bPrint_ok;
408 BOOL bMap_system;
409 BOOL bMap_hidden;
410 BOOL bMap_archive;
411 BOOL bStoreDosAttributes;
412 BOOL bDmapiSupport;
413 BOOL bLocking;
414 int iStrictLocking;
415 BOOL bPosixLocking;
416 BOOL bShareModes;
417 BOOL bOpLocks;
418 BOOL bLevel2OpLocks;
419 BOOL bOnlyUser;
420 BOOL bMangledNames;
421 BOOL bWidelinks;
422 BOOL bSymlinks;
423 BOOL bSyncAlways;
424 BOOL bStrictAllocate;
425 BOOL bStrictSync;
426 char magic_char;
427 BOOL *copymap;
428 BOOL bDeleteReadonly;
429 BOOL bFakeOplocks;
430 BOOL bDeleteVetoFiles;
431 BOOL bDosFilemode;
432 BOOL bDosFiletimes;
433 BOOL bDosFiletimeResolution;
434 BOOL bFakeDirCreateTimes;
435 BOOL bBlockingLocks;
436 BOOL bInheritPerms;
437 BOOL bInheritACLS;
438 BOOL bInheritOwner;
439 BOOL bMSDfsRoot;
440 BOOL bUseClientDriver;
441 BOOL bDefaultDevmode;
442 BOOL bForcePrintername;
443 BOOL bNTAclSupport;
444 BOOL bForceUnknownAclUser;
445 BOOL bUseSendfile;
446 BOOL bProfileAcls;
447 BOOL bMap_acl_inherit;
448 BOOL bAfs_Share;
449 BOOL bEASupport;
450 BOOL bAclCheckPermissions;
451 BOOL bAclMapFullControl;
452 BOOL bAclGroupControl;
453 BOOL bChangeNotify;
454 BOOL bKernelChangeNotify;
455 int iallocation_roundup_size;
456 int iAioReadSize;
457 int iAioWriteSize;
458 int iMap_readonly;
459 int iDirectoryNameCacheSize;
460 param_opt_struct *param_opt;
461
462 char dummy[3]; /* for alignment */
463} service;
464
465
466/* This is a default service used to prime a services structure */
467static service sDefault = {
468 True, /* valid */
469 False, /* not autoloaded */
470 0, /* not a usershare */
471 (time_t)0, /* No last mod time */
472 NULL, /* szService */
473 NULL, /* szPath */
474 NULL, /* szUsername */
475 NULL, /* szInvalidUsers */
476 NULL, /* szValidUsers */
477 NULL, /* szAdminUsers */
478 NULL, /* szCopy */
479 NULL, /* szInclude */
480 NULL, /* szPreExec */
481 NULL, /* szPostExec */
482 NULL, /* szRootPreExec */
483 NULL, /* szRootPostExec */
484 NULL, /* szCupsOptions */
485 NULL, /* szPrintcommand */
486 NULL, /* szLpqcommand */
487 NULL, /* szLprmcommand */
488 NULL, /* szLppausecommand */
489 NULL, /* szLpresumecommand */
490 NULL, /* szQueuepausecommand */
491 NULL, /* szQueueresumecommand */
492 NULL, /* szPrintername */
493 NULL, /* szPrintjobUsername */
494 NULL, /* szDontdescend */
495 NULL, /* szHostsallow */
496 NULL, /* szHostsdeny */
497 NULL, /* szMagicScript */
498 NULL, /* szMagicOutput */
499 NULL, /* szMangledMap */
500 NULL, /* szVetoFiles */
501 NULL, /* szHideFiles */
502 NULL, /* szVetoOplockFiles */
503 NULL, /* comment */
504 NULL, /* force user */
505 NULL, /* force group */
506 NULL, /* readlist */
507 NULL, /* writelist */
508 NULL, /* printer admin */
509 NULL, /* volume */
510 NULL, /* fstype */
511 NULL, /* vfs objects */
512 NULL, /* szMSDfsProxy */
513 NULL, /* szAioWriteBehind */
514 NULL, /* szDfree */
515 0, /* iMinPrintSpace */
516 1000, /* iMaxPrintJobs */
517 0, /* iMaxReportedPrintJobs */
518 0, /* iWriteCacheSize */
519 0744, /* iCreate_mask */
520 0000, /* iCreate_force_mode */
521 0777, /* iSecurity_mask */
522 0, /* iSecurity_force_mode */
523 0755, /* iDir_mask */
524 0000, /* iDir_force_mode */
525 0777, /* iDir_Security_mask */
526 0, /* iDir_Security_force_mode */
527 0, /* iMaxConnections */
528 CASE_LOWER, /* iDefaultCase */
529 DEFAULT_PRINTING, /* iPrinting */
530 2, /* iOplockContentionLimit */
531 0, /* iCSCPolicy */
532 1024, /* iBlock_size */
533 0, /* iDfreeCacheTime */
534 False, /* bPreexecClose */
535 False, /* bRootpreexecClose */
536 Auto, /* case sensitive */
537 True, /* case preserve */
538 True, /* short case preserve */
539 True, /* bHideDotFiles */
540 False, /* bHideSpecialFiles */
541 False, /* bHideUnReadable */
542 False, /* bHideUnWriteableFiles */
543 True, /* bBrowseable */
544 True, /* bAvailable */
545 True, /* bRead_only */
546 True, /* bNo_set_dir */
547 False, /* bGuest_only */
548 False, /* bGuest_ok */
549 False, /* bPrint_ok */
550 False, /* bMap_system */
551 False, /* bMap_hidden */
552 True, /* bMap_archive */
553 False, /* bStoreDosAttributes */
554 False, /* bDmapiSupport */
555 True, /* bLocking */
556 Auto, /* iStrictLocking */
557 True, /* bPosixLocking */
558 True, /* bShareModes */
559 True, /* bOpLocks */
560 True, /* bLevel2OpLocks */
561 False, /* bOnlyUser */
562 True, /* bMangledNames */
563 True, /* bWidelinks */
564 True, /* bSymlinks */
565 False, /* bSyncAlways */
566 False, /* bStrictAllocate */
567 False, /* bStrictSync */
568 '~', /* magic char */
569 NULL, /* copymap */
570 False, /* bDeleteReadonly */
571 False, /* bFakeOplocks */
572 False, /* bDeleteVetoFiles */
573 False, /* bDosFilemode */
574 True, /* bDosFiletimes */
575 False, /* bDosFiletimeResolution */
576 False, /* bFakeDirCreateTimes */
577 True, /* bBlockingLocks */
578 False, /* bInheritPerms */
579 False, /* bInheritACLS */
580 False, /* bInheritOwner */
581 False, /* bMSDfsRoot */
582 False, /* bUseClientDriver */
583 True, /* bDefaultDevmode */
584 False, /* bForcePrintername */
585 True, /* bNTAclSupport */
586 False, /* bForceUnknownAclUser */
587 False, /* bUseSendfile */
588 False, /* bProfileAcls */
589 False, /* bMap_acl_inherit */
590 False, /* bAfs_Share */
591 False, /* bEASupport */
592 True, /* bAclCheckPermissions */
593 True, /* bAclMapFullControl */
594 False, /* bAclGroupControl */
595 True, /* bChangeNotify */
596 True, /* bKernelChangeNotify */
597 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
598 0, /* iAioReadSize */
599 0, /* iAioWriteSize */
600 MAP_READONLY_YES, /* iMap_readonly */
601#ifdef BROKEN_DIRECTORY_HANDLING
602 0, /* iDirectoryNameCacheSize */
603#else
604 100, /* iDirectoryNameCacheSize */
605#endif
606 NULL, /* Parametric options */
607
608 "" /* dummy */
609};
610
611/* local variables */
612static service **ServicePtrs = NULL;
613static int iNumServices = 0;
614static int iServiceIndex = 0;
615static TDB_CONTEXT *ServiceHash;
616static int *invalid_services = NULL;
617static int num_invalid_services = 0;
618static BOOL bInGlobalSection = True;
619static BOOL bGlobalOnly = False;
620static int server_role;
621static int default_server_announce;
622
623#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
624
625/* prototypes for the special type handlers */
626static BOOL handle_include( int snum, const char *pszParmValue, char **ptr);
627static BOOL handle_copy( int snum, const char *pszParmValue, char **ptr);
628static BOOL handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
629static BOOL handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
630static BOOL handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
631static BOOL handle_debug_list( int snum, const char *pszParmValue, char **ptr );
632static BOOL handle_workgroup( int snum, const char *pszParmValue, char **ptr );
633static BOOL handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
634static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
635static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
636static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
637
638static void set_server_role(void);
639static void set_default_server_announce_type(void);
640static void set_allowed_client_auth(void);
641
642static const struct enum_list enum_protocol[] = {
643 {PROTOCOL_NT1, "NT1"},
644 {PROTOCOL_LANMAN2, "LANMAN2"},
645 {PROTOCOL_LANMAN1, "LANMAN1"},
646 {PROTOCOL_CORE, "CORE"},
647 {PROTOCOL_COREPLUS, "COREPLUS"},
648 {PROTOCOL_COREPLUS, "CORE+"},
649 {-1, NULL}
650};
651
652static const struct enum_list enum_security[] = {
653 {SEC_SHARE, "SHARE"},
654 {SEC_USER, "USER"},
655 {SEC_SERVER, "SERVER"},
656 {SEC_DOMAIN, "DOMAIN"},
657#ifdef HAVE_ADS
658 {SEC_ADS, "ADS"},
659#endif
660 {-1, NULL}
661};
662
663static const struct enum_list enum_printing[] = {
664 {PRINT_SYSV, "sysv"},
665 {PRINT_AIX, "aix"},
666 {PRINT_HPUX, "hpux"},
667 {PRINT_BSD, "bsd"},
668 {PRINT_QNX, "qnx"},
669 {PRINT_PLP, "plp"},
670 {PRINT_LPRNG, "lprng"},
671 {PRINT_CUPS, "cups"},
672 {PRINT_IPRINT, "iprint"},
673 {PRINT_LPRNT, "nt"},
674 {PRINT_LPROS2, "os2"},
675#ifdef DEVELOPER
676 {PRINT_TEST, "test"},
677 {PRINT_VLP, "vlp"},
678#endif /* DEVELOPER */
679 {-1, NULL}
680};
681
682static const struct enum_list enum_ldap_ssl[] = {
683 {LDAP_SSL_OFF, "no"},
684 {LDAP_SSL_OFF, "No"},
685 {LDAP_SSL_OFF, "off"},
686 {LDAP_SSL_OFF, "Off"},
687 {LDAP_SSL_START_TLS, "start tls"},
688 {LDAP_SSL_START_TLS, "Start_tls"},
689 {-1, NULL}
690};
691
692static const struct enum_list enum_ldap_passwd_sync[] = {
693 {LDAP_PASSWD_SYNC_OFF, "no"},
694 {LDAP_PASSWD_SYNC_OFF, "No"},
695 {LDAP_PASSWD_SYNC_OFF, "off"},
696 {LDAP_PASSWD_SYNC_OFF, "Off"},
697 {LDAP_PASSWD_SYNC_ON, "Yes"},
698 {LDAP_PASSWD_SYNC_ON, "yes"},
699 {LDAP_PASSWD_SYNC_ON, "on"},
700 {LDAP_PASSWD_SYNC_ON, "On"},
701 {LDAP_PASSWD_SYNC_ONLY, "Only"},
702 {LDAP_PASSWD_SYNC_ONLY, "only"},
703 {-1, NULL}
704};
705
706/* Types of machine we can announce as. */
707#define ANNOUNCE_AS_NT_SERVER 1
708#define ANNOUNCE_AS_WIN95 2
709#define ANNOUNCE_AS_WFW 3
710#define ANNOUNCE_AS_NT_WORKSTATION 4
711
712static const struct enum_list enum_announce_as[] = {
713 {ANNOUNCE_AS_NT_SERVER, "NT"},
714 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
715 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
716 {ANNOUNCE_AS_WIN95, "win95"},
717 {ANNOUNCE_AS_WFW, "WfW"},
718 {-1, NULL}
719};
720
721static const struct enum_list enum_map_readonly[] = {
722 {MAP_READONLY_NO, "no"},
723 {MAP_READONLY_NO, "false"},
724 {MAP_READONLY_NO, "0"},
725 {MAP_READONLY_YES, "yes"},
726 {MAP_READONLY_YES, "true"},
727 {MAP_READONLY_YES, "1"},
728 {MAP_READONLY_PERMISSIONS, "permissions"},
729 {MAP_READONLY_PERMISSIONS, "perms"},
730 {-1, NULL}
731};
732
733static const struct enum_list enum_case[] = {
734 {CASE_LOWER, "lower"},
735 {CASE_UPPER, "upper"},
736 {-1, NULL}
737};
738
739static const struct enum_list enum_bool_auto[] = {
740 {False, "No"},
741 {False, "False"},
742 {False, "0"},
743 {True, "Yes"},
744 {True, "True"},
745 {True, "1"},
746 {Auto, "Auto"},
747 {-1, NULL}
748};
749
750/* Client-side offline caching policy types */
751#define CSC_POLICY_MANUAL 0
752#define CSC_POLICY_DOCUMENTS 1
753#define CSC_POLICY_PROGRAMS 2
754#define CSC_POLICY_DISABLE 3
755
756static const struct enum_list enum_csc_policy[] = {
757 {CSC_POLICY_MANUAL, "manual"},
758 {CSC_POLICY_DOCUMENTS, "documents"},
759 {CSC_POLICY_PROGRAMS, "programs"},
760 {CSC_POLICY_DISABLE, "disable"},
761 {-1, NULL}
762};
763
764/* SMB signing types. */
765static const struct enum_list enum_smb_signing_vals[] = {
766 {False, "No"},
767 {False, "False"},
768 {False, "0"},
769 {False, "Off"},
770 {False, "disabled"},
771 {True, "Yes"},
772 {True, "True"},
773 {True, "1"},
774 {True, "On"},
775 {True, "enabled"},
776 {Auto, "auto"},
777 {Required, "required"},
778 {Required, "mandatory"},
779 {Required, "force"},
780 {Required, "forced"},
781 {Required, "enforced"},
782 {-1, NULL}
783};
784
785/* ACL compatibility options. */
786static const struct enum_list enum_acl_compat_vals[] = {
787 { ACL_COMPAT_AUTO, "auto" },
788 { ACL_COMPAT_WINNT, "winnt" },
789 { ACL_COMPAT_WIN2K, "win2k" },
790 { -1, NULL}
791};
792
793/*
794 Do you want session setups at user level security with a invalid
795 password to be rejected or allowed in as guest? WinNT rejects them
796 but it can be a pain as it means "net view" needs to use a password
797
798 You have 3 choices in the setting of map_to_guest:
799
800 "Never" means session setups with an invalid password
801 are rejected. This is the default.
802
803 "Bad User" means session setups with an invalid password
804 are rejected, unless the username does not exist, in which case it
805 is treated as a guest login
806
807 "Bad Password" means session setups with an invalid password
808 are treated as a guest login
809
810 Note that map_to_guest only has an effect in user or server
811 level security.
812*/
813
814static const struct enum_list enum_map_to_guest[] = {
815 {NEVER_MAP_TO_GUEST, "Never"},
816 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
817 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
818 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
819 {-1, NULL}
820};
821
822/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
823 *
824 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
825 * screen in SWAT. This is used to exclude parameters as well as to squash all
826 * parameters that have been duplicated by pseudonyms.
827 *
828 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
829 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
830 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
831 * respective views.
832 *
833 * NOTE2: Handling of duplicated (synonym) paramters:
834 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
835 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
836 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
837 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
838 */
839
840static struct parm_struct parm_table[] = {
841 {N_("Base Options"), P_SEP, P_SEPARATOR},
842
843 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
844 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
845 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
846 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
847 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
848 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
849 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
850#ifdef WITH_ADS
851 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
852#endif
853 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
854 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED},
855 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED},
856 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED },
857 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
858 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
859
860 {N_("Security Options"), P_SEP, P_SEPARATOR},
861
862 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
863 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED},
864 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
865 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED},
866 {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
867 {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
868 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
869 {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
870 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
871 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
872 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
873 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
874 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
875 {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
876 {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
877 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
878 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
879 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
880 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
881 {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED},
882
883 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
884 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
885 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED},
886 {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED},
887 {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED},
888 {"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED},
889 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED},
890 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED},
891 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED},
892 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED},
893 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED},
894 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED},
895 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED},
896 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED},
897 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED},
898 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED},
899
900 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
901 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
902 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
903
904 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
905 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
906 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
907 {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
908 {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
909 {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED },
910 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
911 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
912 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED},
913
914 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
915 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
916 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
917 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
918
919 {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
920 {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED },
921 {"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
922 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
923 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE},
924 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
925 {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
926 {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
927 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
928 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
929 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
930 {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
931 {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
932 {"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
933 {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
934 {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
935 {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
936 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
937 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
938
939 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
940 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
941
942 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
943 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
944 {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
945 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
946 {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
947 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
948 {"use kerberos keytab", P_BOOL, P_GLOBAL, &Globals.bUseKerberosKeytab, NULL, NULL, FLAG_ADVANCED},
949
950 {N_("Logging Options"), P_SEP, P_SEPARATOR},
951
952 {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED},
953 {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
954 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED},
955 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED},
956 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED},
957
958 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED},
959 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
960 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
961 {"debug prefix timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugPrefixTimestamp, NULL, NULL, FLAG_ADVANCED},
962 {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED},
963 {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED},
964 {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED},
965 {"enable core files", P_BOOL, P_GLOBAL, &Globals.bEnableCoreFiles, NULL, NULL, FLAG_ADVANCED},
966
967 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
968
969 {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED},
970 {"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED},
971 {"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED},
972 {"aio write behind", P_STRING, P_LOCAL, &sDefault.szAioWriteBehind, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
973 {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED},
974 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED},
975 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
976 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
977 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED},
978 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_ADVANCED},
979 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED},
980 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED},
981 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED},
982 {"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED},
983
984 {"acl compatibility", P_ENUM, P_GLOBAL, &Globals.iAclCompat, NULL, enum_acl_compat_vals, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
985 {"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
986 {"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
987 {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
988 {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED},
989 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED},
990 {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
991
992 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED},
993 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_ADVANCED},
994 {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
995 {"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
996 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED},
997 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED},
998
999 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1000 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED},
1001 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED},
1002 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED},
1003 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED},
1004 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED},
1005 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED},
1006 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
1007 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
1008 {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
1009
1010 {"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED},
1011 {"svcctl list", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
1012
1013 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1014
1015 {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1016 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
1017 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
1018 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED},
1019 {"change notify", P_BOOL, P_LOCAL, &sDefault.bChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1020 {"directory name cache size", P_INTEGER, P_LOCAL, &sDefault.iDirectoryNameCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1021 {"kernel change notify", P_BOOL, P_LOCAL, &sDefault.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1022
1023 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
1024 {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
1025 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1026 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED},
1027 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED},
1028 {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED},
1029 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1030 {"open files database hash size", P_INTEGER, P_GLOBAL, &Globals.open_files_db_hash_size, NULL, NULL, FLAG_ADVANCED},
1031
1032 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED},
1033 {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1034 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1035 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1036 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED},
1037 {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1038 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED},
1039 {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
1040
1041 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED},
1042
1043 {N_("Printing Options"), P_SEP, P_SEPARATOR},
1044
1045 {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1046 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1047 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1048 {"printcap cache time", P_INTEGER, P_GLOBAL, &Globals.PrintcapCacheTime, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1049 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1050 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
1051 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1052 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
1053 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1054 {"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1055 {"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1056 {"iprint server", P_STRING, P_GLOBAL, &Globals.szIPrintServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1057 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1058 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1059 {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE},
1060 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1061 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1062 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1063 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1064 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1065 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1066
1067 {"addport command", P_STRING, P_GLOBAL, &Globals.szAddPortCommand, NULL, NULL, FLAG_ADVANCED},
1068 {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
1069 {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED},
1070 {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
1071 {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED},
1072 {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED},
1073
1074 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1075 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
1076 {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1077 {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1078 {"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1079 {"printjob username", P_STRING, P_LOCAL, &sDefault.szPrintjobUsername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1080
1081 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
1082 {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED},
1083 {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED},
1084
1085 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE},
1086 {"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1087 {"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE},
1088 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1089 {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1090 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1091 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1092 {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1093 {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1094 {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1095 {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1096 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1097 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1098 {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1099 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1100 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1101 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1102 {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1103 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1104 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED },
1105 {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED},
1106 {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
1107 {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1108 {"dmapi support", P_BOOL, P_LOCAL, &sDefault.bDmapiSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1109
1110
1111 {N_("Domain Options"), P_SEP, P_SEPARATOR},
1112
1113 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1114
1115 {N_("Logon Options"), P_SEP, P_SEPARATOR},
1116
1117 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED},
1118 {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED},
1119 {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED},
1120 {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED},
1121 {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED},
1122 {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED},
1123 {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED},
1124 {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED},
1125 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED},
1126 {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED},
1127 {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED},
1128 {"username map script", P_STRING, P_GLOBAL, &Globals.szUsernameMapScript, NULL, NULL, FLAG_ADVANCED},
1129
1130 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED},
1131 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED},
1132 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED},
1133 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED},
1134 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED},
1135
1136 {N_("Browse Options"), P_SEP, P_SEPARATOR},
1137
1138 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1139 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED},
1140 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED},
1141 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1142 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
1143 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1144 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1145 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED},
1146 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1147 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1148 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED},
1149
1150 {N_("WINS Options"), P_SEP, P_SEPARATOR},
1151
1152 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED},
1153 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED},
1154
1155 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1156 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1157 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
1158
1159 {N_("Locking Options"), P_SEP, P_SEPARATOR},
1160
1161 {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1162 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1163 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1164 {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1165 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1166 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1167
1168 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1169 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1170 {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1171 {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1172 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1173 {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1174 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1175
1176 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
1177
1178 {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED},
1179 {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED},
1180 {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED},
1181 {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED},
1182 {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED},
1183 {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED},
1184 {"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE},
1185 {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
1186 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED},
1187 {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
1188 {"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
1189 {"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
1190 {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
1191
1192 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
1193 {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
1194 {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
1195 {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
1196
1197 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
1198 {"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
1199
1200 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1201 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1202 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1203 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED},
1204 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
1205 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED},
1206#ifdef WITH_UTMP
1207 {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED},
1208 {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED},
1209 {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED},
1210#endif
1211
1212 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1213 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1214 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED},
1215 {"dfree cache time", P_INTEGER, P_LOCAL, &sDefault.iDfreeCacheTime, NULL, NULL, FLAG_ADVANCED},
1216 {"dfree command", P_STRING, P_LOCAL, &sDefault.szDfree, NULL, NULL, FLAG_ADVANCED},
1217 {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED},
1218 {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED},
1219 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED},
1220 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED},
1221 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
1222 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
1223 {"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED},
1224 {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
1225 {"log nt token command", P_STRING, P_GLOBAL, &Globals.szLogNtTokenCommand, NULL, NULL, FLAG_ADVANCED},
1226 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
1227 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
1228 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1229
1230 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1231 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1232 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1233 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED},
1234
1235 {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1236 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1237 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1238 {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1239 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1240 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1241 {"usershare allow guests", P_BOOL, P_GLOBAL, &Globals.bUsershareAllowGuests, NULL, NULL, FLAG_ADVANCED},
1242 {"usershare max shares", P_INTEGER, P_GLOBAL, &Globals.iUsershareMaxShares, NULL, NULL, FLAG_ADVANCED},
1243 {"usershare owner only", P_BOOL, P_GLOBAL, &Globals.bUsershareOwnerOnly, NULL, NULL, FLAG_ADVANCED},
1244 {"usershare path", P_STRING, P_GLOBAL, &Globals.szUsersharePath, NULL, NULL, FLAG_ADVANCED},
1245 {"usershare prefix allow list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixAllowList, NULL, NULL, FLAG_ADVANCED},
1246 {"usershare prefix deny list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixDenyList, NULL, NULL, FLAG_ADVANCED},
1247 {"usershare template share", P_STRING, P_GLOBAL, &Globals.szUsershareTemplateShare, NULL, NULL, FLAG_ADVANCED},
1248 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1249 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1250 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1251 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1252 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1253 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1254 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1255 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1256 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1257 {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1258 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1259 {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1260
1261 {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1262 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED},
1263
1264 {N_("VFS module options"), P_SEP, P_SEPARATOR},
1265
1266 {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1267 {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
1268
1269
1270 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1271 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1272 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
1273
1274 {N_("Winbind options"), P_SEP, P_SEPARATOR},
1275
1276 {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
1277 {"idmap domains", P_LIST, P_GLOBAL, &Globals.szIdmapDomains, NULL, NULL, FLAG_ADVANCED},
1278 {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED },
1279 {"idmap alloc backend", P_STRING, P_GLOBAL, &Globals.szIdmapAllocBackend, NULL, NULL, FLAG_ADVANCED},
1280 {"idmap cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapCacheTime, NULL, NULL, FLAG_ADVANCED},
1281 {"idmap negative cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapNegativeCacheTime, NULL, NULL, FLAG_ADVANCED},
1282 {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED },
1283 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE },
1284 {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED },
1285 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE },
1286 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED},
1287 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED},
1288 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED},
1289 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED},
1290 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED},
1291 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED},
1292 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
1293 {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
1294 {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED},
1295 {"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED},
1296 {"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED},
1297 {"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
1298 {"winbind normalize names", P_BOOL, P_GLOBAL, &Globals.bWinbindNormalizeNames, NULL, NULL, FLAG_ADVANCED},
1299
1300 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
1301};
1302
1303/***************************************************************************
1304 Initialise the sDefault parameter structure for the printer values.
1305***************************************************************************/
1306
1307static void init_printer_values(service *pService)
1308{
1309 /* choose defaults depending on the type of printing */
1310 switch (pService->iPrinting) {
1311 case PRINT_BSD:
1312 case PRINT_AIX:
1313 case PRINT_LPRNT:
1314#ifndef __OS2__
1315 case PRINT_LPROS2:
1316#endif
1317 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1318 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1319 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1320 break;
1321#ifdef __OS2__
1322 case PRINT_LPROS2:
1323 string_set(&pService->szLpqcommand, "lpq.exe -s %i -p %p");
1324 string_set(&pService->szLprmcommand, "lprm.exe -s %i -p %p %j");
1325 string_set(&pService->szPrintcommand, "lpr.exe -b -s %i -p %p %s & cmd.exe /c del %s");
1326 break;
1327#endif
1328
1329 case PRINT_LPRNG:
1330 case PRINT_PLP:
1331 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1332 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1333 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1334 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
1335 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
1336 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
1337 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
1338 break;
1339
1340 case PRINT_CUPS:
1341 case PRINT_IPRINT:
1342#ifdef HAVE_CUPS
1343 /* set the lpq command to contain the destination printer
1344 name only. This is used by cups_queue_get() */
1345 string_set(&pService->szLpqcommand, "%p");
1346 string_set(&pService->szLprmcommand, "");
1347 string_set(&pService->szPrintcommand, "");
1348 string_set(&pService->szLppausecommand, "");
1349 string_set(&pService->szLpresumecommand, "");
1350 string_set(&pService->szQueuepausecommand, "");
1351 string_set(&pService->szQueueresumecommand, "");
1352#else
1353 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1354 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1355 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
1356 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
1357 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
1358 string_set(&pService->szQueuepausecommand, "disable '%p'");
1359 string_set(&pService->szQueueresumecommand, "enable '%p'");
1360#endif /* HAVE_CUPS */
1361 break;
1362
1363 case PRINT_SYSV:
1364 case PRINT_HPUX:
1365 string_set(&pService->szLpqcommand, "lpstat -o%p");
1366 string_set(&pService->szLprmcommand, "cancel %p-%j");
1367 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
1368 string_set(&pService->szQueuepausecommand, "disable %p");
1369 string_set(&pService->szQueueresumecommand, "enable %p");
1370#ifndef HPUX
1371 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
1372 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
1373#endif /* HPUX */
1374 break;
1375
1376 case PRINT_QNX:
1377 string_set(&pService->szLpqcommand, "lpq -P%p");
1378 string_set(&pService->szLprmcommand, "lprm -P%p %j");
1379 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
1380 break;
1381
1382#ifdef DEVELOPER
1383 case PRINT_TEST:
1384 case PRINT_VLP:
1385 string_set(&pService->szPrintcommand, "vlp print %p %s");
1386 string_set(&pService->szLpqcommand, "vlp lpq %p");
1387 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
1388 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
1389 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
1390 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
1391 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
1392 break;
1393#endif /* DEVELOPER */
1394
1395 }
1396}
1397
1398/***************************************************************************
1399 Initialise the global parameter structure.
1400***************************************************************************/
1401
1402#ifndef __OS2__
1403static
1404#endif
1405void init_globals(BOOL first_time_only)
1406{
1407 static BOOL done_init = False;
1408 pstring s;
1409
1410 /* If requested to initialize only once and we've already done it... */
1411 if (first_time_only && done_init) {
1412 /* ... then we have nothing more to do */
1413 return;
1414 }
1415
1416 if (!done_init) {
1417 int i;
1418
1419 /* The logfile can be set before this is invoked. Free it if so. */
1420 if (Globals.szLogFile != NULL) {
1421 string_free(&Globals.szLogFile);
1422 Globals.szLogFile = NULL;
1423 }
1424
1425 memset((void *)&Globals, '\0', sizeof(Globals));
1426
1427 for (i = 0; parm_table[i].label; i++)
1428 if ((parm_table[i].type == P_STRING ||
1429 parm_table[i].type == P_USTRING) &&
1430 parm_table[i].ptr)
1431 string_set((char **)parm_table[i].ptr, "");
1432
1433 string_set(&sDefault.fstype, FSTYPE_STRING);
1434 string_set(&sDefault.szPrintjobUsername, "%U");
1435
1436 init_printer_values(&sDefault);
1437
1438 done_init = True;
1439 }
1440
1441
1442 DEBUG(3, ("Initialising global parameters\n"));
1443
1444 string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1445 string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1446
1447 /* use the new 'hash2' method by default, with a prefix of 1 */
1448 string_set(&Globals.szManglingMethod, "hash2");
1449 Globals.mangle_prefix = 1;
1450
1451 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1452
1453#ifndef __OS2__
1454 /* using UTF8 by default allows us to support all chars */
1455 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
1456#else
1457 /* On OS/2, using UTF8 causes problems with display of foreign characters - default to SYSTEM codepage */
1458 string_set(&Globals.unix_charset, "SYSTEM");
1459#endif
1460
1461#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
1462 /* If the system supports nl_langinfo(), try to grab the value
1463 from the user's locale */
1464 string_set(&Globals.display_charset, "LOCALE");
1465#else
1466 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
1467#endif
1468
1469 /* Use codepage 850 as a default for the dos character set */
1470 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
1471
1472 /*
1473 * Allow the default PASSWD_CHAT to be overridden in local.h.
1474 */
1475 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1476
1477 set_global_myname(myhostname());
1478 string_set(&Globals.szNetbiosName,global_myname());
1479
1480 set_global_myworkgroup(WORKGROUP);
1481 string_set(&Globals.szWorkgroup, lp_workgroup());
1482
1483 string_set(&Globals.szPasswdProgram, "");
1484 string_set(&Globals.szPidDir, dyn_PIDDIR);
1485 string_set(&Globals.szLockDir, dyn_LOCKDIR);
1486 string_set(&Globals.szSocketAddress, "0.0.0.0");
1487 pstrcpy(s, "Samba ");
1488 pstrcat(s, SAMBA_VERSION_STRING);
1489 string_set(&Globals.szServerString, s);
1490 slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1491 DEFAULT_MINOR_VERSION);
1492 string_set(&Globals.szAnnounceVersion, s);
1493#ifdef DEVELOPER
1494 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
1495#endif
1496
1497 pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1498
1499 string_set(&Globals.szLogonDrive, "");
1500 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1501 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1502 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1503
1504 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1505 string_set(&Globals.szPasswordServer, "*");
1506
1507 Globals.AlgorithmicRidBase = BASE_RID;
1508
1509 Globals.bLoadPrinters = True;
1510 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
1511
1512 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1513 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1514 Globals.max_xmit = 0x4104;
1515 Globals.max_mux = 50; /* This is *needed* for profile support. */
1516 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
1517 Globals.bDisableSpoolss = False;
1518 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1519 Globals.pwordlevel = 0;
1520 Globals.unamelevel = 0;
1521 Globals.deadtime = 0;
1522 Globals.bLargeReadwrite = True;
1523 Globals.max_log_size = 5000;
1524 Globals.max_open_files = MAX_OPEN_FILES;
1525 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
1526 Globals.maxprotocol = PROTOCOL_NT1;
1527 Globals.minprotocol = PROTOCOL_CORE;
1528 Globals.security = SEC_USER;
1529 Globals.paranoid_server_security = True;
1530 Globals.bEncryptPasswords = True;
1531 Globals.bUpdateEncrypt = False;
1532 Globals.clientSchannel = Auto;
1533 Globals.serverSchannel = Auto;
1534 Globals.bReadRaw = True;
1535 Globals.bWriteRaw = True;
1536 Globals.bReadbmpx = False;
1537 Globals.bNullPasswords = False;
1538 Globals.bObeyPamRestrictions = False;
1539 Globals.syslog = 1;
1540 Globals.bSyslogOnly = False;
1541 Globals.bTimestampLogs = True;
1542 string_set(&Globals.szLogLevel, "0");
1543 Globals.bDebugPrefixTimestamp = False;
1544 Globals.bDebugHiresTimestamp = False;
1545 Globals.bDebugPid = False;
1546 Globals.bDebugUid = False;
1547 Globals.bEnableCoreFiles = True;
1548 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
1549 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
1550 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
1551 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
1552 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
1553 Globals.lm_interval = 60;
1554 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1555#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1556 Globals.bNISHomeMap = False;
1557#ifdef WITH_NISPLUS_HOME
1558 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1559#else
1560 string_set(&Globals.szNISHomeMapName, "auto.home");
1561#endif
1562#endif
1563 Globals.bTimeServer = False;
1564 Globals.bBindInterfacesOnly = False;
1565 Globals.bUnixPasswdSync = False;
1566 Globals.bPamPasswordChange = False;
1567 Globals.bPasswdChatDebug = False;
1568 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
1569 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
1570 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1571 Globals.bStatCache = True; /* use stat cache by default */
1572 Globals.iMaxStatCacheSize = 1024; /* one Meg by default. */
1573 Globals.restrict_anonymous = 0;
1574 Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
1575 Globals.bClientPlaintextAuth = True; /* Do use a plaintext password if is requested by the server */
1576 Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */
1577 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1578 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
1579 /* Note, that we will use NTLM2 session security (which is different), if it is available */
1580
1581 Globals.map_to_guest = 0; /* By Default, "Never" */
1582 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
1583 Globals.enhanced_browsing = True;
1584 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
1585#ifdef MMAP_BLACKLIST
1586 Globals.bUseMmap = False;
1587#else
1588 Globals.bUseMmap = True;
1589#endif
1590 Globals.bUnixExtensions = True;
1591 Globals.bResetOnZeroVC = False;
1592
1593 /* hostname lookups can be very expensive and are broken on
1594 a large number of sites (tridge) */
1595 Globals.bHostnameLookups = False;
1596
1597 string_set(&Globals.szPassdbBackend, "smbpasswd");
1598 string_set(&Globals.szLdapSuffix, "");
1599 string_set(&Globals.szLdapMachineSuffix, "");
1600 string_set(&Globals.szLdapUserSuffix, "");
1601 string_set(&Globals.szLdapGroupSuffix, "");
1602 string_set(&Globals.szLdapIdmapSuffix, "");
1603
1604 string_set(&Globals.szLdapAdminDn, "");
1605 Globals.ldap_ssl = LDAP_SSL_ON;
1606 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1607 Globals.ldap_delete_dn = False;
1608 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
1609 Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
1610 Globals.ldap_page_size = LDAP_PAGE_SIZE;
1611
1612 /* This is what we tell the afs client. in reality we set the token
1613 * to never expire, though, when this runs out the afs client will
1614 * forget the token. Set to 0 to get NEVERDATE.*/
1615 Globals.iAfsTokenLifetime = 604800;
1616
1617/* these parameters are set to defaults that are more appropriate
1618 for the increasing samba install base:
1619
1620 as a member of the workgroup, that will possibly become a
1621 _local_ master browser (lm = True). this is opposed to a forced
1622 local master browser startup (pm = True).
1623
1624 doesn't provide WINS server service by default (wsupp = False),
1625 and doesn't provide domain master browser services by default, either.
1626
1627*/
1628
1629 Globals.bMsAddPrinterWizard = True;
1630 Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */
1631 Globals.os_level = 20;
1632 Globals.bLocalMaster = True;
1633 Globals.bDomainMaster = Auto; /* depending on bDomainLogons */
1634 Globals.bDomainLogons = False;
1635 Globals.bBrowseList = True;
1636 Globals.bWINSsupport = False;
1637 Globals.bWINSproxy = False;
1638
1639 Globals.bDNSproxy = True;
1640
1641 /* this just means to use them if they exist */
1642 Globals.bKernelOplocks = True;
1643
1644 Globals.bAllowTrustedDomains = True;
1645
1646 string_set(&Globals.szTemplateShell, "/bin/false");
1647 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1648 string_set(&Globals.szWinbindSeparator, "\\");
1649
1650 string_set(&Globals.szCupsServer, "");
1651 string_set(&Globals.szIPrintServer, "");
1652
1653 Globals.winbind_cache_time = 300; /* 5 minutes */
1654 Globals.bWinbindEnumUsers = False;
1655 Globals.bWinbindEnumGroups = False;
1656 Globals.bWinbindUseDefaultDomain = False;
1657 Globals.bWinbindTrustedDomainsOnly = False;
1658 Globals.bWinbindNestedGroups = True;
1659 Globals.szWinbindNssInfo = str_list_make("template", NULL);
1660 Globals.bWinbindRefreshTickets = False;
1661 Globals.bWinbindOfflineLogon = False;
1662
1663 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
1664 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
1665
1666 Globals.bPassdbExpandExplicit = False;
1667
1668 Globals.name_cache_timeout = 660; /* In seconds */
1669
1670 Globals.bUseSpnego = True;
1671 Globals.bClientUseSpnego = True;
1672
1673 Globals.client_signing = Auto;
1674 Globals.server_signing = False;
1675
1676 Globals.bDeferSharingViolations = True;
1677 string_set(&Globals.smb_ports, SMB_PORTS);
1678
1679 Globals.bEnablePrivileges = True;
1680 Globals.bHostMSDfs = True;
1681 Globals.bASUSupport = False;
1682
1683 /* User defined shares. */
1684 pstrcpy(s, dyn_LOCKDIR);
1685 pstrcat(s, "/usershares");
1686 string_set(&Globals.szUsersharePath, s);
1687 string_set(&Globals.szUsershareTemplateShare, "");
1688 Globals.iUsershareMaxShares = 0;
1689 /* By default disallow sharing of directories not owned by the sharer. */
1690 Globals.bUsershareOwnerOnly = True;
1691 /* By default disallow guest access to usershares. */
1692 Globals.bUsershareAllowGuests = False;
1693}
1694
1695static TALLOC_CTX *lp_talloc;
1696
1697/******************************************************************* a
1698 Free up temporary memory - called from the main loop.
1699********************************************************************/
1700
1701void lp_TALLOC_FREE(void)
1702{
1703 if (!lp_talloc)
1704 return;
1705 TALLOC_FREE(lp_talloc);
1706 lp_talloc = NULL;
1707}
1708
1709TALLOC_CTX *tmp_talloc_ctx(void)
1710{
1711 if (lp_talloc == NULL) {
1712 lp_talloc = talloc_init("tmp_talloc_ctx");
1713 }
1714
1715 if (lp_talloc == NULL) {
1716 smb_panic("Could not create temporary talloc context\n");
1717 }
1718
1719 return lp_talloc;
1720}
1721
1722/*******************************************************************
1723 Convenience routine to grab string parameters into temporary memory
1724 and run standard_sub_basic on them. The buffers can be written to by
1725 callers without affecting the source string.
1726********************************************************************/
1727
1728static char *lp_string(const char *s)
1729{
1730 char *ret, *tmpstr;
1731
1732 /* The follow debug is useful for tracking down memory problems
1733 especially if you have an inner loop that is calling a lp_*()
1734 function that returns a string. Perhaps this debug should be
1735 present all the time? */
1736
1737#if 0
1738 DEBUG(10, ("lp_string(%s)\n", s));
1739#endif
1740
1741 if (!lp_talloc)
1742 lp_talloc = talloc_init("lp_talloc");
1743
1744 tmpstr = alloc_sub_basic(get_current_username(),
1745 current_user_info.domain, s);
1746 if (trim_char(tmpstr, '\"', '\"')) {
1747 if (strchr(tmpstr,'\"') != NULL) {
1748 SAFE_FREE(tmpstr);
1749 tmpstr = alloc_sub_basic(get_current_username(),
1750 current_user_info.domain, s);
1751 }
1752 }
1753 ret = talloc_strdup(lp_talloc, tmpstr);
1754 SAFE_FREE(tmpstr);
1755
1756 return (ret);
1757}
1758
1759/*
1760 In this section all the functions that are used to access the
1761 parameters from the rest of the program are defined
1762*/
1763
1764#define FN_GLOBAL_STRING(fn_name,ptr) \
1765 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1766#define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1767 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1768#define FN_GLOBAL_LIST(fn_name,ptr) \
1769 const char **fn_name(void) {return(*(const char ***)(ptr));}
1770#define FN_GLOBAL_BOOL(fn_name,ptr) \
1771 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1772#define FN_GLOBAL_CHAR(fn_name,ptr) \
1773 char fn_name(void) {return(*(char *)(ptr));}
1774#define FN_GLOBAL_INTEGER(fn_name,ptr) \
1775 int fn_name(void) {return(*(int *)(ptr));}
1776
1777#define FN_LOCAL_STRING(fn_name,val) \
1778 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1779#define FN_LOCAL_CONST_STRING(fn_name,val) \
1780 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1781#define FN_LOCAL_LIST(fn_name,val) \
1782 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1783#define FN_LOCAL_BOOL(fn_name,val) \
1784 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1785#define FN_LOCAL_INTEGER(fn_name,val) \
1786 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1787
1788#define FN_LOCAL_PARM_BOOL(fn_name,val) \
1789 BOOL fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1790#define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1791 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1792#define FN_LOCAL_PARM_STRING(fn_name,val) \
1793 char *fn_name(const struct share_params *p) {return(lp_string((LP_SNUM_OK(p->service) && ServicePtrs[(p->service)]->val) ? ServicePtrs[(p->service)]->val : sDefault.val));}
1794#define FN_LOCAL_CHAR(fn_name,val) \
1795 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1796
1797FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1798FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1799FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1800FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1801FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1802FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1803FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1804FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1805FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1806FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1807FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
1808FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1809FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1810FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1811FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1812FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1813FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1814FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1815FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1816FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1817FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1818FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1819FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1820FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1821FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1822FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1823FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1824FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1825FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1826FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1827FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1828FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1829FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1830FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1831FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1832FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1833FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1834FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1835FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1836FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1837FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1838FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1839FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1840FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1841FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1842FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1843FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1844static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1845FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1846/* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
1847 * lp_passdb_backend() should be replace by the this macro again after
1848 * some releases.
1849 * */
1850const char *lp_passdb_backend(void)
1851{
1852 char *delim, *quote;
1853
1854 delim = strchr( Globals.szPassdbBackend, ' ');
1855 /* no space at all */
1856 if (delim == NULL) {
1857 goto out;
1858 }
1859
1860 quote = strchr(Globals.szPassdbBackend, '"');
1861 /* no quote char or non in the first part */
1862 if (quote == NULL || quote > delim) {
1863 *delim = '\0';
1864 goto warn;
1865 }
1866
1867 quote = strchr(quote+1, '"');
1868 if (quote == NULL) {
1869 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
1870 goto out;
1871 } else if (*(quote+1) == '\0') {
1872 /* space, fitting quote char, and one backend only */
1873 goto out;
1874 } else {
1875 /* terminate string after the fitting quote char */
1876 *(quote+1) = '\0';
1877 }
1878
1879warn:
1880 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
1881 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
1882 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
1883 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
1884
1885out:
1886 return Globals.szPassdbBackend;
1887}
1888FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1889FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1890FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1891FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1892FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1893
1894FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1895FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1896FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1897FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1898FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1899FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1900
1901FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1902
1903FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1904FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1905FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1906
1907FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1908
1909FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1910FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1911FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1912FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1913FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
1914FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1915FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1916FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1917FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1918FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1919FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1920FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1921FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
1922
1923FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
1924FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
1925FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
1926FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
1927FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
1928FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1929
1930FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1931FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1932FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1933FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1934FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1935FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1936FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1937FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1938FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1939FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1940FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1941FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1942FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1943FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1944
1945FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1946
1947FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
1948FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1949FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1950FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1951FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1952FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1953FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1954FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1955FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1956FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1957FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1958FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1959FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1960FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1961FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1962FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1963FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1964FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1965FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1966FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1967FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1968FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1969FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1970FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1971FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
1972FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1973FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1974FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1975FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
1976FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1977FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1978static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1979FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1980FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1981FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1982FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1983FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
1984FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1985FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1986FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1987FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
1988FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1989FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1990FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1991FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1992FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1993FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1994FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1995FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1996FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1997FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1998FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1999FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
2000FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
2001FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
2002FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
2003FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
2004FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
2005FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
2006FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
2007FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
2008FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
2009FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
2010FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
2011FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
2012FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
2013FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
2014FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
2015FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
2016FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
2017FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
2018FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
2019FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
2020FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
2021FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
2022FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
2023FN_GLOBAL_INTEGER(lp_security, &Globals.security)
2024FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
2025FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
2026FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
2027FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
2028FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
2029FN_GLOBAL_INTEGER(_lp_disable_spoolss, &Globals.bDisableSpoolss)
2030FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
2031static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
2032FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
2033FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
2034FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
2035FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
2036FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
2037FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
2038FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
2039
2040FN_LOCAL_STRING(lp_preexec, szPreExec)
2041FN_LOCAL_STRING(lp_postexec, szPostExec)
2042FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
2043FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
2044FN_LOCAL_STRING(lp_servicename, szService)
2045FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
2046FN_LOCAL_STRING(lp_pathname, szPath)
2047FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
2048FN_LOCAL_STRING(lp_username, szUsername)
2049FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
2050FN_LOCAL_LIST(lp_valid_users, szValidUsers)
2051FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
2052FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
2053FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
2054FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
2055FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
2056FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
2057FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
2058FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
2059FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
2060FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
2061FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
2062FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
2063static FN_LOCAL_STRING(_lp_printername, szPrintername)
2064FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
2065FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
2066FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
2067FN_LOCAL_STRING(lp_magicscript, szMagicScript)
2068FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
2069FN_LOCAL_STRING(lp_comment, comment)
2070FN_LOCAL_STRING(lp_force_user, force_user)
2071FN_LOCAL_STRING(lp_force_group, force_group)
2072FN_LOCAL_LIST(lp_readlist, readlist)
2073FN_LOCAL_LIST(lp_writelist, writelist)
2074FN_LOCAL_LIST(lp_printer_admin, printer_admin)
2075FN_LOCAL_STRING(lp_fstype, fstype)
2076FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
2077FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
2078static FN_LOCAL_STRING(lp_volume, volume)
2079FN_LOCAL_PARM_STRING(lp_mangled_map, szMangledMap)
2080FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
2081FN_LOCAL_STRING(lp_hide_files, szHideFiles)
2082FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
2083FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
2084FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
2085FN_LOCAL_STRING(lp_dfree_command, szDfree)
2086FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
2087FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
2088FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
2089FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
2090FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
2091FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
2092FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
2093FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
2094FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
2095FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
2096FN_LOCAL_BOOL(lp_browseable, bBrowseable)
2097FN_LOCAL_BOOL(lp_readonly, bRead_only)
2098FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
2099FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
2100FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
2101FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
2102FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
2103FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
2104FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
2105FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
2106FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
2107FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
2108FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
2109FN_LOCAL_BOOL(lp_share_modes, bShareModes)
2110FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
2111FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
2112FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
2113FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
2114FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
2115FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
2116FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
2117FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
2118FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
2119FN_LOCAL_BOOL(lp_map_system, bMap_system)
2120FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
2121FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
2122FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
2123FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
2124FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
2125FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
2126FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
2127FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
2128FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
2129FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
2130FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
2131FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
2132FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
2133FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
2134FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
2135FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
2136FN_LOCAL_BOOL(lp_ea_support, bEASupport)
2137FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
2138FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
2139FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
2140FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
2141FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
2142FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
2143FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
2144FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
2145FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
2146FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
2147FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
2148FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
2149FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
2150FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
2151FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
2152FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
2153FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
2154FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
2155FN_LOCAL_INTEGER(lp_printing, iPrinting)
2156FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
2157FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
2158FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
2159FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
2160FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
2161FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
2162FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
2163FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
2164FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
2165FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
2166FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
2167FN_LOCAL_CHAR(lp_magicchar, magic_char)
2168FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2169FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2170FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2171FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2172FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2173FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2174
2175/* local prototypes */
2176
2177static int map_parameter(const char *pszParmName);
2178static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
2179static int getservicebyname(const char *pszServiceName,
2180 service * pserviceDest);
2181static void copy_service(service * pserviceDest,
2182 service * pserviceSource, BOOL *pcopymapDest);
2183static BOOL service_ok(int iService);
2184static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
2185static BOOL do_section(const char *pszSectionName);
2186static void init_copymap(service * pservice);
2187static BOOL hash_a_service(const char *name, int number);
2188static void free_service_byindex(int iService);
2189static char * canonicalize_servicename(const char *name);
2190
2191/* This is a helper function for parametrical options support. */
2192/* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2193/* Actual parametrical functions are quite simple */
2194static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2195{
2196 BOOL global_section = False;
2197 char* param_key;
2198 param_opt_struct *data;
2199
2200 if (snum >= iNumServices) return NULL;
2201
2202 if (snum < 0) {
2203 data = Globals.param_opt;
2204 global_section = True;
2205 } else {
2206 data = ServicePtrs[snum]->param_opt;
2207 }
2208
2209 asprintf(&param_key, "%s:%s", type, option);
2210 if (!param_key) {
2211 DEBUG(0,("asprintf failed!\n"));
2212 return NULL;
2213 }
2214
2215 while (data) {
2216 if (strcmp(data->key, param_key) == 0) {
2217 string_free(&param_key);
2218 return data;
2219 }
2220 data = data->next;
2221 }
2222
2223 if (!global_section) {
2224 /* Try to fetch the same option but from globals */
2225 /* but only if we are not already working with Globals */
2226 data = Globals.param_opt;
2227 while (data) {
2228 if (strcmp(data->key, param_key) == 0) {
2229 string_free(&param_key);
2230 return data;
2231 }
2232 data = data->next;
2233 }
2234 }
2235
2236 string_free(&param_key);
2237
2238 return NULL;
2239}
2240
2241
2242#define MISSING_PARAMETER(name) \
2243 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
2244
2245/*******************************************************************
2246convenience routine to return int parameters.
2247********************************************************************/
2248static int lp_int(const char *s)
2249{
2250
2251 if (!s || !*s) {
2252 MISSING_PARAMETER(lp_int);
2253 return (-1);
2254 }
2255
2256 return (int)strtol(s, NULL, 0);
2257}
2258
2259/*******************************************************************
2260convenience routine to return unsigned long parameters.
2261********************************************************************/
2262static unsigned long lp_ulong(const char *s)
2263{
2264
2265 if (!s || !*s) {
2266 MISSING_PARAMETER(lp_ulong);
2267 return (0);
2268 }
2269
2270 return strtoul(s, NULL, 0);
2271}
2272
2273/*******************************************************************
2274convenience routine to return boolean parameters.
2275********************************************************************/
2276static BOOL lp_bool(const char *s)
2277{
2278 BOOL ret = False;
2279
2280 if (!s || !*s) {
2281 MISSING_PARAMETER(lp_bool);
2282 return False;
2283 }
2284
2285 if (!set_boolean(&ret,s)) {
2286 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2287 return False;
2288 }
2289
2290 return ret;
2291}
2292
2293/*******************************************************************
2294convenience routine to return enum parameters.
2295********************************************************************/
2296static int lp_enum(const char *s,const struct enum_list *_enum)
2297{
2298 int i;
2299
2300 if (!s || !*s || !_enum) {
2301 MISSING_PARAMETER(lp_enum);
2302 return (-1);
2303 }
2304
2305 for (i=0; _enum[i].name; i++) {
2306 if (strequal(_enum[i].name,s))
2307 return _enum[i].value;
2308 }
2309
2310 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2311 return (-1);
2312}
2313
2314#undef MISSING_PARAMETER
2315
2316/* DO NOT USE lp_parm_string ANYMORE!!!!
2317 * use lp_parm_const_string or lp_parm_talloc_string
2318 *
2319 * lp_parm_string is only used to let old modules find this symbol
2320 */
2321#undef lp_parm_string
2322 char *lp_parm_string(const char *servicename, const char *type, const char *option);
2323 char *lp_parm_string(const char *servicename, const char *type, const char *option)
2324{
2325 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2326}
2327
2328/* Return parametric option from a given service. Type is a part of option before ':' */
2329/* Parametric option has following syntax: 'Type: option = value' */
2330/* the returned value is talloced in lp_talloc */
2331char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2332{
2333 param_opt_struct *data = get_parametrics(snum, type, option);
2334
2335 if (data == NULL||data->value==NULL) {
2336 if (def) {
2337 return lp_string(def);
2338 } else {
2339 return NULL;
2340 }
2341 }
2342
2343 return lp_string(data->value);
2344}
2345
2346/* Return parametric option from a given service. Type is a part of option before ':' */
2347/* Parametric option has following syntax: 'Type: option = value' */
2348const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2349{
2350 param_opt_struct *data = get_parametrics(snum, type, option);
2351
2352 if (data == NULL||data->value==NULL)
2353 return def;
2354
2355 return data->value;
2356}
2357
2358/* Return parametric option from a given service. Type is a part of option before ':' */
2359/* Parametric option has following syntax: 'Type: option = value' */
2360
2361const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2362{
2363 param_opt_struct *data = get_parametrics(snum, type, option);
2364
2365 if (data == NULL||data->value==NULL)
2366 return (const char **)def;
2367
2368 if (data->list==NULL) {
2369 data->list = str_list_make(data->value, NULL);
2370 }
2371
2372 return (const char **)data->list;
2373}
2374
2375/* Return parametric option from a given service. Type is a part of option before ':' */
2376/* Parametric option has following syntax: 'Type: option = value' */
2377
2378int lp_parm_int(int snum, const char *type, const char *option, int def)
2379{
2380 param_opt_struct *data = get_parametrics(snum, type, option);
2381
2382 if (data && data->value && *data->value)
2383 return lp_int(data->value);
2384
2385 return def;
2386}
2387
2388/* Return parametric option from a given service. Type is a part of option before ':' */
2389/* Parametric option has following syntax: 'Type: option = value' */
2390
2391unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2392{
2393 param_opt_struct *data = get_parametrics(snum, type, option);
2394
2395 if (data && data->value && *data->value)
2396 return lp_ulong(data->value);
2397
2398 return def;
2399}
2400
2401/* Return parametric option from a given service. Type is a part of option before ':' */
2402/* Parametric option has following syntax: 'Type: option = value' */
2403
2404BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
2405{
2406 param_opt_struct *data = get_parametrics(snum, type, option);
2407
2408 if (data && data->value && *data->value)
2409 return lp_bool(data->value);
2410
2411 return def;
2412}
2413
2414/* Return parametric option from a given service. Type is a part of option before ':' */
2415/* Parametric option has following syntax: 'Type: option = value' */
2416
2417int lp_parm_enum(int snum, const char *type, const char *option,
2418 const struct enum_list *_enum, int def)
2419{
2420 param_opt_struct *data = get_parametrics(snum, type, option);
2421
2422 if (data && data->value && *data->value && _enum)
2423 return lp_enum(data->value, _enum);
2424
2425 return def;
2426}
2427
2428
2429/***************************************************************************
2430 Initialise a service to the defaults.
2431***************************************************************************/
2432
2433static void init_service(service * pservice)
2434{
2435 memset((char *)pservice, '\0', sizeof(service));
2436 copy_service(pservice, &sDefault, NULL);
2437}
2438
2439/***************************************************************************
2440 Free the dynamically allocated parts of a service struct.
2441***************************************************************************/
2442
2443static void free_service(service *pservice)
2444{
2445 int i;
2446 param_opt_struct *data, *pdata;
2447 if (!pservice)
2448 return;
2449
2450 if (pservice->szService)
2451 DEBUG(5, ("free_service: Freeing service %s\n",
2452 pservice->szService));
2453
2454 string_free(&pservice->szService);
2455 SAFE_FREE(pservice->copymap);
2456
2457 for (i = 0; parm_table[i].label; i++) {
2458 if ((parm_table[i].type == P_STRING ||
2459 parm_table[i].type == P_USTRING) &&
2460 parm_table[i].p_class == P_LOCAL)
2461 string_free((char **)
2462 (((char *)pservice) +
2463 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2464 else if (parm_table[i].type == P_LIST &&
2465 parm_table[i].p_class == P_LOCAL)
2466 str_list_free((char ***)
2467 (((char *)pservice) +
2468 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2469 }
2470
2471 data = pservice->param_opt;
2472 if (data)
2473 DEBUG(5,("Freeing parametrics:\n"));
2474 while (data) {
2475 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2476 string_free(&data->key);
2477 string_free(&data->value);
2478 str_list_free(&data->list);
2479 pdata = data->next;
2480 SAFE_FREE(data);
2481 data = pdata;
2482 }
2483
2484 ZERO_STRUCTP(pservice);
2485}
2486
2487
2488/***************************************************************************
2489 remove a service indexed in the ServicePtrs array from the ServiceHash
2490 and free the dynamically allocated parts
2491***************************************************************************/
2492
2493static void free_service_byindex(int idx)
2494{
2495 if ( !LP_SNUM_OK(idx) )
2496 return;
2497
2498 ServicePtrs[idx]->valid = False;
2499 invalid_services[num_invalid_services++] = idx;
2500
2501 /* we have to cleanup the hash record */
2502
2503 if (ServicePtrs[idx]->szService) {
2504 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
2505
2506 tdb_delete_bystring(ServiceHash, canon_name );
2507 }
2508
2509 free_service(ServicePtrs[idx]);
2510}
2511
2512/***************************************************************************
2513 Add a new service to the services array initialising it with the given
2514 service.
2515***************************************************************************/
2516
2517static int add_a_service(const service *pservice, const char *name)
2518{
2519 int i;
2520 service tservice;
2521 int num_to_alloc = iNumServices + 1;
2522 param_opt_struct *data, *pdata;
2523
2524 tservice = *pservice;
2525
2526 /* it might already exist */
2527 if (name) {
2528 i = getservicebyname(name, NULL);
2529 if (i >= 0) {
2530 /* Clean all parametric options for service */
2531 /* They will be added during parsing again */
2532 data = ServicePtrs[i]->param_opt;
2533 while (data) {
2534 string_free(&data->key);
2535 string_free(&data->value);
2536 str_list_free(&data->list);
2537 pdata = data->next;
2538 SAFE_FREE(data);
2539 data = pdata;
2540 }
2541 ServicePtrs[i]->param_opt = NULL;
2542 return (i);
2543 }
2544 }
2545
2546 /* find an invalid one */
2547 i = iNumServices;
2548 if (num_invalid_services > 0) {
2549 i = invalid_services[--num_invalid_services];
2550 }
2551
2552 /* if not, then create one */
2553 if (i == iNumServices) {
2554 service **tsp;
2555 int *tinvalid;
2556
2557 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2558 if (tsp == NULL) {
2559 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2560 return (-1);
2561 }
2562 ServicePtrs = tsp;
2563 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2564 if (!ServicePtrs[iNumServices]) {
2565 DEBUG(0,("add_a_service: out of memory!\n"));
2566 return (-1);
2567 }
2568 iNumServices++;
2569
2570 /* enlarge invalid_services here for now... */
2571 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2572 num_to_alloc);
2573 if (tinvalid == NULL) {
2574 DEBUG(0,("add_a_service: failed to enlarge "
2575 "invalid_services!\n"));
2576 return (-1);
2577 }
2578 invalid_services = tinvalid;
2579 } else {
2580 free_service_byindex(i);
2581 }
2582
2583 ServicePtrs[i]->valid = True;
2584
2585 init_service(ServicePtrs[i]);
2586 copy_service(ServicePtrs[i], &tservice, NULL);
2587 if (name)
2588 string_set(&ServicePtrs[i]->szService, name);
2589
2590 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2591 i, ServicePtrs[i]->szService));
2592
2593 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2594 return (-1);
2595 }
2596
2597 return (i);
2598}
2599
2600/***************************************************************************
2601 Convert a string to uppercase and remove whitespaces.
2602***************************************************************************/
2603
2604static char *canonicalize_servicename(const char *src)
2605{
2606 static fstring canon; /* is fstring large enough? */
2607
2608 if ( !src ) {
2609 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2610 return NULL;
2611 }
2612
2613 fstrcpy( canon, src );
2614 strlower_m( canon );
2615
2616 return canon;
2617}
2618
2619/***************************************************************************
2620 Add a name/index pair for the services array to the hash table.
2621***************************************************************************/
2622
2623static BOOL hash_a_service(const char *name, int idx)
2624{
2625 char *canon_name;
2626
2627 if ( !ServiceHash ) {
2628 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
2629 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL,
2630 (O_RDWR|O_CREAT), 0600);
2631 if ( !ServiceHash ) {
2632 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2633 return False;
2634 }
2635 }
2636
2637 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2638 idx, name));
2639
2640 if ( !(canon_name = canonicalize_servicename( name )) )
2641 return False;
2642
2643 tdb_store_int32(ServiceHash, canon_name, idx);
2644
2645 return True;
2646}
2647
2648/***************************************************************************
2649 Add a new home service, with the specified home directory, defaults coming
2650 from service ifrom.
2651***************************************************************************/
2652
2653BOOL lp_add_home(const char *pszHomename, int iDefaultService,
2654 const char *user, const char *pszHomedir)
2655{
2656 int i;
2657 pstring newHomedir;
2658
2659 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2660
2661 if (i < 0)
2662 return (False);
2663
2664 if (!(*(ServicePtrs[iDefaultService]->szPath))
2665 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2666 pstrcpy(newHomedir, pszHomedir);
2667 string_set(&ServicePtrs[i]->szPath, newHomedir);
2668 }
2669
2670 if (!(*(ServicePtrs[i]->comment))) {
2671 pstring comment;
2672 slprintf(comment, sizeof(comment) - 1,
2673 "Home directory of %s", user);
2674 string_set(&ServicePtrs[i]->comment, comment);
2675 }
2676
2677 /* set the browseable flag from the global default */
2678
2679 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2680
2681 ServicePtrs[i]->autoloaded = True;
2682
2683 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2684 user, ServicePtrs[i]->szPath ));
2685
2686 return (True);
2687}
2688
2689/***************************************************************************
2690 Add a new service, based on an old one.
2691***************************************************************************/
2692
2693int lp_add_service(const char *pszService, int iDefaultService)
2694{
2695 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2696}
2697
2698/***************************************************************************
2699 Add the IPC service.
2700***************************************************************************/
2701
2702static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2703{
2704 pstring comment;
2705 int i = add_a_service(&sDefault, ipc_name);
2706
2707 if (i < 0)
2708 return (False);
2709
2710 slprintf(comment, sizeof(comment) - 1,
2711 "IPC Service (%s)", Globals.szServerString);
2712
2713 string_set(&ServicePtrs[i]->szPath, tmpdir());
2714 string_set(&ServicePtrs[i]->szUsername, "");
2715 string_set(&ServicePtrs[i]->comment, comment);
2716 string_set(&ServicePtrs[i]->fstype, "IPC");
2717 ServicePtrs[i]->iMaxConnections = 0;
2718 ServicePtrs[i]->bAvailable = True;
2719 ServicePtrs[i]->bRead_only = True;
2720 ServicePtrs[i]->bGuest_only = False;
2721 ServicePtrs[i]->bGuest_ok = guest_ok;
2722 ServicePtrs[i]->bPrint_ok = False;
2723 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2724
2725 DEBUG(3, ("adding IPC service\n"));
2726
2727 return (True);
2728}
2729
2730/***************************************************************************
2731 Add a new printer service, with defaults coming from service iFrom.
2732***************************************************************************/
2733
2734BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2735{
2736 const char *comment = "From Printcap";
2737 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2738
2739 if (i < 0)
2740 return (False);
2741
2742 /* note that we do NOT default the availability flag to True - */
2743 /* we take it from the default service passed. This allows all */
2744 /* dynamic printers to be disabled by disabling the [printers] */
2745 /* entry (if/when the 'available' keyword is implemented!). */
2746
2747 /* the printer name is set to the service name. */
2748 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2749 string_set(&ServicePtrs[i]->comment, comment);
2750
2751 /* set the browseable flag from the gloabl default */
2752 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2753
2754 /* Printers cannot be read_only. */
2755 ServicePtrs[i]->bRead_only = False;
2756 /* No share modes on printer services. */
2757 ServicePtrs[i]->bShareModes = False;
2758 /* No oplocks on printer services. */
2759 ServicePtrs[i]->bOpLocks = False;
2760 /* Printer services must be printable. */
2761 ServicePtrs[i]->bPrint_ok = True;
2762
2763 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2764
2765 return (True);
2766}
2767
2768/***************************************************************************
2769 Map a parameter's string representation to something we can use.
2770 Returns False if the parameter string is not recognised, else TRUE.
2771***************************************************************************/
2772
2773static int map_parameter(const char *pszParmName)
2774{
2775 int iIndex;
2776
2777 if (*pszParmName == '-')
2778 return (-1);
2779
2780 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2781 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2782 return (iIndex);
2783
2784 /* Warn only if it isn't parametric option */
2785 if (strchr(pszParmName, ':') == NULL)
2786 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2787 /* We do return 'fail' for parametric options as well because they are
2788 stored in different storage
2789 */
2790 return (-1);
2791}
2792
2793/***************************************************************************
2794 Show all parameter's name, type, [values,] and flags.
2795***************************************************************************/
2796
2797void show_parameter_list(void)
2798{
2799 int classIndex, parmIndex, enumIndex, flagIndex;
2800 BOOL hadFlag;
2801 const char *section_names[] = { "local", "global", NULL};
2802 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2803 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
2804 "P_UGSTRING", "P_ENUM", "P_SEP"};
2805 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2806 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2807 FLAG_HIDE, FLAG_DOS_STRING};
2808 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2809 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2810 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
2811
2812 for ( classIndex=0; section_names[classIndex]; classIndex++) {
2813 printf("[%s]\n", section_names[classIndex]);
2814 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2815 if (parm_table[parmIndex].p_class == classIndex) {
2816 printf("%s=%s",
2817 parm_table[parmIndex].label,
2818 type[parm_table[parmIndex].type]);
2819 switch (parm_table[parmIndex].type) {
2820 case P_ENUM:
2821 printf(",");
2822 for (enumIndex=0; parm_table[parmIndex].enum_list[enumIndex].name; enumIndex++)
2823 printf("%s%s",
2824 enumIndex ? "|" : "",
2825 parm_table[parmIndex].enum_list[enumIndex].name);
2826 break;
2827 default:
2828 break;
2829 }
2830 printf(",");
2831 hadFlag = False;
2832 for ( flagIndex=0; flag_names[flagIndex]; flagIndex++ ) {
2833 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2834 printf("%s%s",
2835 hadFlag ? "|" : "",
2836 flag_names[flagIndex]);
2837 hadFlag = True;
2838 }
2839 }
2840 printf("\n");
2841 }
2842 }
2843 }
2844}
2845
2846/***************************************************************************
2847 Set a boolean variable from the text value stored in the passed string.
2848 Returns True in success, False if the passed string does not correctly
2849 represent a boolean.
2850***************************************************************************/
2851
2852static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2853{
2854 BOOL bRetval;
2855
2856 bRetval = True;
2857 if (strwicmp(pszParmValue, "yes") == 0 ||
2858 strwicmp(pszParmValue, "true") == 0 ||
2859 strwicmp(pszParmValue, "1") == 0)
2860 *pb = True;
2861 else if (strwicmp(pszParmValue, "no") == 0 ||
2862 strwicmp(pszParmValue, "False") == 0 ||
2863 strwicmp(pszParmValue, "0") == 0)
2864 *pb = False;
2865 else {
2866 DEBUG(0,
2867 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2868 pszParmValue));
2869 bRetval = False;
2870 }
2871 return (bRetval);
2872}
2873
2874/***************************************************************************
2875Find a service by name. Otherwise works like get_service.
2876***************************************************************************/
2877
2878static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2879{
2880 int iService = -1;
2881 char *canon_name;
2882
2883 if (ServiceHash != NULL) {
2884 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
2885 return -1;
2886
2887 iService = tdb_fetch_int32(ServiceHash, canon_name );
2888
2889 if (LP_SNUM_OK(iService)) {
2890 if (pserviceDest != NULL) {
2891 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2892 }
2893 } else {
2894 iService = -1;
2895 }
2896 }
2897
2898 return (iService);
2899}
2900
2901/***************************************************************************
2902 Copy a service structure to another.
2903 If pcopymapDest is NULL then copy all fields
2904***************************************************************************/
2905
2906static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2907{
2908 int i;
2909 BOOL bcopyall = (pcopymapDest == NULL);
2910 param_opt_struct *data, *pdata, *paramo;
2911 BOOL not_added;
2912
2913 for (i = 0; parm_table[i].label; i++)
2914 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
2915 (bcopyall || pcopymapDest[i])) {
2916 void *def_ptr = parm_table[i].ptr;
2917 void *src_ptr =
2918 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2919 &sDefault);
2920 void *dest_ptr =
2921 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2922 &sDefault);
2923
2924 switch (parm_table[i].type) {
2925 case P_BOOL:
2926 case P_BOOLREV:
2927 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2928 break;
2929
2930 case P_INTEGER:
2931 case P_ENUM:
2932 case P_OCTAL:
2933 *(int *)dest_ptr = *(int *)src_ptr;
2934 break;
2935
2936 case P_CHAR:
2937 *(char *)dest_ptr = *(char *)src_ptr;
2938 break;
2939
2940 case P_STRING:
2941 string_set((char **)dest_ptr,
2942 *(char **)src_ptr);
2943 break;
2944
2945 case P_USTRING:
2946 string_set((char **)dest_ptr,
2947 *(char **)src_ptr);
2948 strupper_m(*(char **)dest_ptr);
2949 break;
2950 case P_LIST:
2951 str_list_free((char ***)dest_ptr);
2952 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2953 break;
2954 default:
2955 break;
2956 }
2957 }
2958
2959 if (bcopyall) {
2960 init_copymap(pserviceDest);
2961 if (pserviceSource->copymap)
2962 memcpy((void *)pserviceDest->copymap,
2963 (void *)pserviceSource->copymap,
2964 sizeof(BOOL) * NUMPARAMETERS);
2965 }
2966
2967 data = pserviceSource->param_opt;
2968 while (data) {
2969 not_added = True;
2970 pdata = pserviceDest->param_opt;
2971 /* Traverse destination */
2972 while (pdata) {
2973 /* If we already have same option, override it */
2974 if (strcmp(pdata->key, data->key) == 0) {
2975 string_free(&pdata->value);
2976 str_list_free(&data->list);
2977 pdata->value = SMB_STRDUP(data->value);
2978 not_added = False;
2979 break;
2980 }
2981 pdata = pdata->next;
2982 }
2983 if (not_added) {
2984 paramo = SMB_XMALLOC_P(param_opt_struct);
2985 paramo->key = SMB_STRDUP(data->key);
2986 paramo->value = SMB_STRDUP(data->value);
2987 paramo->list = NULL;
2988 DLIST_ADD(pserviceDest->param_opt, paramo);
2989 }
2990 data = data->next;
2991 }
2992}
2993
2994/***************************************************************************
2995Check a service for consistency. Return False if the service is in any way
2996incomplete or faulty, else True.
2997***************************************************************************/
2998
2999static BOOL service_ok(int iService)
3000{
3001 BOOL bRetval;
3002
3003 bRetval = True;
3004 if (ServicePtrs[iService]->szService[0] == '\0') {
3005 DEBUG(0, ("The following message indicates an internal error:\n"));
3006 DEBUG(0, ("No service name in service entry.\n"));
3007 bRetval = False;
3008 }
3009
3010 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
3011 /* I can't see why you'd want a non-printable printer service... */
3012 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
3013 if (!ServicePtrs[iService]->bPrint_ok) {
3014 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
3015 ServicePtrs[iService]->szService));
3016 ServicePtrs[iService]->bPrint_ok = True;
3017 }
3018 /* [printers] service must also be non-browsable. */
3019 if (ServicePtrs[iService]->bBrowseable)
3020 ServicePtrs[iService]->bBrowseable = False;
3021 }
3022
3023 if (ServicePtrs[iService]->szPath[0] == '\0' &&
3024 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
3025 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
3026 ) {
3027 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
3028 ServicePtrs[iService]->szService));
3029 ServicePtrs[iService]->bAvailable = False;
3030 }
3031
3032 /* If a service is flagged unavailable, log the fact at level 0. */
3033 if (!ServicePtrs[iService]->bAvailable)
3034 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
3035 ServicePtrs[iService]->szService));
3036
3037 return (bRetval);
3038}
3039
3040static struct file_lists {
3041 struct file_lists *next;
3042 char *name;
3043 char *subfname;
3044 time_t modtime;
3045} *file_lists = NULL;
3046
3047/*******************************************************************
3048 Keep a linked list of all config files so we know when one has changed
3049 it's date and needs to be reloaded.
3050********************************************************************/
3051
3052static void add_to_file_list(const char *fname, const char *subfname)
3053{
3054 struct file_lists *f = file_lists;
3055
3056 while (f) {
3057 if (f->name && !strcmp(f->name, fname))
3058 break;
3059 f = f->next;
3060 }
3061
3062 if (!f) {
3063 f = SMB_MALLOC_P(struct file_lists);
3064 if (!f)
3065 return;
3066 f->next = file_lists;
3067 f->name = SMB_STRDUP(fname);
3068 if (!f->name) {
3069 SAFE_FREE(f);
3070 return;
3071 }
3072 f->subfname = SMB_STRDUP(subfname);
3073 if (!f->subfname) {
3074 SAFE_FREE(f);
3075 return;
3076 }
3077 file_lists = f;
3078 f->modtime = file_modtime(subfname);
3079 } else {
3080 time_t t = file_modtime(subfname);
3081 if (t)
3082 f->modtime = t;
3083 }
3084}
3085
3086/*******************************************************************
3087 Check if a config file has changed date.
3088********************************************************************/
3089
3090BOOL lp_file_list_changed(void)
3091{
3092 struct file_lists *f = file_lists;
3093
3094 DEBUG(6, ("lp_file_list_changed()\n"));
3095
3096 while (f) {
3097 pstring n2;
3098 time_t mod_time;
3099
3100 pstrcpy(n2, f->name);
3101 standard_sub_basic( get_current_username(),
3102 current_user_info.domain,
3103 n2, sizeof(n2) );
3104
3105 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3106 f->name, n2, ctime(&f->modtime)));
3107
3108 mod_time = file_modtime(n2);
3109
3110 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3111 DEBUGADD(6,
3112 ("file %s modified: %s\n", n2,
3113 ctime(&mod_time)));
3114 f->modtime = mod_time;
3115 SAFE_FREE(f->subfname);
3116 f->subfname = SMB_STRDUP(n2);
3117 return (True);
3118 }
3119 f = f->next;
3120 }
3121 return (False);
3122}
3123
3124/***************************************************************************
3125 Run standard_sub_basic on netbios name... needed because global_myname
3126 is not accessed through any lp_ macro.
3127 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3128***************************************************************************/
3129
3130static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3131{
3132 BOOL ret;
3133 pstring netbios_name;
3134
3135 pstrcpy(netbios_name, pszParmValue);
3136
3137 standard_sub_basic(get_current_username(), current_user_info.domain,
3138 netbios_name, sizeof(netbios_name));
3139
3140 ret = set_global_myname(netbios_name);
3141 string_set(&Globals.szNetbiosName,global_myname());
3142
3143 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3144 global_myname()));
3145
3146 return ret;
3147}
3148
3149static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
3150{
3151 if (strcmp(*ptr, pszParmValue) != 0) {
3152 string_set(ptr, pszParmValue);
3153 init_iconv();
3154 }
3155 return True;
3156}
3157
3158
3159
3160static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3161{
3162 BOOL ret;
3163
3164 ret = set_global_myworkgroup(pszParmValue);
3165 string_set(&Globals.szWorkgroup,lp_workgroup());
3166
3167 return ret;
3168}
3169
3170static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3171{
3172 BOOL ret;
3173
3174 ret = set_global_scope(pszParmValue);
3175 string_set(&Globals.szNetbiosScope,global_scope());
3176
3177 return ret;
3178}
3179
3180static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3181{
3182 str_list_free(&Globals.szNetbiosAliases);
3183 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3184 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3185}
3186
3187/***************************************************************************
3188 Handle the include operation.
3189***************************************************************************/
3190
3191static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
3192{
3193 pstring fname;
3194 pstrcpy(fname, pszParmValue);
3195
3196 standard_sub_basic(get_current_username(), current_user_info.domain,
3197 fname,sizeof(fname));
3198
3199 add_to_file_list(pszParmValue, fname);
3200
3201 string_set(ptr, fname);
3202
3203 if (file_exist(fname, NULL))
3204 return (pm_process(fname, do_section, do_parameter));
3205
3206 DEBUG(2, ("Can't find include file %s\n", fname));
3207
3208 return (False);
3209}
3210
3211/***************************************************************************
3212 Handle the interpretation of the copy parameter.
3213***************************************************************************/
3214
3215static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
3216{
3217 BOOL bRetval;
3218 int iTemp;
3219 service serviceTemp;
3220
3221 string_set(ptr, pszParmValue);
3222
3223 init_service(&serviceTemp);
3224
3225 bRetval = False;
3226
3227 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3228
3229 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3230 if (iTemp == iServiceIndex) {
3231 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3232 } else {
3233 copy_service(ServicePtrs[iServiceIndex],
3234 &serviceTemp,
3235 ServicePtrs[iServiceIndex]->copymap);
3236 bRetval = True;
3237 }
3238 } else {
3239 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3240 bRetval = False;
3241 }
3242
3243 free_service(&serviceTemp);
3244 return (bRetval);
3245}
3246
3247/***************************************************************************
3248 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3249 parameters is:
3250
3251 [global]
3252
3253 idmap uid = 1000-1999
3254 idmap gid = 700-899
3255
3256 We only do simple parsing checks here. The strings are parsed into useful
3257 structures in the idmap daemon code.
3258
3259***************************************************************************/
3260
3261/* Some lp_ routines to return idmap [ug]id information */
3262
3263static uid_t idmap_uid_low, idmap_uid_high;
3264static gid_t idmap_gid_low, idmap_gid_high;
3265
3266BOOL lp_idmap_uid(uid_t *low, uid_t *high)
3267{
3268 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3269 return False;
3270
3271 if (low)
3272 *low = idmap_uid_low;
3273
3274 if (high)
3275 *high = idmap_uid_high;
3276
3277 return True;
3278}
3279
3280BOOL lp_idmap_gid(gid_t *low, gid_t *high)
3281{
3282 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3283 return False;
3284
3285 if (low)
3286 *low = idmap_gid_low;
3287
3288 if (high)
3289 *high = idmap_gid_high;
3290
3291 return True;
3292}
3293
3294/* Do some simple checks on "idmap [ug]id" parameter values */
3295
3296static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3297{
3298 uint32 low, high;
3299
3300 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3301 return False;
3302
3303 /* Parse OK */
3304
3305 string_set(ptr, pszParmValue);
3306
3307 idmap_uid_low = low;
3308 idmap_uid_high = high;
3309
3310 return True;
3311}
3312
3313static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3314{
3315 uint32 low, high;
3316
3317 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3318 return False;
3319
3320 /* Parse OK */
3321
3322 string_set(ptr, pszParmValue);
3323
3324 idmap_gid_low = low;
3325 idmap_gid_high = high;
3326
3327 return True;
3328}
3329
3330/***************************************************************************
3331 Handle the DEBUG level list.
3332***************************************************************************/
3333
3334static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3335{
3336 pstring pszParmValue;
3337
3338 pstrcpy(pszParmValue, pszParmValueIn);
3339 string_set(ptr, pszParmValueIn);
3340 return debug_parse_levels( pszParmValue );
3341}
3342
3343/***************************************************************************
3344 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3345***************************************************************************/
3346
3347static const char *append_ldap_suffix( const char *str )
3348{
3349 const char *suffix_string;
3350
3351
3352 if (!lp_talloc)
3353 lp_talloc = talloc_init("lp_talloc");
3354
3355 suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
3356 if ( !suffix_string ) {
3357 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3358 return "";
3359 }
3360
3361 return suffix_string;
3362}
3363
3364const char *lp_ldap_machine_suffix(void)
3365{
3366 if (Globals.szLdapMachineSuffix[0])
3367 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3368
3369 return lp_string(Globals.szLdapSuffix);
3370}
3371
3372const char *lp_ldap_user_suffix(void)
3373{
3374 if (Globals.szLdapUserSuffix[0])
3375 return append_ldap_suffix(Globals.szLdapUserSuffix);
3376
3377 return lp_string(Globals.szLdapSuffix);
3378}
3379
3380const char *lp_ldap_group_suffix(void)
3381{
3382 if (Globals.szLdapGroupSuffix[0])
3383 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3384
3385 return lp_string(Globals.szLdapSuffix);
3386}
3387
3388const char *lp_ldap_idmap_suffix(void)
3389{
3390 if (Globals.szLdapIdmapSuffix[0])
3391 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3392
3393 return lp_string(Globals.szLdapSuffix);
3394}
3395
3396/****************************************************************************
3397 set the value for a P_ENUM
3398 ***************************************************************************/
3399
3400static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3401 int *ptr )
3402{
3403 int i;
3404
3405 for (i = 0; parm->enum_list[i].name; i++) {
3406 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3407 *ptr = parm->enum_list[i].value;
3408 break;
3409 }
3410 }
3411}
3412
3413/***************************************************************************
3414***************************************************************************/
3415
3416static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
3417{
3418 static int parm_num = -1;
3419 service *s;
3420
3421 if ( parm_num == -1 )
3422 parm_num = map_parameter( "printing" );
3423
3424 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3425
3426 if ( snum < 0 )
3427 s = &sDefault;
3428 else
3429 s = ServicePtrs[snum];
3430
3431 init_printer_values( s );
3432
3433 return True;
3434}
3435
3436
3437/***************************************************************************
3438 Initialise a copymap.
3439***************************************************************************/
3440
3441static void init_copymap(service * pservice)
3442{
3443 int i;
3444 SAFE_FREE(pservice->copymap);
3445 pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
3446 if (!pservice->copymap)
3447 DEBUG(0,
3448 ("Couldn't allocate copymap!! (size %d)\n",
3449 (int)NUMPARAMETERS));
3450 else
3451 for (i = 0; i < NUMPARAMETERS; i++)
3452 pservice->copymap[i] = True;
3453}
3454
3455/***************************************************************************
3456 Return the local pointer to a parameter given the service number and the
3457 pointer into the default structure.
3458***************************************************************************/
3459
3460void *lp_local_ptr(int snum, void *ptr)
3461{
3462 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3463}
3464
3465/***************************************************************************
3466 Process a parameter for a particular service number. If snum < 0
3467 then assume we are in the globals.
3468***************************************************************************/
3469
3470BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3471{
3472 int parmnum, i, slen;
3473 void *parm_ptr = NULL; /* where we are going to store the result */
3474 void *def_ptr = NULL;
3475 pstring param_key;
3476 char *sep;
3477 param_opt_struct *paramo, *data;
3478 BOOL not_added;
3479
3480 parmnum = map_parameter(pszParmName);
3481
3482 if (parmnum < 0) {
3483 if ((sep=strchr(pszParmName, ':')) != NULL) {
3484 *sep = '\0';
3485 ZERO_STRUCT(param_key);
3486 pstr_sprintf(param_key, "%s:", pszParmName);
3487 slen = strlen(param_key);
3488 pstrcat(param_key, sep+1);
3489 trim_char(param_key+slen, ' ', ' ');
3490 not_added = True;
3491 data = (snum < 0) ? Globals.param_opt :
3492 ServicePtrs[snum]->param_opt;
3493 /* Traverse destination */
3494 while (data) {
3495 /* If we already have same option, override it */
3496 if (strcmp(data->key, param_key) == 0) {
3497 string_free(&data->value);
3498 str_list_free(&data->list);
3499 data->value = SMB_STRDUP(pszParmValue);
3500 not_added = False;
3501 break;
3502 }
3503 data = data->next;
3504 }
3505 if (not_added) {
3506 paramo = SMB_XMALLOC_P(param_opt_struct);
3507 paramo->key = SMB_STRDUP(param_key);
3508 paramo->value = SMB_STRDUP(pszParmValue);
3509 paramo->list = NULL;
3510 if (snum < 0) {
3511 DLIST_ADD(Globals.param_opt, paramo);
3512 } else {
3513 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3514 }
3515 }
3516
3517 *sep = ':';
3518 return (True);
3519 }
3520 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3521 return (True);
3522 }
3523
3524 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3525 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3526 pszParmName));
3527 }
3528
3529 def_ptr = parm_table[parmnum].ptr;
3530
3531 /* we might point at a service, the default service or a global */
3532 if (snum < 0) {
3533 parm_ptr = def_ptr;
3534 } else {
3535 if (parm_table[parmnum].p_class == P_GLOBAL) {
3536 DEBUG(0,
3537 ("Global parameter %s found in service section!\n",
3538 pszParmName));
3539 return (True);
3540 }
3541 parm_ptr =
3542 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3543 &sDefault);
3544 }
3545
3546 if (snum >= 0) {
3547 if (!ServicePtrs[snum]->copymap)
3548 init_copymap(ServicePtrs[snum]);
3549
3550 /* this handles the aliases - set the copymap for other entries with
3551 the same data pointer */
3552 for (i = 0; parm_table[i].label; i++)
3553 if (parm_table[i].ptr == parm_table[parmnum].ptr)
3554 ServicePtrs[snum]->copymap[i] = False;
3555 }
3556
3557 /* if it is a special case then go ahead */
3558 if (parm_table[parmnum].special) {
3559 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
3560 return (True);
3561 }
3562
3563 /* now switch on the type of variable it is */
3564 switch (parm_table[parmnum].type)
3565 {
3566 case P_BOOL:
3567 *(BOOL *)parm_ptr = lp_bool(pszParmValue);
3568 break;
3569
3570 case P_BOOLREV:
3571 *(BOOL *)parm_ptr = !lp_bool(pszParmValue);
3572 break;
3573
3574 case P_INTEGER:
3575 *(int *)parm_ptr = lp_int(pszParmValue);
3576 break;
3577
3578 case P_CHAR:
3579 *(char *)parm_ptr = *pszParmValue;
3580 break;
3581
3582 case P_OCTAL:
3583 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3584 if ( i != 1 ) {
3585 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3586 }
3587 break;
3588
3589 case P_LIST:
3590 str_list_free((char ***)parm_ptr);
3591 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3592 break;
3593
3594 case P_STRING:
3595 string_set((char **)parm_ptr, pszParmValue);
3596 break;
3597
3598 case P_USTRING:
3599 string_set((char **)parm_ptr, pszParmValue);
3600 strupper_m(*(char **)parm_ptr);
3601 break;
3602
3603 case P_GSTRING:
3604 pstrcpy((char *)parm_ptr, pszParmValue);
3605 break;
3606
3607 case P_UGSTRING:
3608 pstrcpy((char *)parm_ptr, pszParmValue);
3609 strupper_m((char *)parm_ptr);
3610 break;
3611
3612 case P_ENUM:
3613 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3614 break;
3615 case P_SEP:
3616 break;
3617 }
3618
3619 return (True);
3620}
3621
3622/***************************************************************************
3623 Process a parameter.
3624***************************************************************************/
3625
3626static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3627{
3628 if (!bInGlobalSection && bGlobalOnly)
3629 return (True);
3630
3631 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3632
3633 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3634 pszParmName, pszParmValue));
3635}
3636
3637/***************************************************************************
3638 Print a parameter of the specified type.
3639***************************************************************************/
3640
3641static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3642{
3643 int i;
3644 switch (p->type)
3645 {
3646 case P_ENUM:
3647 for (i = 0; p->enum_list[i].name; i++) {
3648 if (*(int *)ptr == p->enum_list[i].value) {
3649 fprintf(f, "%s",
3650 p->enum_list[i].name);
3651 break;
3652 }
3653 }
3654 break;
3655
3656 case P_BOOL:
3657 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3658 break;
3659
3660 case P_BOOLREV:
3661 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3662 break;
3663
3664 case P_INTEGER:
3665 fprintf(f, "%d", *(int *)ptr);
3666 break;
3667
3668 case P_CHAR:
3669 fprintf(f, "%c", *(char *)ptr);
3670 break;
3671
3672 case P_OCTAL:
3673 fprintf(f, "%s", octal_string(*(int *)ptr));
3674 break;
3675
3676 case P_LIST:
3677 if ((char ***)ptr && *(char ***)ptr) {
3678 char **list = *(char ***)ptr;
3679
3680 for (; *list; list++) {
3681 /* surround strings with whitespace in double quotes */
3682 if ( strchr_m( *list, ' ' ) )
3683 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
3684 else
3685 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
3686 }
3687 }
3688 break;
3689
3690 case P_GSTRING:
3691 case P_UGSTRING:
3692 if ((char *)ptr) {
3693 fprintf(f, "%s", (char *)ptr);
3694 }
3695 break;
3696
3697 case P_STRING:
3698 case P_USTRING:
3699 if (*(char **)ptr) {
3700 fprintf(f, "%s", *(char **)ptr);
3701 }
3702 break;
3703 case P_SEP:
3704 break;
3705 }
3706}
3707
3708/***************************************************************************
3709 Check if two parameters are equal.
3710***************************************************************************/
3711
3712static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3713{
3714 switch (type) {
3715 case P_BOOL:
3716 case P_BOOLREV:
3717 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3718
3719 case P_INTEGER:
3720 case P_ENUM:
3721 case P_OCTAL:
3722 return (*((int *)ptr1) == *((int *)ptr2));
3723
3724 case P_CHAR:
3725 return (*((char *)ptr1) == *((char *)ptr2));
3726
3727 case P_LIST:
3728 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3729
3730 case P_GSTRING:
3731 case P_UGSTRING:
3732 {
3733 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3734 if (p1 && !*p1)
3735 p1 = NULL;
3736 if (p2 && !*p2)
3737 p2 = NULL;
3738 return (p1 == p2 || strequal(p1, p2));
3739 }
3740 case P_STRING:
3741 case P_USTRING:
3742 {
3743 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3744 if (p1 && !*p1)
3745 p1 = NULL;
3746 if (p2 && !*p2)
3747 p2 = NULL;
3748 return (p1 == p2 || strequal(p1, p2));
3749 }
3750 case P_SEP:
3751 break;
3752 }
3753 return (False);
3754}
3755
3756/***************************************************************************
3757 Initialize any local varients in the sDefault table.
3758***************************************************************************/
3759
3760void init_locals(void)
3761{
3762 /* None as yet. */
3763}
3764
3765/***************************************************************************
3766 Process a new section (service). At this stage all sections are services.
3767 Later we'll have special sections that permit server parameters to be set.
3768 Returns True on success, False on failure.
3769***************************************************************************/
3770
3771static BOOL do_section(const char *pszSectionName)
3772{
3773 BOOL bRetval;
3774 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3775 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3776 bRetval = False;
3777
3778 /* if we were in a global section then do the local inits */
3779 if (bInGlobalSection && !isglobal)
3780 init_locals();
3781
3782 /* if we've just struck a global section, note the fact. */
3783 bInGlobalSection = isglobal;
3784
3785 /* check for multiple global sections */
3786 if (bInGlobalSection) {
3787 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3788 return (True);
3789 }
3790
3791 if (!bInGlobalSection && bGlobalOnly)
3792 return (True);
3793
3794 /* if we have a current service, tidy it up before moving on */
3795 bRetval = True;
3796
3797 if (iServiceIndex >= 0)
3798 bRetval = service_ok(iServiceIndex);
3799
3800 /* if all is still well, move to the next record in the services array */
3801 if (bRetval) {
3802 /* We put this here to avoid an odd message order if messages are */
3803 /* issued by the post-processing of a previous section. */
3804 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3805
3806 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3807 < 0) {
3808 DEBUG(0, ("Failed to add a new service\n"));
3809 return (False);
3810 }
3811 }
3812
3813 return (bRetval);
3814}
3815
3816
3817/***************************************************************************
3818 Determine if a partcular base parameter is currentl set to the default value.
3819***************************************************************************/
3820
3821static BOOL is_default(int i)
3822{
3823 if (!defaults_saved)
3824 return False;
3825 switch (parm_table[i].type) {
3826 case P_LIST:
3827 return str_list_compare (parm_table[i].def.lvalue,
3828 *(char ***)parm_table[i].ptr);
3829 case P_STRING:
3830 case P_USTRING:
3831 return strequal(parm_table[i].def.svalue,
3832 *(char **)parm_table[i].ptr);
3833 case P_GSTRING:
3834 case P_UGSTRING:
3835 return strequal(parm_table[i].def.svalue,
3836 (char *)parm_table[i].ptr);
3837 case P_BOOL:
3838 case P_BOOLREV:
3839 return parm_table[i].def.bvalue ==
3840 *(BOOL *)parm_table[i].ptr;
3841 case P_CHAR:
3842 return parm_table[i].def.cvalue ==
3843 *(char *)parm_table[i].ptr;
3844 case P_INTEGER:
3845 case P_OCTAL:
3846 case P_ENUM:
3847 return parm_table[i].def.ivalue ==
3848 *(int *)parm_table[i].ptr;
3849 case P_SEP:
3850 break;
3851 }
3852 return False;
3853}
3854
3855/***************************************************************************
3856Display the contents of the global structure.
3857***************************************************************************/
3858
3859static void dump_globals(FILE *f)
3860{
3861 int i;
3862 param_opt_struct *data;
3863
3864 fprintf(f, "[global]\n");
3865
3866 for (i = 0; parm_table[i].label; i++)
3867 if (parm_table[i].p_class == P_GLOBAL &&
3868 parm_table[i].ptr &&
3869 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3870 if (defaults_saved && is_default(i))
3871 continue;
3872 fprintf(f, "\t%s = ", parm_table[i].label);
3873 print_parameter(&parm_table[i], parm_table[i].ptr, f);
3874 fprintf(f, "\n");
3875 }
3876 if (Globals.param_opt != NULL) {
3877 data = Globals.param_opt;
3878 while(data) {
3879 fprintf(f, "\t%s = %s\n", data->key, data->value);
3880 data = data->next;
3881 }
3882 }
3883
3884}
3885
3886/***************************************************************************
3887 Return True if a local parameter is currently set to the global default.
3888***************************************************************************/
3889
3890BOOL lp_is_default(int snum, struct parm_struct *parm)
3891{
3892 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3893
3894 return equal_parameter(parm->type,
3895 ((char *)ServicePtrs[snum]) + pdiff,
3896 ((char *)&sDefault) + pdiff);
3897}
3898
3899/***************************************************************************
3900 Display the contents of a single services record.
3901***************************************************************************/
3902
3903static void dump_a_service(service * pService, FILE * f)
3904{
3905 int i;
3906 param_opt_struct *data;
3907
3908 if (pService != &sDefault)
3909 fprintf(f, "[%s]\n", pService->szService);
3910
3911 for (i = 0; parm_table[i].label; i++) {
3912
3913 if (parm_table[i].p_class == P_LOCAL &&
3914 parm_table[i].ptr &&
3915 (*parm_table[i].label != '-') &&
3916 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3917 {
3918
3919 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3920
3921 if (pService == &sDefault) {
3922 if (defaults_saved && is_default(i))
3923 continue;
3924 } else {
3925 if (equal_parameter(parm_table[i].type,
3926 ((char *)pService) +
3927 pdiff,
3928 ((char *)&sDefault) +
3929 pdiff))
3930 continue;
3931 }
3932
3933 fprintf(f, "\t%s = ", parm_table[i].label);
3934 print_parameter(&parm_table[i],
3935 ((char *)pService) + pdiff, f);
3936 fprintf(f, "\n");
3937 }
3938 }
3939
3940 if (pService->param_opt != NULL) {
3941 data = pService->param_opt;
3942 while(data) {
3943 fprintf(f, "\t%s = %s\n", data->key, data->value);
3944 data = data->next;
3945 }
3946 }
3947}
3948
3949/***************************************************************************
3950 Display the contents of a parameter of a single services record.
3951***************************************************************************/
3952
3953BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
3954{
3955 int i;
3956 BOOL result = False;
3957 parm_class p_class;
3958 unsigned flag = 0;
3959 fstring local_parm_name;
3960 char *parm_opt;
3961 const char *parm_opt_value;
3962
3963 /* check for parametrical option */
3964 fstrcpy( local_parm_name, parm_name);
3965 parm_opt = strchr( local_parm_name, ':');
3966
3967 if (parm_opt) {
3968 *parm_opt = '\0';
3969 parm_opt++;
3970 if (strlen(parm_opt)) {
3971 parm_opt_value = lp_parm_const_string( snum,
3972 local_parm_name, parm_opt, NULL);
3973 if (parm_opt_value) {
3974 printf( "%s\n", parm_opt_value);
3975 result = True;
3976 }
3977 }
3978 return result;
3979 }
3980
3981 /* check for a key and print the value */
3982 if (isGlobal) {
3983 p_class = P_GLOBAL;
3984 flag = FLAG_GLOBAL;
3985 } else
3986 p_class = P_LOCAL;
3987
3988 for (i = 0; parm_table[i].label; i++) {
3989 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
3990 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
3991 parm_table[i].ptr &&
3992 (*parm_table[i].label != '-') &&
3993 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3994 {
3995 void *ptr;
3996
3997 if (isGlobal) {
3998 ptr = parm_table[i].ptr;
3999 } else {
4000 service * pService = ServicePtrs[snum];
4001 ptr = ((char *)pService) +
4002 PTR_DIFF(parm_table[i].ptr, &sDefault);
4003 }
4004
4005 print_parameter(&parm_table[i],
4006 ptr, f);
4007 fprintf(f, "\n");
4008 result = True;
4009 break;
4010 }
4011 }
4012
4013 return result;
4014}
4015
4016/***************************************************************************
4017 Return info about the next service in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
4018 Return NULL when out of parameters.
4019***************************************************************************/
4020
4021struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
4022{
4023 if (snum < 0) {
4024 /* do the globals */
4025 for (; parm_table[*i].label; (*i)++) {
4026 if (parm_table[*i].p_class == P_SEPARATOR)
4027 return &parm_table[(*i)++];
4028
4029 if (!parm_table[*i].ptr
4030 || (*parm_table[*i].label == '-'))
4031 continue;
4032
4033 if ((*i) > 0
4034 && (parm_table[*i].ptr ==
4035 parm_table[(*i) - 1].ptr))
4036 continue;
4037
4038 return &parm_table[(*i)++];
4039 }
4040 } else {
4041 service *pService = ServicePtrs[snum];
4042
4043 for (; parm_table[*i].label; (*i)++) {
4044 if (parm_table[*i].p_class == P_SEPARATOR)
4045 return &parm_table[(*i)++];
4046
4047 if (parm_table[*i].p_class == P_LOCAL &&
4048 parm_table[*i].ptr &&
4049 (*parm_table[*i].label != '-') &&
4050 ((*i) == 0 ||
4051 (parm_table[*i].ptr !=
4052 parm_table[(*i) - 1].ptr)))
4053 {
4054 int pdiff =
4055 PTR_DIFF(parm_table[*i].ptr,
4056 &sDefault);
4057
4058 if (allparameters ||
4059 !equal_parameter(parm_table[*i].type,
4060 ((char *)pService) +
4061 pdiff,
4062 ((char *)&sDefault) +
4063 pdiff))
4064 {
4065 return &parm_table[(*i)++];
4066 }
4067 }
4068 }
4069 }
4070
4071 return NULL;
4072}
4073
4074
4075#if 0
4076/***************************************************************************
4077 Display the contents of a single copy structure.
4078***************************************************************************/
4079static void dump_copy_map(BOOL *pcopymap)
4080{
4081 int i;
4082 if (!pcopymap)
4083 return;
4084
4085 printf("\n\tNon-Copied parameters:\n");
4086
4087 for (i = 0; parm_table[i].label; i++)
4088 if (parm_table[i].p_class == P_LOCAL &&
4089 parm_table[i].ptr && !pcopymap[i] &&
4090 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4091 {
4092 printf("\t\t%s\n", parm_table[i].label);
4093 }
4094}
4095#endif
4096
4097/***************************************************************************
4098 Return TRUE if the passed service number is within range.
4099***************************************************************************/
4100
4101BOOL lp_snum_ok(int iService)
4102{
4103 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4104}
4105
4106/***************************************************************************
4107 Auto-load some home services.
4108***************************************************************************/
4109
4110static void lp_add_auto_services(char *str)
4111{
4112 char *s;
4113 char *p;
4114 int homes;
4115
4116 if (!str)
4117 return;
4118
4119 s = SMB_STRDUP(str);
4120 if (!s)
4121 return;
4122
4123 homes = lp_servicenumber(HOMES_NAME);
4124
4125 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4126 char *home = get_user_home_dir(p);
4127
4128 if (lp_servicenumber(p) >= 0)
4129 continue;
4130
4131 if (home && homes >= 0)
4132 lp_add_home(p, homes, p, home);
4133 }
4134 SAFE_FREE(s);
4135}
4136
4137/***************************************************************************
4138 Auto-load one printer.
4139***************************************************************************/
4140
4141void lp_add_one_printer(char *name, char *comment)
4142{
4143 int printers = lp_servicenumber(PRINTERS_NAME);
4144 int i;
4145
4146 if (lp_servicenumber(name) < 0) {
4147 lp_add_printer(name, printers);
4148 if ((i = lp_servicenumber(name)) >= 0) {
4149 string_set(&ServicePtrs[i]->comment, comment);
4150 ServicePtrs[i]->autoloaded = True;
4151 }
4152 }
4153}
4154
4155/***************************************************************************
4156 Have we loaded a services file yet?
4157***************************************************************************/
4158
4159BOOL lp_loaded(void)
4160{
4161 return (bLoaded);
4162}
4163
4164/***************************************************************************
4165 Unload unused services.
4166***************************************************************************/
4167
4168void lp_killunused(BOOL (*snumused) (int))
4169{
4170 int i;
4171 for (i = 0; i < iNumServices; i++) {
4172 if (!VALID(i))
4173 continue;
4174
4175 /* don't kill autoloaded or usershare services */
4176 if ( ServicePtrs[i]->autoloaded ||
4177 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4178 continue;
4179 }
4180
4181 if (!snumused || !snumused(i)) {
4182 free_service_byindex(i);
4183 }
4184 }
4185}
4186
4187/***************************************************************************
4188 Unload a service.
4189***************************************************************************/
4190
4191void lp_killservice(int iServiceIn)
4192{
4193 if (VALID(iServiceIn)) {
4194 free_service_byindex(iServiceIn);
4195 }
4196}
4197
4198/***************************************************************************
4199 Save the curent values of all global and sDefault parameters into the
4200 defaults union. This allows swat and testparm to show only the
4201 changed (ie. non-default) parameters.
4202***************************************************************************/
4203
4204static void lp_save_defaults(void)
4205{
4206 int i;
4207 for (i = 0; parm_table[i].label; i++) {
4208 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4209 continue;
4210 switch (parm_table[i].type) {
4211 case P_LIST:
4212 str_list_copy(&(parm_table[i].def.lvalue),
4213 *(const char ***)parm_table[i].ptr);
4214 break;
4215 case P_STRING:
4216 case P_USTRING:
4217 if (parm_table[i].ptr) {
4218 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4219 } else {
4220 parm_table[i].def.svalue = NULL;
4221 }
4222 break;
4223 case P_GSTRING:
4224 case P_UGSTRING:
4225 if (parm_table[i].ptr) {
4226 parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4227 } else {
4228 parm_table[i].def.svalue = NULL;
4229 }
4230 break;
4231 case P_BOOL:
4232 case P_BOOLREV:
4233 parm_table[i].def.bvalue =
4234 *(BOOL *)parm_table[i].ptr;
4235 break;
4236 case P_CHAR:
4237 parm_table[i].def.cvalue =
4238 *(char *)parm_table[i].ptr;
4239 break;
4240 case P_INTEGER:
4241 case P_OCTAL:
4242 case P_ENUM:
4243 parm_table[i].def.ivalue =
4244 *(int *)parm_table[i].ptr;
4245 break;
4246 case P_SEP:
4247 break;
4248 }
4249 }
4250 defaults_saved = True;
4251}
4252
4253/*******************************************************************
4254 Set the server type we will announce as via nmbd.
4255********************************************************************/
4256
4257static const struct srv_role_tab {
4258 uint32 role;
4259 const char *role_str;
4260} srv_role_tab [] = {
4261 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4262 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4263 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4264 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4265 { 0, NULL }
4266};
4267
4268const char* server_role_str(uint32 role)
4269{
4270 int i = 0;
4271 for (i=0; srv_role_tab[i].role_str; i++) {
4272 if (role == srv_role_tab[i].role) {
4273 return srv_role_tab[i].role_str;
4274 }
4275 }
4276 return NULL;
4277}
4278
4279static void set_server_role(void)
4280{
4281 server_role = ROLE_STANDALONE;
4282
4283 switch (lp_security()) {
4284 case SEC_SHARE:
4285 if (lp_domain_logons())
4286 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4287 break;
4288 case SEC_SERVER:
4289 if (lp_domain_logons())
4290 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4291 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
4292 server_role = ROLE_STANDALONE;
4293 break;
4294 case SEC_DOMAIN:
4295 if (lp_domain_logons()) {
4296 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4297 server_role = ROLE_DOMAIN_BDC;
4298 break;
4299 }
4300 server_role = ROLE_DOMAIN_MEMBER;
4301 break;
4302 case SEC_ADS:
4303 if (lp_domain_logons()) {
4304 server_role = ROLE_DOMAIN_PDC;
4305 break;
4306 }
4307 server_role = ROLE_DOMAIN_MEMBER;
4308 break;
4309 case SEC_USER:
4310 if (lp_domain_logons()) {
4311
4312 if (Globals.bDomainMaster) /* auto or yes */
4313 server_role = ROLE_DOMAIN_PDC;
4314 else
4315 server_role = ROLE_DOMAIN_BDC;
4316 }
4317 break;
4318 default:
4319 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4320 break;
4321 }
4322
4323 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4324}
4325
4326/***********************************************************
4327 If we should send plaintext/LANMAN passwords in the clinet
4328************************************************************/
4329
4330static void set_allowed_client_auth(void)
4331{
4332 if (Globals.bClientNTLMv2Auth) {
4333 Globals.bClientLanManAuth = False;
4334 }
4335 if (!Globals.bClientLanManAuth) {
4336 Globals.bClientPlaintextAuth = False;
4337 }
4338}
4339
4340/***************************************************************************
4341 JRA.
4342 The following code allows smbd to read a user defined share file.
4343 Yes, this is my intent. Yes, I'm comfortable with that...
4344
4345 THE FOLLOWING IS SECURITY CRITICAL CODE.
4346
4347 It washes your clothes, it cleans your house, it guards you while you sleep...
4348 Do not f%^k with it....
4349***************************************************************************/
4350
4351#define MAX_USERSHARE_FILE_SIZE (10*1024)
4352
4353/***************************************************************************
4354 Check allowed stat state of a usershare file.
4355 Ensure we print out who is dicking with us so the admin can
4356 get their sorry ass fired.
4357***************************************************************************/
4358
4359static BOOL check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4360{
4361 if (!S_ISREG(psbuf->st_mode)) {
4362 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4363 "not a regular file\n",
4364 fname, (unsigned int)psbuf->st_uid ));
4365 return False;
4366 }
4367
4368 /* Ensure this doesn't have the other write bit set. */
4369 if (psbuf->st_mode & S_IWOTH) {
4370 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4371 "public write. Refusing to allow as a usershare file.\n",
4372 fname, (unsigned int)psbuf->st_uid ));
4373 return False;
4374 }
4375
4376 /* Should be 10k or less. */
4377 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4378 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4379 "too large (%u) to be a user share file.\n",
4380 fname, (unsigned int)psbuf->st_uid,
4381 (unsigned int)psbuf->st_size ));
4382 return False;
4383 }
4384
4385 return True;
4386}
4387
4388/***************************************************************************
4389 Parse the contents of a usershare file.
4390***************************************************************************/
4391
4392enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4393 SMB_STRUCT_STAT *psbuf,
4394 const char *servicename,
4395 int snum,
4396 char **lines,
4397 int numlines,
4398 pstring sharepath,
4399 pstring comment,
4400 SEC_DESC **ppsd,
4401 BOOL *pallow_guest)
4402{
4403 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4404 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4405 int us_vers;
4406 SMB_STRUCT_DIR *dp;
4407 SMB_STRUCT_STAT sbuf;
4408
4409 *pallow_guest = False;
4410
4411 if (numlines < 4) {
4412 return USERSHARE_MALFORMED_FILE;
4413 }
4414
4415 if (strcmp(lines[0], "#VERSION 1") == 0) {
4416 us_vers = 1;
4417 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4418 us_vers = 2;
4419 if (numlines < 5) {
4420 return USERSHARE_MALFORMED_FILE;
4421 }
4422 } else {
4423 return USERSHARE_BAD_VERSION;
4424 }
4425
4426 if (strncmp(lines[1], "path=", 5) != 0) {
4427 return USERSHARE_MALFORMED_PATH;
4428 }
4429
4430 pstrcpy(sharepath, &lines[1][5]);
4431 trim_string(sharepath, " ", " ");
4432
4433 if (strncmp(lines[2], "comment=", 8) != 0) {
4434 return USERSHARE_MALFORMED_COMMENT_DEF;
4435 }
4436
4437 pstrcpy(comment, &lines[2][8]);
4438 trim_string(comment, " ", " ");
4439 trim_char(comment, '"', '"');
4440
4441 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
4442 return USERSHARE_MALFORMED_ACL_DEF;
4443 }
4444
4445 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4446 return USERSHARE_ACL_ERR;
4447 }
4448
4449 if (us_vers == 2) {
4450 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
4451 return USERSHARE_MALFORMED_ACL_DEF;
4452 }
4453 if (lines[4][9] == 'y') {
4454 *pallow_guest = True;
4455 }
4456 }
4457
4458 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
4459 /* Path didn't change, no checks needed. */
4460 return USERSHARE_OK;
4461 }
4462
4463 /* The path *must* be absolute. */
4464 if (sharepath[0] != '/') {
4465 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4466 servicename, sharepath));
4467 return USERSHARE_PATH_NOT_ABSOLUTE;
4468 }
4469
4470 /* If there is a usershare prefix deny list ensure one of these paths
4471 doesn't match the start of the user given path. */
4472 if (prefixdenylist) {
4473 int i;
4474 for ( i=0; prefixdenylist[i]; i++ ) {
4475 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4476 servicename, i, prefixdenylist[i], sharepath ));
4477 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4478 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4479 "usershare prefix deny list entries.\n",
4480 servicename, sharepath));
4481 return USERSHARE_PATH_IS_DENIED;
4482 }
4483 }
4484 }
4485
4486 /* If there is a usershare prefix allow list ensure one of these paths
4487 does match the start of the user given path. */
4488
4489 if (prefixallowlist) {
4490 int i;
4491 for ( i=0; prefixallowlist[i]; i++ ) {
4492 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4493 servicename, i, prefixallowlist[i], sharepath ));
4494 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4495 break;
4496 }
4497 }
4498 if (prefixallowlist[i] == NULL) {
4499 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4500 "usershare prefix allow list entries.\n",
4501 servicename, sharepath));
4502 return USERSHARE_PATH_NOT_ALLOWED;
4503 }
4504 }
4505
4506 /* Ensure this is pointing to a directory. */
4507 dp = sys_opendir(sharepath);
4508
4509 if (!dp) {
4510 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4511 servicename, sharepath));
4512 return USERSHARE_PATH_NOT_DIRECTORY;
4513 }
4514
4515 /* Ensure the owner of the usershare file has permission to share
4516 this directory. */
4517
4518 if (sys_stat(sharepath, &sbuf) == -1) {
4519 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4520 servicename, sharepath, strerror(errno) ));
4521 sys_closedir(dp);
4522 return USERSHARE_POSIX_ERR;
4523 }
4524
4525 sys_closedir(dp);
4526
4527 if (!S_ISDIR(sbuf.st_mode)) {
4528 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4529 servicename, sharepath ));
4530 return USERSHARE_PATH_NOT_DIRECTORY;
4531 }
4532
4533 /* Check if sharing is restricted to owner-only. */
4534 /* psbuf is the stat of the usershare definition file,
4535 sbuf is the stat of the target directory to be shared. */
4536
4537 if (lp_usershare_owner_only()) {
4538 /* root can share anything. */
4539 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
4540 return USERSHARE_PATH_NOT_ALLOWED;
4541 }
4542 }
4543
4544 return USERSHARE_OK;
4545}
4546
4547/***************************************************************************
4548 Deal with a usershare file.
4549 Returns:
4550 >= 0 - snum
4551 -1 - Bad name, invalid contents.
4552 - service name already existed and not a usershare, problem
4553 with permissions to share directory etc.
4554***************************************************************************/
4555
4556static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4557{
4558 SMB_STRUCT_STAT sbuf;
4559 SMB_STRUCT_STAT lsbuf;
4560 pstring fname;
4561 pstring sharepath;
4562 pstring comment;
4563 fstring service_name;
4564 char **lines = NULL;
4565 int numlines = 0;
4566 int fd = -1;
4567 int iService = -1;
4568 TALLOC_CTX *ctx = NULL;
4569 SEC_DESC *psd = NULL;
4570 BOOL guest_ok = False;
4571
4572 /* Ensure share name doesn't contain invalid characters. */
4573 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4574 DEBUG(0,("process_usershare_file: share name %s contains "
4575 "invalid characters (any of %s)\n",
4576 file_name, INVALID_SHARENAME_CHARS ));
4577 return -1;
4578 }
4579
4580 fstrcpy(service_name, file_name);
4581
4582 pstrcpy(fname, dir_name);
4583 pstrcat(fname, "/");
4584 pstrcat(fname, file_name);
4585
4586 /* Minimize the race condition by doing an lstat before we
4587 open and fstat. Ensure this isn't a symlink link. */
4588
4589 if (sys_lstat(fname, &lsbuf) != 0) {
4590 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4591 fname, strerror(errno) ));
4592 return -1;
4593 }
4594
4595 /* This must be a regular file, not a symlink, directory or
4596 other strange filetype. */
4597 if (!check_usershare_stat(fname, &lsbuf)) {
4598 return -1;
4599 }
4600
4601 /* See if there is already a servicenum for this name. */
4602 /* tdb_fetch_int32 returns -1 if not found. */
4603 iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
4604
4605 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
4606 /* Nothing changed - Mark valid and return. */
4607 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4608 service_name ));
4609 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4610 return iService;
4611 }
4612
4613 /* Try and open the file read only - no symlinks allowed. */
4614#ifdef O_NOFOLLOW
4615 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
4616#else
4617 fd = sys_open(fname, O_RDONLY, 0);
4618#endif
4619
4620 if (fd == -1) {
4621 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4622 fname, strerror(errno) ));
4623 return -1;
4624 }
4625
4626 /* Now fstat to be *SURE* it's a regular file. */
4627 if (sys_fstat(fd, &sbuf) != 0) {
4628 close(fd);
4629 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4630 fname, strerror(errno) ));
4631 return -1;
4632 }
4633
4634 /* Is it the same dev/inode as was lstated ? */
4635 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
4636 close(fd);
4637 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4638 "Symlink spoofing going on ?\n", fname ));
4639 return -1;
4640 }
4641
4642 /* This must be a regular file, not a symlink, directory or
4643 other strange filetype. */
4644 if (!check_usershare_stat(fname, &sbuf)) {
4645 return -1;
4646 }
4647
4648 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
4649
4650 close(fd);
4651 if (lines == NULL) {
4652 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4653 fname, (unsigned int)sbuf.st_uid ));
4654 return -1;
4655 }
4656
4657 /* Should we allow printers to be shared... ? */
4658 ctx = talloc_init("usershare_sd_xctx");
4659 if (!ctx) {
4660 file_lines_free(lines);
4661 return 1;
4662 }
4663
4664 if (parse_usershare_file(ctx, &sbuf, service_name,
4665 iService, lines, numlines, sharepath,
4666 comment, &psd, &guest_ok) != USERSHARE_OK) {
4667 talloc_destroy(ctx);
4668 file_lines_free(lines);
4669 return -1;
4670 }
4671
4672 file_lines_free(lines);
4673
4674 /* Everything ok - add the service possibly using a template. */
4675 if (iService < 0) {
4676 const service *sp = &sDefault;
4677 if (snum_template != -1) {
4678 sp = ServicePtrs[snum_template];
4679 }
4680
4681 if ((iService = add_a_service(sp, service_name)) < 0) {
4682 DEBUG(0, ("process_usershare_file: Failed to add "
4683 "new service %s\n", service_name));
4684 talloc_destroy(ctx);
4685 return -1;
4686 }
4687
4688 /* Read only is controlled by usershare ACL below. */
4689 ServicePtrs[iService]->bRead_only = False;
4690 }
4691
4692 /* Write the ACL of the new/modified share. */
4693 if (!set_share_security(service_name, psd)) {
4694 DEBUG(0, ("process_usershare_file: Failed to set share "
4695 "security for user share %s\n",
4696 service_name ));
4697 lp_remove_service(iService);
4698 talloc_destroy(ctx);
4699 return -1;
4700 }
4701
4702 talloc_destroy(ctx);
4703
4704 /* If from a template it may be marked invalid. */
4705 ServicePtrs[iService]->valid = True;
4706
4707 /* Set the service as a valid usershare. */
4708 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4709
4710 /* Set guest access. */
4711 if (lp_usershare_allow_guests()) {
4712 ServicePtrs[iService]->bGuest_ok = guest_ok;
4713 }
4714
4715 /* And note when it was loaded. */
4716 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
4717 string_set(&ServicePtrs[iService]->szPath, sharepath);
4718 string_set(&ServicePtrs[iService]->comment, comment);
4719
4720 return iService;
4721}
4722
4723/***************************************************************************
4724 Checks if a usershare entry has been modified since last load.
4725***************************************************************************/
4726
4727static BOOL usershare_exists(int iService, time_t *last_mod)
4728{
4729 SMB_STRUCT_STAT lsbuf;
4730 const char *usersharepath = Globals.szUsersharePath;
4731 pstring fname;
4732
4733 pstrcpy(fname, usersharepath);
4734 pstrcat(fname, "/");
4735 pstrcat(fname, ServicePtrs[iService]->szService);
4736
4737 if (sys_lstat(fname, &lsbuf) != 0) {
4738 return False;
4739 }
4740
4741 if (!S_ISREG(lsbuf.st_mode)) {
4742 return False;
4743 }
4744
4745 *last_mod = lsbuf.st_mtime;
4746 return True;
4747}
4748
4749/***************************************************************************
4750 Load a usershare service by name. Returns a valid servicenumber or -1.
4751***************************************************************************/
4752
4753int load_usershare_service(const char *servicename)
4754{
4755 SMB_STRUCT_STAT sbuf;
4756 const char *usersharepath = Globals.szUsersharePath;
4757 int max_user_shares = Globals.iUsershareMaxShares;
4758 int snum_template = -1;
4759
4760 if (*usersharepath == 0 || max_user_shares == 0) {
4761 return -1;
4762 }
4763
4764 if (sys_stat(usersharepath, &sbuf) != 0) {
4765 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4766 usersharepath, strerror(errno) ));
4767 return -1;
4768 }
4769
4770 if (!S_ISDIR(sbuf.st_mode)) {
4771 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4772 usersharepath ));
4773 return -1;
4774 }
4775
4776 /*
4777 * This directory must be owned by root, and have the 't' bit set.
4778 * It also must not be writable by "other".
4779 */
4780
4781#ifdef S_ISVTX
4782 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4783#else
4784 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4785#endif
4786 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4787 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4788 usersharepath ));
4789 return -1;
4790 }
4791
4792 /* Ensure the template share exists if it's set. */
4793 if (Globals.szUsershareTemplateShare[0]) {
4794 /* We can't use lp_servicenumber here as we are recommending that
4795 template shares have -valid=False set. */
4796 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4797 if (ServicePtrs[snum_template]->szService &&
4798 strequal(ServicePtrs[snum_template]->szService,
4799 Globals.szUsershareTemplateShare)) {
4800 break;
4801 }
4802 }
4803
4804 if (snum_template == -1) {
4805 DEBUG(0,("load_usershare_service: usershare template share %s "
4806 "does not exist.\n",
4807 Globals.szUsershareTemplateShare ));
4808 return -1;
4809 }
4810 }
4811
4812 return process_usershare_file(usersharepath, servicename, snum_template);
4813}
4814
4815/***************************************************************************
4816 Load all user defined shares from the user share directory.
4817 We only do this if we're enumerating the share list.
4818 This is the function that can delete usershares that have
4819 been removed.
4820***************************************************************************/
4821
4822int load_usershare_shares(void)
4823{
4824 SMB_STRUCT_DIR *dp;
4825 SMB_STRUCT_STAT sbuf;
4826 SMB_STRUCT_DIRENT *de;
4827 int num_usershares = 0;
4828 int max_user_shares = Globals.iUsershareMaxShares;
4829 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4830 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4831 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4832 int iService;
4833 int snum_template = -1;
4834 const char *usersharepath = Globals.szUsersharePath;
4835 int ret = lp_numservices();
4836
4837 if (max_user_shares == 0 || *usersharepath == '\0') {
4838 return lp_numservices();
4839 }
4840
4841 if (sys_stat(usersharepath, &sbuf) != 0) {
4842 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4843 usersharepath, strerror(errno) ));
4844 return ret;
4845 }
4846
4847 /*
4848 * This directory must be owned by root, and have the 't' bit set.
4849 * It also must not be writable by "other".
4850 */
4851
4852#ifdef S_ISVTX
4853 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4854#else
4855 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4856#endif
4857 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4858 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4859 usersharepath ));
4860 return ret;
4861 }
4862
4863 /* Ensure the template share exists if it's set. */
4864 if (Globals.szUsershareTemplateShare[0]) {
4865 /* We can't use lp_servicenumber here as we are recommending that
4866 template shares have -valid=False set. */
4867 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4868 if (ServicePtrs[snum_template]->szService &&
4869 strequal(ServicePtrs[snum_template]->szService,
4870 Globals.szUsershareTemplateShare)) {
4871 break;
4872 }
4873 }
4874
4875 if (snum_template == -1) {
4876 DEBUG(0,("load_usershare_shares: usershare template share %s "
4877 "does not exist.\n",
4878 Globals.szUsershareTemplateShare ));
4879 return ret;
4880 }
4881 }
4882
4883 /* Mark all existing usershares as pending delete. */
4884 for (iService = iNumServices - 1; iService >= 0; iService--) {
4885 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4886 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4887 }
4888 }
4889
4890 dp = sys_opendir(usersharepath);
4891 if (!dp) {
4892 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4893 usersharepath, strerror(errno) ));
4894 return ret;
4895 }
4896
4897 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4898 (de = sys_readdir(dp));
4899 num_dir_entries++ ) {
4900 int r;
4901 const char *n = de->d_name;
4902
4903 /* Ignore . and .. */
4904 if (*n == '.') {
4905 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4906 continue;
4907 }
4908 }
4909
4910 if (n[0] == ':') {
4911 /* Temporary file used when creating a share. */
4912 num_tmp_dir_entries++;
4913 }
4914
4915 /* Allow 20% tmp entries. */
4916 if (num_tmp_dir_entries > allowed_tmp_entries) {
4917 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4918 "in directory %s\n",
4919 num_tmp_dir_entries, usersharepath));
4920 break;
4921 }
4922
4923 r = process_usershare_file(usersharepath, n, snum_template);
4924 if (r == 0) {
4925 /* Update the services count. */
4926 num_usershares++;
4927 if (num_usershares >= max_user_shares) {
4928 DEBUG(0,("load_usershare_shares: max user shares reached "
4929 "on file %s in directory %s\n",
4930 n, usersharepath ));
4931 break;
4932 }
4933 } else if (r == -1) {
4934 num_bad_dir_entries++;
4935 }
4936
4937 /* Allow 20% bad entries. */
4938 if (num_bad_dir_entries > allowed_bad_entries) {
4939 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4940 "in directory %s\n",
4941 num_bad_dir_entries, usersharepath));
4942 break;
4943 }
4944
4945 /* Allow 20% bad entries. */
4946 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4947 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4948 "in directory %s\n",
4949 num_dir_entries, usersharepath));
4950 break;
4951 }
4952 }
4953
4954 sys_closedir(dp);
4955
4956 /* Sweep through and delete any non-refreshed usershares that are
4957 not currently in use. */
4958 for (iService = iNumServices - 1; iService >= 0; iService--) {
4959 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4960 if (conn_snum_used(iService)) {
4961 continue;
4962 }
4963 /* Remove from the share ACL db. */
4964 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4965 lp_servicename(iService) ));
4966 delete_share_security(snum2params_static(iService));
4967 free_service_byindex(iService);
4968 }
4969 }
4970
4971 return lp_numservices();
4972}
4973
4974/********************************************************
4975 Destroy global resources allocated in this file
4976********************************************************/
4977
4978void gfree_loadparm(void)
4979{
4980 struct file_lists *f;
4981 struct file_lists *next;
4982 int i;
4983
4984 lp_TALLOC_FREE();
4985
4986 /* Free the file lists */
4987
4988 f = file_lists;
4989 while( f ) {
4990 next = f->next;
4991 SAFE_FREE( f->name );
4992 SAFE_FREE( f->subfname );
4993 SAFE_FREE( f );
4994 f = next;
4995 }
4996
4997 /* Free resources allocated to services */
4998
4999 for ( i = 0; i < iNumServices; i++ ) {
5000 if ( VALID(i) ) {
5001 free_service_byindex(i);
5002 }
5003 }
5004
5005 SAFE_FREE( ServicePtrs );
5006 iNumServices = 0;
5007
5008 /* Now release all resources allocated to global
5009 parameters and the default service */
5010
5011 for (i = 0; parm_table[i].label; i++)
5012 {
5013 if ( parm_table[i].type == P_STRING
5014 || parm_table[i].type == P_USTRING )
5015 {
5016 string_free( (char**)parm_table[i].ptr );
5017 }
5018 else if (parm_table[i].type == P_LIST) {
5019 str_list_free( (char***)parm_table[i].ptr );
5020 }
5021 }
5022}
5023
5024/***************************************************************************
5025 Load the services array from the services file. Return True on success,
5026 False on failure.
5027***************************************************************************/
5028
5029BOOL lp_load(const char *pszFname,
5030 BOOL global_only,
5031 BOOL save_defaults,
5032 BOOL add_ipc,
5033 BOOL initialize_globals)
5034{
5035 pstring n2;
5036 BOOL bRetval;
5037 param_opt_struct *data, *pdata;
5038
5039 pstrcpy(n2, pszFname);
5040
5041 standard_sub_basic( get_current_username(), current_user_info.domain,
5042 n2,sizeof(n2) );
5043
5044 add_to_file_list(pszFname, n2);
5045
5046 bRetval = False;
5047
5048 DEBUG(3, ("lp_load: refreshing parameters\n"));
5049
5050 bInGlobalSection = True;
5051 bGlobalOnly = global_only;
5052
5053 init_globals(! initialize_globals);
5054 debug_init();
5055
5056 if (save_defaults) {
5057 init_locals();
5058 lp_save_defaults();
5059 }
5060
5061 if (Globals.param_opt != NULL) {
5062 data = Globals.param_opt;
5063 while (data) {
5064 string_free(&data->key);
5065 string_free(&data->value);
5066 str_list_free(&data->list);
5067 pdata = data->next;
5068 SAFE_FREE(data);
5069 data = pdata;
5070 }
5071 Globals.param_opt = NULL;
5072 }
5073
5074 /* We get sections first, so have to start 'behind' to make up */
5075 iServiceIndex = -1;
5076 bRetval = pm_process(n2, do_section, do_parameter);
5077
5078 /* finish up the last section */
5079 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
5080 if (bRetval)
5081 if (iServiceIndex >= 0)
5082 bRetval = service_ok(iServiceIndex);
5083
5084 lp_add_auto_services(lp_auto_services());
5085
5086 if (add_ipc) {
5087 /* When 'restrict anonymous = 2' guest connections to ipc$
5088 are denied */
5089 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
5090 if ( lp_enable_asu_support() )
5091 lp_add_ipc("ADMIN$", False);
5092 }
5093
5094 set_server_role();
5095 set_default_server_announce_type();
5096 set_allowed_client_auth();
5097
5098 bLoaded = True;
5099
5100 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
5101 /* if bWINSsupport is true and we are in the client */
5102 if (in_client && Globals.bWINSsupport) {
5103 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5104 }
5105
5106 init_iconv();
5107
5108 return (bRetval);
5109}
5110
5111/***************************************************************************
5112 Reset the max number of services.
5113***************************************************************************/
5114
5115void lp_resetnumservices(void)
5116{
5117 iNumServices = 0;
5118}
5119
5120/***************************************************************************
5121 Return the max number of services.
5122***************************************************************************/
5123
5124int lp_numservices(void)
5125{
5126 return (iNumServices);
5127}
5128
5129/***************************************************************************
5130Display the contents of the services array in human-readable form.
5131***************************************************************************/
5132
5133void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
5134{
5135 int iService;
5136
5137 if (show_defaults)
5138 defaults_saved = False;
5139
5140 dump_globals(f);
5141
5142 dump_a_service(&sDefault, f);
5143
5144 for (iService = 0; iService < maxtoprint; iService++) {
5145 fprintf(f,"\n");
5146 lp_dump_one(f, show_defaults, iService);
5147 }
5148}
5149
5150/***************************************************************************
5151Display the contents of one service in human-readable form.
5152***************************************************************************/
5153
5154void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
5155{
5156 if (VALID(snum)) {
5157 if (ServicePtrs[snum]->szService[0] == '\0')
5158 return;
5159 dump_a_service(ServicePtrs[snum], f);
5160 }
5161}
5162
5163/***************************************************************************
5164Return the number of the service with the given name, or -1 if it doesn't
5165exist. Note that this is a DIFFERENT ANIMAL from the internal function
5166getservicebyname()! This works ONLY if all services have been loaded, and
5167does not copy the found service.
5168***************************************************************************/
5169
5170int lp_servicenumber(const char *pszServiceName)
5171{
5172 int iService;
5173 fstring serviceName;
5174
5175 if (!pszServiceName) {
5176 return GLOBAL_SECTION_SNUM;
5177 }
5178
5179 for (iService = iNumServices - 1; iService >= 0; iService--) {
5180 if (VALID(iService) && ServicePtrs[iService]->szService) {
5181 /*
5182 * The substitution here is used to support %U is
5183 * service names
5184 */
5185 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5186 standard_sub_basic(get_current_username(),
5187 current_user_info.domain,
5188 serviceName,sizeof(serviceName));
5189 if (strequal(serviceName, pszServiceName)) {
5190 break;
5191 }
5192 }
5193 }
5194
5195 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5196 time_t last_mod;
5197
5198 if (!usershare_exists(iService, &last_mod)) {
5199 /* Remove the share security tdb entry for it. */
5200 delete_share_security(snum2params_static(iService));
5201 /* Remove it from the array. */
5202 free_service_byindex(iService);
5203 /* Doesn't exist anymore. */
5204 return GLOBAL_SECTION_SNUM;
5205 }
5206
5207 /* Has it been modified ? If so delete and reload. */
5208 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5209 /* Remove it from the array. */
5210 free_service_byindex(iService);
5211 /* and now reload it. */
5212 iService = load_usershare_service(pszServiceName);
5213 }
5214 }
5215
5216 if (iService < 0) {
5217 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5218 return GLOBAL_SECTION_SNUM;
5219 }
5220
5221 return (iService);
5222}
5223
5224BOOL share_defined(const char *service_name)
5225{
5226 return (lp_servicenumber(service_name) != -1);
5227}
5228
5229struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
5230 const char *sharename)
5231{
5232 struct share_params *result;
5233 char *sname;
5234 int snum;
5235
5236 if (!(sname = SMB_STRDUP(sharename))) {
5237 return NULL;
5238 }
5239
5240 snum = find_service(sname);
5241 SAFE_FREE(sname);
5242
5243 if (snum < 0) {
5244 return NULL;
5245 }
5246
5247 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
5248 DEBUG(0, ("talloc failed\n"));
5249 return NULL;
5250 }
5251
5252 result->service = snum;
5253 return result;
5254}
5255
5256struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
5257{
5258 struct share_iterator *result;
5259
5260 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
5261 DEBUG(0, ("talloc failed\n"));
5262 return NULL;
5263 }
5264
5265 result->next_id = 0;
5266 return result;
5267}
5268
5269struct share_params *next_share(struct share_iterator *list)
5270{
5271 struct share_params *result;
5272
5273 while (!lp_snum_ok(list->next_id) &&
5274 (list->next_id < lp_numservices())) {
5275 list->next_id += 1;
5276 }
5277
5278 if (list->next_id >= lp_numservices()) {
5279 return NULL;
5280 }
5281
5282 if (!(result = TALLOC_P(list, struct share_params))) {
5283 DEBUG(0, ("talloc failed\n"));
5284 return NULL;
5285 }
5286
5287 result->service = list->next_id;
5288 list->next_id += 1;
5289 return result;
5290}
5291
5292struct share_params *next_printer(struct share_iterator *list)
5293{
5294 struct share_params *result;
5295
5296 while ((result = next_share(list)) != NULL) {
5297 if (lp_print_ok(result->service)) {
5298 break;
5299 }
5300 }
5301 return result;
5302}
5303
5304/*
5305 * This is a hack for a transition period until we transformed all code from
5306 * service numbers to struct share_params.
5307 */
5308
5309struct share_params *snum2params_static(int snum)
5310{
5311 static struct share_params result;
5312 result.service = snum;
5313 return &result;
5314}
5315
5316/*******************************************************************
5317 A useful volume label function.
5318********************************************************************/
5319
5320const char *volume_label(int snum)
5321{
5322 char *ret;
5323 const char *label = lp_volume(snum);
5324 if (!*label) {
5325 label = lp_servicename(snum);
5326 }
5327
5328 /* This returns a 33 byte guarenteed null terminated string. */
5329 ret = talloc_strndup(main_loop_talloc_get(), label, 32);
5330 if (!ret) {
5331 return "";
5332 }
5333 return ret;
5334}
5335
5336/*******************************************************************
5337 Set the server type we will announce as via nmbd.
5338********************************************************************/
5339
5340static void set_default_server_announce_type(void)
5341{
5342 default_server_announce = 0;
5343 default_server_announce |= SV_TYPE_WORKSTATION;
5344 default_server_announce |= SV_TYPE_SERVER;
5345 default_server_announce |= SV_TYPE_SERVER_UNIX;
5346
5347 /* note that the flag should be set only if we have a
5348 printer service but nmbd doesn't actually load the
5349 services so we can't tell --jerry */
5350
5351 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5352
5353 switch (lp_announce_as()) {
5354 case ANNOUNCE_AS_NT_SERVER:
5355 default_server_announce |= SV_TYPE_SERVER_NT;
5356 /* fall through... */
5357 case ANNOUNCE_AS_NT_WORKSTATION:
5358 default_server_announce |= SV_TYPE_NT;
5359 break;
5360 case ANNOUNCE_AS_WIN95:
5361 default_server_announce |= SV_TYPE_WIN95_PLUS;
5362 break;
5363 case ANNOUNCE_AS_WFW:
5364 default_server_announce |= SV_TYPE_WFW;
5365 break;
5366 default:
5367 break;
5368 }
5369
5370 switch (lp_server_role()) {
5371 case ROLE_DOMAIN_MEMBER:
5372 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5373 break;
5374 case ROLE_DOMAIN_PDC:
5375 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5376 break;
5377 case ROLE_DOMAIN_BDC:
5378 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5379 break;
5380 case ROLE_STANDALONE:
5381 default:
5382 break;
5383 }
5384 if (lp_time_server())
5385 default_server_announce |= SV_TYPE_TIME_SOURCE;
5386
5387 if (lp_host_msdfs())
5388 default_server_announce |= SV_TYPE_DFS_SERVER;
5389}
5390
5391/***********************************************************
5392 returns role of Samba server
5393************************************************************/
5394
5395int lp_server_role(void)
5396{
5397 return server_role;
5398}
5399
5400/***********************************************************
5401 If we are PDC then prefer us as DMB
5402************************************************************/
5403
5404BOOL lp_domain_master(void)
5405{
5406 if (Globals.bDomainMaster == Auto)
5407 return (lp_server_role() == ROLE_DOMAIN_PDC);
5408
5409 return Globals.bDomainMaster;
5410}
5411
5412/***********************************************************
5413 If we are DMB then prefer us as LMB
5414************************************************************/
5415
5416BOOL lp_preferred_master(void)
5417{
5418 if (Globals.bPreferredMaster == Auto)
5419 return (lp_local_master() && lp_domain_master());
5420
5421 return Globals.bPreferredMaster;
5422}
5423
5424/*******************************************************************
5425 Remove a service.
5426********************************************************************/
5427
5428void lp_remove_service(int snum)
5429{
5430 ServicePtrs[snum]->valid = False;
5431 invalid_services[num_invalid_services++] = snum;
5432}
5433
5434/*******************************************************************
5435 Copy a service.
5436********************************************************************/
5437
5438void lp_copy_service(int snum, const char *new_name)
5439{
5440 do_section(new_name);
5441 if (snum >= 0) {
5442 snum = lp_servicenumber(new_name);
5443 if (snum >= 0)
5444 lp_do_parameter(snum, "copy", lp_servicename(snum));
5445 }
5446}
5447
5448
5449/*******************************************************************
5450 Get the default server type we will announce as via nmbd.
5451********************************************************************/
5452
5453int lp_default_server_announce(void)
5454{
5455 return default_server_announce;
5456}
5457
5458/*******************************************************************
5459 Split the announce version into major and minor numbers.
5460********************************************************************/
5461
5462int lp_major_announce_version(void)
5463{
5464 static BOOL got_major = False;
5465 static int major_version = DEFAULT_MAJOR_VERSION;
5466 char *vers;
5467 char *p;
5468
5469 if (got_major)
5470 return major_version;
5471
5472 got_major = True;
5473 if ((vers = lp_announce_version()) == NULL)
5474 return major_version;
5475
5476 if ((p = strchr_m(vers, '.')) == 0)
5477 return major_version;
5478
5479 *p = '\0';
5480 major_version = atoi(vers);
5481 return major_version;
5482}
5483
5484int lp_minor_announce_version(void)
5485{
5486 static BOOL got_minor = False;
5487 static int minor_version = DEFAULT_MINOR_VERSION;
5488 char *vers;
5489 char *p;
5490
5491 if (got_minor)
5492 return minor_version;
5493
5494 got_minor = True;
5495 if ((vers = lp_announce_version()) == NULL)
5496 return minor_version;
5497
5498 if ((p = strchr_m(vers, '.')) == 0)
5499 return minor_version;
5500
5501 p++;
5502 minor_version = atoi(p);
5503 return minor_version;
5504}
5505
5506/***********************************************************
5507 Set the global name resolution order (used in smbclient).
5508************************************************************/
5509
5510void lp_set_name_resolve_order(const char *new_order)
5511{
5512 string_set(&Globals.szNameResolveOrder, new_order);
5513}
5514
5515const char *lp_printername(int snum)
5516{
5517 const char *ret = _lp_printername(snum);
5518 if (ret == NULL || (ret != NULL && *ret == '\0'))
5519 ret = lp_const_servicename(snum);
5520
5521 return ret;
5522}
5523
5524
5525/***********************************************************
5526 Allow daemons such as winbindd to fix their logfile name.
5527************************************************************/
5528
5529void lp_set_logfile(const char *name)
5530{
5531 string_set(&Globals.szLogFile, name);
5532 pstrcpy(debugf, name);
5533}
5534
5535/*******************************************************************
5536 Return the max print jobs per queue.
5537********************************************************************/
5538
5539int lp_maxprintjobs(int snum)
5540{
5541 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5542 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5543 maxjobs = PRINT_MAX_JOBID - 1;
5544
5545 return maxjobs;
5546}
5547
5548const char *lp_printcapname(void)
5549{
5550 if ((Globals.szPrintcapname != NULL) &&
5551 (Globals.szPrintcapname[0] != '\0'))
5552 return Globals.szPrintcapname;
5553
5554 if (sDefault.iPrinting == PRINT_CUPS) {
5555#ifdef HAVE_CUPS
5556 return "cups";
5557#else
5558 return "lpstat";
5559#endif
5560 }
5561
5562 if (sDefault.iPrinting == PRINT_BSD)
5563 return "/etc/printcap";
5564
5565 return PRINTCAP_NAME;
5566}
5567
5568/*******************************************************************
5569 Ensure we don't use sendfile if server smb signing is active.
5570********************************************************************/
5571
5572static uint32 spoolss_state;
5573
5574BOOL lp_disable_spoolss( void )
5575{
5576 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5577 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5578
5579 return spoolss_state == SVCCTL_STOPPED ? True : False;
5580}
5581
5582void lp_set_spoolss_state( uint32 state )
5583{
5584 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5585
5586 spoolss_state = state;
5587}
5588
5589uint32 lp_get_spoolss_state( void )
5590{
5591 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5592}
5593
5594/*******************************************************************
5595 Ensure we don't use sendfile if server smb signing is active.
5596********************************************************************/
5597
5598BOOL lp_use_sendfile(int snum)
5599{
5600 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5601 if (Protocol < PROTOCOL_NT1) {
5602 return False;
5603 }
5604 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
5605}
5606
5607/*******************************************************************
5608 Turn off sendfile if we find the underlying OS doesn't support it.
5609********************************************************************/
5610
5611void set_use_sendfile(int snum, BOOL val)
5612{
5613 if (LP_SNUM_OK(snum))
5614 ServicePtrs[snum]->bUseSendfile = val;
5615 else
5616 sDefault.bUseSendfile = val;
5617}
5618
5619/*******************************************************************
5620 Turn off storing DOS attributes if this share doesn't support it.
5621********************************************************************/
5622
5623void set_store_dos_attributes(int snum, BOOL val)
5624{
5625 if (!LP_SNUM_OK(snum))
5626 return;
5627 ServicePtrs[(snum)]->bStoreDosAttributes = val;
5628}
5629
5630void lp_set_mangling_method(const char *new_method)
5631{
5632 string_set(&Globals.szManglingMethod, new_method);
5633}
5634
5635/*******************************************************************
5636 Global state for POSIX pathname processing.
5637********************************************************************/
5638
5639static BOOL posix_pathnames;
5640
5641BOOL lp_posix_pathnames(void)
5642{
5643 return posix_pathnames;
5644}
5645
5646/*******************************************************************
5647 Change everything needed to ensure POSIX pathname processing (currently
5648 not much).
5649********************************************************************/
5650
5651void lp_set_posix_pathnames(void)
5652{
5653 posix_pathnames = True;
5654}
5655
5656/*******************************************************************
5657 Global state for POSIX lock processing - CIFS unix extensions.
5658********************************************************************/
5659
5660BOOL posix_default_lock_was_set;
5661static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5662
5663enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5664{
5665 if (posix_default_lock_was_set) {
5666 return posix_cifsx_locktype;
5667 } else {
5668 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5669 }
5670}
5671
5672/*******************************************************************
5673********************************************************************/
5674
5675void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5676{
5677 posix_default_lock_was_set = True;
5678 posix_cifsx_locktype = val;
5679}
Note: See TracBrowser for help on using the repository browser.