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

Last change on this file since 406 was 406, checked in by Herwig Bauernfeind, 16 years ago

Workaround for Ticket #126 as suggested by the Samba people

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