source: trunk-3.0/source/param/loadparm.c@ 101

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

Update source to 3.0.26a

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