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

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

Fix for Ticket #85 (by diver)

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