source: branches/samba-3.2.x/source/param/loadparm.c@ 216

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

Update 3.2 branch to 3.2.4

File size: 251.0 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
5
6 Largely re-written by Andrew Tridgell, September 1994
7
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12 Copyright (C) Michael Adam 2008
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 3 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
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 bLoaded = False;
57
58extern enum protocol_types Protocol;
59extern userdom_struct current_user_info;
60
61#ifndef GLOBAL_NAME
62#define GLOBAL_NAME "global"
63#endif
64
65#ifndef PRINTERS_NAME
66#define PRINTERS_NAME "printers"
67#endif
68
69#ifndef HOMES_NAME
70#define HOMES_NAME "homes"
71#endif
72
73/* the special value for the include parameter
74 * to be interpreted not as a file name but to
75 * trigger loading of the global smb.conf options
76 * from registry. */
77#ifndef INCLUDE_REGISTRY_NAME
78#define INCLUDE_REGISTRY_NAME "registry"
79#endif
80
81static bool in_client = False; /* Not in the client by default */
82static struct smbconf_csn conf_last_csn;
83
84#define CONFIG_BACKEND_FILE 0
85#define CONFIG_BACKEND_REGISTRY 1
86
87static int config_backend = CONFIG_BACKEND_FILE;
88
89/* some helpful bits */
90#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
91#define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
92
93#define USERSHARE_VALID 1
94#define USERSHARE_PENDING_DELETE 2
95
96extern int extra_time_offset;
97
98static bool defaults_saved = False;
99
100typedef struct _param_opt_struct param_opt_struct;
101struct _param_opt_struct {
102 param_opt_struct *prev, *next;
103 char *key;
104 char *value;
105 char **list;
106};
107
108/*
109 * This structure describes global (ie., server-wide) parameters.
110 */
111struct global {
112 int ConfigBackend;
113 char *smb_ports;
114 char *dos_charset;
115 char *unix_charset;
116 char *display_charset;
117 char *szPrintcapname;
118 char *szAddPortCommand;
119 char *szEnumPortsCommand;
120 char *szAddPrinterCommand;
121 char *szDeletePrinterCommand;
122 char *szOs2DriverMap;
123 char *szLockDir;
124 char *szPidDir;
125 char *szRootdir;
126 char *szDefaultService;
127 char *szGetQuota;
128 char *szSetQuota;
129 char *szMsgCommand;
130 char *szServerString;
131 char *szAutoServices;
132 char *szPasswdProgram;
133 char *szPasswdChat;
134 char *szLogFile;
135 char *szConfigFile;
136 char *szSMBPasswdFile;
137 char *szPrivateDir;
138 char *szPassdbBackend;
139 char **szPreloadModules;
140 char *szPasswordServer;
141 char *szSocketOptions;
142 char *szRealm;
143 char *szAfsUsernameMap;
144 int iAfsTokenLifetime;
145 char *szLogNtTokenCommand;
146 char *szUsernameMap;
147 char *szLogonScript;
148 char *szLogonPath;
149 char *szLogonDrive;
150 char *szLogonHome;
151 char **szWINSservers;
152 char **szInterfaces;
153 char *szRemoteAnnounce;
154 char *szRemoteBrowseSync;
155 char *szSocketAddress;
156 char *szNISHomeMapName;
157 char *szAnnounceVersion; /* This is initialised in init_globals */
158 char *szWorkgroup;
159 char *szNetbiosName;
160 char **szNetbiosAliases;
161 char *szNetbiosScope;
162 char *szNameResolveOrder;
163 char *szPanicAction;
164 char *szAddUserScript;
165 char *szRenameUserScript;
166 char *szDelUserScript;
167 char *szAddGroupScript;
168 char *szDelGroupScript;
169 char *szAddUserToGroupScript;
170 char *szDelUserFromGroupScript;
171 char *szSetPrimaryGroupScript;
172 char *szAddMachineScript;
173 char *szShutdownScript;
174 char *szAbortShutdownScript;
175 char *szUsernameMapScript;
176 char *szCheckPasswordScript;
177 char *szWINSHook;
178 char *szUtmpDir;
179 char *szWtmpDir;
180 bool bUtmp;
181 char *szIdmapUID;
182 char *szIdmapGID;
183 bool bPassdbExpandExplicit;
184 int AlgorithmicRidBase;
185 char *szTemplateHomedir;
186 char *szTemplateShell;
187 char *szWinbindSeparator;
188 bool bWinbindEnumUsers;
189 bool bWinbindEnumGroups;
190 bool bWinbindUseDefaultDomain;
191 bool bWinbindTrustedDomainsOnly;
192 bool bWinbindNestedGroups;
193 int winbind_expand_groups;
194 bool bWinbindRefreshTickets;
195 bool bWinbindOfflineLogon;
196 bool bWinbindNormalizeNames;
197 bool bWinbindRpcOnly;
198 char **szIdmapDomains;
199 char **szIdmapBackend; /* deprecated */
200 char *szIdmapAllocBackend;
201 char *szAddShareCommand;
202 char *szChangeShareCommand;
203 char *szDeleteShareCommand;
204 char **szEventLogs;
205 char *szGuestaccount;
206 char *szManglingMethod;
207 char **szServicesList;
208 char *szUsersharePath;
209 char *szUsershareTemplateShare;
210 char **szUsersharePrefixAllowList;
211 char **szUsersharePrefixDenyList;
212 int mangle_prefix;
213 int max_log_size;
214 char *szLogLevel;
215 int max_xmit;
216 int max_mux;
217 int max_open_files;
218 int open_files_db_hash_size;
219 int pwordlevel;
220 int unamelevel;
221 int deadtime;
222 bool getwd_cache;
223 int maxprotocol;
224 int minprotocol;
225 int security;
226 char **AuthMethods;
227 bool paranoid_server_security;
228 int maxdisksize;
229 int lpqcachetime;
230 int iMaxSmbdProcesses;
231 bool bDisableSpoolss;
232 int syslog;
233 int os_level;
234 bool enhanced_browsing;
235 int max_ttl;
236 int max_wins_ttl;
237 int min_wins_ttl;
238 int lm_announce;
239 int lm_interval;
240 int announce_as; /* This is initialised in init_globals */
241 int machine_password_timeout;
242 int map_to_guest;
243 int oplock_break_wait_time;
244 int winbind_cache_time;
245 int winbind_max_idle_children;
246 char **szWinbindNssInfo;
247 int iLockSpinTime;
248 char *szLdapMachineSuffix;
249 char *szLdapUserSuffix;
250 char *szLdapIdmapSuffix;
251 char *szLdapGroupSuffix;
252 int ldap_ssl;
253 char *szLdapSuffix;
254 char *szLdapAdminDn;
255 int ldap_debug_level;
256 int ldap_debug_threshold;
257 int iAclCompat;
258 char *szCupsServer;
259 char *szIPrintServer;
260 char *ctdbdSocket;
261 char **szClusterAddresses;
262 bool clustering;
263 int ldap_passwd_sync;
264 int ldap_replication_sleep;
265 int ldap_timeout; /* This is initialised in init_globals */
266 int ldap_connection_timeout;
267 int ldap_page_size;
268 bool ldap_delete_dn;
269 bool bMsAddPrinterWizard;
270 bool bDNSproxy;
271 bool bWINSsupport;
272 bool bWINSproxy;
273 bool bLocalMaster;
274 int iPreferredMaster;
275 int iDomainMaster;
276 bool bDomainLogons;
277 bool bEncryptPasswords;
278 bool bUpdateEncrypt;
279 int clientSchannel;
280 int serverSchannel;
281 bool bNullPasswords;
282 bool bObeyPamRestrictions;
283 bool bLoadPrinters;
284 int PrintcapCacheTime;
285 bool bLargeReadwrite;
286 bool bReadRaw;
287 bool bWriteRaw;
288 bool bSyslogOnly;
289 bool bBrowseList;
290 bool bNISHomeMap;
291 bool bTimeServer;
292 bool bBindInterfacesOnly;
293 bool bPamPasswordChange;
294 bool bUnixPasswdSync;
295 bool bPasswdChatDebug;
296 int iPasswdChatTimeout;
297 bool bTimestampLogs;
298 bool bNTSmbSupport;
299 bool bNTPipeSupport;
300 bool bNTStatusSupport;
301 bool bStatCache;
302 int iMaxStatCacheSize;
303 bool bKernelOplocks;
304 bool bAllowTrustedDomains;
305 bool bLanmanAuth;
306 bool bNTLMAuth;
307 bool bUseSpnego;
308 bool bClientLanManAuth;
309 bool bClientNTLMv2Auth;
310 bool bClientPlaintextAuth;
311 bool bClientUseSpnego;
312 bool bDebugPrefixTimestamp;
313 bool bDebugHiresTimestamp;
314 bool bDebugPid;
315 bool bDebugUid;
316 bool bDebugClass;
317 bool bEnableCoreFiles;
318 bool bHostMSDfs;
319 bool bUseMmap;
320 bool bHostnameLookups;
321 bool bUnixExtensions;
322 bool bDisableNetbios;
323 bool bUseKerberosKeytab;
324 bool bDeferSharingViolations;
325 bool bEnablePrivileges;
326 bool bASUSupport;
327 bool bUsershareOwnerOnly;
328 bool bUsershareAllowGuests;
329 bool bRegistryShares;
330 int restrict_anonymous;
331 int name_cache_timeout;
332 int client_signing;
333 int server_signing;
334 int client_ldap_sasl_wrapping;
335 int iUsershareMaxShares;
336 int iIdmapCacheTime;
337 int iIdmapNegativeCacheTime;
338 bool bResetOnZeroVC;
339 int iKeepalive;
340 int iminreceivefile;
341 param_opt_struct *param_opt;
342};
343
344static struct global Globals;
345
346/*
347 * This structure describes a single service.
348 */
349struct service {
350 bool valid;
351 bool autoloaded;
352 int usershare;
353 time_t usershare_last_mod;
354 char *szService;
355 char *szPath;
356 char *szUsername;
357 char **szInvalidUsers;
358 char **szValidUsers;
359 char **szAdminUsers;
360 char *szCopy;
361 char *szInclude;
362 char *szPreExec;
363 char *szPostExec;
364 char *szRootPreExec;
365 char *szRootPostExec;
366 char *szCupsOptions;
367 char *szPrintcommand;
368 char *szLpqcommand;
369 char *szLprmcommand;
370 char *szLppausecommand;
371 char *szLpresumecommand;
372 char *szQueuepausecommand;
373 char *szQueueresumecommand;
374 char *szPrintername;
375 char *szPrintjobUsername;
376 char *szDontdescend;
377 char **szHostsallow;
378 char **szHostsdeny;
379 char *szMagicScript;
380 char *szMagicOutput;
381 char *szVetoFiles;
382 char *szHideFiles;
383 char *szVetoOplockFiles;
384 char *comment;
385 char *force_user;
386 char *force_group;
387 char **readlist;
388 char **writelist;
389 char **printer_admin;
390 char *volume;
391 char *fstype;
392 char **szVfsObjects;
393 char *szMSDfsProxy;
394 char *szAioWriteBehind;
395 char *szDfree;
396 int iMinPrintSpace;
397 int iMaxPrintJobs;
398 int iMaxReportedPrintJobs;
399 int iWriteCacheSize;
400 int iCreate_mask;
401 int iCreate_force_mode;
402 int iSecurity_mask;
403 int iSecurity_force_mode;
404 int iDir_mask;
405 int iDir_force_mode;
406 int iDir_Security_mask;
407 int iDir_Security_force_mode;
408 int iMaxConnections;
409 int iDefaultCase;
410 int iPrinting;
411 int iOplockContentionLimit;
412 int iCSCPolicy;
413 int iBlock_size;
414 int iDfreeCacheTime;
415 bool bPreexecClose;
416 bool bRootpreexecClose;
417 int iCaseSensitive;
418 bool bCasePreserve;
419 bool bShortCasePreserve;
420 bool bHideDotFiles;
421 bool bHideSpecialFiles;
422 bool bHideUnReadable;
423 bool bHideUnWriteableFiles;
424 bool bBrowseable;
425 bool bAvailable;
426 bool bRead_only;
427 bool bNo_set_dir;
428 bool bGuest_only;
429 bool bAdministrative_share;
430 bool bGuest_ok;
431 bool bPrint_ok;
432 bool bMap_system;
433 bool bMap_hidden;
434 bool bMap_archive;
435 bool bStoreDosAttributes;
436 bool bDmapiSupport;
437 bool bLocking;
438 int iStrictLocking;
439 bool bPosixLocking;
440 bool bShareModes;
441 bool bOpLocks;
442 bool bLevel2OpLocks;
443 bool bOnlyUser;
444 bool bMangledNames;
445 bool bWidelinks;
446 bool bSymlinks;
447 bool bSyncAlways;
448 bool bStrictAllocate;
449 bool bStrictSync;
450 char magic_char;
451 struct bitmap *copymap;
452 bool bDeleteReadonly;
453 bool bFakeOplocks;
454 bool bDeleteVetoFiles;
455 bool bDosFilemode;
456 bool bDosFiletimes;
457 bool bDosFiletimeResolution;
458 bool bFakeDirCreateTimes;
459 bool bBlockingLocks;
460 bool bInheritPerms;
461 bool bInheritACLS;
462 bool bInheritOwner;
463 bool bMSDfsRoot;
464 bool bUseClientDriver;
465 bool bDefaultDevmode;
466 bool bForcePrintername;
467 bool bNTAclSupport;
468 bool bForceUnknownAclUser;
469 bool bUseSendfile;
470 bool bProfileAcls;
471 bool bMap_acl_inherit;
472 bool bAfs_Share;
473 bool bEASupport;
474 bool bAclCheckPermissions;
475 bool bAclMapFullControl;
476 bool bAclGroupControl;
477 bool bChangeNotify;
478 bool bKernelChangeNotify;
479 int iallocation_roundup_size;
480 int iAioReadSize;
481 int iAioWriteSize;
482 int iMap_readonly;
483 int iDirectoryNameCacheSize;
484 int ismb_encrypt;
485 param_opt_struct *param_opt;
486
487 char dummy[3]; /* for alignment */
488};
489
490
491/* This is a default service used to prime a services structure */
492static struct service sDefault = {
493 True, /* valid */
494 False, /* not autoloaded */
495 0, /* not a usershare */
496 (time_t)0, /* No last mod time */
497 NULL, /* szService */
498 NULL, /* szPath */
499 NULL, /* szUsername */
500 NULL, /* szInvalidUsers */
501 NULL, /* szValidUsers */
502 NULL, /* szAdminUsers */
503 NULL, /* szCopy */
504 NULL, /* szInclude */
505 NULL, /* szPreExec */
506 NULL, /* szPostExec */
507 NULL, /* szRootPreExec */
508 NULL, /* szRootPostExec */
509 NULL, /* szCupsOptions */
510 NULL, /* szPrintcommand */
511 NULL, /* szLpqcommand */
512 NULL, /* szLprmcommand */
513 NULL, /* szLppausecommand */
514 NULL, /* szLpresumecommand */
515 NULL, /* szQueuepausecommand */
516 NULL, /* szQueueresumecommand */
517 NULL, /* szPrintername */
518 NULL, /* szPrintjobUsername */
519 NULL, /* szDontdescend */
520 NULL, /* szHostsallow */
521 NULL, /* szHostsdeny */
522 NULL, /* szMagicScript */
523 NULL, /* szMagicOutput */
524 NULL, /* szVetoFiles */
525 NULL, /* szHideFiles */
526 NULL, /* szVetoOplockFiles */
527 NULL, /* comment */
528 NULL, /* force user */
529 NULL, /* force group */
530 NULL, /* readlist */
531 NULL, /* writelist */
532 NULL, /* printer admin */
533 NULL, /* volume */
534 NULL, /* fstype */
535 NULL, /* vfs objects */
536 NULL, /* szMSDfsProxy */
537 NULL, /* szAioWriteBehind */
538 NULL, /* szDfree */
539 0, /* iMinPrintSpace */
540 1000, /* iMaxPrintJobs */
541 0, /* iMaxReportedPrintJobs */
542 0, /* iWriteCacheSize */
543 0744, /* iCreate_mask */
544 0000, /* iCreate_force_mode */
545 0777, /* iSecurity_mask */
546 0, /* iSecurity_force_mode */
547 0755, /* iDir_mask */
548 0000, /* iDir_force_mode */
549 0777, /* iDir_Security_mask */
550 0, /* iDir_Security_force_mode */
551 0, /* iMaxConnections */
552 CASE_LOWER, /* iDefaultCase */
553 DEFAULT_PRINTING, /* iPrinting */
554 2, /* iOplockContentionLimit */
555 0, /* iCSCPolicy */
556 1024, /* iBlock_size */
557 0, /* iDfreeCacheTime */
558 False, /* bPreexecClose */
559 False, /* bRootpreexecClose */
560 Auto, /* case sensitive */
561 True, /* case preserve */
562 True, /* short case preserve */
563 True, /* bHideDotFiles */
564 False, /* bHideSpecialFiles */
565 False, /* bHideUnReadable */
566 False, /* bHideUnWriteableFiles */
567 True, /* bBrowseable */
568 True, /* bAvailable */
569 True, /* bRead_only */
570 True, /* bNo_set_dir */
571 False, /* bGuest_only */
572 False, /* bAdministrative_share */
573 False, /* bGuest_ok */
574 False, /* bPrint_ok */
575 False, /* bMap_system */
576 False, /* bMap_hidden */
577 True, /* bMap_archive */
578 False, /* bStoreDosAttributes */
579 False, /* bDmapiSupport */
580 True, /* bLocking */
581 Auto, /* iStrictLocking */
582 True, /* bPosixLocking */
583 True, /* bShareModes */
584 True, /* bOpLocks */
585 True, /* bLevel2OpLocks */
586 False, /* bOnlyUser */
587 True, /* bMangledNames */
588 True, /* bWidelinks */
589 True, /* bSymlinks */
590 False, /* bSyncAlways */
591 False, /* bStrictAllocate */
592 False, /* bStrictSync */
593 '~', /* magic char */
594 NULL, /* copymap */
595 False, /* bDeleteReadonly */
596 False, /* bFakeOplocks */
597 False, /* bDeleteVetoFiles */
598 False, /* bDosFilemode */
599 True, /* bDosFiletimes */
600 False, /* bDosFiletimeResolution */
601 False, /* bFakeDirCreateTimes */
602 True, /* bBlockingLocks */
603 False, /* bInheritPerms */
604 False, /* bInheritACLS */
605 False, /* bInheritOwner */
606 False, /* bMSDfsRoot */
607 False, /* bUseClientDriver */
608 True, /* bDefaultDevmode */
609 False, /* bForcePrintername */
610 True, /* bNTAclSupport */
611 False, /* bForceUnknownAclUser */
612 False, /* bUseSendfile */
613 False, /* bProfileAcls */
614 False, /* bMap_acl_inherit */
615 False, /* bAfs_Share */
616 False, /* bEASupport */
617 True, /* bAclCheckPermissions */
618 True, /* bAclMapFullControl */
619 False, /* bAclGroupControl */
620 True, /* bChangeNotify */
621 True, /* bKernelChangeNotify */
622 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
623 0, /* iAioReadSize */
624 0, /* iAioWriteSize */
625 MAP_READONLY_YES, /* iMap_readonly */
626#ifdef BROKEN_DIRECTORY_HANDLING
627 0, /* iDirectoryNameCacheSize */
628#else
629 100, /* iDirectoryNameCacheSize */
630#endif
631 Auto, /* ismb_encrypt */
632 NULL, /* Parametric options */
633
634 "" /* dummy */
635};
636
637/* local variables */
638static struct service **ServicePtrs = NULL;
639static int iNumServices = 0;
640static int iServiceIndex = 0;
641static struct db_context *ServiceHash;
642static int *invalid_services = NULL;
643static int num_invalid_services = 0;
644static bool bInGlobalSection = True;
645static bool bGlobalOnly = False;
646static int server_role;
647static int default_server_announce;
648
649#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
650
651/* prototypes for the special type handlers */
652static bool handle_include( int snum, const char *pszParmValue, char **ptr);
653static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
654static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
655static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
656static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
657static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
658static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
659static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
660static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
661static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
662static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
663static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
664
665static void set_server_role(void);
666static void set_default_server_announce_type(void);
667static void set_allowed_client_auth(void);
668
669static const struct enum_list enum_protocol[] = {
670 {PROTOCOL_NT1, "NT1"},
671 {PROTOCOL_LANMAN2, "LANMAN2"},
672 {PROTOCOL_LANMAN1, "LANMAN1"},
673 {PROTOCOL_CORE, "CORE"},
674 {PROTOCOL_COREPLUS, "COREPLUS"},
675 {PROTOCOL_COREPLUS, "CORE+"},
676 {-1, NULL}
677};
678
679static const struct enum_list enum_security[] = {
680 {SEC_SHARE, "SHARE"},
681 {SEC_USER, "USER"},
682 {SEC_SERVER, "SERVER"},
683 {SEC_DOMAIN, "DOMAIN"},
684#ifdef HAVE_ADS
685 {SEC_ADS, "ADS"},
686#endif
687 {-1, NULL}
688};
689
690static const struct enum_list enum_printing[] = {
691 {PRINT_SYSV, "sysv"},
692 {PRINT_AIX, "aix"},
693 {PRINT_HPUX, "hpux"},
694 {PRINT_BSD, "bsd"},
695 {PRINT_QNX, "qnx"},
696 {PRINT_PLP, "plp"},
697 {PRINT_LPRNG, "lprng"},
698 {PRINT_CUPS, "cups"},
699 {PRINT_IPRINT, "iprint"},
700 {PRINT_LPRNT, "nt"},
701 {PRINT_LPROS2, "os2"},
702#ifdef DEVELOPER
703 {PRINT_TEST, "test"},
704 {PRINT_VLP, "vlp"},
705#endif /* DEVELOPER */
706 {-1, NULL}
707};
708
709static const struct enum_list enum_ldap_sasl_wrapping[] = {
710 {0, "plain"},
711 {ADS_AUTH_SASL_SIGN, "sign"},
712 {ADS_AUTH_SASL_SEAL, "seal"},
713 {-1, NULL}
714};
715
716static const struct enum_list enum_ldap_ssl[] = {
717 {LDAP_SSL_OFF, "no"},
718 {LDAP_SSL_OFF, "No"},
719 {LDAP_SSL_OFF, "off"},
720 {LDAP_SSL_OFF, "Off"},
721 {LDAP_SSL_START_TLS, "start tls"},
722 {LDAP_SSL_START_TLS, "Start_tls"},
723 {-1, NULL}
724};
725
726static const struct enum_list enum_ldap_passwd_sync[] = {
727 {LDAP_PASSWD_SYNC_OFF, "no"},
728 {LDAP_PASSWD_SYNC_OFF, "No"},
729 {LDAP_PASSWD_SYNC_OFF, "off"},
730 {LDAP_PASSWD_SYNC_OFF, "Off"},
731 {LDAP_PASSWD_SYNC_ON, "Yes"},
732 {LDAP_PASSWD_SYNC_ON, "yes"},
733 {LDAP_PASSWD_SYNC_ON, "on"},
734 {LDAP_PASSWD_SYNC_ON, "On"},
735 {LDAP_PASSWD_SYNC_ONLY, "Only"},
736 {LDAP_PASSWD_SYNC_ONLY, "only"},
737 {-1, NULL}
738};
739
740/* Types of machine we can announce as. */
741#define ANNOUNCE_AS_NT_SERVER 1
742#define ANNOUNCE_AS_WIN95 2
743#define ANNOUNCE_AS_WFW 3
744#define ANNOUNCE_AS_NT_WORKSTATION 4
745
746static const struct enum_list enum_announce_as[] = {
747 {ANNOUNCE_AS_NT_SERVER, "NT"},
748 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
749 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
750 {ANNOUNCE_AS_WIN95, "win95"},
751 {ANNOUNCE_AS_WFW, "WfW"},
752 {-1, NULL}
753};
754
755static const struct enum_list enum_map_readonly[] = {
756 {MAP_READONLY_NO, "no"},
757 {MAP_READONLY_NO, "false"},
758 {MAP_READONLY_NO, "0"},
759 {MAP_READONLY_YES, "yes"},
760 {MAP_READONLY_YES, "true"},
761 {MAP_READONLY_YES, "1"},
762 {MAP_READONLY_PERMISSIONS, "permissions"},
763 {MAP_READONLY_PERMISSIONS, "perms"},
764 {-1, NULL}
765};
766
767static const struct enum_list enum_case[] = {
768 {CASE_LOWER, "lower"},
769 {CASE_UPPER, "upper"},
770 {-1, NULL}
771};
772
773static const struct enum_list enum_bool_auto[] = {
774 {False, "No"},
775 {False, "False"},
776 {False, "0"},
777 {True, "Yes"},
778 {True, "True"},
779 {True, "1"},
780 {Auto, "Auto"},
781 {-1, NULL}
782};
783
784/* Client-side offline caching policy types */
785#define CSC_POLICY_MANUAL 0
786#define CSC_POLICY_DOCUMENTS 1
787#define CSC_POLICY_PROGRAMS 2
788#define CSC_POLICY_DISABLE 3
789
790static const struct enum_list enum_csc_policy[] = {
791 {CSC_POLICY_MANUAL, "manual"},
792 {CSC_POLICY_DOCUMENTS, "documents"},
793 {CSC_POLICY_PROGRAMS, "programs"},
794 {CSC_POLICY_DISABLE, "disable"},
795 {-1, NULL}
796};
797
798/* SMB signing types. */
799static const struct enum_list enum_smb_signing_vals[] = {
800 {False, "No"},
801 {False, "False"},
802 {False, "0"},
803 {False, "Off"},
804 {False, "disabled"},
805 {True, "Yes"},
806 {True, "True"},
807 {True, "1"},
808 {True, "On"},
809 {True, "enabled"},
810 {Auto, "auto"},
811 {Required, "required"},
812 {Required, "mandatory"},
813 {Required, "force"},
814 {Required, "forced"},
815 {Required, "enforced"},
816 {-1, NULL}
817};
818
819/* ACL compatibility options. */
820static const struct enum_list enum_acl_compat_vals[] = {
821 { ACL_COMPAT_AUTO, "auto" },
822 { ACL_COMPAT_WINNT, "winnt" },
823 { ACL_COMPAT_WIN2K, "win2k" },
824 { -1, NULL}
825};
826
827/*
828 Do you want session setups at user level security with a invalid
829 password to be rejected or allowed in as guest? WinNT rejects them
830 but it can be a pain as it means "net view" needs to use a password
831
832 You have 3 choices in the setting of map_to_guest:
833
834 "Never" means session setups with an invalid password
835 are rejected. This is the default.
836
837 "Bad User" means session setups with an invalid password
838 are rejected, unless the username does not exist, in which case it
839 is treated as a guest login
840
841 "Bad Password" means session setups with an invalid password
842 are treated as a guest login
843
844 Note that map_to_guest only has an effect in user or server
845 level security.
846*/
847
848static const struct enum_list enum_map_to_guest[] = {
849 {NEVER_MAP_TO_GUEST, "Never"},
850 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
851 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
852 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
853 {-1, NULL}
854};
855
856/* Config backend options */
857
858static const struct enum_list enum_config_backend[] = {
859 {CONFIG_BACKEND_FILE, "file"},
860 {CONFIG_BACKEND_REGISTRY, "registry"},
861 {-1, NULL}
862};
863
864/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
865 *
866 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
867 * screen in SWAT. This is used to exclude parameters as well as to squash all
868 * parameters that have been duplicated by pseudonyms.
869 *
870 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
871 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
872 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
873 * respective views.
874 *
875 * NOTE2: Handling of duplicated (synonym) paramters:
876 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
877 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
878 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
879 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
880 */
881
882static struct parm_struct parm_table[] = {
883 {N_("Base Options"), P_SEP, P_SEPARATOR},
884
885 {
886 .label = "dos charset",
887 .type = P_STRING,
888 .p_class = P_GLOBAL,
889 .ptr = &Globals.dos_charset,
890 .special = handle_charset,
891 .enum_list = NULL,
892 .flags = FLAG_ADVANCED
893 },
894 {
895 .label = "unix charset",
896 .type = P_STRING,
897 .p_class = P_GLOBAL,
898 .ptr = &Globals.unix_charset,
899 .special = handle_charset,
900 .enum_list = NULL,
901 .flags = FLAG_ADVANCED
902 },
903 {
904 .label = "display charset",
905 .type = P_STRING,
906 .p_class = P_GLOBAL,
907 .ptr = &Globals.display_charset,
908 .special = handle_charset,
909 .enum_list = NULL,
910 .flags = FLAG_ADVANCED
911 },
912 {
913 .label = "comment",
914 .type = P_STRING,
915 .p_class = P_LOCAL,
916 .ptr = &sDefault.comment,
917 .special = NULL,
918 .enum_list = NULL,
919 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
920 },
921 {
922 .label = "path",
923 .type = P_STRING,
924 .p_class = P_LOCAL,
925 .ptr = &sDefault.szPath,
926 .special = NULL,
927 .enum_list = NULL,
928 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
929 },
930 {
931 .label = "directory",
932 .type = P_STRING,
933 .p_class = P_LOCAL,
934 .ptr = &sDefault.szPath,
935 .special = NULL,
936 .enum_list = NULL,
937 .flags = FLAG_HIDE,
938 },
939 {
940 .label = "workgroup",
941 .type = P_USTRING,
942 .p_class = P_GLOBAL,
943 .ptr = &Globals.szWorkgroup,
944 .special = handle_workgroup,
945 .enum_list = NULL,
946 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
947 },
948#ifdef WITH_ADS
949 {
950 .label = "realm",
951 .type = P_USTRING,
952 .p_class = P_GLOBAL,
953 .ptr = &Globals.szRealm,
954 .special = NULL,
955 .enum_list = NULL,
956 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
957 },
958#endif
959 {
960 .label = "netbios name",
961 .type = P_USTRING,
962 .p_class = P_GLOBAL,
963 .ptr = &Globals.szNetbiosName,
964 .special = handle_netbios_name,
965 .enum_list = NULL,
966 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
967 },
968 {
969 .label = "netbios aliases",
970 .type = P_LIST,
971 .p_class = P_GLOBAL,
972 .ptr = &Globals.szNetbiosAliases,
973 .special = handle_netbios_aliases,
974 .enum_list = NULL,
975 .flags = FLAG_ADVANCED,
976 },
977 {
978 .label = "netbios scope",
979 .type = P_USTRING,
980 .p_class = P_GLOBAL,
981 .ptr = &Globals.szNetbiosScope,
982 .special = handle_netbios_scope,
983 .enum_list = NULL,
984 .flags = FLAG_ADVANCED,
985 },
986 {
987 .label = "server string",
988 .type = P_STRING,
989 .p_class = P_GLOBAL,
990 .ptr = &Globals.szServerString,
991 .special = NULL,
992 .enum_list = NULL,
993 .flags = FLAG_BASIC | FLAG_ADVANCED,
994 },
995 {
996 .label = "interfaces",
997 .type = P_LIST,
998 .p_class = P_GLOBAL,
999 .ptr = &Globals.szInterfaces,
1000 .special = NULL,
1001 .enum_list = NULL,
1002 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1003 },
1004 {
1005 .label = "bind interfaces only",
1006 .type = P_BOOL,
1007 .p_class = P_GLOBAL,
1008 .ptr = &Globals.bBindInterfacesOnly,
1009 .special = NULL,
1010 .enum_list = NULL,
1011 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1012 },
1013 {
1014 .label = "config backend",
1015 .type = P_ENUM,
1016 .p_class = P_GLOBAL,
1017 .ptr = &Globals.ConfigBackend,
1018 .special = NULL,
1019 .enum_list = enum_config_backend,
1020 .flags = FLAG_ADVANCED,
1021 },
1022
1023 {N_("Security Options"), P_SEP, P_SEPARATOR},
1024
1025 {
1026 .label = "security",
1027 .type = P_ENUM,
1028 .p_class = P_GLOBAL,
1029 .ptr = &Globals.security,
1030 .special = NULL,
1031 .enum_list = enum_security,
1032 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1033 },
1034 {
1035 .label = "auth methods",
1036 .type = P_LIST,
1037 .p_class = P_GLOBAL,
1038 .ptr = &Globals.AuthMethods,
1039 .special = NULL,
1040 .enum_list = NULL,
1041 .flags = FLAG_ADVANCED,
1042 },
1043 {
1044 .label = "encrypt passwords",
1045 .type = P_BOOL,
1046 .p_class = P_GLOBAL,
1047 .ptr = &Globals.bEncryptPasswords,
1048 .special = NULL,
1049 .enum_list = NULL,
1050 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1051 },
1052 {
1053 .label = "update encrypted",
1054 .type = P_BOOL,
1055 .p_class = P_GLOBAL,
1056 .ptr = &Globals.bUpdateEncrypt,
1057 .special = NULL,
1058 .enum_list = NULL,
1059 .flags = FLAG_ADVANCED,
1060 },
1061 {
1062 .label = "client schannel",
1063 .type = P_ENUM,
1064 .p_class = P_GLOBAL,
1065 .ptr = &Globals.clientSchannel,
1066 .special = NULL,
1067 .enum_list = enum_bool_auto,
1068 .flags = FLAG_BASIC | FLAG_ADVANCED,
1069 },
1070 {
1071 .label = "server schannel",
1072 .type = P_ENUM,
1073 .p_class = P_GLOBAL,
1074 .ptr = &Globals.serverSchannel,
1075 .special = NULL,
1076 .enum_list = enum_bool_auto,
1077 .flags = FLAG_BASIC | FLAG_ADVANCED,
1078 },
1079 {
1080 .label = "allow trusted domains",
1081 .type = P_BOOL,
1082 .p_class = P_GLOBAL,
1083 .ptr = &Globals.bAllowTrustedDomains,
1084 .special = NULL,
1085 .enum_list = NULL,
1086 .flags = FLAG_ADVANCED,
1087 },
1088 {
1089 .label = "map to guest",
1090 .type = P_ENUM,
1091 .p_class = P_GLOBAL,
1092 .ptr = &Globals.map_to_guest,
1093 .special = NULL,
1094 .enum_list = enum_map_to_guest,
1095 .flags = FLAG_ADVANCED,
1096 },
1097 {
1098 .label = "null passwords",
1099 .type = P_BOOL,
1100 .p_class = P_GLOBAL,
1101 .ptr = &Globals.bNullPasswords,
1102 .special = NULL,
1103 .enum_list = NULL,
1104 .flags = FLAG_ADVANCED,
1105 },
1106 {
1107 .label = "obey pam restrictions",
1108 .type = P_BOOL,
1109 .p_class = P_GLOBAL,
1110 .ptr = &Globals.bObeyPamRestrictions,
1111 .special = NULL,
1112 .enum_list = NULL,
1113 .flags = FLAG_ADVANCED,
1114 },
1115 {
1116 .label = "password server",
1117 .type = P_STRING,
1118 .p_class = P_GLOBAL,
1119 .ptr = &Globals.szPasswordServer,
1120 .special = NULL,
1121 .enum_list = NULL,
1122 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1123 },
1124 {
1125 .label = "smb passwd file",
1126 .type = P_STRING,
1127 .p_class = P_GLOBAL,
1128 .ptr = &Globals.szSMBPasswdFile,
1129 .special = NULL,
1130 .enum_list = NULL,
1131 .flags = FLAG_ADVANCED,
1132 },
1133 {
1134 .label = "private dir",
1135 .type = P_STRING,
1136 .p_class = P_GLOBAL,
1137 .ptr = &Globals.szPrivateDir,
1138 .special = NULL,
1139 .enum_list = NULL,
1140 .flags = FLAG_ADVANCED,
1141 },
1142 {
1143 .label = "passdb backend",
1144 .type = P_STRING,
1145 .p_class = P_GLOBAL,
1146 .ptr = &Globals.szPassdbBackend,
1147 .special = NULL,
1148 .enum_list = NULL,
1149 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1150 },
1151 {
1152 .label = "algorithmic rid base",
1153 .type = P_INTEGER,
1154 .p_class = P_GLOBAL,
1155 .ptr = &Globals.AlgorithmicRidBase,
1156 .special = NULL,
1157 .enum_list = NULL,
1158 .flags = FLAG_ADVANCED,
1159 },
1160 {
1161 .label = "root directory",
1162 .type = P_STRING,
1163 .p_class = P_GLOBAL,
1164 .ptr = &Globals.szRootdir,
1165 .special = NULL,
1166 .enum_list = NULL,
1167 .flags = FLAG_ADVANCED,
1168 },
1169 {
1170 .label = "root dir",
1171 .type = P_STRING,
1172 .p_class = P_GLOBAL,
1173 .ptr = &Globals.szRootdir,
1174 .special = NULL,
1175 .enum_list = NULL,
1176 .flags = FLAG_HIDE,
1177 },
1178 {
1179 .label = "root",
1180 .type = P_STRING,
1181 .p_class = P_GLOBAL,
1182 .ptr = &Globals.szRootdir,
1183 .special = NULL,
1184 .enum_list = NULL,
1185 .flags = FLAG_HIDE,
1186 },
1187 {
1188 .label = "guest account",
1189 .type = P_STRING,
1190 .p_class = P_GLOBAL,
1191 .ptr = &Globals.szGuestaccount,
1192 .special = NULL,
1193 .enum_list = NULL,
1194 .flags = FLAG_BASIC | FLAG_ADVANCED,
1195 },
1196 {
1197 .label = "enable privileges",
1198 .type = P_BOOL,
1199 .p_class = P_GLOBAL,
1200 .ptr = &Globals.bEnablePrivileges,
1201 .special = NULL,
1202 .enum_list = NULL,
1203 .flags = FLAG_ADVANCED,
1204 },
1205
1206 {
1207 .label = "pam password change",
1208 .type = P_BOOL,
1209 .p_class = P_GLOBAL,
1210 .ptr = &Globals.bPamPasswordChange,
1211 .special = NULL,
1212 .enum_list = NULL,
1213 .flags = FLAG_ADVANCED,
1214 },
1215 {
1216 .label = "passwd program",
1217 .type = P_STRING,
1218 .p_class = P_GLOBAL,
1219 .ptr = &Globals.szPasswdProgram,
1220 .special = NULL,
1221 .enum_list = NULL,
1222 .flags = FLAG_ADVANCED,
1223 },
1224 {
1225 .label = "passwd chat",
1226 .type = P_STRING,
1227 .p_class = P_GLOBAL,
1228 .ptr = &Globals.szPasswdChat,
1229 .special = NULL,
1230 .enum_list = NULL,
1231 .flags = FLAG_ADVANCED,
1232 },
1233 {
1234 .label = "passwd chat debug",
1235 .type = P_BOOL,
1236 .p_class = P_GLOBAL,
1237 .ptr = &Globals.bPasswdChatDebug,
1238 .special = NULL,
1239 .enum_list = NULL,
1240 .flags = FLAG_ADVANCED,
1241 },
1242 {
1243 .label = "passwd chat timeout",
1244 .type = P_INTEGER,
1245 .p_class = P_GLOBAL,
1246 .ptr = &Globals.iPasswdChatTimeout,
1247 .special = NULL,
1248 .enum_list = NULL,
1249 .flags = FLAG_ADVANCED,
1250 },
1251 {
1252 .label = "check password script",
1253 .type = P_STRING,
1254 .p_class = P_GLOBAL,
1255 .ptr = &Globals.szCheckPasswordScript,
1256 .special = NULL,
1257 .enum_list = NULL,
1258 .flags = FLAG_ADVANCED,
1259 },
1260 {
1261 .label = "username map",
1262 .type = P_STRING,
1263 .p_class = P_GLOBAL,
1264 .ptr = &Globals.szUsernameMap,
1265 .special = NULL,
1266 .enum_list = NULL,
1267 .flags = FLAG_ADVANCED,
1268 },
1269 {
1270 .label = "password level",
1271 .type = P_INTEGER,
1272 .p_class = P_GLOBAL,
1273 .ptr = &Globals.pwordlevel,
1274 .special = NULL,
1275 .enum_list = NULL,
1276 .flags = FLAG_ADVANCED,
1277 },
1278 {
1279 .label = "username level",
1280 .type = P_INTEGER,
1281 .p_class = P_GLOBAL,
1282 .ptr = &Globals.unamelevel,
1283 .special = NULL,
1284 .enum_list = NULL,
1285 .flags = FLAG_ADVANCED,
1286 },
1287 {
1288 .label = "unix password sync",
1289 .type = P_BOOL,
1290 .p_class = P_GLOBAL,
1291 .ptr = &Globals.bUnixPasswdSync,
1292 .special = NULL,
1293 .enum_list = NULL,
1294 .flags = FLAG_ADVANCED,
1295 },
1296 {
1297 .label = "restrict anonymous",
1298 .type = P_INTEGER,
1299 .p_class = P_GLOBAL,
1300 .ptr = &Globals.restrict_anonymous,
1301 .special = NULL,
1302 .enum_list = NULL,
1303 .flags = FLAG_ADVANCED,
1304 },
1305 {
1306 .label = "lanman auth",
1307 .type = P_BOOL,
1308 .p_class = P_GLOBAL,
1309 .ptr = &Globals.bLanmanAuth,
1310 .special = NULL,
1311 .enum_list = NULL,
1312 .flags = FLAG_ADVANCED,
1313 },
1314 {
1315 .label = "ntlm auth",
1316 .type = P_BOOL,
1317 .p_class = P_GLOBAL,
1318 .ptr = &Globals.bNTLMAuth,
1319 .special = NULL,
1320 .enum_list = NULL,
1321 .flags = FLAG_ADVANCED,
1322 },
1323 {
1324 .label = "client NTLMv2 auth",
1325 .type = P_BOOL,
1326 .p_class = P_GLOBAL,
1327 .ptr = &Globals.bClientNTLMv2Auth,
1328 .special = NULL,
1329 .enum_list = NULL,
1330 .flags = FLAG_ADVANCED,
1331 },
1332 {
1333 .label = "client lanman auth",
1334 .type = P_BOOL,
1335 .p_class = P_GLOBAL,
1336 .ptr = &Globals.bClientLanManAuth,
1337 .special = NULL,
1338 .enum_list = NULL,
1339 .flags = FLAG_ADVANCED,
1340 },
1341 {
1342 .label = "client plaintext auth",
1343 .type = P_BOOL,
1344 .p_class = P_GLOBAL,
1345 .ptr = &Globals.bClientPlaintextAuth,
1346 .special = NULL,
1347 .enum_list = NULL,
1348 .flags = FLAG_ADVANCED,
1349 },
1350 {
1351 .label = "username",
1352 .type = P_STRING,
1353 .p_class = P_LOCAL,
1354 .ptr = &sDefault.szUsername,
1355 .special = NULL,
1356 .enum_list = NULL,
1357 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1358 },
1359 {
1360 .label = "user",
1361 .type = P_STRING,
1362 .p_class = P_LOCAL,
1363 .ptr = &sDefault.szUsername,
1364 .special = NULL,
1365 .enum_list = NULL,
1366 .flags = FLAG_HIDE,
1367 },
1368 {
1369 .label = "users",
1370 .type = P_STRING,
1371 .p_class = P_LOCAL,
1372 .ptr = &sDefault.szUsername,
1373 .special = NULL,
1374 .enum_list = NULL,
1375 .flags = FLAG_HIDE,
1376 },
1377 {
1378 .label = "invalid users",
1379 .type = P_LIST,
1380 .p_class = P_LOCAL,
1381 .ptr = &sDefault.szInvalidUsers,
1382 .special = NULL,
1383 .enum_list = NULL,
1384 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1385 },
1386 {
1387 .label = "valid users",
1388 .type = P_LIST,
1389 .p_class = P_LOCAL,
1390 .ptr = &sDefault.szValidUsers,
1391 .special = NULL,
1392 .enum_list = NULL,
1393 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1394 },
1395 {
1396 .label = "admin users",
1397 .type = P_LIST,
1398 .p_class = P_LOCAL,
1399 .ptr = &sDefault.szAdminUsers,
1400 .special = NULL,
1401 .enum_list = NULL,
1402 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1403 },
1404 {
1405 .label = "read list",
1406 .type = P_LIST,
1407 .p_class = P_LOCAL,
1408 .ptr = &sDefault.readlist,
1409 .special = NULL,
1410 .enum_list = NULL,
1411 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1412 },
1413 {
1414 .label = "write list",
1415 .type = P_LIST,
1416 .p_class = P_LOCAL,
1417 .ptr = &sDefault.writelist,
1418 .special = NULL,
1419 .enum_list = NULL,
1420 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1421 },
1422 {
1423 .label = "printer admin",
1424 .type = P_LIST,
1425 .p_class = P_LOCAL,
1426 .ptr = &sDefault.printer_admin,
1427 .special = NULL,
1428 .enum_list = NULL,
1429 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1430 },
1431 {
1432 .label = "force user",
1433 .type = P_STRING,
1434 .p_class = P_LOCAL,
1435 .ptr = &sDefault.force_user,
1436 .special = NULL,
1437 .enum_list = NULL,
1438 .flags = FLAG_ADVANCED | FLAG_SHARE,
1439 },
1440 {
1441 .label = "force group",
1442 .type = P_STRING,
1443 .p_class = P_LOCAL,
1444 .ptr = &sDefault.force_group,
1445 .special = NULL,
1446 .enum_list = NULL,
1447 .flags = FLAG_ADVANCED | FLAG_SHARE,
1448 },
1449 {
1450 .label = "group",
1451 .type = P_STRING,
1452 .p_class = P_LOCAL,
1453 .ptr = &sDefault.force_group,
1454 .special = NULL,
1455 .enum_list = NULL,
1456 .flags = FLAG_ADVANCED,
1457 },
1458 {
1459 .label = "read only",
1460 .type = P_BOOL,
1461 .p_class = P_LOCAL,
1462 .ptr = &sDefault.bRead_only,
1463 .special = NULL,
1464 .enum_list = NULL,
1465 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1466 },
1467 {
1468 .label = "write ok",
1469 .type = P_BOOLREV,
1470 .p_class = P_LOCAL,
1471 .ptr = &sDefault.bRead_only,
1472 .special = NULL,
1473 .enum_list = NULL,
1474 .flags = FLAG_HIDE,
1475 },
1476 {
1477 .label = "writeable",
1478 .type = P_BOOLREV,
1479 .p_class = P_LOCAL,
1480 .ptr = &sDefault.bRead_only,
1481 .special = NULL,
1482 .enum_list = NULL,
1483 .flags = FLAG_HIDE,
1484 },
1485 {
1486 .label = "writable",
1487 .type = P_BOOLREV,
1488 .p_class = P_LOCAL,
1489 .ptr = &sDefault.bRead_only,
1490 .special = NULL,
1491 .enum_list = NULL,
1492 .flags = FLAG_HIDE,
1493 },
1494 {
1495 .label = "acl check permissions",
1496 .type = P_BOOL,
1497 .p_class = P_LOCAL,
1498 .ptr = &sDefault.bAclCheckPermissions,
1499 .special = NULL,
1500 .enum_list = NULL,
1501 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1502 },
1503 {
1504 .label = "acl group control",
1505 .type = P_BOOL,
1506 .p_class = P_LOCAL,
1507 .ptr = &sDefault.bAclGroupControl,
1508 .special = NULL,
1509 .enum_list = NULL,
1510 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1511 },
1512 {
1513 .label = "acl map full control",
1514 .type = P_BOOL,
1515 .p_class = P_LOCAL,
1516 .ptr = &sDefault.bAclMapFullControl,
1517 .special = NULL,
1518 .enum_list = NULL,
1519 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1520 },
1521 {
1522 .label = "create mask",
1523 .type = P_OCTAL,
1524 .p_class = P_LOCAL,
1525 .ptr = &sDefault.iCreate_mask,
1526 .special = NULL,
1527 .enum_list = NULL,
1528 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1529 },
1530 {
1531 .label = "create mode",
1532 .type = P_OCTAL,
1533 .p_class = P_LOCAL,
1534 .ptr = &sDefault.iCreate_mask,
1535 .special = NULL,
1536 .enum_list = NULL,
1537 .flags = FLAG_HIDE,
1538 },
1539 {
1540 .label = "force create mode",
1541 .type = P_OCTAL,
1542 .p_class = P_LOCAL,
1543 .ptr = &sDefault.iCreate_force_mode,
1544 .special = NULL,
1545 .enum_list = NULL,
1546 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1547 },
1548 {
1549 .label = "security mask",
1550 .type = P_OCTAL,
1551 .p_class = P_LOCAL,
1552 .ptr = &sDefault.iSecurity_mask,
1553 .special = NULL,
1554 .enum_list = NULL,
1555 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1556 },
1557 {
1558 .label = "force security mode",
1559 .type = P_OCTAL,
1560 .p_class = P_LOCAL,
1561 .ptr = &sDefault.iSecurity_force_mode,
1562 .special = NULL,
1563 .enum_list = NULL,
1564 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1565 },
1566 {
1567 .label = "directory mask",
1568 .type = P_OCTAL,
1569 .p_class = P_LOCAL,
1570 .ptr = &sDefault.iDir_mask,
1571 .special = NULL,
1572 .enum_list = NULL,
1573 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1574 },
1575 {
1576 .label = "directory mode",
1577 .type = P_OCTAL,
1578 .p_class = P_LOCAL,
1579 .ptr = &sDefault.iDir_mask,
1580 .special = NULL,
1581 .enum_list = NULL,
1582 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1583 },
1584 {
1585 .label = "force directory mode",
1586 .type = P_OCTAL,
1587 .p_class = P_LOCAL,
1588 .ptr = &sDefault.iDir_force_mode,
1589 .special = NULL,
1590 .enum_list = NULL,
1591 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1592 },
1593 {
1594 .label = "directory security mask",
1595 .type = P_OCTAL,
1596 .p_class = P_LOCAL,
1597 .ptr = &sDefault.iDir_Security_mask,
1598 .special = NULL,
1599 .enum_list = NULL,
1600 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1601 },
1602 {
1603 .label = "force directory security mode",
1604 .type = P_OCTAL,
1605 .p_class = P_LOCAL,
1606 .ptr = &sDefault.iDir_Security_force_mode,
1607 .special = NULL,
1608 .enum_list = NULL,
1609 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1610 },
1611 {
1612 .label = "force unknown acl user",
1613 .type = P_BOOL,
1614 .p_class = P_LOCAL,
1615 .ptr = &sDefault.bForceUnknownAclUser,
1616 .special = NULL,
1617 .enum_list = NULL,
1618 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1619 },
1620 {
1621 .label = "inherit permissions",
1622 .type = P_BOOL,
1623 .p_class = P_LOCAL,
1624 .ptr = &sDefault.bInheritPerms,
1625 .special = NULL,
1626 .enum_list = NULL,
1627 .flags = FLAG_ADVANCED | FLAG_SHARE,
1628 },
1629 {
1630 .label = "inherit acls",
1631 .type = P_BOOL,
1632 .p_class = P_LOCAL,
1633 .ptr = &sDefault.bInheritACLS,
1634 .special = NULL,
1635 .enum_list = NULL,
1636 .flags = FLAG_ADVANCED | FLAG_SHARE,
1637 },
1638 {
1639 .label = "inherit owner",
1640 .type = P_BOOL,
1641 .p_class = P_LOCAL,
1642 .ptr = &sDefault.bInheritOwner,
1643 .special = NULL,
1644 .enum_list = NULL,
1645 .flags = FLAG_ADVANCED | FLAG_SHARE,
1646 },
1647 {
1648 .label = "guest only",
1649 .type = P_BOOL,
1650 .p_class = P_LOCAL,
1651 .ptr = &sDefault.bGuest_only,
1652 .special = NULL,
1653 .enum_list = NULL,
1654 .flags = FLAG_ADVANCED | FLAG_SHARE,
1655 },
1656 {
1657 .label = "only guest",
1658 .type = P_BOOL,
1659 .p_class = P_LOCAL,
1660 .ptr = &sDefault.bGuest_only,
1661 .special = NULL,
1662 .enum_list = NULL,
1663 .flags = FLAG_HIDE,
1664 },
1665 {
1666 .label = "administrative share",
1667 .type = P_BOOL,
1668 .p_class = P_LOCAL,
1669 .ptr = &sDefault.bAdministrative_share,
1670 .special = NULL,
1671 .enum_list = NULL,
1672 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1673 },
1674
1675 {
1676 .label = "guest ok",
1677 .type = P_BOOL,
1678 .p_class = P_LOCAL,
1679 .ptr = &sDefault.bGuest_ok,
1680 .special = NULL,
1681 .enum_list = NULL,
1682 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1683 },
1684 {
1685 .label = "public",
1686 .type = P_BOOL,
1687 .p_class = P_LOCAL,
1688 .ptr = &sDefault.bGuest_ok,
1689 .special = NULL,
1690 .enum_list = NULL,
1691 .flags = FLAG_HIDE,
1692 },
1693 {
1694 .label = "only user",
1695 .type = P_BOOL,
1696 .p_class = P_LOCAL,
1697 .ptr = &sDefault.bOnlyUser,
1698 .special = NULL,
1699 .enum_list = NULL,
1700 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1701 },
1702 {
1703 .label = "hosts allow",
1704 .type = P_LIST,
1705 .p_class = P_LOCAL,
1706 .ptr = &sDefault.szHostsallow,
1707 .special = NULL,
1708 .enum_list = NULL,
1709 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1710 },
1711 {
1712 .label = "allow hosts",
1713 .type = P_LIST,
1714 .p_class = P_LOCAL,
1715 .ptr = &sDefault.szHostsallow,
1716 .special = NULL,
1717 .enum_list = NULL,
1718 .flags = FLAG_HIDE,
1719 },
1720 {
1721 .label = "hosts deny",
1722 .type = P_LIST,
1723 .p_class = P_LOCAL,
1724 .ptr = &sDefault.szHostsdeny,
1725 .special = NULL,
1726 .enum_list = NULL,
1727 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1728 },
1729 {
1730 .label = "deny hosts",
1731 .type = P_LIST,
1732 .p_class = P_LOCAL,
1733 .ptr = &sDefault.szHostsdeny,
1734 .special = NULL,
1735 .enum_list = NULL,
1736 .flags = FLAG_HIDE,
1737 },
1738 {
1739 .label = "preload modules",
1740 .type = P_LIST,
1741 .p_class = P_GLOBAL,
1742 .ptr = &Globals.szPreloadModules,
1743 .special = NULL,
1744 .enum_list = NULL,
1745 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1746 },
1747 {
1748 .label = "use kerberos keytab",
1749 .type = P_BOOL,
1750 .p_class = P_GLOBAL,
1751 .ptr = &Globals.bUseKerberosKeytab,
1752 .special = NULL,
1753 .enum_list = NULL,
1754 .flags = FLAG_ADVANCED,
1755 },
1756
1757 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1758
1759 {
1760 .label = "log level",
1761 .type = P_STRING,
1762 .p_class = P_GLOBAL,
1763 .ptr = &Globals.szLogLevel,
1764 .special = handle_debug_list,
1765 .enum_list = NULL,
1766 .flags = FLAG_ADVANCED,
1767 },
1768 {
1769 .label = "debuglevel",
1770 .type = P_STRING,
1771 .p_class = P_GLOBAL,
1772 .ptr = &Globals.szLogLevel,
1773 .special = handle_debug_list,
1774 .enum_list = NULL,
1775 .flags = FLAG_HIDE,
1776 },
1777 {
1778 .label = "syslog",
1779 .type = P_INTEGER,
1780 .p_class = P_GLOBAL,
1781 .ptr = &Globals.syslog,
1782 .special = NULL,
1783 .enum_list = NULL,
1784 .flags = FLAG_ADVANCED,
1785 },
1786 {
1787 .label = "syslog only",
1788 .type = P_BOOL,
1789 .p_class = P_GLOBAL,
1790 .ptr = &Globals.bSyslogOnly,
1791 .special = NULL,
1792 .enum_list = NULL,
1793 .flags = FLAG_ADVANCED,
1794 },
1795 {
1796 .label = "log file",
1797 .type = P_STRING,
1798 .p_class = P_GLOBAL,
1799 .ptr = &Globals.szLogFile,
1800 .special = NULL,
1801 .enum_list = NULL,
1802 .flags = FLAG_ADVANCED,
1803 },
1804 {
1805 .label = "max log size",
1806 .type = P_INTEGER,
1807 .p_class = P_GLOBAL,
1808 .ptr = &Globals.max_log_size,
1809 .special = NULL,
1810 .enum_list = NULL,
1811 .flags = FLAG_ADVANCED,
1812 },
1813 {
1814 .label = "debug timestamp",
1815 .type = P_BOOL,
1816 .p_class = P_GLOBAL,
1817 .ptr = &Globals.bTimestampLogs,
1818 .special = NULL,
1819 .enum_list = NULL,
1820 .flags = FLAG_ADVANCED,
1821 },
1822 {
1823 .label = "timestamp logs",
1824 .type = P_BOOL,
1825 .p_class = P_GLOBAL,
1826 .ptr = &Globals.bTimestampLogs,
1827 .special = NULL,
1828 .enum_list = NULL,
1829 .flags = FLAG_ADVANCED,
1830 },
1831 {
1832 .label = "debug prefix timestamp",
1833 .type = P_BOOL,
1834 .p_class = P_GLOBAL,
1835 .ptr = &Globals.bDebugPrefixTimestamp,
1836 .special = NULL,
1837 .enum_list = NULL,
1838 .flags = FLAG_ADVANCED,
1839 },
1840 {
1841 .label = "debug hires timestamp",
1842 .type = P_BOOL,
1843 .p_class = P_GLOBAL,
1844 .ptr = &Globals.bDebugHiresTimestamp,
1845 .special = NULL,
1846 .enum_list = NULL,
1847 .flags = FLAG_ADVANCED,
1848 },
1849 {
1850 .label = "debug pid",
1851 .type = P_BOOL,
1852 .p_class = P_GLOBAL,
1853 .ptr = &Globals.bDebugPid,
1854 .special = NULL,
1855 .enum_list = NULL,
1856 .flags = FLAG_ADVANCED,
1857 },
1858 {
1859 .label = "debug uid",
1860 .type = P_BOOL,
1861 .p_class = P_GLOBAL,
1862 .ptr = &Globals.bDebugUid,
1863 .special = NULL,
1864 .enum_list = NULL,
1865 .flags = FLAG_ADVANCED,
1866 },
1867 {
1868 .label = "debug class",
1869 .type = P_BOOL,
1870 .p_class = P_GLOBAL,
1871 .ptr = &Globals.bDebugClass,
1872 .special = NULL,
1873 .enum_list = NULL,
1874 .flags = FLAG_ADVANCED,
1875 },
1876 {
1877 .label = "enable core files",
1878 .type = P_BOOL,
1879 .p_class = P_GLOBAL,
1880 .ptr = &Globals.bEnableCoreFiles,
1881 .special = NULL,
1882 .enum_list = NULL,
1883 .flags = FLAG_ADVANCED,
1884 },
1885
1886 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1887
1888 {
1889 .label = "allocation roundup size",
1890 .type = P_INTEGER,
1891 .p_class = P_LOCAL,
1892 .ptr = &sDefault.iallocation_roundup_size,
1893 .special = NULL,
1894 .enum_list = NULL,
1895 .flags = FLAG_ADVANCED,
1896 },
1897 {
1898 .label = "aio read size",
1899 .type = P_INTEGER,
1900 .p_class = P_LOCAL,
1901 .ptr = &sDefault.iAioReadSize,
1902 .special = NULL,
1903 .enum_list = NULL,
1904 .flags = FLAG_ADVANCED,
1905 },
1906 {
1907 .label = "aio write size",
1908 .type = P_INTEGER,
1909 .p_class = P_LOCAL,
1910 .ptr = &sDefault.iAioWriteSize,
1911 .special = NULL,
1912 .enum_list = NULL,
1913 .flags = FLAG_ADVANCED,
1914 },
1915 {
1916 .label = "aio write behind",
1917 .type = P_STRING,
1918 .p_class = P_LOCAL,
1919 .ptr = &sDefault.szAioWriteBehind,
1920 .special = NULL,
1921 .enum_list = NULL,
1922 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1923 },
1924 {
1925 .label = "smb ports",
1926 .type = P_STRING,
1927 .p_class = P_GLOBAL,
1928 .ptr = &Globals.smb_ports,
1929 .special = NULL,
1930 .enum_list = NULL,
1931 .flags = FLAG_ADVANCED,
1932 },
1933 {
1934 .label = "large readwrite",
1935 .type = P_BOOL,
1936 .p_class = P_GLOBAL,
1937 .ptr = &Globals.bLargeReadwrite,
1938 .special = NULL,
1939 .enum_list = NULL,
1940 .flags = FLAG_ADVANCED,
1941 },
1942 {
1943 .label = "max protocol",
1944 .type = P_ENUM,
1945 .p_class = P_GLOBAL,
1946 .ptr = &Globals.maxprotocol,
1947 .special = NULL,
1948 .enum_list = enum_protocol,
1949 .flags = FLAG_ADVANCED,
1950 },
1951 {
1952 .label = "protocol",
1953 .type = P_ENUM,
1954 .p_class = P_GLOBAL,
1955 .ptr = &Globals.maxprotocol,
1956 .special = NULL,
1957 .enum_list = enum_protocol,
1958 .flags = FLAG_ADVANCED,
1959 },
1960 {
1961 .label = "min protocol",
1962 .type = P_ENUM,
1963 .p_class = P_GLOBAL,
1964 .ptr = &Globals.minprotocol,
1965 .special = NULL,
1966 .enum_list = enum_protocol,
1967 .flags = FLAG_ADVANCED,
1968 },
1969 {
1970 .label = "min receivefile size",
1971 .type = P_INTEGER,
1972 .p_class = P_GLOBAL,
1973 .ptr = &Globals.iminreceivefile,
1974 .special = NULL,
1975 .enum_list = NULL,
1976 .flags = FLAG_ADVANCED,
1977 },
1978 {
1979 .label = "read raw",
1980 .type = P_BOOL,
1981 .p_class = P_GLOBAL,
1982 .ptr = &Globals.bReadRaw,
1983 .special = NULL,
1984 .enum_list = NULL,
1985 .flags = FLAG_ADVANCED,
1986 },
1987 {
1988 .label = "write raw",
1989 .type = P_BOOL,
1990 .p_class = P_GLOBAL,
1991 .ptr = &Globals.bWriteRaw,
1992 .special = NULL,
1993 .enum_list = NULL,
1994 .flags = FLAG_ADVANCED,
1995 },
1996 {
1997 .label = "disable netbios",
1998 .type = P_BOOL,
1999 .p_class = P_GLOBAL,
2000 .ptr = &Globals.bDisableNetbios,
2001 .special = NULL,
2002 .enum_list = NULL,
2003 .flags = FLAG_ADVANCED,
2004 },
2005 {
2006 .label = "reset on zero vc",
2007 .type = P_BOOL,
2008 .p_class = P_GLOBAL,
2009 .ptr = &Globals.bResetOnZeroVC,
2010 .special = NULL,
2011 .enum_list = NULL,
2012 .flags = FLAG_ADVANCED,
2013 },
2014 {
2015 .label = "acl compatibility",
2016 .type = P_ENUM,
2017 .p_class = P_GLOBAL,
2018 .ptr = &Globals.iAclCompat,
2019 .special = NULL,
2020 .enum_list = enum_acl_compat_vals,
2021 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2022 },
2023 {
2024 .label = "defer sharing violations",
2025 .type = P_BOOL,
2026 .p_class = P_GLOBAL,
2027 .ptr = &Globals.bDeferSharingViolations,
2028 .special = NULL,
2029 .enum_list = NULL,
2030 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2031 },
2032 {
2033 .label = "ea support",
2034 .type = P_BOOL,
2035 .p_class = P_LOCAL,
2036 .ptr = &sDefault.bEASupport,
2037 .special = NULL,
2038 .enum_list = NULL,
2039 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2040 },
2041 {
2042 .label = "nt acl support",
2043 .type = P_BOOL,
2044 .p_class = P_LOCAL,
2045 .ptr = &sDefault.bNTAclSupport,
2046 .special = NULL,
2047 .enum_list = NULL,
2048 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2049 },
2050 {
2051 .label = "nt pipe support",
2052 .type = P_BOOL,
2053 .p_class = P_GLOBAL,
2054 .ptr = &Globals.bNTPipeSupport,
2055 .special = NULL,
2056 .enum_list = NULL,
2057 .flags = FLAG_ADVANCED,
2058 },
2059 {
2060 .label = "nt status support",
2061 .type = P_BOOL,
2062 .p_class = P_GLOBAL,
2063 .ptr = &Globals.bNTStatusSupport,
2064 .special = NULL,
2065 .enum_list = NULL,
2066 .flags = FLAG_ADVANCED,
2067 },
2068 {
2069 .label = "profile acls",
2070 .type = P_BOOL,
2071 .p_class = P_LOCAL,
2072 .ptr = &sDefault.bProfileAcls,
2073 .special = NULL,
2074 .enum_list = NULL,
2075 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2076 },
2077 {
2078 .label = "announce version",
2079 .type = P_STRING,
2080 .p_class = P_GLOBAL,
2081 .ptr = &Globals.szAnnounceVersion,
2082 .special = NULL,
2083 .enum_list = NULL,
2084 .flags = FLAG_ADVANCED,
2085 },
2086 {
2087 .label = "announce as",
2088 .type = P_ENUM,
2089 .p_class = P_GLOBAL,
2090 .ptr = &Globals.announce_as,
2091 .special = NULL,
2092 .enum_list = enum_announce_as,
2093 .flags = FLAG_ADVANCED,
2094 },
2095 {
2096 .label = "map acl inherit",
2097 .type = P_BOOL,
2098 .p_class = P_LOCAL,
2099 .ptr = &sDefault.bMap_acl_inherit,
2100 .special = NULL,
2101 .enum_list = NULL,
2102 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2103 },
2104 {
2105 .label = "afs share",
2106 .type = P_BOOL,
2107 .p_class = P_LOCAL,
2108 .ptr = &sDefault.bAfs_Share,
2109 .special = NULL,
2110 .enum_list = NULL,
2111 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2112 },
2113 {
2114 .label = "max mux",
2115 .type = P_INTEGER,
2116 .p_class = P_GLOBAL,
2117 .ptr = &Globals.max_mux,
2118 .special = NULL,
2119 .enum_list = NULL,
2120 .flags = FLAG_ADVANCED,
2121 },
2122 {
2123 .label = "max xmit",
2124 .type = P_INTEGER,
2125 .p_class = P_GLOBAL,
2126 .ptr = &Globals.max_xmit,
2127 .special = NULL,
2128 .enum_list = NULL,
2129 .flags = FLAG_ADVANCED,
2130 },
2131 {
2132 .label = "name resolve order",
2133 .type = P_STRING,
2134 .p_class = P_GLOBAL,
2135 .ptr = &Globals.szNameResolveOrder,
2136 .special = NULL,
2137 .enum_list = NULL,
2138 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2139 },
2140 {
2141 .label = "max ttl",
2142 .type = P_INTEGER,
2143 .p_class = P_GLOBAL,
2144 .ptr = &Globals.max_ttl,
2145 .special = NULL,
2146 .enum_list = NULL,
2147 .flags = FLAG_ADVANCED,
2148 },
2149 {
2150 .label = "max wins ttl",
2151 .type = P_INTEGER,
2152 .p_class = P_GLOBAL,
2153 .ptr = &Globals.max_wins_ttl,
2154 .special = NULL,
2155 .enum_list = NULL,
2156 .flags = FLAG_ADVANCED,
2157 },
2158 {
2159 .label = "min wins ttl",
2160 .type = P_INTEGER,
2161 .p_class = P_GLOBAL,
2162 .ptr = &Globals.min_wins_ttl,
2163 .special = NULL,
2164 .enum_list = NULL,
2165 .flags = FLAG_ADVANCED,
2166 },
2167 {
2168 .label = "time server",
2169 .type = P_BOOL,
2170 .p_class = P_GLOBAL,
2171 .ptr = &Globals.bTimeServer,
2172 .special = NULL,
2173 .enum_list = NULL,
2174 .flags = FLAG_ADVANCED,
2175 },
2176 {
2177 .label = "unix extensions",
2178 .type = P_BOOL,
2179 .p_class = P_GLOBAL,
2180 .ptr = &Globals.bUnixExtensions,
2181 .special = NULL,
2182 .enum_list = NULL,
2183 .flags = FLAG_ADVANCED,
2184 },
2185 {
2186 .label = "use spnego",
2187 .type = P_BOOL,
2188 .p_class = P_GLOBAL,
2189 .ptr = &Globals.bUseSpnego,
2190 .special = NULL,
2191 .enum_list = NULL,
2192 .flags = FLAG_ADVANCED,
2193 },
2194 {
2195 .label = "client signing",
2196 .type = P_ENUM,
2197 .p_class = P_GLOBAL,
2198 .ptr = &Globals.client_signing,
2199 .special = NULL,
2200 .enum_list = enum_smb_signing_vals,
2201 .flags = FLAG_ADVANCED,
2202 },
2203 {
2204 .label = "server signing",
2205 .type = P_ENUM,
2206 .p_class = P_GLOBAL,
2207 .ptr = &Globals.server_signing,
2208 .special = NULL,
2209 .enum_list = enum_smb_signing_vals,
2210 .flags = FLAG_ADVANCED,
2211 },
2212 {
2213 .label = "smb encrypt",
2214 .type = P_ENUM,
2215 .p_class = P_LOCAL,
2216 .ptr = &sDefault.ismb_encrypt,
2217 .special = NULL,
2218 .enum_list = enum_smb_signing_vals,
2219 .flags = FLAG_ADVANCED,
2220 },
2221 {
2222 .label = "client use spnego",
2223 .type = P_BOOL,
2224 .p_class = P_GLOBAL,
2225 .ptr = &Globals.bClientUseSpnego,
2226 .special = NULL,
2227 .enum_list = NULL,
2228 .flags = FLAG_ADVANCED,
2229 },
2230 {
2231 .label = "client ldap sasl wrapping",
2232 .type = P_ENUM,
2233 .p_class = P_GLOBAL,
2234 .ptr = &Globals.client_ldap_sasl_wrapping,
2235 .special = NULL,
2236 .enum_list = enum_ldap_sasl_wrapping,
2237 .flags = FLAG_ADVANCED,
2238 },
2239 {
2240 .label = "enable asu support",
2241 .type = P_BOOL,
2242 .p_class = P_GLOBAL,
2243 .ptr = &Globals.bASUSupport,
2244 .special = NULL,
2245 .enum_list = NULL,
2246 .flags = FLAG_ADVANCED,
2247 },
2248 {
2249 .label = "svcctl list",
2250 .type = P_LIST,
2251 .p_class = P_GLOBAL,
2252 .ptr = &Globals.szServicesList,
2253 .special = NULL,
2254 .enum_list = NULL,
2255 .flags = FLAG_ADVANCED,
2256 },
2257
2258 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2259
2260 {
2261 .label = "block size",
2262 .type = P_INTEGER,
2263 .p_class = P_LOCAL,
2264 .ptr = &sDefault.iBlock_size,
2265 .special = NULL,
2266 .enum_list = NULL,
2267 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2268 },
2269 {
2270 .label = "deadtime",
2271 .type = P_INTEGER,
2272 .p_class = P_GLOBAL,
2273 .ptr = &Globals.deadtime,
2274 .special = NULL,
2275 .enum_list = NULL,
2276 .flags = FLAG_ADVANCED,
2277 },
2278 {
2279 .label = "getwd cache",
2280 .type = P_BOOL,
2281 .p_class = P_GLOBAL,
2282 .ptr = &Globals.getwd_cache,
2283 .special = NULL,
2284 .enum_list = NULL,
2285 .flags = FLAG_ADVANCED,
2286 },
2287 {
2288 .label = "keepalive",
2289 .type = P_INTEGER,
2290 .p_class = P_GLOBAL,
2291 .ptr = &Globals.iKeepalive,
2292 .special = NULL,
2293 .enum_list = NULL,
2294 .flags = FLAG_ADVANCED,
2295 },
2296 {
2297 .label = "change notify",
2298 .type = P_BOOL,
2299 .p_class = P_LOCAL,
2300 .ptr = &sDefault.bChangeNotify,
2301 .special = NULL,
2302 .enum_list = NULL,
2303 .flags = FLAG_ADVANCED | FLAG_SHARE,
2304 },
2305 {
2306 .label = "directory name cache size",
2307 .type = P_INTEGER,
2308 .p_class = P_LOCAL,
2309 .ptr = &sDefault.iDirectoryNameCacheSize,
2310 .special = NULL,
2311 .enum_list = NULL,
2312 .flags = FLAG_ADVANCED | FLAG_SHARE,
2313 },
2314 {
2315 .label = "kernel change notify",
2316 .type = P_BOOL,
2317 .p_class = P_LOCAL,
2318 .ptr = &sDefault.bKernelChangeNotify,
2319 .special = NULL,
2320 .enum_list = NULL,
2321 .flags = FLAG_ADVANCED | FLAG_SHARE,
2322 },
2323 {
2324 .label = "lpq cache time",
2325 .type = P_INTEGER,
2326 .p_class = P_GLOBAL,
2327 .ptr = &Globals.lpqcachetime,
2328 .special = NULL,
2329 .enum_list = NULL,
2330 .flags = FLAG_ADVANCED,
2331 },
2332 {
2333 .label = "max smbd processes",
2334 .type = P_INTEGER,
2335 .p_class = P_GLOBAL,
2336 .ptr = &Globals.iMaxSmbdProcesses,
2337 .special = NULL,
2338 .enum_list = NULL,
2339 .flags = FLAG_ADVANCED,
2340 },
2341 {
2342 .label = "max connections",
2343 .type = P_INTEGER,
2344 .p_class = P_LOCAL,
2345 .ptr = &sDefault.iMaxConnections,
2346 .special = NULL,
2347 .enum_list = NULL,
2348 .flags = FLAG_ADVANCED | FLAG_SHARE,
2349 },
2350 {
2351 .label = "paranoid server security",
2352 .type = P_BOOL,
2353 .p_class = P_GLOBAL,
2354 .ptr = &Globals.paranoid_server_security,
2355 .special = NULL,
2356 .enum_list = NULL,
2357 .flags = FLAG_ADVANCED,
2358 },
2359 {
2360 .label = "max disk size",
2361 .type = P_INTEGER,
2362 .p_class = P_GLOBAL,
2363 .ptr = &Globals.maxdisksize,
2364 .special = NULL,
2365 .enum_list = NULL,
2366 .flags = FLAG_ADVANCED,
2367 },
2368 {
2369 .label = "max open files",
2370 .type = P_INTEGER,
2371 .p_class = P_GLOBAL,
2372 .ptr = &Globals.max_open_files,
2373 .special = NULL,
2374 .enum_list = NULL,
2375 .flags = FLAG_ADVANCED,
2376 },
2377 {
2378 .label = "min print space",
2379 .type = P_INTEGER,
2380 .p_class = P_LOCAL,
2381 .ptr = &sDefault.iMinPrintSpace,
2382 .special = NULL,
2383 .enum_list = NULL,
2384 .flags = FLAG_ADVANCED | FLAG_PRINT,
2385 },
2386 {
2387 .label = "socket options",
2388 .type = P_STRING,
2389 .p_class = P_GLOBAL,
2390 .ptr = &Globals.szSocketOptions,
2391 .special = NULL,
2392 .enum_list = NULL,
2393 .flags = FLAG_ADVANCED,
2394 },
2395 {
2396 .label = "strict allocate",
2397 .type = P_BOOL,
2398 .p_class = P_LOCAL,
2399 .ptr = &sDefault.bStrictAllocate,
2400 .special = NULL,
2401 .enum_list = NULL,
2402 .flags = FLAG_ADVANCED | FLAG_SHARE,
2403 },
2404 {
2405 .label = "strict sync",
2406 .type = P_BOOL,
2407 .p_class = P_LOCAL,
2408 .ptr = &sDefault.bStrictSync,
2409 .special = NULL,
2410 .enum_list = NULL,
2411 .flags = FLAG_ADVANCED | FLAG_SHARE,
2412 },
2413 {
2414 .label = "sync always",
2415 .type = P_BOOL,
2416 .p_class = P_LOCAL,
2417 .ptr = &sDefault.bSyncAlways,
2418 .special = NULL,
2419 .enum_list = NULL,
2420 .flags = FLAG_ADVANCED | FLAG_SHARE,
2421 },
2422 {
2423 .label = "use mmap",
2424 .type = P_BOOL,
2425 .p_class = P_GLOBAL,
2426 .ptr = &Globals.bUseMmap,
2427 .special = NULL,
2428 .enum_list = NULL,
2429 .flags = FLAG_ADVANCED,
2430 },
2431 {
2432 .label = "use sendfile",
2433 .type = P_BOOL,
2434 .p_class = P_LOCAL,
2435 .ptr = &sDefault.bUseSendfile,
2436 .special = NULL,
2437 .enum_list = NULL,
2438 .flags = FLAG_ADVANCED | FLAG_SHARE,
2439 },
2440 {
2441 .label = "hostname lookups",
2442 .type = P_BOOL,
2443 .p_class = P_GLOBAL,
2444 .ptr = &Globals.bHostnameLookups,
2445 .special = NULL,
2446 .enum_list = NULL,
2447 .flags = FLAG_ADVANCED,
2448 },
2449 {
2450 .label = "write cache size",
2451 .type = P_INTEGER,
2452 .p_class = P_LOCAL,
2453 .ptr = &sDefault.iWriteCacheSize,
2454 .special = NULL,
2455 .enum_list = NULL,
2456 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2457 },
2458 {
2459 .label = "name cache timeout",
2460 .type = P_INTEGER,
2461 .p_class = P_GLOBAL,
2462 .ptr = &Globals.name_cache_timeout,
2463 .special = NULL,
2464 .enum_list = NULL,
2465 .flags = FLAG_ADVANCED,
2466 },
2467 {
2468 .label = "ctdbd socket",
2469 .type = P_STRING,
2470 .p_class = P_GLOBAL,
2471 .ptr = &Globals.ctdbdSocket,
2472 .special = NULL,
2473 .enum_list = NULL,
2474 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2475 },
2476 {
2477 .label = "cluster addresses",
2478 .type = P_LIST,
2479 .p_class = P_GLOBAL,
2480 .ptr = &Globals.szClusterAddresses,
2481 .special = NULL,
2482 .enum_list = NULL,
2483 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2484 },
2485 {
2486 .label = "clustering",
2487 .type = P_BOOL,
2488 .p_class = P_GLOBAL,
2489 .ptr = &Globals.clustering,
2490 .special = NULL,
2491 .enum_list = NULL,
2492 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2493 },
2494
2495 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2496
2497 {
2498 .label = "max reported print jobs",
2499 .type = P_INTEGER,
2500 .p_class = P_LOCAL,
2501 .ptr = &sDefault.iMaxReportedPrintJobs,
2502 .special = NULL,
2503 .enum_list = NULL,
2504 .flags = FLAG_ADVANCED | FLAG_PRINT,
2505 },
2506 {
2507 .label = "max print jobs",
2508 .type = P_INTEGER,
2509 .p_class = P_LOCAL,
2510 .ptr = &sDefault.iMaxPrintJobs,
2511 .special = NULL,
2512 .enum_list = NULL,
2513 .flags = FLAG_ADVANCED | FLAG_PRINT,
2514 },
2515 {
2516 .label = "load printers",
2517 .type = P_BOOL,
2518 .p_class = P_GLOBAL,
2519 .ptr = &Globals.bLoadPrinters,
2520 .special = NULL,
2521 .enum_list = NULL,
2522 .flags = FLAG_ADVANCED | FLAG_PRINT,
2523 },
2524 {
2525 .label = "printcap cache time",
2526 .type = P_INTEGER,
2527 .p_class = P_GLOBAL,
2528 .ptr = &Globals.PrintcapCacheTime,
2529 .special = NULL,
2530 .enum_list = NULL,
2531 .flags = FLAG_ADVANCED | FLAG_PRINT,
2532 },
2533 {
2534 .label = "printcap name",
2535 .type = P_STRING,
2536 .p_class = P_GLOBAL,
2537 .ptr = &Globals.szPrintcapname,
2538 .special = NULL,
2539 .enum_list = NULL,
2540 .flags = FLAG_ADVANCED | FLAG_PRINT,
2541 },
2542 {
2543 .label = "printcap",
2544 .type = P_STRING,
2545 .p_class = P_GLOBAL,
2546 .ptr = &Globals.szPrintcapname,
2547 .special = NULL,
2548 .enum_list = NULL,
2549 .flags = FLAG_HIDE,
2550 },
2551 {
2552 .label = "printable",
2553 .type = P_BOOL,
2554 .p_class = P_LOCAL,
2555 .ptr = &sDefault.bPrint_ok,
2556 .special = NULL,
2557 .enum_list = NULL,
2558 .flags = FLAG_ADVANCED | FLAG_PRINT,
2559 },
2560 {
2561 .label = "print ok",
2562 .type = P_BOOL,
2563 .p_class = P_LOCAL,
2564 .ptr = &sDefault.bPrint_ok,
2565 .special = NULL,
2566 .enum_list = NULL,
2567 .flags = FLAG_HIDE,
2568 },
2569 {
2570 .label = "printing",
2571 .type = P_ENUM,
2572 .p_class = P_LOCAL,
2573 .ptr = &sDefault.iPrinting,
2574 .special = handle_printing,
2575 .enum_list = enum_printing,
2576 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2577 },
2578 {
2579 .label = "cups options",
2580 .type = P_STRING,
2581 .p_class = P_LOCAL,
2582 .ptr = &sDefault.szCupsOptions,
2583 .special = NULL,
2584 .enum_list = NULL,
2585 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2586 },
2587 {
2588 .label = "cups server",
2589 .type = P_STRING,
2590 .p_class = P_GLOBAL,
2591 .ptr = &Globals.szCupsServer,
2592 .special = NULL,
2593 .enum_list = NULL,
2594 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2595 },
2596 {
2597 .label = "iprint server",
2598 .type = P_STRING,
2599 .p_class = P_GLOBAL,
2600 .ptr = &Globals.szIPrintServer,
2601 .special = NULL,
2602 .enum_list = NULL,
2603 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2604 },
2605 {
2606 .label = "print command",
2607 .type = P_STRING,
2608 .p_class = P_LOCAL,
2609 .ptr = &sDefault.szPrintcommand,
2610 .special = NULL,
2611 .enum_list = NULL,
2612 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2613 },
2614 {
2615 .label = "disable spoolss",
2616 .type = P_BOOL,
2617 .p_class = P_GLOBAL,
2618 .ptr = &Globals.bDisableSpoolss,
2619 .special = NULL,
2620 .enum_list = NULL,
2621 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2622 },
2623 {
2624 .label = "enable spoolss",
2625 .type = P_BOOLREV,
2626 .p_class = P_GLOBAL,
2627 .ptr = &Globals.bDisableSpoolss,
2628 .special = NULL,
2629 .enum_list = NULL,
2630 .flags = FLAG_HIDE,
2631 },
2632 {
2633 .label = "lpq command",
2634 .type = P_STRING,
2635 .p_class = P_LOCAL,
2636 .ptr = &sDefault.szLpqcommand,
2637 .special = NULL,
2638 .enum_list = NULL,
2639 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2640 },
2641 {
2642 .label = "lprm command",
2643 .type = P_STRING,
2644 .p_class = P_LOCAL,
2645 .ptr = &sDefault.szLprmcommand,
2646 .special = NULL,
2647 .enum_list = NULL,
2648 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2649 },
2650 {
2651 .label = "lppause command",
2652 .type = P_STRING,
2653 .p_class = P_LOCAL,
2654 .ptr = &sDefault.szLppausecommand,
2655 .special = NULL,
2656 .enum_list = NULL,
2657 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2658 },
2659 {
2660 .label = "lpresume command",
2661 .type = P_STRING,
2662 .p_class = P_LOCAL,
2663 .ptr = &sDefault.szLpresumecommand,
2664 .special = NULL,
2665 .enum_list = NULL,
2666 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2667 },
2668 {
2669 .label = "queuepause command",
2670 .type = P_STRING,
2671 .p_class = P_LOCAL,
2672 .ptr = &sDefault.szQueuepausecommand,
2673 .special = NULL,
2674 .enum_list = NULL,
2675 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2676 },
2677 {
2678 .label = "queueresume command",
2679 .type = P_STRING,
2680 .p_class = P_LOCAL,
2681 .ptr = &sDefault.szQueueresumecommand,
2682 .special = NULL,
2683 .enum_list = NULL,
2684 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2685 },
2686 {
2687 .label = "addport command",
2688 .type = P_STRING,
2689 .p_class = P_GLOBAL,
2690 .ptr = &Globals.szAddPortCommand,
2691 .special = NULL,
2692 .enum_list = NULL,
2693 .flags = FLAG_ADVANCED,
2694 },
2695 {
2696 .label = "enumports command",
2697 .type = P_STRING,
2698 .p_class = P_GLOBAL,
2699 .ptr = &Globals.szEnumPortsCommand,
2700 .special = NULL,
2701 .enum_list = NULL,
2702 .flags = FLAG_ADVANCED,
2703 },
2704 {
2705 .label = "addprinter command",
2706 .type = P_STRING,
2707 .p_class = P_GLOBAL,
2708 .ptr = &Globals.szAddPrinterCommand,
2709 .special = NULL,
2710 .enum_list = NULL,
2711 .flags = FLAG_ADVANCED,
2712 },
2713 {
2714 .label = "deleteprinter command",
2715 .type = P_STRING,
2716 .p_class = P_GLOBAL,
2717 .ptr = &Globals.szDeletePrinterCommand,
2718 .special = NULL,
2719 .enum_list = NULL,
2720 .flags = FLAG_ADVANCED,
2721 },
2722 {
2723 .label = "show add printer wizard",
2724 .type = P_BOOL,
2725 .p_class = P_GLOBAL,
2726 .ptr = &Globals.bMsAddPrinterWizard,
2727 .special = NULL,
2728 .enum_list = NULL,
2729 .flags = FLAG_ADVANCED,
2730 },
2731 {
2732 .label = "os2 driver map",
2733 .type = P_STRING,
2734 .p_class = P_GLOBAL,
2735 .ptr = &Globals.szOs2DriverMap,
2736 .special = NULL,
2737 .enum_list = NULL,
2738 .flags = FLAG_ADVANCED,
2739 },
2740
2741 {
2742 .label = "printer name",
2743 .type = P_STRING,
2744 .p_class = P_LOCAL,
2745 .ptr = &sDefault.szPrintername,
2746 .special = NULL,
2747 .enum_list = NULL,
2748 .flags = FLAG_ADVANCED | FLAG_PRINT,
2749 },
2750 {
2751 .label = "printer",
2752 .type = P_STRING,
2753 .p_class = P_LOCAL,
2754 .ptr = &sDefault.szPrintername,
2755 .special = NULL,
2756 .enum_list = NULL,
2757 .flags = FLAG_HIDE,
2758 },
2759 {
2760 .label = "use client driver",
2761 .type = P_BOOL,
2762 .p_class = P_LOCAL,
2763 .ptr = &sDefault.bUseClientDriver,
2764 .special = NULL,
2765 .enum_list = NULL,
2766 .flags = FLAG_ADVANCED | FLAG_PRINT,
2767 },
2768 {
2769 .label = "default devmode",
2770 .type = P_BOOL,
2771 .p_class = P_LOCAL,
2772 .ptr = &sDefault.bDefaultDevmode,
2773 .special = NULL,
2774 .enum_list = NULL,
2775 .flags = FLAG_ADVANCED | FLAG_PRINT,
2776 },
2777 {
2778 .label = "force printername",
2779 .type = P_BOOL,
2780 .p_class = P_LOCAL,
2781 .ptr = &sDefault.bForcePrintername,
2782 .special = NULL,
2783 .enum_list = NULL,
2784 .flags = FLAG_ADVANCED | FLAG_PRINT,
2785 },
2786 {
2787 .label = "printjob username",
2788 .type = P_STRING,
2789 .p_class = P_LOCAL,
2790 .ptr = &sDefault.szPrintjobUsername,
2791 .special = NULL,
2792 .enum_list = NULL,
2793 .flags = FLAG_ADVANCED | FLAG_PRINT,
2794 },
2795
2796 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2797
2798 {
2799 .label = "mangling method",
2800 .type = P_STRING,
2801 .p_class = P_GLOBAL,
2802 .ptr = &Globals.szManglingMethod,
2803 .special = NULL,
2804 .enum_list = NULL,
2805 .flags = FLAG_ADVANCED,
2806 },
2807 {
2808 .label = "mangle prefix",
2809 .type = P_INTEGER,
2810 .p_class = P_GLOBAL,
2811 .ptr = &Globals.mangle_prefix,
2812 .special = NULL,
2813 .enum_list = NULL,
2814 .flags = FLAG_ADVANCED,
2815 },
2816
2817 {
2818 .label = "default case",
2819 .type = P_ENUM,
2820 .p_class = P_LOCAL,
2821 .ptr = &sDefault.iDefaultCase,
2822 .special = NULL,
2823 .enum_list = enum_case,
2824 .flags = FLAG_ADVANCED | FLAG_SHARE,
2825 },
2826 {
2827 .label = "case sensitive",
2828 .type = P_ENUM,
2829 .p_class = P_LOCAL,
2830 .ptr = &sDefault.iCaseSensitive,
2831 .special = NULL,
2832 .enum_list = enum_bool_auto,
2833 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2834 },
2835 {
2836 .label = "casesignames",
2837 .type = P_ENUM,
2838 .p_class = P_LOCAL,
2839 .ptr = &sDefault.iCaseSensitive,
2840 .special = NULL,
2841 .enum_list = enum_bool_auto,
2842 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2843 },
2844 {
2845 .label = "preserve case",
2846 .type = P_BOOL,
2847 .p_class = P_LOCAL,
2848 .ptr = &sDefault.bCasePreserve,
2849 .special = NULL,
2850 .enum_list = NULL,
2851 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2852 },
2853 {
2854 .label = "short preserve case",
2855 .type = P_BOOL,
2856 .p_class = P_LOCAL,
2857 .ptr = &sDefault.bShortCasePreserve,
2858 .special = NULL,
2859 .enum_list = NULL,
2860 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2861 },
2862 {
2863 .label = "mangling char",
2864 .type = P_CHAR,
2865 .p_class = P_LOCAL,
2866 .ptr = &sDefault.magic_char,
2867 .special = NULL,
2868 .enum_list = NULL,
2869 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2870 },
2871 {
2872 .label = "hide dot files",
2873 .type = P_BOOL,
2874 .p_class = P_LOCAL,
2875 .ptr = &sDefault.bHideDotFiles,
2876 .special = NULL,
2877 .enum_list = NULL,
2878 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2879 },
2880 {
2881 .label = "hide special files",
2882 .type = P_BOOL,
2883 .p_class = P_LOCAL,
2884 .ptr = &sDefault.bHideSpecialFiles,
2885 .special = NULL,
2886 .enum_list = NULL,
2887 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2888 },
2889 {
2890 .label = "hide unreadable",
2891 .type = P_BOOL,
2892 .p_class = P_LOCAL,
2893 .ptr = &sDefault.bHideUnReadable,
2894 .special = NULL,
2895 .enum_list = NULL,
2896 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2897 },
2898 {
2899 .label = "hide unwriteable files",
2900 .type = P_BOOL,
2901 .p_class = P_LOCAL,
2902 .ptr = &sDefault.bHideUnWriteableFiles,
2903 .special = NULL,
2904 .enum_list = NULL,
2905 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2906 },
2907 {
2908 .label = "delete veto files",
2909 .type = P_BOOL,
2910 .p_class = P_LOCAL,
2911 .ptr = &sDefault.bDeleteVetoFiles,
2912 .special = NULL,
2913 .enum_list = NULL,
2914 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2915 },
2916 {
2917 .label = "veto files",
2918 .type = P_STRING,
2919 .p_class = P_LOCAL,
2920 .ptr = &sDefault.szVetoFiles,
2921 .special = NULL,
2922 .enum_list = NULL,
2923 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2924 },
2925 {
2926 .label = "hide files",
2927 .type = P_STRING,
2928 .p_class = P_LOCAL,
2929 .ptr = &sDefault.szHideFiles,
2930 .special = NULL,
2931 .enum_list = NULL,
2932 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2933 },
2934 {
2935 .label = "veto oplock files",
2936 .type = P_STRING,
2937 .p_class = P_LOCAL,
2938 .ptr = &sDefault.szVetoOplockFiles,
2939 .special = NULL,
2940 .enum_list = NULL,
2941 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2942 },
2943 {
2944 .label = "map archive",
2945 .type = P_BOOL,
2946 .p_class = P_LOCAL,
2947 .ptr = &sDefault.bMap_archive,
2948 .special = NULL,
2949 .enum_list = NULL,
2950 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2951 },
2952 {
2953 .label = "map hidden",
2954 .type = P_BOOL,
2955 .p_class = P_LOCAL,
2956 .ptr = &sDefault.bMap_hidden,
2957 .special = NULL,
2958 .enum_list = NULL,
2959 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2960 },
2961 {
2962 .label = "map system",
2963 .type = P_BOOL,
2964 .p_class = P_LOCAL,
2965 .ptr = &sDefault.bMap_system,
2966 .special = NULL,
2967 .enum_list = NULL,
2968 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2969 },
2970 {
2971 .label = "map readonly",
2972 .type = P_ENUM,
2973 .p_class = P_LOCAL,
2974 .ptr = &sDefault.iMap_readonly,
2975 .special = NULL,
2976 .enum_list = enum_map_readonly,
2977 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2978 },
2979 {
2980 .label = "mangled names",
2981 .type = P_BOOL,
2982 .p_class = P_LOCAL,
2983 .ptr = &sDefault.bMangledNames,
2984 .special = NULL,
2985 .enum_list = NULL,
2986 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2987 },
2988 {
2989 .label = "max stat cache size",
2990 .type = P_INTEGER,
2991 .p_class = P_GLOBAL,
2992 .ptr = &Globals.iMaxStatCacheSize,
2993 .special = NULL,
2994 .enum_list = NULL,
2995 .flags = FLAG_ADVANCED,
2996 },
2997 {
2998 .label = "stat cache",
2999 .type = P_BOOL,
3000 .p_class = P_GLOBAL,
3001 .ptr = &Globals.bStatCache,
3002 .special = NULL,
3003 .enum_list = NULL,
3004 .flags = FLAG_ADVANCED,
3005 },
3006 {
3007 .label = "store dos attributes",
3008 .type = P_BOOL,
3009 .p_class = P_LOCAL,
3010 .ptr = &sDefault.bStoreDosAttributes,
3011 .special = NULL,
3012 .enum_list = NULL,
3013 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3014 },
3015 {
3016 .label = "dmapi support",
3017 .type = P_BOOL,
3018 .p_class = P_LOCAL,
3019 .ptr = &sDefault.bDmapiSupport,
3020 .special = NULL,
3021 .enum_list = NULL,
3022 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3023 },
3024
3025
3026 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3027
3028 {
3029 .label = "machine password timeout",
3030 .type = P_INTEGER,
3031 .p_class = P_GLOBAL,
3032 .ptr = &Globals.machine_password_timeout,
3033 .special = NULL,
3034 .enum_list = NULL,
3035 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3036 },
3037
3038 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3039
3040 {
3041 .label = "add user script",
3042 .type = P_STRING,
3043 .p_class = P_GLOBAL,
3044 .ptr = &Globals.szAddUserScript,
3045 .special = NULL,
3046 .enum_list = NULL,
3047 .flags = FLAG_ADVANCED,
3048 },
3049 {
3050 .label = "rename user script",
3051 .type = P_STRING,
3052 .p_class = P_GLOBAL,
3053 .ptr = &Globals.szRenameUserScript,
3054 .special = NULL,
3055 .enum_list = NULL,
3056 .flags = FLAG_ADVANCED,
3057 },
3058 {
3059 .label = "delete user script",
3060 .type = P_STRING,
3061 .p_class = P_GLOBAL,
3062 .ptr = &Globals.szDelUserScript,
3063 .special = NULL,
3064 .enum_list = NULL,
3065 .flags = FLAG_ADVANCED,
3066 },
3067 {
3068 .label = "add group script",
3069 .type = P_STRING,
3070 .p_class = P_GLOBAL,
3071 .ptr = &Globals.szAddGroupScript,
3072 .special = NULL,
3073 .enum_list = NULL,
3074 .flags = FLAG_ADVANCED,
3075 },
3076 {
3077 .label = "delete group script",
3078 .type = P_STRING,
3079 .p_class = P_GLOBAL,
3080 .ptr = &Globals.szDelGroupScript,
3081 .special = NULL,
3082 .enum_list = NULL,
3083 .flags = FLAG_ADVANCED,
3084 },
3085 {
3086 .label = "add user to group script",
3087 .type = P_STRING,
3088 .p_class = P_GLOBAL,
3089 .ptr = &Globals.szAddUserToGroupScript,
3090 .special = NULL,
3091 .enum_list = NULL,
3092 .flags = FLAG_ADVANCED,
3093 },
3094 {
3095 .label = "delete user from group script",
3096 .type = P_STRING,
3097 .p_class = P_GLOBAL,
3098 .ptr = &Globals.szDelUserFromGroupScript,
3099 .special = NULL,
3100 .enum_list = NULL,
3101 .flags = FLAG_ADVANCED,
3102 },
3103 {
3104 .label = "set primary group script",
3105 .type = P_STRING,
3106 .p_class = P_GLOBAL,
3107 .ptr = &Globals.szSetPrimaryGroupScript,
3108 .special = NULL,
3109 .enum_list = NULL,
3110 .flags = FLAG_ADVANCED,
3111 },
3112 {
3113 .label = "add machine script",
3114 .type = P_STRING,
3115 .p_class = P_GLOBAL,
3116 .ptr = &Globals.szAddMachineScript,
3117 .special = NULL,
3118 .enum_list = NULL,
3119 .flags = FLAG_ADVANCED,
3120 },
3121 {
3122 .label = "shutdown script",
3123 .type = P_STRING,
3124 .p_class = P_GLOBAL,
3125 .ptr = &Globals.szShutdownScript,
3126 .special = NULL,
3127 .enum_list = NULL,
3128 .flags = FLAG_ADVANCED,
3129 },
3130 {
3131 .label = "abort shutdown script",
3132 .type = P_STRING,
3133 .p_class = P_GLOBAL,
3134 .ptr = &Globals.szAbortShutdownScript,
3135 .special = NULL,
3136 .enum_list = NULL,
3137 .flags = FLAG_ADVANCED,
3138 },
3139 {
3140 .label = "username map script",
3141 .type = P_STRING,
3142 .p_class = P_GLOBAL,
3143 .ptr = &Globals.szUsernameMapScript,
3144 .special = NULL,
3145 .enum_list = NULL,
3146 .flags = FLAG_ADVANCED,
3147 },
3148 {
3149 .label = "logon script",
3150 .type = P_STRING,
3151 .p_class = P_GLOBAL,
3152 .ptr = &Globals.szLogonScript,
3153 .special = NULL,
3154 .enum_list = NULL,
3155 .flags = FLAG_ADVANCED,
3156 },
3157 {
3158 .label = "logon path",
3159 .type = P_STRING,
3160 .p_class = P_GLOBAL,
3161 .ptr = &Globals.szLogonPath,
3162 .special = NULL,
3163 .enum_list = NULL,
3164 .flags = FLAG_ADVANCED,
3165 },
3166 {
3167 .label = "logon drive",
3168 .type = P_STRING,
3169 .p_class = P_GLOBAL,
3170 .ptr = &Globals.szLogonDrive,
3171 .special = NULL,
3172 .enum_list = NULL,
3173 .flags = FLAG_ADVANCED,
3174 },
3175 {
3176 .label = "logon home",
3177 .type = P_STRING,
3178 .p_class = P_GLOBAL,
3179 .ptr = &Globals.szLogonHome,
3180 .special = NULL,
3181 .enum_list = NULL,
3182 .flags = FLAG_ADVANCED,
3183 },
3184 {
3185 .label = "domain logons",
3186 .type = P_BOOL,
3187 .p_class = P_GLOBAL,
3188 .ptr = &Globals.bDomainLogons,
3189 .special = NULL,
3190 .enum_list = NULL,
3191 .flags = FLAG_ADVANCED,
3192 },
3193
3194 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3195
3196 {
3197 .label = "os level",
3198 .type = P_INTEGER,
3199 .p_class = P_GLOBAL,
3200 .ptr = &Globals.os_level,
3201 .special = NULL,
3202 .enum_list = NULL,
3203 .flags = FLAG_BASIC | FLAG_ADVANCED,
3204 },
3205 {
3206 .label = "lm announce",
3207 .type = P_ENUM,
3208 .p_class = P_GLOBAL,
3209 .ptr = &Globals.lm_announce,
3210 .special = NULL,
3211 .enum_list = enum_bool_auto,
3212 .flags = FLAG_ADVANCED,
3213 },
3214 {
3215 .label = "lm interval",
3216 .type = P_INTEGER,
3217 .p_class = P_GLOBAL,
3218 .ptr = &Globals.lm_interval,
3219 .special = NULL,
3220 .enum_list = NULL,
3221 .flags = FLAG_ADVANCED,
3222 },
3223 {
3224 .label = "preferred master",
3225 .type = P_ENUM,
3226 .p_class = P_GLOBAL,
3227 .ptr = &Globals.iPreferredMaster,
3228 .special = NULL,
3229 .enum_list = enum_bool_auto,
3230 .flags = FLAG_BASIC | FLAG_ADVANCED,
3231 },
3232 {
3233 .label = "prefered master",
3234 .type = P_ENUM,
3235 .p_class = P_GLOBAL,
3236 .ptr = &Globals.iPreferredMaster,
3237 .special = NULL,
3238 .enum_list = enum_bool_auto,
3239 .flags = FLAG_HIDE,
3240 },
3241 {
3242 .label = "local master",
3243 .type = P_BOOL,
3244 .p_class = P_GLOBAL,
3245 .ptr = &Globals.bLocalMaster,
3246 .special = NULL,
3247 .enum_list = NULL,
3248 .flags = FLAG_BASIC | FLAG_ADVANCED,
3249 },
3250 {
3251 .label = "domain master",
3252 .type = P_ENUM,
3253 .p_class = P_GLOBAL,
3254 .ptr = &Globals.iDomainMaster,
3255 .special = NULL,
3256 .enum_list = enum_bool_auto,
3257 .flags = FLAG_BASIC | FLAG_ADVANCED,
3258 },
3259 {
3260 .label = "browse list",
3261 .type = P_BOOL,
3262 .p_class = P_GLOBAL,
3263 .ptr = &Globals.bBrowseList,
3264 .special = NULL,
3265 .enum_list = NULL,
3266 .flags = FLAG_ADVANCED,
3267 },
3268 {
3269 .label = "browseable",
3270 .type = P_BOOL,
3271 .p_class = P_LOCAL,
3272 .ptr = &sDefault.bBrowseable,
3273 .special = NULL,
3274 .enum_list = NULL,
3275 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3276 },
3277 {
3278 .label = "browsable",
3279 .type = P_BOOL,
3280 .p_class = P_LOCAL,
3281 .ptr = &sDefault.bBrowseable,
3282 .special = NULL,
3283 .enum_list = NULL,
3284 .flags = FLAG_HIDE,
3285 },
3286 {
3287 .label = "enhanced browsing",
3288 .type = P_BOOL,
3289 .p_class = P_GLOBAL,
3290 .ptr = &Globals.enhanced_browsing,
3291 .special = NULL,
3292 .enum_list = NULL,
3293 .flags = FLAG_ADVANCED,
3294 },
3295
3296 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3297
3298 {
3299 .label = "dns proxy",
3300 .type = P_BOOL,
3301 .p_class = P_GLOBAL,
3302 .ptr = &Globals.bDNSproxy,
3303 .special = NULL,
3304 .enum_list = NULL,
3305 .flags = FLAG_ADVANCED,
3306 },
3307 {
3308 .label = "wins proxy",
3309 .type = P_BOOL,
3310 .p_class = P_GLOBAL,
3311 .ptr = &Globals.bWINSproxy,
3312 .special = NULL,
3313 .enum_list = NULL,
3314 .flags = FLAG_ADVANCED,
3315 },
3316 {
3317 .label = "wins server",
3318 .type = P_LIST,
3319 .p_class = P_GLOBAL,
3320 .ptr = &Globals.szWINSservers,
3321 .special = NULL,
3322 .enum_list = NULL,
3323 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3324 },
3325 {
3326 .label = "wins support",
3327 .type = P_BOOL,
3328 .p_class = P_GLOBAL,
3329 .ptr = &Globals.bWINSsupport,
3330 .special = NULL,
3331 .enum_list = NULL,
3332 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3333 },
3334 {
3335 .label = "wins hook",
3336 .type = P_STRING,
3337 .p_class = P_GLOBAL,
3338 .ptr = &Globals.szWINSHook,
3339 .special = NULL,
3340 .enum_list = NULL,
3341 .flags = FLAG_ADVANCED,
3342 },
3343
3344 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3345
3346 {
3347 .label = "blocking locks",
3348 .type = P_BOOL,
3349 .p_class = P_LOCAL,
3350 .ptr = &sDefault.bBlockingLocks,
3351 .special = NULL,
3352 .enum_list = NULL,
3353 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3354 },
3355 {
3356 .label = "csc policy",
3357 .type = P_ENUM,
3358 .p_class = P_LOCAL,
3359 .ptr = &sDefault.iCSCPolicy,
3360 .special = NULL,
3361 .enum_list = enum_csc_policy,
3362 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3363 },
3364 {
3365 .label = "fake oplocks",
3366 .type = P_BOOL,
3367 .p_class = P_LOCAL,
3368 .ptr = &sDefault.bFakeOplocks,
3369 .special = NULL,
3370 .enum_list = NULL,
3371 .flags = FLAG_ADVANCED | FLAG_SHARE,
3372 },
3373 {
3374 .label = "kernel oplocks",
3375 .type = P_BOOL,
3376 .p_class = P_GLOBAL,
3377 .ptr = &Globals.bKernelOplocks,
3378 .special = NULL,
3379 .enum_list = NULL,
3380 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3381 },
3382 {
3383 .label = "locking",
3384 .type = P_BOOL,
3385 .p_class = P_LOCAL,
3386 .ptr = &sDefault.bLocking,
3387 .special = NULL,
3388 .enum_list = NULL,
3389 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3390 },
3391 {
3392 .label = "lock spin time",
3393 .type = P_INTEGER,
3394 .p_class = P_GLOBAL,
3395 .ptr = &Globals.iLockSpinTime,
3396 .special = NULL,
3397 .enum_list = NULL,
3398 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3399 },
3400 {
3401 .label = "oplocks",
3402 .type = P_BOOL,
3403 .p_class = P_LOCAL,
3404 .ptr = &sDefault.bOpLocks,
3405 .special = NULL,
3406 .enum_list = NULL,
3407 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3408 },
3409 {
3410 .label = "level2 oplocks",
3411 .type = P_BOOL,
3412 .p_class = P_LOCAL,
3413 .ptr = &sDefault.bLevel2OpLocks,
3414 .special = NULL,
3415 .enum_list = NULL,
3416 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3417 },
3418 {
3419 .label = "oplock break wait time",
3420 .type = P_INTEGER,
3421 .p_class = P_GLOBAL,
3422 .ptr = &Globals.oplock_break_wait_time,
3423 .special = NULL,
3424 .enum_list = NULL,
3425 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3426 },
3427 {
3428 .label = "oplock contention limit",
3429 .type = P_INTEGER,
3430 .p_class = P_LOCAL,
3431 .ptr = &sDefault.iOplockContentionLimit,
3432 .special = NULL,
3433 .enum_list = NULL,
3434 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3435 },
3436 {
3437 .label = "posix locking",
3438 .type = P_BOOL,
3439 .p_class = P_LOCAL,
3440 .ptr = &sDefault.bPosixLocking,
3441 .special = NULL,
3442 .enum_list = NULL,
3443 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3444 },
3445 {
3446 .label = "strict locking",
3447 .type = P_ENUM,
3448 .p_class = P_LOCAL,
3449 .ptr = &sDefault.iStrictLocking,
3450 .special = NULL,
3451 .enum_list = enum_bool_auto,
3452 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3453 },
3454 {
3455 .label = "share modes",
3456 .type = P_BOOL,
3457 .p_class = P_LOCAL,
3458 .ptr = &sDefault.bShareModes,
3459 .special = NULL,
3460 .enum_list = NULL,
3461 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3462 },
3463
3464 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3465
3466 {
3467 .label = "ldap admin dn",
3468 .type = P_STRING,
3469 .p_class = P_GLOBAL,
3470 .ptr = &Globals.szLdapAdminDn,
3471 .special = NULL,
3472 .enum_list = NULL,
3473 .flags = FLAG_ADVANCED,
3474 },
3475 {
3476 .label = "ldap delete dn",
3477 .type = P_BOOL,
3478 .p_class = P_GLOBAL,
3479 .ptr = &Globals.ldap_delete_dn,
3480 .special = NULL,
3481 .enum_list = NULL,
3482 .flags = FLAG_ADVANCED,
3483 },
3484 {
3485 .label = "ldap group suffix",
3486 .type = P_STRING,
3487 .p_class = P_GLOBAL,
3488 .ptr = &Globals.szLdapGroupSuffix,
3489 .special = NULL,
3490 .enum_list = NULL,
3491 .flags = FLAG_ADVANCED,
3492 },
3493 {
3494 .label = "ldap idmap suffix",
3495 .type = P_STRING,
3496 .p_class = P_GLOBAL,
3497 .ptr = &Globals.szLdapIdmapSuffix,
3498 .special = NULL,
3499 .enum_list = NULL,
3500 .flags = FLAG_ADVANCED,
3501 },
3502 {
3503 .label = "ldap machine suffix",
3504 .type = P_STRING,
3505 .p_class = P_GLOBAL,
3506 .ptr = &Globals.szLdapMachineSuffix,
3507 .special = NULL,
3508 .enum_list = NULL,
3509 .flags = FLAG_ADVANCED,
3510 },
3511 {
3512 .label = "ldap passwd sync",
3513 .type = P_ENUM,
3514 .p_class = P_GLOBAL,
3515 .ptr = &Globals.ldap_passwd_sync,
3516 .special = NULL,
3517 .enum_list = enum_ldap_passwd_sync,
3518 .flags = FLAG_ADVANCED,
3519 },
3520 {
3521 .label = "ldap password sync",
3522 .type = P_ENUM,
3523 .p_class = P_GLOBAL,
3524 .ptr = &Globals.ldap_passwd_sync,
3525 .special = NULL,
3526 .enum_list = enum_ldap_passwd_sync,
3527 .flags = FLAG_HIDE,
3528 },
3529 {
3530 .label = "ldap replication sleep",
3531 .type = P_INTEGER,
3532 .p_class = P_GLOBAL,
3533 .ptr = &Globals.ldap_replication_sleep,
3534 .special = NULL,
3535 .enum_list = NULL,
3536 .flags = FLAG_ADVANCED,
3537 },
3538 {
3539 .label = "ldap suffix",
3540 .type = P_STRING,
3541 .p_class = P_GLOBAL,
3542 .ptr = &Globals.szLdapSuffix,
3543 .special = NULL,
3544 .enum_list = NULL,
3545 .flags = FLAG_ADVANCED,
3546 },
3547 {
3548 .label = "ldap ssl",
3549 .type = P_ENUM,
3550 .p_class = P_GLOBAL,
3551 .ptr = &Globals.ldap_ssl,
3552 .special = NULL,
3553 .enum_list = enum_ldap_ssl,
3554 .flags = FLAG_ADVANCED,
3555 },
3556 {
3557 .label = "ldap timeout",
3558 .type = P_INTEGER,
3559 .p_class = P_GLOBAL,
3560 .ptr = &Globals.ldap_timeout,
3561 .special = NULL,
3562 .enum_list = NULL,
3563 .flags = FLAG_ADVANCED,
3564 },
3565 {
3566 .label = "ldap connection timeout",
3567 .type = P_INTEGER,
3568 .p_class = P_GLOBAL,
3569 .ptr = &Globals.ldap_connection_timeout,
3570 .special = NULL,
3571 .enum_list = NULL,
3572 .flags = FLAG_ADVANCED,
3573 },
3574 {
3575 .label = "ldap page size",
3576 .type = P_INTEGER,
3577 .p_class = P_GLOBAL,
3578 .ptr = &Globals.ldap_page_size,
3579 .special = NULL,
3580 .enum_list = NULL,
3581 .flags = FLAG_ADVANCED,
3582 },
3583 {
3584 .label = "ldap user suffix",
3585 .type = P_STRING,
3586 .p_class = P_GLOBAL,
3587 .ptr = &Globals.szLdapUserSuffix,
3588 .special = NULL,
3589 .enum_list = NULL,
3590 .flags = FLAG_ADVANCED,
3591 },
3592 {
3593 .label = "ldap debug level",
3594 .type = P_INTEGER,
3595 .p_class = P_GLOBAL,
3596 .ptr = &Globals.ldap_debug_level,
3597 .special = handle_ldap_debug_level,
3598 .enum_list = NULL,
3599 .flags = FLAG_ADVANCED,
3600 },
3601 {
3602 .label = "ldap debug threshold",
3603 .type = P_INTEGER,
3604 .p_class = P_GLOBAL,
3605 .ptr = &Globals.ldap_debug_threshold,
3606 .special = NULL,
3607 .enum_list = NULL,
3608 .flags = FLAG_ADVANCED,
3609 },
3610
3611 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3612
3613 {
3614 .label = "eventlog list",
3615 .type = P_LIST,
3616 .p_class = P_GLOBAL,
3617 .ptr = &Globals.szEventLogs,
3618 .special = NULL,
3619 .enum_list = NULL,
3620 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3621 },
3622
3623 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3624
3625 {
3626 .label = "add share command",
3627 .type = P_STRING,
3628 .p_class = P_GLOBAL,
3629 .ptr = &Globals.szAddShareCommand,
3630 .special = NULL,
3631 .enum_list = NULL,
3632 .flags = FLAG_ADVANCED,
3633 },
3634 {
3635 .label = "change share command",
3636 .type = P_STRING,
3637 .p_class = P_GLOBAL,
3638 .ptr = &Globals.szChangeShareCommand,
3639 .special = NULL,
3640 .enum_list = NULL,
3641 .flags = FLAG_ADVANCED,
3642 },
3643 {
3644 .label = "delete share command",
3645 .type = P_STRING,
3646 .p_class = P_GLOBAL,
3647 .ptr = &Globals.szDeleteShareCommand,
3648 .special = NULL,
3649 .enum_list = NULL,
3650 .flags = FLAG_ADVANCED,
3651 },
3652 {
3653 .label = "config file",
3654 .type = P_STRING,
3655 .p_class = P_GLOBAL,
3656 .ptr = &Globals.szConfigFile,
3657 .special = NULL,
3658 .enum_list = NULL,
3659 .flags = FLAG_HIDE,
3660 },
3661 {
3662 .label = "preload",
3663 .type = P_STRING,
3664 .p_class = P_GLOBAL,
3665 .ptr = &Globals.szAutoServices,
3666 .special = NULL,
3667 .enum_list = NULL,
3668 .flags = FLAG_ADVANCED,
3669 },
3670 {
3671 .label = "auto services",
3672 .type = P_STRING,
3673 .p_class = P_GLOBAL,
3674 .ptr = &Globals.szAutoServices,
3675 .special = NULL,
3676 .enum_list = NULL,
3677 .flags = FLAG_ADVANCED,
3678 },
3679 {
3680 .label = "lock directory",
3681 .type = P_STRING,
3682 .p_class = P_GLOBAL,
3683 .ptr = &Globals.szLockDir,
3684 .special = NULL,
3685 .enum_list = NULL,
3686 .flags = FLAG_ADVANCED,
3687 },
3688 {
3689 .label = "lock dir",
3690 .type = P_STRING,
3691 .p_class = P_GLOBAL,
3692 .ptr = &Globals.szLockDir,
3693 .special = NULL,
3694 .enum_list = NULL,
3695 .flags = FLAG_HIDE,
3696 },
3697 {
3698 .label = "pid directory",
3699 .type = P_STRING,
3700 .p_class = P_GLOBAL,
3701 .ptr = &Globals.szPidDir,
3702 .special = NULL,
3703 .enum_list = NULL,
3704 .flags = FLAG_ADVANCED,
3705 },
3706#ifdef WITH_UTMP
3707 {
3708 .label = "utmp directory",
3709 .type = P_STRING,
3710 .p_class = P_GLOBAL,
3711 .ptr = &Globals.szUtmpDir,
3712 .special = NULL,
3713 .enum_list = NULL,
3714 .flags = FLAG_ADVANCED,
3715 },
3716 {
3717 .label = "wtmp directory",
3718 .type = P_STRING,
3719 .p_class = P_GLOBAL,
3720 .ptr = &Globals.szWtmpDir,
3721 .special = NULL,
3722 .enum_list = NULL,
3723 .flags = FLAG_ADVANCED,
3724 },
3725 {
3726 .label = "utmp",
3727 .type = P_BOOL,
3728 .p_class = P_GLOBAL,
3729 .ptr = &Globals.bUtmp,
3730 .special = NULL,
3731 .enum_list = NULL,
3732 .flags = FLAG_ADVANCED,
3733 },
3734#endif
3735 {
3736 .label = "default service",
3737 .type = P_STRING,
3738 .p_class = P_GLOBAL,
3739 .ptr = &Globals.szDefaultService,
3740 .special = NULL,
3741 .enum_list = NULL,
3742 .flags = FLAG_ADVANCED,
3743 },
3744 {
3745 .label = "default",
3746 .type = P_STRING,
3747 .p_class = P_GLOBAL,
3748 .ptr = &Globals.szDefaultService,
3749 .special = NULL,
3750 .enum_list = NULL,
3751 .flags = FLAG_ADVANCED,
3752 },
3753 {
3754 .label = "message command",
3755 .type = P_STRING,
3756 .p_class = P_GLOBAL,
3757 .ptr = &Globals.szMsgCommand,
3758 .special = NULL,
3759 .enum_list = NULL,
3760 .flags = FLAG_ADVANCED,
3761 },
3762 {
3763 .label = "dfree cache time",
3764 .type = P_INTEGER,
3765 .p_class = P_LOCAL,
3766 .ptr = &sDefault.iDfreeCacheTime,
3767 .special = NULL,
3768 .enum_list = NULL,
3769 .flags = FLAG_ADVANCED,
3770 },
3771 {
3772 .label = "dfree command",
3773 .type = P_STRING,
3774 .p_class = P_LOCAL,
3775 .ptr = &sDefault.szDfree,
3776 .special = NULL,
3777 .enum_list = NULL,
3778 .flags = FLAG_ADVANCED,
3779 },
3780 {
3781 .label = "get quota command",
3782 .type = P_STRING,
3783 .p_class = P_GLOBAL,
3784 .ptr = &Globals.szGetQuota,
3785 .special = NULL,
3786 .enum_list = NULL,
3787 .flags = FLAG_ADVANCED,
3788 },
3789 {
3790 .label = "set quota command",
3791 .type = P_STRING,
3792 .p_class = P_GLOBAL,
3793 .ptr = &Globals.szSetQuota,
3794 .special = NULL,
3795 .enum_list = NULL,
3796 .flags = FLAG_ADVANCED,
3797 },
3798 {
3799 .label = "remote announce",
3800 .type = P_STRING,
3801 .p_class = P_GLOBAL,
3802 .ptr = &Globals.szRemoteAnnounce,
3803 .special = NULL,
3804 .enum_list = NULL,
3805 .flags = FLAG_ADVANCED,
3806 },
3807 {
3808 .label = "remote browse sync",
3809 .type = P_STRING,
3810 .p_class = P_GLOBAL,
3811 .ptr = &Globals.szRemoteBrowseSync,
3812 .special = NULL,
3813 .enum_list = NULL,
3814 .flags = FLAG_ADVANCED,
3815 },
3816 {
3817 .label = "socket address",
3818 .type = P_STRING,
3819 .p_class = P_GLOBAL,
3820 .ptr = &Globals.szSocketAddress,
3821 .special = NULL,
3822 .enum_list = NULL,
3823 .flags = FLAG_ADVANCED,
3824 },
3825 {
3826 .label = "homedir map",
3827 .type = P_STRING,
3828 .p_class = P_GLOBAL,
3829 .ptr = &Globals.szNISHomeMapName,
3830 .special = NULL,
3831 .enum_list = NULL,
3832 .flags = FLAG_ADVANCED,
3833 },
3834 {
3835 .label = "afs username map",
3836 .type = P_STRING,
3837 .p_class = P_GLOBAL,
3838 .ptr = &Globals.szAfsUsernameMap,
3839 .special = NULL,
3840 .enum_list = NULL,
3841 .flags = FLAG_ADVANCED,
3842 },
3843 {
3844 .label = "afs token lifetime",
3845 .type = P_INTEGER,
3846 .p_class = P_GLOBAL,
3847 .ptr = &Globals.iAfsTokenLifetime,
3848 .special = NULL,
3849 .enum_list = NULL,
3850 .flags = FLAG_ADVANCED,
3851 },
3852 {
3853 .label = "log nt token command",
3854 .type = P_STRING,
3855 .p_class = P_GLOBAL,
3856 .ptr = &Globals.szLogNtTokenCommand,
3857 .special = NULL,
3858 .enum_list = NULL,
3859 .flags = FLAG_ADVANCED,
3860 },
3861 {
3862 .label = "time offset",
3863 .type = P_INTEGER,
3864 .p_class = P_GLOBAL,
3865 .ptr = &extra_time_offset,
3866 .special = NULL,
3867 .enum_list = NULL,
3868 .flags = FLAG_ADVANCED,
3869 },
3870 {
3871 .label = "NIS homedir",
3872 .type = P_BOOL,
3873 .p_class = P_GLOBAL,
3874 .ptr = &Globals.bNISHomeMap,
3875 .special = NULL,
3876 .enum_list = NULL,
3877 .flags = FLAG_ADVANCED,
3878 },
3879 {
3880 .label = "-valid",
3881 .type = P_BOOL,
3882 .p_class = P_LOCAL,
3883 .ptr = &sDefault.valid,
3884 .special = NULL,
3885 .enum_list = NULL,
3886 .flags = FLAG_HIDE,
3887 },
3888 {
3889 .label = "copy",
3890 .type = P_STRING,
3891 .p_class = P_LOCAL,
3892 .ptr = &sDefault.szCopy,
3893 .special = handle_copy,
3894 .enum_list = NULL,
3895 .flags = FLAG_HIDE,
3896 },
3897 {
3898 .label = "include",
3899 .type = P_STRING,
3900 .p_class = P_LOCAL,
3901 .ptr = &sDefault.szInclude,
3902 .special = handle_include,
3903 .enum_list = NULL,
3904 .flags = FLAG_HIDE,
3905 },
3906 {
3907 .label = "preexec",
3908 .type = P_STRING,
3909 .p_class = P_LOCAL,
3910 .ptr = &sDefault.szPreExec,
3911 .special = NULL,
3912 .enum_list = NULL,
3913 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3914 },
3915 {
3916 .label = "exec",
3917 .type = P_STRING,
3918 .p_class = P_LOCAL,
3919 .ptr = &sDefault.szPreExec,
3920 .special = NULL,
3921 .enum_list = NULL,
3922 .flags = FLAG_ADVANCED,
3923 },
3924 {
3925 .label = "preexec close",
3926 .type = P_BOOL,
3927 .p_class = P_LOCAL,
3928 .ptr = &sDefault.bPreexecClose,
3929 .special = NULL,
3930 .enum_list = NULL,
3931 .flags = FLAG_ADVANCED | FLAG_SHARE,
3932 },
3933 {
3934 .label = "postexec",
3935 .type = P_STRING,
3936 .p_class = P_LOCAL,
3937 .ptr = &sDefault.szPostExec,
3938 .special = NULL,
3939 .enum_list = NULL,
3940 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3941 },
3942 {
3943 .label = "root preexec",
3944 .type = P_STRING,
3945 .p_class = P_LOCAL,
3946 .ptr = &sDefault.szRootPreExec,
3947 .special = NULL,
3948 .enum_list = NULL,
3949 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3950 },
3951 {
3952 .label = "root preexec close",
3953 .type = P_BOOL,
3954 .p_class = P_LOCAL,
3955 .ptr = &sDefault.bRootpreexecClose,
3956 .special = NULL,
3957 .enum_list = NULL,
3958 .flags = FLAG_ADVANCED | FLAG_SHARE,
3959 },
3960 {
3961 .label = "root postexec",
3962 .type = P_STRING,
3963 .p_class = P_LOCAL,
3964 .ptr = &sDefault.szRootPostExec,
3965 .special = NULL,
3966 .enum_list = NULL,
3967 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3968 },
3969 {
3970 .label = "available",
3971 .type = P_BOOL,
3972 .p_class = P_LOCAL,
3973 .ptr = &sDefault.bAvailable,
3974 .special = NULL,
3975 .enum_list = NULL,
3976 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3977 },
3978 {
3979 .label = "registry shares",
3980 .type = P_BOOL,
3981 .p_class = P_GLOBAL,
3982 .ptr = &Globals.bRegistryShares,
3983 .special = NULL,
3984 .enum_list = NULL,
3985 .flags = FLAG_ADVANCED,
3986 },
3987 {
3988 .label = "usershare allow guests",
3989 .type = P_BOOL,
3990 .p_class = P_GLOBAL,
3991 .ptr = &Globals.bUsershareAllowGuests,
3992 .special = NULL,
3993 .enum_list = NULL,
3994 .flags = FLAG_ADVANCED,
3995 },
3996 {
3997 .label = "usershare max shares",
3998 .type = P_INTEGER,
3999 .p_class = P_GLOBAL,
4000 .ptr = &Globals.iUsershareMaxShares,
4001 .special = NULL,
4002 .enum_list = NULL,
4003 .flags = FLAG_ADVANCED,
4004 },
4005 {
4006 .label = "usershare owner only",
4007 .type = P_BOOL,
4008 .p_class = P_GLOBAL,
4009 .ptr = &Globals.bUsershareOwnerOnly,
4010 .special = NULL,
4011 .enum_list = NULL,
4012 .flags = FLAG_ADVANCED,
4013 },
4014 {
4015 .label = "usershare path",
4016 .type = P_STRING,
4017 .p_class = P_GLOBAL,
4018 .ptr = &Globals.szUsersharePath,
4019 .special = NULL,
4020 .enum_list = NULL,
4021 .flags = FLAG_ADVANCED,
4022 },
4023 {
4024 .label = "usershare prefix allow list",
4025 .type = P_LIST,
4026 .p_class = P_GLOBAL,
4027 .ptr = &Globals.szUsersharePrefixAllowList,
4028 .special = NULL,
4029 .enum_list = NULL,
4030 .flags = FLAG_ADVANCED,
4031 },
4032 {
4033 .label = "usershare prefix deny list",
4034 .type = P_LIST,
4035 .p_class = P_GLOBAL,
4036 .ptr = &Globals.szUsersharePrefixDenyList,
4037 .special = NULL,
4038 .enum_list = NULL,
4039 .flags = FLAG_ADVANCED,
4040 },
4041 {
4042 .label = "usershare template share",
4043 .type = P_STRING,
4044 .p_class = P_GLOBAL,
4045 .ptr = &Globals.szUsershareTemplateShare,
4046 .special = NULL,
4047 .enum_list = NULL,
4048 .flags = FLAG_ADVANCED,
4049 },
4050 {
4051 .label = "volume",
4052 .type = P_STRING,
4053 .p_class = P_LOCAL,
4054 .ptr = &sDefault.volume,
4055 .special = NULL,
4056 .enum_list = NULL,
4057 .flags = FLAG_ADVANCED | FLAG_SHARE,
4058 },
4059 {
4060 .label = "fstype",
4061 .type = P_STRING,
4062 .p_class = P_LOCAL,
4063 .ptr = &sDefault.fstype,
4064 .special = NULL,
4065 .enum_list = NULL,
4066 .flags = FLAG_ADVANCED | FLAG_SHARE,
4067 },
4068 {
4069 .label = "set directory",
4070 .type = P_BOOLREV,
4071 .p_class = P_LOCAL,
4072 .ptr = &sDefault.bNo_set_dir,
4073 .special = NULL,
4074 .enum_list = NULL,
4075 .flags = FLAG_ADVANCED | FLAG_SHARE,
4076 },
4077 {
4078 .label = "wide links",
4079 .type = P_BOOL,
4080 .p_class = P_LOCAL,
4081 .ptr = &sDefault.bWidelinks,
4082 .special = NULL,
4083 .enum_list = NULL,
4084 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4085 },
4086 {
4087 .label = "follow symlinks",
4088 .type = P_BOOL,
4089 .p_class = P_LOCAL,
4090 .ptr = &sDefault.bSymlinks,
4091 .special = NULL,
4092 .enum_list = NULL,
4093 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4094 },
4095 {
4096 .label = "dont descend",
4097 .type = P_STRING,
4098 .p_class = P_LOCAL,
4099 .ptr = &sDefault.szDontdescend,
4100 .special = NULL,
4101 .enum_list = NULL,
4102 .flags = FLAG_ADVANCED | FLAG_SHARE,
4103 },
4104 {
4105 .label = "magic script",
4106 .type = P_STRING,
4107 .p_class = P_LOCAL,
4108 .ptr = &sDefault.szMagicScript,
4109 .special = NULL,
4110 .enum_list = NULL,
4111 .flags = FLAG_ADVANCED | FLAG_SHARE,
4112 },
4113 {
4114 .label = "magic output",
4115 .type = P_STRING,
4116 .p_class = P_LOCAL,
4117 .ptr = &sDefault.szMagicOutput,
4118 .special = NULL,
4119 .enum_list = NULL,
4120 .flags = FLAG_ADVANCED | FLAG_SHARE,
4121 },
4122 {
4123 .label = "delete readonly",
4124 .type = P_BOOL,
4125 .p_class = P_LOCAL,
4126 .ptr = &sDefault.bDeleteReadonly,
4127 .special = NULL,
4128 .enum_list = NULL,
4129 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4130 },
4131 {
4132 .label = "dos filemode",
4133 .type = P_BOOL,
4134 .p_class = P_LOCAL,
4135 .ptr = &sDefault.bDosFilemode,
4136 .special = NULL,
4137 .enum_list = NULL,
4138 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4139 },
4140 {
4141 .label = "dos filetimes",
4142 .type = P_BOOL,
4143 .p_class = P_LOCAL,
4144 .ptr = &sDefault.bDosFiletimes,
4145 .special = NULL,
4146 .enum_list = NULL,
4147 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4148 },
4149 {
4150 .label = "dos filetime resolution",
4151 .type = P_BOOL,
4152 .p_class = P_LOCAL,
4153 .ptr = &sDefault.bDosFiletimeResolution,
4154 .special = NULL,
4155 .enum_list = NULL,
4156 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4157 },
4158 {
4159 .label = "fake directory create times",
4160 .type = P_BOOL,
4161 .p_class = P_LOCAL,
4162 .ptr = &sDefault.bFakeDirCreateTimes,
4163 .special = NULL,
4164 .enum_list = NULL,
4165 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4166 },
4167 {
4168 .label = "panic action",
4169 .type = P_STRING,
4170 .p_class = P_GLOBAL,
4171 .ptr = &Globals.szPanicAction,
4172 .special = NULL,
4173 .enum_list = NULL,
4174 .flags = FLAG_ADVANCED,
4175 },
4176
4177 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4178
4179 {
4180 .label = "vfs objects",
4181 .type = P_LIST,
4182 .p_class = P_LOCAL,
4183 .ptr = &sDefault.szVfsObjects,
4184 .special = NULL,
4185 .enum_list = NULL,
4186 .flags = FLAG_ADVANCED | FLAG_SHARE,
4187 },
4188 {
4189 .label = "vfs object",
4190 .type = P_LIST,
4191 .p_class = P_LOCAL,
4192 .ptr = &sDefault.szVfsObjects,
4193 .special = NULL,
4194 .enum_list = NULL,
4195 .flags = FLAG_HIDE,
4196 },
4197
4198
4199 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4200
4201 {
4202 .label = "msdfs root",
4203 .type = P_BOOL,
4204 .p_class = P_LOCAL,
4205 .ptr = &sDefault.bMSDfsRoot,
4206 .special = NULL,
4207 .enum_list = NULL,
4208 .flags = FLAG_ADVANCED | FLAG_SHARE,
4209 },
4210 {
4211 .label = "msdfs proxy",
4212 .type = P_STRING,
4213 .p_class = P_LOCAL,
4214 .ptr = &sDefault.szMSDfsProxy,
4215 .special = NULL,
4216 .enum_list = NULL,
4217 .flags = FLAG_ADVANCED | FLAG_SHARE,
4218 },
4219 {
4220 .label = "host msdfs",
4221 .type = P_BOOL,
4222 .p_class = P_GLOBAL,
4223 .ptr = &Globals.bHostMSDfs,
4224 .special = NULL,
4225 .enum_list = NULL,
4226 .flags = FLAG_ADVANCED,
4227 },
4228
4229 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4230
4231 {
4232 .label = "passdb expand explicit",
4233 .type = P_BOOL,
4234 .p_class = P_GLOBAL,
4235 .ptr = &Globals.bPassdbExpandExplicit,
4236 .special = NULL,
4237 .enum_list = NULL,
4238 .flags = FLAG_ADVANCED,
4239 },
4240 {
4241 .label = "idmap domains",
4242 .type = P_LIST,
4243 .p_class = P_GLOBAL,
4244 .ptr = &Globals.szIdmapDomains,
4245 .special = NULL,
4246 .enum_list = NULL,
4247 .flags = FLAG_ADVANCED,
4248 },
4249 {
4250 .label = "idmap backend",
4251 .type = P_LIST,
4252 .p_class = P_GLOBAL,
4253 .ptr = &Globals.szIdmapBackend,
4254 .special = NULL,
4255 .enum_list = NULL,
4256 .flags = FLAG_ADVANCED,
4257 },
4258 {
4259 .label = "idmap alloc backend",
4260 .type = P_STRING,
4261 .p_class = P_GLOBAL,
4262 .ptr = &Globals.szIdmapAllocBackend,
4263 .special = NULL,
4264 .enum_list = NULL,
4265 .flags = FLAG_ADVANCED,
4266 },
4267 {
4268 .label = "idmap cache time",
4269 .type = P_INTEGER,
4270 .p_class = P_GLOBAL,
4271 .ptr = &Globals.iIdmapCacheTime,
4272 .special = NULL,
4273 .enum_list = NULL,
4274 .flags = FLAG_ADVANCED,
4275 },
4276 {
4277 .label = "idmap negative cache time",
4278 .type = P_INTEGER,
4279 .p_class = P_GLOBAL,
4280 .ptr = &Globals.iIdmapNegativeCacheTime,
4281 .special = NULL,
4282 .enum_list = NULL,
4283 .flags = FLAG_ADVANCED,
4284 },
4285 {
4286 .label = "idmap uid",
4287 .type = P_STRING,
4288 .p_class = P_GLOBAL,
4289 .ptr = &Globals.szIdmapUID,
4290 .special = handle_idmap_uid,
4291 .enum_list = NULL,
4292 .flags = FLAG_ADVANCED,
4293 },
4294 {
4295 .label = "winbind uid",
4296 .type = P_STRING,
4297 .p_class = P_GLOBAL,
4298 .ptr = &Globals.szIdmapUID,
4299 .special = handle_idmap_uid,
4300 .enum_list = NULL,
4301 .flags = FLAG_HIDE,
4302 },
4303 {
4304 .label = "idmap gid",
4305 .type = P_STRING,
4306 .p_class = P_GLOBAL,
4307 .ptr = &Globals.szIdmapGID,
4308 .special = handle_idmap_gid,
4309 .enum_list = NULL,
4310 .flags = FLAG_ADVANCED,
4311 },
4312 {
4313 .label = "winbind gid",
4314 .type = P_STRING,
4315 .p_class = P_GLOBAL,
4316 .ptr = &Globals.szIdmapGID,
4317 .special = handle_idmap_gid,
4318 .enum_list = NULL,
4319 .flags = FLAG_HIDE,
4320 },
4321 {
4322 .label = "template homedir",
4323 .type = P_STRING,
4324 .p_class = P_GLOBAL,
4325 .ptr = &Globals.szTemplateHomedir,
4326 .special = NULL,
4327 .enum_list = NULL,
4328 .flags = FLAG_ADVANCED,
4329 },
4330 {
4331 .label = "template shell",
4332 .type = P_STRING,
4333 .p_class = P_GLOBAL,
4334 .ptr = &Globals.szTemplateShell,
4335 .special = NULL,
4336 .enum_list = NULL,
4337 .flags = FLAG_ADVANCED,
4338 },
4339 {
4340 .label = "winbind separator",
4341 .type = P_STRING,
4342 .p_class = P_GLOBAL,
4343 .ptr = &Globals.szWinbindSeparator,
4344 .special = NULL,
4345 .enum_list = NULL,
4346 .flags = FLAG_ADVANCED,
4347 },
4348 {
4349 .label = "winbind cache time",
4350 .type = P_INTEGER,
4351 .p_class = P_GLOBAL,
4352 .ptr = &Globals.winbind_cache_time,
4353 .special = NULL,
4354 .enum_list = NULL,
4355 .flags = FLAG_ADVANCED,
4356 },
4357 {
4358 .label = "winbind enum users",
4359 .type = P_BOOL,
4360 .p_class = P_GLOBAL,
4361 .ptr = &Globals.bWinbindEnumUsers,
4362 .special = NULL,
4363 .enum_list = NULL,
4364 .flags = FLAG_ADVANCED,
4365 },
4366 {
4367 .label = "winbind enum groups",
4368 .type = P_BOOL,
4369 .p_class = P_GLOBAL,
4370 .ptr = &Globals.bWinbindEnumGroups,
4371 .special = NULL,
4372 .enum_list = NULL,
4373 .flags = FLAG_ADVANCED,
4374 },
4375 {
4376 .label = "winbind use default domain",
4377 .type = P_BOOL,
4378 .p_class = P_GLOBAL,
4379 .ptr = &Globals.bWinbindUseDefaultDomain,
4380 .special = NULL,
4381 .enum_list = NULL,
4382 .flags = FLAG_ADVANCED,
4383 },
4384 {
4385 .label = "winbind trusted domains only",
4386 .type = P_BOOL,
4387 .p_class = P_GLOBAL,
4388 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4389 .special = NULL,
4390 .enum_list = NULL,
4391 .flags = FLAG_ADVANCED,
4392 },
4393 {
4394 .label = "winbind nested groups",
4395 .type = P_BOOL,
4396 .p_class = P_GLOBAL,
4397 .ptr = &Globals.bWinbindNestedGroups,
4398 .special = NULL,
4399 .enum_list = NULL,
4400 .flags = FLAG_ADVANCED,
4401 },
4402 {
4403 .label = "winbind expand groups",
4404 .type = P_INTEGER,
4405 .p_class = P_GLOBAL,
4406 .ptr = &Globals.winbind_expand_groups,
4407 .special = NULL,
4408 .enum_list = NULL,
4409 .flags = FLAG_ADVANCED,
4410 },
4411 {
4412 .label = "winbind nss info",
4413 .type = P_LIST,
4414 .p_class = P_GLOBAL,
4415 .ptr = &Globals.szWinbindNssInfo,
4416 .special = NULL,
4417 .enum_list = NULL,
4418 .flags = FLAG_ADVANCED,
4419 },
4420 {
4421 .label = "winbind refresh tickets",
4422 .type = P_BOOL,
4423 .p_class = P_GLOBAL,
4424 .ptr = &Globals.bWinbindRefreshTickets,
4425 .special = NULL,
4426 .enum_list = NULL,
4427 .flags = FLAG_ADVANCED,
4428 },
4429 {
4430 .label = "winbind offline logon",
4431 .type = P_BOOL,
4432 .p_class = P_GLOBAL,
4433 .ptr = &Globals.bWinbindOfflineLogon,
4434 .special = NULL,
4435 .enum_list = NULL,
4436 .flags = FLAG_ADVANCED,
4437 },
4438 {
4439 .label = "winbind normalize names",
4440 .type = P_BOOL,
4441 .p_class = P_GLOBAL,
4442 .ptr = &Globals.bWinbindNormalizeNames,
4443 .special = NULL,
4444 .enum_list = NULL,
4445 .flags = FLAG_ADVANCED,
4446 },
4447 {
4448 .label = "winbind rpc only",
4449 .type = P_BOOL,
4450 .p_class = P_GLOBAL,
4451 .ptr = &Globals.bWinbindRpcOnly,
4452 .special = NULL,
4453 .enum_list = NULL,
4454 .flags = FLAG_ADVANCED,
4455 },
4456
4457 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4458};
4459
4460/***************************************************************************
4461 Initialise the sDefault parameter structure for the printer values.
4462***************************************************************************/
4463
4464static void init_printer_values(struct service *pService)
4465{
4466 /* choose defaults depending on the type of printing */
4467 switch (pService->iPrinting) {
4468 case PRINT_BSD:
4469 case PRINT_AIX:
4470 case PRINT_LPRNT:
4471 case PRINT_LPROS2:
4472 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4473 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4474 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4475 break;
4476
4477 case PRINT_LPRNG:
4478 case PRINT_PLP:
4479 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4480 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4481 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4482 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4483 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4484 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4485 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4486 break;
4487
4488 case PRINT_CUPS:
4489 case PRINT_IPRINT:
4490#ifdef HAVE_CUPS
4491 /* set the lpq command to contain the destination printer
4492 name only. This is used by cups_queue_get() */
4493 string_set(&pService->szLpqcommand, "%p");
4494 string_set(&pService->szLprmcommand, "");
4495 string_set(&pService->szPrintcommand, "");
4496 string_set(&pService->szLppausecommand, "");
4497 string_set(&pService->szLpresumecommand, "");
4498 string_set(&pService->szQueuepausecommand, "");
4499 string_set(&pService->szQueueresumecommand, "");
4500#else
4501 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4502 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4503 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4504 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4505 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4506 string_set(&pService->szQueuepausecommand, "disable '%p'");
4507 string_set(&pService->szQueueresumecommand, "enable '%p'");
4508#endif /* HAVE_CUPS */
4509 break;
4510
4511 case PRINT_SYSV:
4512 case PRINT_HPUX:
4513 string_set(&pService->szLpqcommand, "lpstat -o%p");
4514 string_set(&pService->szLprmcommand, "cancel %p-%j");
4515 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4516 string_set(&pService->szQueuepausecommand, "disable %p");
4517 string_set(&pService->szQueueresumecommand, "enable %p");
4518#ifndef HPUX
4519 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4520 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4521#endif /* HPUX */
4522 break;
4523
4524 case PRINT_QNX:
4525 string_set(&pService->szLpqcommand, "lpq -P%p");
4526 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4527 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4528 break;
4529
4530#ifdef DEVELOPER
4531 case PRINT_TEST:
4532 case PRINT_VLP:
4533 string_set(&pService->szPrintcommand, "vlp print %p %s");
4534 string_set(&pService->szLpqcommand, "vlp lpq %p");
4535 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4536 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4537 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4538 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4539 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4540 break;
4541#endif /* DEVELOPER */
4542
4543 }
4544}
4545
4546/***************************************************************************
4547 Initialise the global parameter structure.
4548***************************************************************************/
4549
4550#ifndef __OS2__
4551static
4552#endif
4553void init_globals(bool first_time_only)
4554{
4555 static bool done_init = False;
4556 char *s = NULL;
4557 int i;
4558
4559 /* If requested to initialize only once and we've already done it... */
4560 if (first_time_only && done_init) {
4561 /* ... then we have nothing more to do */
4562 return;
4563 }
4564
4565 if (!done_init) {
4566 /* The logfile can be set before this is invoked. Free it if so. */
4567 if (Globals.szLogFile != NULL) {
4568 string_free(&Globals.szLogFile);
4569 Globals.szLogFile = NULL;
4570 }
4571 done_init = True;
4572 } else {
4573 for (i = 0; parm_table[i].label; i++) {
4574 if ((parm_table[i].type == P_STRING ||
4575 parm_table[i].type == P_USTRING) &&
4576 parm_table[i].ptr)
4577 {
4578 string_free((char **)parm_table[i].ptr);
4579 }
4580 }
4581 }
4582
4583 memset((void *)&Globals, '\0', sizeof(Globals));
4584
4585 for (i = 0; parm_table[i].label; i++) {
4586 if ((parm_table[i].type == P_STRING ||
4587 parm_table[i].type == P_USTRING) &&
4588 parm_table[i].ptr)
4589 {
4590 string_set((char **)parm_table[i].ptr, "");
4591 }
4592 }
4593
4594 string_set(&sDefault.fstype, FSTYPE_STRING);
4595 string_set(&sDefault.szPrintjobUsername, "%U");
4596
4597 init_printer_values(&sDefault);
4598
4599
4600 DEBUG(3, ("Initialising global parameters\n"));
4601
4602 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4603 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4604
4605 /* use the new 'hash2' method by default, with a prefix of 1 */
4606 string_set(&Globals.szManglingMethod, "hash2");
4607 Globals.mangle_prefix = 1;
4608
4609 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4610
4611#ifndef __OS2__
4612 /* using UTF8 by default allows us to support all chars */
4613 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4614#else
4615 /* On OS/2, using UTF8 causes problems with display of foreign characters - default to SYSTEM codepage */
4616 string_set(&Globals.unix_charset, "SYSTEM");
4617#endif
4618
4619#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4620 /* If the system supports nl_langinfo(), try to grab the value
4621 from the user's locale */
4622 string_set(&Globals.display_charset, "LOCALE");
4623#else
4624 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4625#endif
4626
4627 /* Use codepage 850 as a default for the dos character set */
4628 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4629
4630 /*
4631 * Allow the default PASSWD_CHAT to be overridden in local.h.
4632 */
4633 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4634
4635 set_global_myname(myhostname());
4636 string_set(&Globals.szNetbiosName,global_myname());
4637
4638 set_global_myworkgroup(WORKGROUP);
4639 string_set(&Globals.szWorkgroup, lp_workgroup());
4640
4641 string_set(&Globals.szPasswdProgram, "");
4642 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4643 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4644 string_set(&Globals.szSocketAddress, "0.0.0.0");
4645
4646 if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
4647 smb_panic("init_globals: ENOMEM");
4648 }
4649 string_set(&Globals.szServerString, s);
4650 SAFE_FREE(s);
4651 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4652 DEFAULT_MINOR_VERSION) < 0) {
4653 smb_panic("init_globals: ENOMEM");
4654 }
4655 string_set(&Globals.szAnnounceVersion, s);
4656 SAFE_FREE(s);
4657#ifdef DEVELOPER
4658 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4659#endif
4660
4661 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4662
4663 string_set(&Globals.szLogonDrive, "");
4664 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4665 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4666 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4667
4668 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4669 string_set(&Globals.szPasswordServer, "*");
4670
4671 Globals.AlgorithmicRidBase = BASE_RID;
4672
4673 Globals.bLoadPrinters = True;
4674 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4675
4676 Globals.ConfigBackend = config_backend;
4677
4678 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4679 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4680 Globals.max_xmit = 0x4104;
4681 Globals.max_mux = 50; /* This is *needed* for profile support. */
4682 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4683 Globals.bDisableSpoolss = False;
4684 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4685 Globals.pwordlevel = 0;
4686 Globals.unamelevel = 0;
4687 Globals.deadtime = 0;
4688 Globals.getwd_cache = true;
4689 Globals.bLargeReadwrite = True;
4690 Globals.max_log_size = 5000;
4691 Globals.max_open_files = MAX_OPEN_FILES;
4692 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4693 Globals.maxprotocol = PROTOCOL_NT1;
4694 Globals.minprotocol = PROTOCOL_CORE;
4695 Globals.security = SEC_USER;
4696 Globals.paranoid_server_security = True;
4697 Globals.bEncryptPasswords = True;
4698 Globals.bUpdateEncrypt = False;
4699 Globals.clientSchannel = Auto;
4700 Globals.serverSchannel = Auto;
4701 Globals.bReadRaw = True;
4702 Globals.bWriteRaw = True;
4703 Globals.bNullPasswords = False;
4704 Globals.bObeyPamRestrictions = False;
4705 Globals.syslog = 1;
4706 Globals.bSyslogOnly = False;
4707 Globals.bTimestampLogs = True;
4708 string_set(&Globals.szLogLevel, "0");
4709 Globals.bDebugPrefixTimestamp = False;
4710 Globals.bDebugHiresTimestamp = False;
4711 Globals.bDebugPid = False;
4712 Globals.bDebugUid = False;
4713 Globals.bDebugClass = False;
4714 Globals.bEnableCoreFiles = True;
4715 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4716 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4717 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4718 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4719 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4720 Globals.lm_interval = 60;
4721 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4722#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4723 Globals.bNISHomeMap = False;
4724#ifdef WITH_NISPLUS_HOME
4725 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4726#else
4727 string_set(&Globals.szNISHomeMapName, "auto.home");
4728#endif
4729#endif
4730 Globals.bTimeServer = False;
4731 Globals.bBindInterfacesOnly = False;
4732 Globals.bUnixPasswdSync = False;
4733 Globals.bPamPasswordChange = False;
4734 Globals.bPasswdChatDebug = False;
4735 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4736 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4737 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4738 Globals.bStatCache = True; /* use stat cache by default */
4739 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4740 Globals.restrict_anonymous = 0;
4741 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4742 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4743 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4744 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4745 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4746 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4747
4748 Globals.map_to_guest = 0; /* By Default, "Never" */
4749 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4750 Globals.enhanced_browsing = true;
4751 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4752#ifdef MMAP_BLACKLIST
4753 Globals.bUseMmap = False;
4754#else
4755 Globals.bUseMmap = True;
4756#endif
4757 Globals.bUnixExtensions = True;
4758 Globals.bResetOnZeroVC = False;
4759
4760 /* hostname lookups can be very expensive and are broken on
4761 a large number of sites (tridge) */
4762 Globals.bHostnameLookups = False;
4763
4764 string_set(&Globals.szPassdbBackend, "smbpasswd");
4765 string_set(&Globals.szLdapSuffix, "");
4766 string_set(&Globals.szLdapMachineSuffix, "");
4767 string_set(&Globals.szLdapUserSuffix, "");
4768 string_set(&Globals.szLdapGroupSuffix, "");
4769 string_set(&Globals.szLdapIdmapSuffix, "");
4770
4771 string_set(&Globals.szLdapAdminDn, "");
4772 Globals.ldap_ssl = LDAP_SSL_ON;
4773 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4774 Globals.ldap_delete_dn = False;
4775 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4776 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4777 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4778 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4779
4780 Globals.ldap_debug_level = 0;
4781 Globals.ldap_debug_threshold = 10;
4782
4783 /* This is what we tell the afs client. in reality we set the token
4784 * to never expire, though, when this runs out the afs client will
4785 * forget the token. Set to 0 to get NEVERDATE.*/
4786 Globals.iAfsTokenLifetime = 604800;
4787
4788/* these parameters are set to defaults that are more appropriate
4789 for the increasing samba install base:
4790
4791 as a member of the workgroup, that will possibly become a
4792 _local_ master browser (lm = True). this is opposed to a forced
4793 local master browser startup (pm = True).
4794
4795 doesn't provide WINS server service by default (wsupp = False),
4796 and doesn't provide domain master browser services by default, either.
4797
4798*/
4799
4800 Globals.bMsAddPrinterWizard = True;
4801 Globals.os_level = 20;
4802 Globals.bLocalMaster = True;
4803 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4804 Globals.bDomainLogons = False;
4805 Globals.bBrowseList = True;
4806 Globals.bWINSsupport = False;
4807 Globals.bWINSproxy = False;
4808
4809 Globals.bDNSproxy = True;
4810
4811 /* this just means to use them if they exist */
4812 Globals.bKernelOplocks = True;
4813
4814 Globals.bAllowTrustedDomains = True;
4815
4816 string_set(&Globals.szTemplateShell, "/bin/false");
4817 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4818 string_set(&Globals.szWinbindSeparator, "\\");
4819
4820 string_set(&Globals.szCupsServer, "");
4821 string_set(&Globals.szIPrintServer, "");
4822
4823 string_set(&Globals.ctdbdSocket, "");
4824 Globals.szClusterAddresses = NULL;
4825 Globals.clustering = False;
4826
4827 Globals.winbind_cache_time = 300; /* 5 minutes */
4828 Globals.bWinbindEnumUsers = False;
4829 Globals.bWinbindEnumGroups = False;
4830 Globals.bWinbindUseDefaultDomain = False;
4831 Globals.bWinbindTrustedDomainsOnly = False;
4832 Globals.bWinbindNestedGroups = True;
4833 Globals.winbind_expand_groups = 1;
4834 Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
4835 Globals.bWinbindRefreshTickets = False;
4836 Globals.bWinbindOfflineLogon = False;
4837
4838 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
4839 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4840
4841 Globals.bPassdbExpandExplicit = False;
4842
4843 Globals.name_cache_timeout = 660; /* In seconds */
4844
4845 Globals.bUseSpnego = True;
4846 Globals.bClientUseSpnego = True;
4847
4848 Globals.client_signing = Auto;
4849 Globals.server_signing = False;
4850
4851 Globals.bDeferSharingViolations = True;
4852 string_set(&Globals.smb_ports, SMB_PORTS);
4853
4854 Globals.bEnablePrivileges = True;
4855 Globals.bHostMSDfs = True;
4856 Globals.bASUSupport = False;
4857
4858 /* User defined shares. */
4859 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4860 smb_panic("init_globals: ENOMEM");
4861 }
4862 string_set(&Globals.szUsersharePath, s);
4863 SAFE_FREE(s);
4864 string_set(&Globals.szUsershareTemplateShare, "");
4865 Globals.iUsershareMaxShares = 0;
4866 /* By default disallow sharing of directories not owned by the sharer. */
4867 Globals.bUsershareOwnerOnly = True;
4868 /* By default disallow guest access to usershares. */
4869 Globals.bUsershareAllowGuests = False;
4870
4871 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4872
4873 /* By default no shares out of the registry */
4874 Globals.bRegistryShares = False;
4875
4876 Globals.iminreceivefile = 0;
4877}
4878
4879/*******************************************************************
4880 Convenience routine to grab string parameters into temporary memory
4881 and run standard_sub_basic on them. The buffers can be written to by
4882 callers without affecting the source string.
4883********************************************************************/
4884
4885static char *lp_string(const char *s)
4886{
4887 char *ret;
4888 TALLOC_CTX *ctx = talloc_tos();
4889
4890 /* The follow debug is useful for tracking down memory problems
4891 especially if you have an inner loop that is calling a lp_*()
4892 function that returns a string. Perhaps this debug should be
4893 present all the time? */
4894
4895#if 0
4896 DEBUG(10, ("lp_string(%s)\n", s));
4897#endif
4898
4899 ret = talloc_sub_basic(ctx,
4900 get_current_username(),
4901 current_user_info.domain,
4902 s);
4903 if (trim_char(ret, '\"', '\"')) {
4904 if (strchr(ret,'\"') != NULL) {
4905 TALLOC_FREE(ret);
4906 ret = talloc_sub_basic(ctx,
4907 get_current_username(),
4908 current_user_info.domain,
4909 s);
4910 }
4911 }
4912 return ret;
4913}
4914
4915/*
4916 In this section all the functions that are used to access the
4917 parameters from the rest of the program are defined
4918*/
4919
4920#define FN_GLOBAL_STRING(fn_name,ptr) \
4921 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4922#define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4923 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4924#define FN_GLOBAL_LIST(fn_name,ptr) \
4925 const char **fn_name(void) {return(*(const char ***)(ptr));}
4926#define FN_GLOBAL_BOOL(fn_name,ptr) \
4927 bool fn_name(void) {return(*(bool *)(ptr));}
4928#define FN_GLOBAL_CHAR(fn_name,ptr) \
4929 char fn_name(void) {return(*(char *)(ptr));}
4930#define FN_GLOBAL_INTEGER(fn_name,ptr) \
4931 int fn_name(void) {return(*(int *)(ptr));}
4932
4933#define FN_LOCAL_STRING(fn_name,val) \
4934 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
4935#define FN_LOCAL_CONST_STRING(fn_name,val) \
4936 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
4937#define FN_LOCAL_LIST(fn_name,val) \
4938 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4939#define FN_LOCAL_BOOL(fn_name,val) \
4940 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4941#define FN_LOCAL_INTEGER(fn_name,val) \
4942 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4943
4944#define FN_LOCAL_PARM_BOOL(fn_name,val) \
4945 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4946#define FN_LOCAL_PARM_INTEGER(fn_name,val) \
4947 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4948#define FN_LOCAL_PARM_STRING(fn_name,val) \
4949 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));}
4950#define FN_LOCAL_CHAR(fn_name,val) \
4951 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4952
4953FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
4954FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
4955FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
4956FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
4957FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
4958FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
4959FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
4960FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
4961FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
4962FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
4963FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
4964FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
4965FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
4966FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
4967FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
4968FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
4969FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
4970FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
4971FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
4972FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
4973FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
4974FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
4975FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
4976FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
4977FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
4978FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
4979FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
4980FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
4981FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
4982FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
4983FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
4984FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
4985FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
4986FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
4987FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
4988FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
4989FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
4990FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
4991FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
4992FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
4993FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
4994FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
4995FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
4996FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
4997FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
4998FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
4999FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5000static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5001FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5002/* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5003 * lp_passdb_backend() should be replace by the this macro again after
5004 * some releases.
5005 * */
5006const char *lp_passdb_backend(void)
5007{
5008 char *delim, *quote;
5009
5010 delim = strchr( Globals.szPassdbBackend, ' ');
5011 /* no space at all */
5012 if (delim == NULL) {
5013 goto out;
5014 }
5015
5016 quote = strchr(Globals.szPassdbBackend, '"');
5017 /* no quote char or non in the first part */
5018 if (quote == NULL || quote > delim) {
5019 *delim = '\0';
5020 goto warn;
5021 }
5022
5023 quote = strchr(quote+1, '"');
5024 if (quote == NULL) {
5025 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5026 goto out;
5027 } else if (*(quote+1) == '\0') {
5028 /* space, fitting quote char, and one backend only */
5029 goto out;
5030 } else {
5031 /* terminate string after the fitting quote char */
5032 *(quote+1) = '\0';
5033 }
5034
5035warn:
5036 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5037 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5038 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5039 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5040
5041out:
5042 return Globals.szPassdbBackend;
5043}
5044FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5045FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5046FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5047FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5048FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5049
5050FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5051FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5052FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5053FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5054FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5055FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5056
5057FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5058
5059FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5060FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5061FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5062
5063FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5064
5065FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5066FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5067FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5068FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5069FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5070FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5071FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5072FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5073FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5074FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5075FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5076FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5077FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5078FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5079FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5080
5081FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
5082FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
5083FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5084FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5085FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5086FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5087FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5088
5089FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5090FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5091FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5092FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5093FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5094FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5095FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5096FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5097FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5098FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5099FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5100FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5101FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5102FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5103FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5104FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5105FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5106
5107FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5108
5109FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5110FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5111FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5112FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5113FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5114FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5115FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5116FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5117FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5118FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5119FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5120FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5121FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5122FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5123FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5124FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5125FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5126FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5127FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5128FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5129FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5130FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5131FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5132FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5133FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5134FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5135FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5136FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5137FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5138FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5139FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5140FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5141static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5142FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5143FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5144FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5145FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5146FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5147FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5148FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5149FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5150FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5151FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5152FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5153FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5154FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5155FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5156FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5157FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5158FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5159FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5160FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5161FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5162FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5163FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5164FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5165FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5166FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5167FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5168FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5169FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5170FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5171FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5172FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5173FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5174FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5175FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5176FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5177FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5178FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5179FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5180FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5181FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5182FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5183FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5184FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5185FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5186FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5187FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5188FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5189FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5190FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5191FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5192FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5193FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5194FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5195static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5196FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5197FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5198FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5199FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5200FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5201FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5202FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5203FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5204FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5205
5206FN_LOCAL_STRING(lp_preexec, szPreExec)
5207FN_LOCAL_STRING(lp_postexec, szPostExec)
5208FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5209FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5210FN_LOCAL_STRING(lp_servicename, szService)
5211FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5212FN_LOCAL_STRING(lp_pathname, szPath)
5213FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5214FN_LOCAL_STRING(lp_username, szUsername)
5215FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5216FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5217FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5218FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5219FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5220FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5221FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5222FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5223FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5224FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5225FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5226FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5227FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5228FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5229FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5230FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5231FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5232static FN_LOCAL_STRING(_lp_printername, szPrintername)
5233FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5234FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5235FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5236FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5237FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5238FN_LOCAL_STRING(lp_comment, comment)
5239FN_LOCAL_STRING(lp_force_user, force_user)
5240FN_LOCAL_STRING(lp_force_group, force_group)
5241FN_LOCAL_LIST(lp_readlist, readlist)
5242FN_LOCAL_LIST(lp_writelist, writelist)
5243FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5244FN_LOCAL_STRING(lp_fstype, fstype)
5245FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5246FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5247static FN_LOCAL_STRING(lp_volume, volume)
5248FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5249FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5250FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5251FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5252FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5253FN_LOCAL_STRING(lp_dfree_command, szDfree)
5254FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5255FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5256FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5257FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5258FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5259FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5260FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5261FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5262FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5263FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5264FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5265FN_LOCAL_BOOL(lp_readonly, bRead_only)
5266FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5267FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5268FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5269FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5270FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5271FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5272FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5273FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5274FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5275FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5276FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5277FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5278FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5279FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5280FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5281FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5282FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5283FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5284FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5285FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5286FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5287FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5288FN_LOCAL_BOOL(lp_map_system, bMap_system)
5289FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5290FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5291FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5292FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5293FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5294FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5295FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5296FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5297FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5298FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5299FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5300FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5301FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5302FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5303FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5304FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5305FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5306FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5307FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5308FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5309FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5310FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5311FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5312FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5313FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5314FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5315FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5316FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5317FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5318FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5319FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5320FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5321FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5322FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5323FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5324FN_LOCAL_INTEGER(lp_printing, iPrinting)
5325FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5326FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5327FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5328FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5329FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5330FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5331FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5332FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5333FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5334FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5335FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5336FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5337FN_LOCAL_CHAR(lp_magicchar, magic_char)
5338FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5339FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5340FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5341FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5342FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5343FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5344FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5345
5346/* local prototypes */
5347
5348static int map_parameter(const char *pszParmName);
5349static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5350static bool set_boolean(bool *pb, const char *pszParmValue);
5351static const char *get_boolean(bool bool_value);
5352static int getservicebyname(const char *pszServiceName,
5353 struct service *pserviceDest);
5354static void copy_service(struct service *pserviceDest,
5355 struct service *pserviceSource,
5356 struct bitmap *pcopymapDest);
5357static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5358 void *userdata);
5359static bool do_section(const char *pszSectionName, void *userdata);
5360static void init_copymap(struct service *pservice);
5361static bool hash_a_service(const char *name, int number);
5362static void free_service_byindex(int iService);
5363static char * canonicalize_servicename(const char *name);
5364static void show_parameter(int parmIndex);
5365static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5366
5367/* This is a helper function for parametrical options support. */
5368/* It returns a pointer to parametrical option value if it exists or NULL otherwise */
5369/* Actual parametrical functions are quite simple */
5370static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
5371{
5372 bool global_section = False;
5373 char* param_key;
5374 param_opt_struct *data;
5375
5376 if (snum >= iNumServices) return NULL;
5377
5378 if (snum < 0) {
5379 data = Globals.param_opt;
5380 global_section = True;
5381 } else {
5382 data = ServicePtrs[snum]->param_opt;
5383 }
5384
5385 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5386 DEBUG(0,("asprintf failed!\n"));
5387 return NULL;
5388 }
5389
5390 while (data) {
5391 if (strcmp(data->key, param_key) == 0) {
5392 string_free(&param_key);
5393 return data;
5394 }
5395 data = data->next;
5396 }
5397
5398 if (!global_section) {
5399 /* Try to fetch the same option but from globals */
5400 /* but only if we are not already working with Globals */
5401 data = Globals.param_opt;
5402 while (data) {
5403 if (strcmp(data->key, param_key) == 0) {
5404 string_free(&param_key);
5405 return data;
5406 }
5407 data = data->next;
5408 }
5409 }
5410
5411 string_free(&param_key);
5412
5413 return NULL;
5414}
5415
5416
5417#define MISSING_PARAMETER(name) \
5418 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5419
5420/*******************************************************************
5421convenience routine to return int parameters.
5422********************************************************************/
5423static int lp_int(const char *s)
5424{
5425
5426 if (!s || !*s) {
5427 MISSING_PARAMETER(lp_int);
5428 return (-1);
5429 }
5430
5431 return (int)strtol(s, NULL, 0);
5432}
5433
5434/*******************************************************************
5435convenience routine to return unsigned long parameters.
5436********************************************************************/
5437static unsigned long lp_ulong(const char *s)
5438{
5439
5440 if (!s || !*s) {
5441 MISSING_PARAMETER(lp_ulong);
5442 return (0);
5443 }
5444
5445 return strtoul(s, NULL, 0);
5446}
5447
5448/*******************************************************************
5449convenience routine to return boolean parameters.
5450********************************************************************/
5451static bool lp_bool(const char *s)
5452{
5453 bool ret = False;
5454
5455 if (!s || !*s) {
5456 MISSING_PARAMETER(lp_bool);
5457 return False;
5458 }
5459
5460 if (!set_boolean(&ret,s)) {
5461 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5462 return False;
5463 }
5464
5465 return ret;
5466}
5467
5468/*******************************************************************
5469convenience routine to return enum parameters.
5470********************************************************************/
5471static int lp_enum(const char *s,const struct enum_list *_enum)
5472{
5473 int i;
5474
5475 if (!s || !*s || !_enum) {
5476 MISSING_PARAMETER(lp_enum);
5477 return (-1);
5478 }
5479
5480 for (i=0; _enum[i].name; i++) {
5481 if (strequal(_enum[i].name,s))
5482 return _enum[i].value;
5483 }
5484
5485 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5486 return (-1);
5487}
5488
5489#undef MISSING_PARAMETER
5490
5491/* DO NOT USE lp_parm_string ANYMORE!!!!
5492 * use lp_parm_const_string or lp_parm_talloc_string
5493 *
5494 * lp_parm_string is only used to let old modules find this symbol
5495 */
5496#undef lp_parm_string
5497 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5498 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5499{
5500 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5501}
5502
5503/* Return parametric option from a given service. Type is a part of option before ':' */
5504/* Parametric option has following syntax: 'Type: option = value' */
5505/* the returned value is talloced on the talloc_tos() */
5506char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5507{
5508 param_opt_struct *data = get_parametrics(snum, type, option);
5509
5510 if (data == NULL||data->value==NULL) {
5511 if (def) {
5512 return lp_string(def);
5513 } else {
5514 return NULL;
5515 }
5516 }
5517
5518 return lp_string(data->value);
5519}
5520
5521/* Return parametric option from a given service. Type is a part of option before ':' */
5522/* Parametric option has following syntax: 'Type: option = value' */
5523const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5524{
5525 param_opt_struct *data = get_parametrics(snum, type, option);
5526
5527 if (data == NULL||data->value==NULL)
5528 return def;
5529
5530 return data->value;
5531}
5532
5533/* Return parametric option from a given service. Type is a part of option before ':' */
5534/* Parametric option has following syntax: 'Type: option = value' */
5535
5536const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5537{
5538 param_opt_struct *data = get_parametrics(snum, type, option);
5539
5540 if (data == NULL||data->value==NULL)
5541 return (const char **)def;
5542
5543 if (data->list==NULL) {
5544 data->list = str_list_make(NULL, data->value, NULL);
5545 }
5546
5547 return (const char **)data->list;
5548}
5549
5550/* Return parametric option from a given service. Type is a part of option before ':' */
5551/* Parametric option has following syntax: 'Type: option = value' */
5552
5553int lp_parm_int(int snum, const char *type, const char *option, int def)
5554{
5555 param_opt_struct *data = get_parametrics(snum, type, option);
5556
5557 if (data && data->value && *data->value)
5558 return lp_int(data->value);
5559
5560 return def;
5561}
5562
5563/* Return parametric option from a given service. Type is a part of option before ':' */
5564/* Parametric option has following syntax: 'Type: option = value' */
5565
5566unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5567{
5568 param_opt_struct *data = get_parametrics(snum, type, option);
5569
5570 if (data && data->value && *data->value)
5571 return lp_ulong(data->value);
5572
5573 return def;
5574}
5575
5576/* Return parametric option from a given service. Type is a part of option before ':' */
5577/* Parametric option has following syntax: 'Type: option = value' */
5578
5579bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5580{
5581 param_opt_struct *data = get_parametrics(snum, type, option);
5582
5583 if (data && data->value && *data->value)
5584 return lp_bool(data->value);
5585
5586 return def;
5587}
5588
5589/* Return parametric option from a given service. Type is a part of option before ':' */
5590/* Parametric option has following syntax: 'Type: option = value' */
5591
5592int lp_parm_enum(int snum, const char *type, const char *option,
5593 const struct enum_list *_enum, int def)
5594{
5595 param_opt_struct *data = get_parametrics(snum, type, option);
5596
5597 if (data && data->value && *data->value && _enum)
5598 return lp_enum(data->value, _enum);
5599
5600 return def;
5601}
5602
5603
5604/***************************************************************************
5605 Initialise a service to the defaults.
5606***************************************************************************/
5607
5608static void init_service(struct service *pservice)
5609{
5610 memset((char *)pservice, '\0', sizeof(struct service));
5611 copy_service(pservice, &sDefault, NULL);
5612}
5613
5614/***************************************************************************
5615 Free the dynamically allocated parts of a service struct.
5616***************************************************************************/
5617
5618static void free_service(struct service *pservice)
5619{
5620 int i;
5621 param_opt_struct *data, *pdata;
5622 if (!pservice)
5623 return;
5624
5625 if (pservice->szService)
5626 DEBUG(5, ("free_service: Freeing service %s\n",
5627 pservice->szService));
5628
5629 string_free(&pservice->szService);
5630 bitmap_free(pservice->copymap);
5631
5632 for (i = 0; parm_table[i].label; i++) {
5633 if ((parm_table[i].type == P_STRING ||
5634 parm_table[i].type == P_USTRING) &&
5635 parm_table[i].p_class == P_LOCAL)
5636 string_free((char **)
5637 (((char *)pservice) +
5638 PTR_DIFF(parm_table[i].ptr, &sDefault)));
5639 else if (parm_table[i].type == P_LIST &&
5640 parm_table[i].p_class == P_LOCAL)
5641 TALLOC_FREE(*((char ***)
5642 (((char *)pservice) +
5643 PTR_DIFF(parm_table[i].ptr,
5644 &sDefault))));
5645 }
5646
5647 data = pservice->param_opt;
5648 if (data)
5649 DEBUG(5,("Freeing parametrics:\n"));
5650 while (data) {
5651 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5652 string_free(&data->key);
5653 string_free(&data->value);
5654 TALLOC_FREE(data->list);
5655 pdata = data->next;
5656 SAFE_FREE(data);
5657 data = pdata;
5658 }
5659
5660 ZERO_STRUCTP(pservice);
5661}
5662
5663
5664/***************************************************************************
5665 remove a service indexed in the ServicePtrs array from the ServiceHash
5666 and free the dynamically allocated parts
5667***************************************************************************/
5668
5669static void free_service_byindex(int idx)
5670{
5671 if ( !LP_SNUM_OK(idx) )
5672 return;
5673
5674 ServicePtrs[idx]->valid = False;
5675 invalid_services[num_invalid_services++] = idx;
5676
5677 /* we have to cleanup the hash record */
5678
5679 if (ServicePtrs[idx]->szService) {
5680 char *canon_name = canonicalize_servicename(
5681 ServicePtrs[idx]->szService );
5682
5683 dbwrap_delete_bystring(ServiceHash, canon_name );
5684 TALLOC_FREE(canon_name);
5685 }
5686
5687 free_service(ServicePtrs[idx]);
5688}
5689
5690/***************************************************************************
5691 Add a new service to the services array initialising it with the given
5692 service.
5693***************************************************************************/
5694
5695static int add_a_service(const struct service *pservice, const char *name)
5696{
5697 int i;
5698 struct service tservice;
5699 int num_to_alloc = iNumServices + 1;
5700 param_opt_struct *data, *pdata;
5701
5702 tservice = *pservice;
5703
5704 /* it might already exist */
5705 if (name) {
5706 i = getservicebyname(name, NULL);
5707 if (i >= 0) {
5708 /* Clean all parametric options for service */
5709 /* They will be added during parsing again */
5710 data = ServicePtrs[i]->param_opt;
5711 while (data) {
5712 string_free(&data->key);
5713 string_free(&data->value);
5714 TALLOC_FREE(data->list);
5715 pdata = data->next;
5716 SAFE_FREE(data);
5717 data = pdata;
5718 }
5719 ServicePtrs[i]->param_opt = NULL;
5720 return (i);
5721 }
5722 }
5723
5724 /* find an invalid one */
5725 i = iNumServices;
5726 if (num_invalid_services > 0) {
5727 i = invalid_services[--num_invalid_services];
5728 }
5729
5730 /* if not, then create one */
5731 if (i == iNumServices) {
5732 struct service **tsp;
5733 int *tinvalid;
5734
5735 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5736 if (tsp == NULL) {
5737 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5738 return (-1);
5739 }
5740 ServicePtrs = tsp;
5741 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5742 if (!ServicePtrs[iNumServices]) {
5743 DEBUG(0,("add_a_service: out of memory!\n"));
5744 return (-1);
5745 }
5746 iNumServices++;
5747
5748 /* enlarge invalid_services here for now... */
5749 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5750 num_to_alloc);
5751 if (tinvalid == NULL) {
5752 DEBUG(0,("add_a_service: failed to enlarge "
5753 "invalid_services!\n"));
5754 return (-1);
5755 }
5756 invalid_services = tinvalid;
5757 } else {
5758 free_service_byindex(i);
5759 }
5760
5761 ServicePtrs[i]->valid = True;
5762
5763 init_service(ServicePtrs[i]);
5764 copy_service(ServicePtrs[i], &tservice, NULL);
5765 if (name)
5766 string_set(&ServicePtrs[i]->szService, name);
5767
5768 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5769 i, ServicePtrs[i]->szService));
5770
5771 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5772 return (-1);
5773 }
5774
5775 return (i);
5776}
5777
5778/***************************************************************************
5779 Convert a string to uppercase and remove whitespaces.
5780***************************************************************************/
5781
5782static char *canonicalize_servicename(const char *src)
5783{
5784 char *result;
5785
5786 if ( !src ) {
5787 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5788 return NULL;
5789 }
5790
5791 result = talloc_strdup(talloc_tos(), src);
5792 SMB_ASSERT(result != NULL);
5793
5794 strlower_m(result);
5795 return result;
5796}
5797
5798/***************************************************************************
5799 Add a name/index pair for the services array to the hash table.
5800***************************************************************************/
5801
5802static bool hash_a_service(const char *name, int idx)
5803{
5804 char *canon_name;
5805
5806 if ( !ServiceHash ) {
5807 DEBUG(10,("hash_a_service: creating servicehash\n"));
5808 ServiceHash = db_open_rbt(NULL);
5809 if ( !ServiceHash ) {
5810 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5811 return False;
5812 }
5813 }
5814
5815 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5816 idx, name));
5817
5818 canon_name = canonicalize_servicename( name );
5819
5820 dbwrap_store_bystring(ServiceHash, canon_name,
5821 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5822 TDB_REPLACE);
5823
5824 TALLOC_FREE(canon_name);
5825
5826 return True;
5827}
5828
5829/***************************************************************************
5830 Add a new home service, with the specified home directory, defaults coming
5831 from service ifrom.
5832***************************************************************************/
5833
5834bool lp_add_home(const char *pszHomename, int iDefaultService,
5835 const char *user, const char *pszHomedir)
5836{
5837 int i;
5838
5839 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5840
5841 if (i < 0)
5842 return (False);
5843
5844 if (!(*(ServicePtrs[iDefaultService]->szPath))
5845 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5846 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5847 }
5848
5849 if (!(*(ServicePtrs[i]->comment))) {
5850 char *comment = NULL;
5851 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5852 return false;
5853 }
5854 string_set(&ServicePtrs[i]->comment, comment);
5855 SAFE_FREE(comment);
5856 }
5857
5858 /* set the browseable flag from the global default */
5859
5860 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5861
5862 ServicePtrs[i]->autoloaded = True;
5863
5864 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5865 user, ServicePtrs[i]->szPath ));
5866
5867 return (True);
5868}
5869
5870/***************************************************************************
5871 Add a new service, based on an old one.
5872***************************************************************************/
5873
5874int lp_add_service(const char *pszService, int iDefaultService)
5875{
5876 if (iDefaultService < 0) {
5877 return add_a_service(&sDefault, pszService);
5878 }
5879
5880 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5881}
5882
5883/***************************************************************************
5884 Add the IPC service.
5885***************************************************************************/
5886
5887static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5888{
5889 char *comment = NULL;
5890 int i = add_a_service(&sDefault, ipc_name);
5891
5892 if (i < 0)
5893 return (False);
5894
5895 if (asprintf(&comment, "IPC Service (%s)",
5896 Globals.szServerString) < 0) {
5897 return (False);
5898 }
5899
5900 string_set(&ServicePtrs[i]->szPath, tmpdir());
5901 string_set(&ServicePtrs[i]->szUsername, "");
5902 string_set(&ServicePtrs[i]->comment, comment);
5903 string_set(&ServicePtrs[i]->fstype, "IPC");
5904 ServicePtrs[i]->iMaxConnections = 0;
5905 ServicePtrs[i]->bAvailable = True;
5906 ServicePtrs[i]->bRead_only = True;
5907 ServicePtrs[i]->bGuest_only = False;
5908 ServicePtrs[i]->bAdministrative_share = True;
5909 ServicePtrs[i]->bGuest_ok = guest_ok;
5910 ServicePtrs[i]->bPrint_ok = False;
5911 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5912
5913 DEBUG(3, ("adding IPC service\n"));
5914
5915 SAFE_FREE(comment);
5916 return (True);
5917}
5918
5919/***************************************************************************
5920 Add a new printer service, with defaults coming from service iFrom.
5921***************************************************************************/
5922
5923bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5924{
5925 const char *comment = "From Printcap";
5926 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5927
5928 if (i < 0)
5929 return (False);
5930
5931 /* note that we do NOT default the availability flag to True - */
5932 /* we take it from the default service passed. This allows all */
5933 /* dynamic printers to be disabled by disabling the [printers] */
5934 /* entry (if/when the 'available' keyword is implemented!). */
5935
5936 /* the printer name is set to the service name. */
5937 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5938 string_set(&ServicePtrs[i]->comment, comment);
5939
5940 /* set the browseable flag from the gloabl default */
5941 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5942
5943 /* Printers cannot be read_only. */
5944 ServicePtrs[i]->bRead_only = False;
5945 /* No share modes on printer services. */
5946 ServicePtrs[i]->bShareModes = False;
5947 /* No oplocks on printer services. */
5948 ServicePtrs[i]->bOpLocks = False;
5949 /* Printer services must be printable. */
5950 ServicePtrs[i]->bPrint_ok = True;
5951
5952 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5953
5954 return (True);
5955}
5956
5957
5958/***************************************************************************
5959 Check whether the given parameter name is valid.
5960 Parametric options (names containing a colon) are considered valid.
5961***************************************************************************/
5962
5963bool lp_parameter_is_valid(const char *pszParmName)
5964{
5965 return ((map_parameter(pszParmName) != -1) ||
5966 (strchr(pszParmName, ':') != NULL));
5967}
5968
5969/***************************************************************************
5970 Check whether the given name is the name of a global parameter.
5971 Returns True for strings belonging to parameters of class
5972 P_GLOBAL, False for all other strings, also for parametric options
5973 and strings not belonging to any option.
5974***************************************************************************/
5975
5976bool lp_parameter_is_global(const char *pszParmName)
5977{
5978 int num = map_parameter(pszParmName);
5979
5980 if (num >= 0) {
5981 return (parm_table[num].p_class == P_GLOBAL);
5982 }
5983
5984 return False;
5985}
5986
5987/**************************************************************************
5988 Check whether the given name is the canonical name of a parameter.
5989 Returns False if it is not a valid parameter Name.
5990 For parametric options, True is returned.
5991**************************************************************************/
5992
5993bool lp_parameter_is_canonical(const char *parm_name)
5994{
5995 if (!lp_parameter_is_valid(parm_name)) {
5996 return False;
5997 }
5998
5999 return (map_parameter(parm_name) ==
6000 map_parameter_canonical(parm_name, NULL));
6001}
6002
6003/**************************************************************************
6004 Determine the canonical name for a parameter.
6005 Indicate when it is an inverse (boolean) synonym instead of a
6006 "usual" synonym.
6007**************************************************************************/
6008
6009bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6010 bool *inverse)
6011{
6012 int num;
6013
6014 if (!lp_parameter_is_valid(parm_name)) {
6015 *canon_parm = NULL;
6016 return False;
6017 }
6018
6019 num = map_parameter_canonical(parm_name, inverse);
6020 if (num < 0) {
6021 /* parametric option */
6022 *canon_parm = parm_name;
6023 } else {
6024 *canon_parm = parm_table[num].label;
6025 }
6026
6027 return True;
6028
6029}
6030
6031/**************************************************************************
6032 Determine the canonical name for a parameter.
6033 Turn the value given into the inverse boolean expression when
6034 the synonym is an invers boolean synonym.
6035
6036 Return True if parm_name is a valid parameter name and
6037 in case it is an invers boolean synonym, if the val string could
6038 successfully be converted to the reverse bool.
6039 Return false in all other cases.
6040**************************************************************************/
6041
6042bool lp_canonicalize_parameter_with_value(const char *parm_name,
6043 const char *val,
6044 const char **canon_parm,
6045 const char **canon_val)
6046{
6047 int num;
6048 bool inverse;
6049
6050 if (!lp_parameter_is_valid(parm_name)) {
6051 *canon_parm = NULL;
6052 *canon_val = NULL;
6053 return False;
6054 }
6055
6056 num = map_parameter_canonical(parm_name, &inverse);
6057 if (num < 0) {
6058 /* parametric option */
6059 *canon_parm = parm_name;
6060 *canon_val = val;
6061 } else {
6062 *canon_parm = parm_table[num].label;
6063 if (inverse) {
6064 if (!lp_invert_boolean(val, canon_val)) {
6065 *canon_val = NULL;
6066 return False;
6067 }
6068 } else {
6069 *canon_val = val;
6070 }
6071 }
6072
6073 return True;
6074}
6075
6076/***************************************************************************
6077 Map a parameter's string representation to something we can use.
6078 Returns False if the parameter string is not recognised, else TRUE.
6079***************************************************************************/
6080
6081static int map_parameter(const char *pszParmName)
6082{
6083 int iIndex;
6084
6085 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6086 return (-1);
6087
6088 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6089 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6090 return (iIndex);
6091
6092 /* Warn only if it isn't parametric option */
6093 if (strchr(pszParmName, ':') == NULL)
6094 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6095 /* We do return 'fail' for parametric options as well because they are
6096 stored in different storage
6097 */
6098 return (-1);
6099}
6100
6101/***************************************************************************
6102 Map a parameter's string representation to the index of the canonical
6103 form of the parameter (it might be a synonym).
6104 Returns -1 if the parameter string is not recognised.
6105***************************************************************************/
6106
6107static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6108{
6109 int parm_num, canon_num;
6110 bool loc_inverse = False;
6111
6112 parm_num = map_parameter(pszParmName);
6113 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6114 /* invalid, parametric or no canidate for synonyms ... */
6115 goto done;
6116 }
6117
6118 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6119 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6120 parm_num = canon_num;
6121 goto done;
6122 }
6123 }
6124
6125done:
6126 if (inverse != NULL) {
6127 *inverse = loc_inverse;
6128 }
6129 return parm_num;
6130}
6131
6132/***************************************************************************
6133 return true if parameter number parm1 is a synonym of parameter
6134 number parm2 (parm2 being the principal name).
6135 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6136 False otherwise.
6137***************************************************************************/
6138
6139static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6140{
6141 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6142 (parm_table[parm1].flags & FLAG_HIDE) &&
6143 !(parm_table[parm2].flags & FLAG_HIDE))
6144 {
6145 if (inverse != NULL) {
6146 if ((parm_table[parm1].type == P_BOOLREV) &&
6147 (parm_table[parm2].type == P_BOOL))
6148 {
6149 *inverse = True;
6150 } else {
6151 *inverse = False;
6152 }
6153 }
6154 return True;
6155 }
6156 return False;
6157}
6158
6159/***************************************************************************
6160 Show one parameter's name, type, [values,] and flags.
6161 (helper functions for show_parameter_list)
6162***************************************************************************/
6163
6164static void show_parameter(int parmIndex)
6165{
6166 int enumIndex, flagIndex;
6167 int parmIndex2;
6168 bool hadFlag;
6169 bool hadSyn;
6170 bool inverse;
6171 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6172 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6173 "P_ENUM", "P_SEP"};
6174 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6175 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6176 FLAG_HIDE, FLAG_DOS_STRING};
6177 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6178 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6179 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6180
6181 printf("%s=%s", parm_table[parmIndex].label,
6182 type[parm_table[parmIndex].type]);
6183 if (parm_table[parmIndex].type == P_ENUM) {
6184 printf(",");
6185 for (enumIndex=0;
6186 parm_table[parmIndex].enum_list[enumIndex].name;
6187 enumIndex++)
6188 {
6189 printf("%s%s",
6190 enumIndex ? "|" : "",
6191 parm_table[parmIndex].enum_list[enumIndex].name);
6192 }
6193 }
6194 printf(",");
6195 hadFlag = False;
6196 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6197 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6198 printf("%s%s",
6199 hadFlag ? "|" : "",
6200 flag_names[flagIndex]);
6201 hadFlag = True;
6202 }
6203 }
6204
6205 /* output synonyms */
6206 hadSyn = False;
6207 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6208 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6209 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6210 parm_table[parmIndex2].label);
6211 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6212 if (!hadSyn) {
6213 printf(" (synonyms: ");
6214 hadSyn = True;
6215 } else {
6216 printf(", ");
6217 }
6218 printf("%s%s", parm_table[parmIndex2].label,
6219 inverse ? "[i]" : "");
6220 }
6221 }
6222 if (hadSyn) {
6223 printf(")");
6224 }
6225
6226 printf("\n");
6227}
6228
6229/***************************************************************************
6230 Show all parameter's name, type, [values,] and flags.
6231***************************************************************************/
6232
6233void show_parameter_list(void)
6234{
6235 int classIndex, parmIndex;
6236 const char *section_names[] = { "local", "global", NULL};
6237
6238 for (classIndex=0; section_names[classIndex]; classIndex++) {
6239 printf("[%s]\n", section_names[classIndex]);
6240 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6241 if (parm_table[parmIndex].p_class == classIndex) {
6242 show_parameter(parmIndex);
6243 }
6244 }
6245 }
6246}
6247
6248/***************************************************************************
6249 Set a boolean variable from the text value stored in the passed string.
6250 Returns True in success, False if the passed string does not correctly
6251 represent a boolean.
6252***************************************************************************/
6253
6254static bool set_boolean(bool *pb, const char *pszParmValue)
6255{
6256 bool bRetval;
6257 bool value;
6258
6259 bRetval = True;
6260 value = False;
6261 if (strwicmp(pszParmValue, "yes") == 0 ||
6262 strwicmp(pszParmValue, "true") == 0 ||
6263 strwicmp(pszParmValue, "1") == 0)
6264 value = True;
6265 else if (strwicmp(pszParmValue, "no") == 0 ||
6266 strwicmp(pszParmValue, "False") == 0 ||
6267 strwicmp(pszParmValue, "0") == 0)
6268 value = False;
6269 else {
6270 DEBUG(2,
6271 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6272 pszParmValue));
6273 bRetval = False;
6274 }
6275
6276 if ((pb != NULL) && (bRetval != False)) {
6277 *pb = value;
6278 }
6279
6280 return (bRetval);
6281}
6282
6283
6284/***************************************************************************
6285 Check if a given string correctly represents a boolean value.
6286***************************************************************************/
6287
6288bool lp_string_is_valid_boolean(const char *parm_value)
6289{
6290 return set_boolean(NULL, parm_value);
6291}
6292
6293/***************************************************************************
6294 Get the standard string representation of a boolean value ("yes" or "no")
6295***************************************************************************/
6296
6297static const char *get_boolean(bool bool_value)
6298{
6299 static const char *yes_str = "yes";
6300 static const char *no_str = "no";
6301
6302 return (bool_value ? yes_str : no_str);
6303}
6304
6305/***************************************************************************
6306 Provide the string of the negated boolean value associated to the boolean
6307 given as a string. Returns False if the passed string does not correctly
6308 represent a boolean.
6309***************************************************************************/
6310
6311bool lp_invert_boolean(const char *str, const char **inverse_str)
6312{
6313 bool val;
6314
6315 if (!set_boolean(&val, str)) {
6316 return False;
6317 }
6318
6319 *inverse_str = get_boolean(!val);
6320 return True;
6321}
6322
6323/***************************************************************************
6324 Provide the canonical string representation of a boolean value given
6325 as a string. Return True on success, False if the string given does
6326 not correctly represent a boolean.
6327***************************************************************************/
6328
6329bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6330{
6331 bool val;
6332
6333 if (!set_boolean(&val, str)) {
6334 return False;
6335 }
6336
6337 *canon_str = get_boolean(val);
6338 return True;
6339}
6340
6341/***************************************************************************
6342Find a service by name. Otherwise works like get_service.
6343***************************************************************************/
6344
6345static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6346{
6347 int iService = -1;
6348 char *canon_name;
6349 TDB_DATA data;
6350
6351 if (ServiceHash == NULL) {
6352 return -1;
6353 }
6354
6355 canon_name = canonicalize_servicename(pszServiceName);
6356
6357 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6358
6359 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6360 iService = *(int *)data.dptr;
6361 }
6362
6363 TALLOC_FREE(canon_name);
6364
6365 if ((iService != -1) && (LP_SNUM_OK(iService))
6366 && (pserviceDest != NULL)) {
6367 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6368 }
6369
6370 return (iService);
6371}
6372
6373/***************************************************************************
6374 Copy a service structure to another.
6375 If pcopymapDest is NULL then copy all fields
6376***************************************************************************/
6377
6378static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6379 struct bitmap *pcopymapDest)
6380{
6381 int i;
6382 bool bcopyall = (pcopymapDest == NULL);
6383 param_opt_struct *data, *pdata, *paramo;
6384 bool not_added;
6385
6386 for (i = 0; parm_table[i].label; i++)
6387 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6388 (bcopyall || bitmap_query(pcopymapDest,i))) {
6389 void *def_ptr = parm_table[i].ptr;
6390 void *src_ptr =
6391 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6392 &sDefault);
6393 void *dest_ptr =
6394 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6395 &sDefault);
6396
6397 switch (parm_table[i].type) {
6398 case P_BOOL:
6399 case P_BOOLREV:
6400 *(bool *)dest_ptr = *(bool *)src_ptr;
6401 break;
6402
6403 case P_INTEGER:
6404 case P_ENUM:
6405 case P_OCTAL:
6406 *(int *)dest_ptr = *(int *)src_ptr;
6407 break;
6408
6409 case P_CHAR:
6410 *(char *)dest_ptr = *(char *)src_ptr;
6411 break;
6412
6413 case P_STRING:
6414 string_set((char **)dest_ptr,
6415 *(char **)src_ptr);
6416 break;
6417
6418 case P_USTRING:
6419 string_set((char **)dest_ptr,
6420 *(char **)src_ptr);
6421 strupper_m(*(char **)dest_ptr);
6422 break;
6423 case P_LIST:
6424 TALLOC_FREE(*((char ***)dest_ptr));
6425 str_list_copy(NULL, (char ***)dest_ptr,
6426 *(const char ***)src_ptr);
6427 break;
6428 default:
6429 break;
6430 }
6431 }
6432
6433 if (bcopyall) {
6434 init_copymap(pserviceDest);
6435 if (pserviceSource->copymap)
6436 bitmap_copy(pserviceDest->copymap,
6437 pserviceSource->copymap);
6438 }
6439
6440 data = pserviceSource->param_opt;
6441 while (data) {
6442 not_added = True;
6443 pdata = pserviceDest->param_opt;
6444 /* Traverse destination */
6445 while (pdata) {
6446 /* If we already have same option, override it */
6447 if (strcmp(pdata->key, data->key) == 0) {
6448 string_free(&pdata->value);
6449 TALLOC_FREE(data->list);
6450 pdata->value = SMB_STRDUP(data->value);
6451 not_added = False;
6452 break;
6453 }
6454 pdata = pdata->next;
6455 }
6456 if (not_added) {
6457 paramo = SMB_XMALLOC_P(param_opt_struct);
6458 paramo->key = SMB_STRDUP(data->key);
6459 paramo->value = SMB_STRDUP(data->value);
6460 paramo->list = NULL;
6461 DLIST_ADD(pserviceDest->param_opt, paramo);
6462 }
6463 data = data->next;
6464 }
6465}
6466
6467/***************************************************************************
6468Check a service for consistency. Return False if the service is in any way
6469incomplete or faulty, else True.
6470***************************************************************************/
6471
6472bool service_ok(int iService)
6473{
6474 bool bRetval;
6475
6476 bRetval = True;
6477 if (ServicePtrs[iService]->szService[0] == '\0') {
6478 DEBUG(0, ("The following message indicates an internal error:\n"));
6479 DEBUG(0, ("No service name in service entry.\n"));
6480 bRetval = False;
6481 }
6482
6483 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6484 /* I can't see why you'd want a non-printable printer service... */
6485 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6486 if (!ServicePtrs[iService]->bPrint_ok) {
6487 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6488 ServicePtrs[iService]->szService));
6489 ServicePtrs[iService]->bPrint_ok = True;
6490 }
6491 /* [printers] service must also be non-browsable. */
6492 if (ServicePtrs[iService]->bBrowseable)
6493 ServicePtrs[iService]->bBrowseable = False;
6494 }
6495
6496 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6497 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6498 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6499 ) {
6500 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6501 ServicePtrs[iService]->szService));
6502 ServicePtrs[iService]->bAvailable = False;
6503 }
6504
6505 /* If a service is flagged unavailable, log the fact at level 1. */
6506 if (!ServicePtrs[iService]->bAvailable)
6507 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6508 ServicePtrs[iService]->szService));
6509
6510 return (bRetval);
6511}
6512
6513static struct smbconf_ctx *lp_smbconf_ctx(void)
6514{
6515 WERROR werr;
6516 static struct smbconf_ctx *conf_ctx = NULL;
6517
6518 if (conf_ctx == NULL) {
6519 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6520 if (!W_ERROR_IS_OK(werr)) {
6521 DEBUG(1, ("error initializing registry configuration: "
6522 "%s\n", dos_errstr(werr)));
6523 conf_ctx = NULL;
6524 }
6525 }
6526
6527 return conf_ctx;
6528}
6529
6530static bool process_registry_service(struct smbconf_service *service)
6531{
6532 uint32_t count;
6533 bool ret;
6534
6535 if (service == NULL) {
6536 return false;
6537 }
6538
6539 ret = do_section(service->name, NULL);
6540 if (ret != true) {
6541 return false;
6542 }
6543 for (count = 0; count < service->num_params; count++) {
6544 ret = do_parameter(service->param_names[count],
6545 service->param_values[count],
6546 NULL);
6547 if (ret != true) {
6548 return false;
6549 }
6550 }
6551 return true;
6552}
6553
6554/*
6555 * process_registry_globals
6556 */
6557static bool process_registry_globals(void)
6558{
6559 WERROR werr;
6560 struct smbconf_service *service = NULL;
6561 TALLOC_CTX *mem_ctx = talloc_stackframe();
6562 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6563 bool ret = false;
6564
6565 if (conf_ctx == NULL) {
6566 goto done;
6567 }
6568
6569 ret = do_parameter("registry shares", "yes", NULL);
6570 if (!ret) {
6571 goto done;
6572 }
6573
6574 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6575 /* nothing to read from the registry yet but make sure lp_load
6576 * doesn't return false */
6577 ret = true;
6578 goto done;
6579 }
6580
6581 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6582 if (!W_ERROR_IS_OK(werr)) {
6583 goto done;
6584 }
6585
6586 ret = process_registry_service(service);
6587 if (!ret) {
6588 goto done;
6589 }
6590
6591 /* store the csn */
6592 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6593
6594done:
6595 TALLOC_FREE(mem_ctx);
6596 return ret;
6597}
6598
6599static bool process_registry_shares(void)
6600{
6601 WERROR werr;
6602 uint32_t count;
6603 struct smbconf_service **service = NULL;
6604 uint32_t num_shares = 0;
6605 TALLOC_CTX *mem_ctx = talloc_stackframe();
6606 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6607 bool ret = false;
6608
6609 if (conf_ctx == NULL) {
6610 goto done;
6611 }
6612
6613 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6614 if (!W_ERROR_IS_OK(werr)) {
6615 goto done;
6616 }
6617
6618 ret = true;
6619
6620 for (count = 0; count < num_shares; count++) {
6621 if (strequal(service[count]->name, GLOBAL_NAME)) {
6622 continue;
6623 }
6624 ret = process_registry_service(service[count]);
6625 if (!ret) {
6626 goto done;
6627 }
6628 }
6629
6630 /* store the csn */
6631 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6632
6633done:
6634 TALLOC_FREE(mem_ctx);
6635 return ret;
6636}
6637
6638static struct file_lists {
6639 struct file_lists *next;
6640 char *name;
6641 char *subfname;
6642 time_t modtime;
6643} *file_lists = NULL;
6644
6645/*******************************************************************
6646 Keep a linked list of all config files so we know when one has changed
6647 it's date and needs to be reloaded.
6648********************************************************************/
6649
6650static void add_to_file_list(const char *fname, const char *subfname)
6651{
6652 struct file_lists *f = file_lists;
6653
6654 while (f) {
6655 if (f->name && !strcmp(f->name, fname))
6656 break;
6657 f = f->next;
6658 }
6659
6660 if (!f) {
6661 f = SMB_MALLOC_P(struct file_lists);
6662 if (!f)
6663 return;
6664 f->next = file_lists;
6665 f->name = SMB_STRDUP(fname);
6666 if (!f->name) {
6667 SAFE_FREE(f);
6668 return;
6669 }
6670 f->subfname = SMB_STRDUP(subfname);
6671 if (!f->subfname) {
6672 SAFE_FREE(f);
6673 return;
6674 }
6675 file_lists = f;
6676 f->modtime = file_modtime(subfname);
6677 } else {
6678 time_t t = file_modtime(subfname);
6679 if (t)
6680 f->modtime = t;
6681 }
6682}
6683
6684/**
6685 * Utility function for outsiders to check if we're running on registry.
6686 */
6687bool lp_config_backend_is_registry(void)
6688{
6689 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6690}
6691
6692/**
6693 * Utility function to check if the config backend is FILE.
6694 */
6695bool lp_config_backend_is_file(void)
6696{
6697 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6698}
6699
6700/*******************************************************************
6701 Check if a config file has changed date.
6702********************************************************************/
6703
6704bool lp_file_list_changed(void)
6705{
6706 struct file_lists *f = file_lists;
6707
6708 DEBUG(6, ("lp_file_list_changed()\n"));
6709
6710 if (lp_config_backend_is_registry()) {
6711 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6712
6713 if (conf_ctx == NULL) {
6714 return false;
6715 }
6716 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6717 DEBUGADD(6, ("registry config changed\n"));
6718 return true;
6719 }
6720 }
6721
6722 while (f) {
6723 char *n2 = NULL;
6724 time_t mod_time;
6725
6726 n2 = alloc_sub_basic(get_current_username(),
6727 current_user_info.domain,
6728 f->name);
6729 if (!n2) {
6730 return false;
6731 }
6732 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6733 f->name, n2, ctime(&f->modtime)));
6734
6735 mod_time = file_modtime(n2);
6736
6737 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6738 DEBUGADD(6,
6739 ("file %s modified: %s\n", n2,
6740 ctime(&mod_time)));
6741 f->modtime = mod_time;
6742 SAFE_FREE(f->subfname);
6743 f->subfname = n2; /* Passing ownership of
6744 return from alloc_sub_basic
6745 above. */
6746 return true;
6747 }
6748 SAFE_FREE(n2);
6749 f = f->next;
6750 }
6751 return (False);
6752}
6753
6754
6755/***************************************************************************
6756 Run standard_sub_basic on netbios name... needed because global_myname
6757 is not accessed through any lp_ macro.
6758 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6759***************************************************************************/
6760
6761static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6762{
6763 bool ret;
6764 char *netbios_name = alloc_sub_basic(get_current_username(),
6765 current_user_info.domain,
6766 pszParmValue);
6767
6768 ret = set_global_myname(netbios_name);
6769 SAFE_FREE(netbios_name);
6770 string_set(&Globals.szNetbiosName,global_myname());
6771
6772 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6773 global_myname()));
6774
6775 return ret;
6776}
6777
6778static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6779{
6780 if (strcmp(*ptr, pszParmValue) != 0) {
6781 string_set(ptr, pszParmValue);
6782 init_iconv();
6783 }
6784 return True;
6785}
6786
6787
6788
6789static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6790{
6791 bool ret;
6792
6793 ret = set_global_myworkgroup(pszParmValue);
6794 string_set(&Globals.szWorkgroup,lp_workgroup());
6795
6796 return ret;
6797}
6798
6799static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6800{
6801 bool ret;
6802
6803 ret = set_global_scope(pszParmValue);
6804 string_set(&Globals.szNetbiosScope,global_scope());
6805
6806 return ret;
6807}
6808
6809static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6810{
6811 TALLOC_FREE(Globals.szNetbiosAliases);
6812 Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6813 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6814}
6815
6816/***************************************************************************
6817 Handle the include operation.
6818***************************************************************************/
6819static bool bAllowIncludeRegistry = true;
6820
6821static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6822{
6823 char *fname;
6824
6825 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6826 if (!bAllowIncludeRegistry) {
6827 return true;
6828 }
6829 if (bInGlobalSection) {
6830 return process_registry_globals();
6831 } else {
6832 DEBUG(1, ("\"include = registry\" only effective "
6833 "in %s section\n", GLOBAL_NAME));
6834 return false;
6835 }
6836 }
6837
6838 fname = alloc_sub_basic(get_current_username(),
6839 current_user_info.domain,
6840 pszParmValue);
6841
6842 add_to_file_list(pszParmValue, fname);
6843
6844 string_set(ptr, fname);
6845
6846 if (file_exist(fname, NULL)) {
6847 bool ret = pm_process(fname, do_section, do_parameter, NULL);
6848 SAFE_FREE(fname);
6849 return ret;
6850 }
6851
6852 DEBUG(2, ("Can't find include file %s\n", fname));
6853 SAFE_FREE(fname);
6854 return false;
6855}
6856
6857/***************************************************************************
6858 Handle the interpretation of the copy parameter.
6859***************************************************************************/
6860
6861static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6862{
6863 bool bRetval;
6864 int iTemp;
6865 struct service serviceTemp;
6866
6867 string_set(ptr, pszParmValue);
6868
6869 init_service(&serviceTemp);
6870
6871 bRetval = False;
6872
6873 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6874
6875 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6876 if (iTemp == iServiceIndex) {
6877 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6878 } else {
6879 copy_service(ServicePtrs[iServiceIndex],
6880 &serviceTemp,
6881 ServicePtrs[iServiceIndex]->copymap);
6882 bRetval = True;
6883 }
6884 } else {
6885 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6886 bRetval = False;
6887 }
6888
6889 free_service(&serviceTemp);
6890 return (bRetval);
6891}
6892
6893static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6894{
6895 Globals.ldap_debug_level = lp_int(pszParmValue);
6896 init_ldap_debugging();
6897 return true;
6898}
6899
6900/***************************************************************************
6901 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6902 parameters is:
6903
6904 [global]
6905
6906 idmap uid = 1000-1999
6907 idmap gid = 700-899
6908
6909 We only do simple parsing checks here. The strings are parsed into useful
6910 structures in the idmap daemon code.
6911
6912***************************************************************************/
6913
6914/* Some lp_ routines to return idmap [ug]id information */
6915
6916static uid_t idmap_uid_low, idmap_uid_high;
6917static gid_t idmap_gid_low, idmap_gid_high;
6918
6919bool lp_idmap_uid(uid_t *low, uid_t *high)
6920{
6921 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6922 return False;
6923
6924 if (low)
6925 *low = idmap_uid_low;
6926
6927 if (high)
6928 *high = idmap_uid_high;
6929
6930 return True;
6931}
6932
6933bool lp_idmap_gid(gid_t *low, gid_t *high)
6934{
6935 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6936 return False;
6937
6938 if (low)
6939 *low = idmap_gid_low;
6940
6941 if (high)
6942 *high = idmap_gid_high;
6943
6944 return True;
6945}
6946
6947/* Do some simple checks on "idmap [ug]id" parameter values */
6948
6949static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6950{
6951 uint32 low, high;
6952
6953 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6954 return False;
6955
6956 /* Parse OK */
6957
6958 string_set(ptr, pszParmValue);
6959
6960 idmap_uid_low = low;
6961 idmap_uid_high = high;
6962
6963 return True;
6964}
6965
6966static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6967{
6968 uint32 low, high;
6969
6970 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6971 return False;
6972
6973 /* Parse OK */
6974
6975 string_set(ptr, pszParmValue);
6976
6977 idmap_gid_low = low;
6978 idmap_gid_high = high;
6979
6980 return True;
6981}
6982
6983/***************************************************************************
6984 Handle the DEBUG level list.
6985***************************************************************************/
6986
6987static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
6988{
6989 string_set(ptr, pszParmValueIn);
6990 return debug_parse_levels(pszParmValueIn);
6991}
6992
6993/***************************************************************************
6994 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
6995***************************************************************************/
6996
6997static const char *append_ldap_suffix( const char *str )
6998{
6999 const char *suffix_string;
7000
7001
7002 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7003 Globals.szLdapSuffix );
7004 if ( !suffix_string ) {
7005 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7006 return "";
7007 }
7008
7009 return suffix_string;
7010}
7011
7012const char *lp_ldap_machine_suffix(void)
7013{
7014 if (Globals.szLdapMachineSuffix[0])
7015 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7016
7017 return lp_string(Globals.szLdapSuffix);
7018}
7019
7020const char *lp_ldap_user_suffix(void)
7021{
7022 if (Globals.szLdapUserSuffix[0])
7023 return append_ldap_suffix(Globals.szLdapUserSuffix);
7024
7025 return lp_string(Globals.szLdapSuffix);
7026}
7027
7028const char *lp_ldap_group_suffix(void)
7029{
7030 if (Globals.szLdapGroupSuffix[0])
7031 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7032
7033 return lp_string(Globals.szLdapSuffix);
7034}
7035
7036const char *lp_ldap_idmap_suffix(void)
7037{
7038 if (Globals.szLdapIdmapSuffix[0])
7039 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7040
7041 return lp_string(Globals.szLdapSuffix);
7042}
7043
7044/****************************************************************************
7045 set the value for a P_ENUM
7046 ***************************************************************************/
7047
7048static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7049 int *ptr )
7050{
7051 int i;
7052
7053 for (i = 0; parm->enum_list[i].name; i++) {
7054 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7055 *ptr = parm->enum_list[i].value;
7056 break;
7057 }
7058 }
7059}
7060
7061/***************************************************************************
7062***************************************************************************/
7063
7064static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7065{
7066 static int parm_num = -1;
7067 struct service *s;
7068
7069 if ( parm_num == -1 )
7070 parm_num = map_parameter( "printing" );
7071
7072 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7073
7074 if ( snum < 0 )
7075 s = &sDefault;
7076 else
7077 s = ServicePtrs[snum];
7078
7079 init_printer_values( s );
7080
7081 return True;
7082}
7083
7084
7085/***************************************************************************
7086 Initialise a copymap.
7087***************************************************************************/
7088
7089static void init_copymap(struct service *pservice)
7090{
7091 int i;
7092 if (pservice->copymap) {
7093 bitmap_free(pservice->copymap);
7094 }
7095 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7096 if (!pservice->copymap)
7097 DEBUG(0,
7098 ("Couldn't allocate copymap!! (size %d)\n",
7099 (int)NUMPARAMETERS));
7100 else
7101 for (i = 0; i < NUMPARAMETERS; i++)
7102 bitmap_set(pservice->copymap, i);
7103}
7104
7105/***************************************************************************
7106 Return the local pointer to a parameter given the service number and the
7107 pointer into the default structure.
7108***************************************************************************/
7109
7110void *lp_local_ptr(int snum, void *ptr)
7111{
7112 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7113}
7114
7115/***************************************************************************
7116 Process a parameter for a particular service number. If snum < 0
7117 then assume we are in the globals.
7118***************************************************************************/
7119
7120bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7121{
7122 int parmnum, i, slen;
7123 void *parm_ptr = NULL; /* where we are going to store the result */
7124 void *def_ptr = NULL;
7125 char *param_key = NULL;
7126 char *sep;
7127 param_opt_struct *paramo, *data;
7128 bool not_added;
7129
7130 parmnum = map_parameter(pszParmName);
7131
7132 if (parmnum < 0) {
7133 if ((sep=strchr(pszParmName, ':')) != NULL) {
7134 TALLOC_CTX *frame = talloc_stackframe();
7135
7136 *sep = '\0';
7137 param_key = talloc_asprintf(frame, "%s:", pszParmName);
7138 if (!param_key) {
7139 TALLOC_FREE(frame);
7140 return false;
7141 }
7142 slen = strlen(param_key);
7143 param_key = talloc_asprintf_append(param_key, sep+1);
7144 if (!param_key) {
7145 TALLOC_FREE(frame);
7146 return false;
7147 }
7148 trim_char(param_key+slen, ' ', ' ');
7149 not_added = True;
7150 data = (snum < 0) ? Globals.param_opt :
7151 ServicePtrs[snum]->param_opt;
7152 /* Traverse destination */
7153 while (data) {
7154 /* If we already have same option, override it */
7155 if (strcmp(data->key, param_key) == 0) {
7156 string_free(&data->value);
7157 TALLOC_FREE(data->list);
7158 data->value = SMB_STRDUP(pszParmValue);
7159 not_added = False;
7160 break;
7161 }
7162 data = data->next;
7163 }
7164 if (not_added) {
7165 paramo = SMB_XMALLOC_P(param_opt_struct);
7166 paramo->key = SMB_STRDUP(param_key);
7167 paramo->value = SMB_STRDUP(pszParmValue);
7168 paramo->list = NULL;
7169 if (snum < 0) {
7170 DLIST_ADD(Globals.param_opt, paramo);
7171 } else {
7172 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
7173 }
7174 }
7175
7176 *sep = ':';
7177 TALLOC_FREE(frame);
7178 return (True);
7179 }
7180 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7181 return (True);
7182 }
7183
7184 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7185 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7186 pszParmName));
7187 }
7188
7189 def_ptr = parm_table[parmnum].ptr;
7190
7191 /* we might point at a service, the default service or a global */
7192 if (snum < 0) {
7193 parm_ptr = def_ptr;
7194 } else {
7195 if (parm_table[parmnum].p_class == P_GLOBAL) {
7196 DEBUG(0,
7197 ("Global parameter %s found in service section!\n",
7198 pszParmName));
7199 return (True);
7200 }
7201 parm_ptr =
7202 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7203 &sDefault);
7204 }
7205
7206 if (snum >= 0) {
7207 if (!ServicePtrs[snum]->copymap)
7208 init_copymap(ServicePtrs[snum]);
7209
7210 /* this handles the aliases - set the copymap for other entries with
7211 the same data pointer */
7212 for (i = 0; parm_table[i].label; i++)
7213 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7214 bitmap_clear(ServicePtrs[snum]->copymap, i);
7215 }
7216
7217 /* if it is a special case then go ahead */
7218 if (parm_table[parmnum].special) {
7219 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
7220 return (True);
7221 }
7222
7223 /* now switch on the type of variable it is */
7224 switch (parm_table[parmnum].type)
7225 {
7226 case P_BOOL:
7227 *(bool *)parm_ptr = lp_bool(pszParmValue);
7228 break;
7229
7230 case P_BOOLREV:
7231 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7232 break;
7233
7234 case P_INTEGER:
7235 *(int *)parm_ptr = lp_int(pszParmValue);
7236 break;
7237
7238 case P_CHAR:
7239 *(char *)parm_ptr = *pszParmValue;
7240 break;
7241
7242 case P_OCTAL:
7243 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7244 if ( i != 1 ) {
7245 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7246 }
7247 break;
7248
7249 case P_LIST:
7250 TALLOC_FREE(*((char ***)parm_ptr));
7251 *(char ***)parm_ptr = str_list_make(
7252 NULL, pszParmValue, NULL);
7253 break;
7254
7255 case P_STRING:
7256 string_set((char **)parm_ptr, pszParmValue);
7257 break;
7258
7259 case P_USTRING:
7260 string_set((char **)parm_ptr, pszParmValue);
7261 strupper_m(*(char **)parm_ptr);
7262 break;
7263
7264 case P_ENUM:
7265 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7266 break;
7267 case P_SEP:
7268 break;
7269 }
7270
7271 return (True);
7272}
7273
7274/***************************************************************************
7275 Process a parameter.
7276***************************************************************************/
7277
7278static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7279 void *userdata)
7280{
7281 if (!bInGlobalSection && bGlobalOnly)
7282 return (True);
7283
7284 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7285
7286 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7287 pszParmName, pszParmValue));
7288}
7289
7290/***************************************************************************
7291 Print a parameter of the specified type.
7292***************************************************************************/
7293
7294static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7295{
7296 int i;
7297 switch (p->type)
7298 {
7299 case P_ENUM:
7300 for (i = 0; p->enum_list[i].name; i++) {
7301 if (*(int *)ptr == p->enum_list[i].value) {
7302 fprintf(f, "%s",
7303 p->enum_list[i].name);
7304 break;
7305 }
7306 }
7307 break;
7308
7309 case P_BOOL:
7310 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7311 break;
7312
7313 case P_BOOLREV:
7314 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7315 break;
7316
7317 case P_INTEGER:
7318 fprintf(f, "%d", *(int *)ptr);
7319 break;
7320
7321 case P_CHAR:
7322 fprintf(f, "%c", *(char *)ptr);
7323 break;
7324
7325 case P_OCTAL: {
7326 char *o = octal_string(*(int *)ptr);
7327 fprintf(f, "%s", o);
7328 TALLOC_FREE(o);
7329 break;
7330 }
7331
7332 case P_LIST:
7333 if ((char ***)ptr && *(char ***)ptr) {
7334 char **list = *(char ***)ptr;
7335 for (; *list; list++) {
7336 /* surround strings with whitespace in double quotes */
7337 if ( strchr_m( *list, ' ' ) )
7338 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7339 else
7340 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7341 }
7342 }
7343 break;
7344
7345 case P_STRING:
7346 case P_USTRING:
7347 if (*(char **)ptr) {
7348 fprintf(f, "%s", *(char **)ptr);
7349 }
7350 break;
7351 case P_SEP:
7352 break;
7353 }
7354}
7355
7356/***************************************************************************
7357 Check if two parameters are equal.
7358***************************************************************************/
7359
7360static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7361{
7362 switch (type) {
7363 case P_BOOL:
7364 case P_BOOLREV:
7365 return (*((bool *)ptr1) == *((bool *)ptr2));
7366
7367 case P_INTEGER:
7368 case P_ENUM:
7369 case P_OCTAL:
7370 return (*((int *)ptr1) == *((int *)ptr2));
7371
7372 case P_CHAR:
7373 return (*((char *)ptr1) == *((char *)ptr2));
7374
7375 case P_LIST:
7376 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7377
7378 case P_STRING:
7379 case P_USTRING:
7380 {
7381 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7382 if (p1 && !*p1)
7383 p1 = NULL;
7384 if (p2 && !*p2)
7385 p2 = NULL;
7386 return (p1 == p2 || strequal(p1, p2));
7387 }
7388 case P_SEP:
7389 break;
7390 }
7391 return (False);
7392}
7393
7394/***************************************************************************
7395 Initialize any local varients in the sDefault table.
7396***************************************************************************/
7397
7398void init_locals(void)
7399{
7400 /* None as yet. */
7401}
7402
7403/***************************************************************************
7404 Process a new section (service). At this stage all sections are services.
7405 Later we'll have special sections that permit server parameters to be set.
7406 Returns True on success, False on failure.
7407***************************************************************************/
7408
7409static bool do_section(const char *pszSectionName, void *userdata)
7410{
7411 bool bRetval;
7412 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7413 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7414 bRetval = False;
7415
7416 /* if we were in a global section then do the local inits */
7417 if (bInGlobalSection && !isglobal)
7418 init_locals();
7419
7420 /* if we've just struck a global section, note the fact. */
7421 bInGlobalSection = isglobal;
7422
7423 /* check for multiple global sections */
7424 if (bInGlobalSection) {
7425 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7426 return (True);
7427 }
7428
7429 if (!bInGlobalSection && bGlobalOnly)
7430 return (True);
7431
7432 /* if we have a current service, tidy it up before moving on */
7433 bRetval = True;
7434
7435 if (iServiceIndex >= 0)
7436 bRetval = service_ok(iServiceIndex);
7437
7438 /* if all is still well, move to the next record in the services array */
7439 if (bRetval) {
7440 /* We put this here to avoid an odd message order if messages are */
7441 /* issued by the post-processing of a previous section. */
7442 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7443
7444 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7445 < 0) {
7446 DEBUG(0, ("Failed to add a new service\n"));
7447 return (False);
7448 }
7449 }
7450
7451 return (bRetval);
7452}
7453
7454
7455/***************************************************************************
7456 Determine if a partcular base parameter is currentl set to the default value.
7457***************************************************************************/
7458
7459static bool is_default(int i)
7460{
7461 if (!defaults_saved)
7462 return False;
7463 switch (parm_table[i].type) {
7464 case P_LIST:
7465 return str_list_compare (parm_table[i].def.lvalue,
7466 *(char ***)parm_table[i].ptr);
7467 case P_STRING:
7468 case P_USTRING:
7469 return strequal(parm_table[i].def.svalue,
7470 *(char **)parm_table[i].ptr);
7471 case P_BOOL:
7472 case P_BOOLREV:
7473 return parm_table[i].def.bvalue ==
7474 *(bool *)parm_table[i].ptr;
7475 case P_CHAR:
7476 return parm_table[i].def.cvalue ==
7477 *(char *)parm_table[i].ptr;
7478 case P_INTEGER:
7479 case P_OCTAL:
7480 case P_ENUM:
7481 return parm_table[i].def.ivalue ==
7482 *(int *)parm_table[i].ptr;
7483 case P_SEP:
7484 break;
7485 }
7486 return False;
7487}
7488
7489/***************************************************************************
7490Display the contents of the global structure.
7491***************************************************************************/
7492
7493static void dump_globals(FILE *f)
7494{
7495 int i;
7496 param_opt_struct *data;
7497
7498 fprintf(f, "[global]\n");
7499
7500 for (i = 0; parm_table[i].label; i++)
7501 if (parm_table[i].p_class == P_GLOBAL &&
7502 parm_table[i].ptr &&
7503 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7504 if (defaults_saved && is_default(i))
7505 continue;
7506 fprintf(f, "\t%s = ", parm_table[i].label);
7507 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7508 fprintf(f, "\n");
7509 }
7510 if (Globals.param_opt != NULL) {
7511 data = Globals.param_opt;
7512 while(data) {
7513 fprintf(f, "\t%s = %s\n", data->key, data->value);
7514 data = data->next;
7515 }
7516 }
7517
7518}
7519
7520/***************************************************************************
7521 Return True if a local parameter is currently set to the global default.
7522***************************************************************************/
7523
7524bool lp_is_default(int snum, struct parm_struct *parm)
7525{
7526 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7527
7528 return equal_parameter(parm->type,
7529 ((char *)ServicePtrs[snum]) + pdiff,
7530 ((char *)&sDefault) + pdiff);
7531}
7532
7533/***************************************************************************
7534 Display the contents of a single services record.
7535***************************************************************************/
7536
7537static void dump_a_service(struct service *pService, FILE * f)
7538{
7539 int i;
7540 param_opt_struct *data;
7541
7542 if (pService != &sDefault)
7543 fprintf(f, "[%s]\n", pService->szService);
7544
7545 for (i = 0; parm_table[i].label; i++) {
7546
7547 if (parm_table[i].p_class == P_LOCAL &&
7548 parm_table[i].ptr &&
7549 (*parm_table[i].label != '-') &&
7550 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7551 {
7552
7553 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7554
7555 if (pService == &sDefault) {
7556 if (defaults_saved && is_default(i))
7557 continue;
7558 } else {
7559 if (equal_parameter(parm_table[i].type,
7560 ((char *)pService) +
7561 pdiff,
7562 ((char *)&sDefault) +
7563 pdiff))
7564 continue;
7565 }
7566
7567 fprintf(f, "\t%s = ", parm_table[i].label);
7568 print_parameter(&parm_table[i],
7569 ((char *)pService) + pdiff, f);
7570 fprintf(f, "\n");
7571 }
7572 }
7573
7574 if (pService->param_opt != NULL) {
7575 data = pService->param_opt;
7576 while(data) {
7577 fprintf(f, "\t%s = %s\n", data->key, data->value);
7578 data = data->next;
7579 }
7580 }
7581}
7582
7583/***************************************************************************
7584 Display the contents of a parameter of a single services record.
7585***************************************************************************/
7586
7587bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7588{
7589 int i;
7590 bool result = False;
7591 parm_class p_class;
7592 unsigned flag = 0;
7593 fstring local_parm_name;
7594 char *parm_opt;
7595 const char *parm_opt_value;
7596
7597 /* check for parametrical option */
7598 fstrcpy( local_parm_name, parm_name);
7599 parm_opt = strchr( local_parm_name, ':');
7600
7601 if (parm_opt) {
7602 *parm_opt = '\0';
7603 parm_opt++;
7604 if (strlen(parm_opt)) {
7605 parm_opt_value = lp_parm_const_string( snum,
7606 local_parm_name, parm_opt, NULL);
7607 if (parm_opt_value) {
7608 printf( "%s\n", parm_opt_value);
7609 result = True;
7610 }
7611 }
7612 return result;
7613 }
7614
7615 /* check for a key and print the value */
7616 if (isGlobal) {
7617 p_class = P_GLOBAL;
7618 flag = FLAG_GLOBAL;
7619 } else
7620 p_class = P_LOCAL;
7621
7622 for (i = 0; parm_table[i].label; i++) {
7623 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7624 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7625 parm_table[i].ptr &&
7626 (*parm_table[i].label != '-') &&
7627 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7628 {
7629 void *ptr;
7630
7631 if (isGlobal) {
7632 ptr = parm_table[i].ptr;
7633 } else {
7634 struct service *pService = ServicePtrs[snum];
7635 ptr = ((char *)pService) +
7636 PTR_DIFF(parm_table[i].ptr, &sDefault);
7637 }
7638
7639 print_parameter(&parm_table[i],
7640 ptr, f);
7641 fprintf(f, "\n");
7642 result = True;
7643 break;
7644 }
7645 }
7646
7647 return result;
7648}
7649
7650/***************************************************************************
7651 Return info about the requested parameter (given as a string).
7652 Return NULL when the string is not a valid parameter name.
7653***************************************************************************/
7654
7655struct parm_struct *lp_get_parameter(const char *param_name)
7656{
7657 int num = map_parameter(param_name);
7658
7659 if (num < 0) {
7660 return NULL;
7661 }
7662
7663 return &parm_table[num];
7664}
7665
7666/***************************************************************************
7667 Return info about the next parameter in a service.
7668 snum==GLOBAL_SECTION_SNUM gives the globals.
7669 Return NULL when out of parameters.
7670***************************************************************************/
7671
7672struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7673{
7674 if (snum < 0) {
7675 /* do the globals */
7676 for (; parm_table[*i].label; (*i)++) {
7677 if (parm_table[*i].p_class == P_SEPARATOR)
7678 return &parm_table[(*i)++];
7679
7680 if (!parm_table[*i].ptr
7681 || (*parm_table[*i].label == '-'))
7682 continue;
7683
7684 if ((*i) > 0
7685 && (parm_table[*i].ptr ==
7686 parm_table[(*i) - 1].ptr))
7687 continue;
7688
7689 if (is_default(*i) && !allparameters)
7690 continue;
7691
7692 return &parm_table[(*i)++];
7693 }
7694 } else {
7695 struct service *pService = ServicePtrs[snum];
7696
7697 for (; parm_table[*i].label; (*i)++) {
7698 if (parm_table[*i].p_class == P_SEPARATOR)
7699 return &parm_table[(*i)++];
7700
7701 if (parm_table[*i].p_class == P_LOCAL &&
7702 parm_table[*i].ptr &&
7703 (*parm_table[*i].label != '-') &&
7704 ((*i) == 0 ||
7705 (parm_table[*i].ptr !=
7706 parm_table[(*i) - 1].ptr)))
7707 {
7708 int pdiff =
7709 PTR_DIFF(parm_table[*i].ptr,
7710 &sDefault);
7711
7712 if (allparameters ||
7713 !equal_parameter(parm_table[*i].type,
7714 ((char *)pService) +
7715 pdiff,
7716 ((char *)&sDefault) +
7717 pdiff))
7718 {
7719 return &parm_table[(*i)++];
7720 }
7721 }
7722 }
7723 }
7724
7725 return NULL;
7726}
7727
7728
7729#if 0
7730/***************************************************************************
7731 Display the contents of a single copy structure.
7732***************************************************************************/
7733static void dump_copy_map(bool *pcopymap)
7734{
7735 int i;
7736 if (!pcopymap)
7737 return;
7738
7739 printf("\n\tNon-Copied parameters:\n");
7740
7741 for (i = 0; parm_table[i].label; i++)
7742 if (parm_table[i].p_class == P_LOCAL &&
7743 parm_table[i].ptr && !pcopymap[i] &&
7744 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7745 {
7746 printf("\t\t%s\n", parm_table[i].label);
7747 }
7748}
7749#endif
7750
7751/***************************************************************************
7752 Return TRUE if the passed service number is within range.
7753***************************************************************************/
7754
7755bool lp_snum_ok(int iService)
7756{
7757 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7758}
7759
7760/***************************************************************************
7761 Auto-load some home services.
7762***************************************************************************/
7763
7764static void lp_add_auto_services(char *str)
7765{
7766 char *s;
7767 char *p;
7768 int homes;
7769 char *saveptr;
7770
7771 if (!str)
7772 return;
7773
7774 s = SMB_STRDUP(str);
7775 if (!s)
7776 return;
7777
7778 homes = lp_servicenumber(HOMES_NAME);
7779
7780 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7781 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7782 char *home;
7783
7784 if (lp_servicenumber(p) >= 0)
7785 continue;
7786
7787 home = get_user_home_dir(talloc_tos(), p);
7788
7789 if (home && homes >= 0)
7790 lp_add_home(p, homes, p, home);
7791
7792 TALLOC_FREE(home);
7793 }
7794 SAFE_FREE(s);
7795}
7796
7797/***************************************************************************
7798 Auto-load one printer.
7799***************************************************************************/
7800
7801void lp_add_one_printer(char *name, char *comment)
7802{
7803 int printers = lp_servicenumber(PRINTERS_NAME);
7804 int i;
7805
7806 if (lp_servicenumber(name) < 0) {
7807 lp_add_printer(name, printers);
7808 if ((i = lp_servicenumber(name)) >= 0) {
7809 string_set(&ServicePtrs[i]->comment, comment);
7810 ServicePtrs[i]->autoloaded = True;
7811 }
7812 }
7813}
7814
7815/***************************************************************************
7816 Have we loaded a services file yet?
7817***************************************************************************/
7818
7819bool lp_loaded(void)
7820{
7821 return (bLoaded);
7822}
7823
7824/***************************************************************************
7825 Unload unused services.
7826***************************************************************************/
7827
7828void lp_killunused(bool (*snumused) (int))
7829{
7830 int i;
7831 for (i = 0; i < iNumServices; i++) {
7832 if (!VALID(i))
7833 continue;
7834
7835 /* don't kill autoloaded or usershare services */
7836 if ( ServicePtrs[i]->autoloaded ||
7837 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7838 continue;
7839 }
7840
7841 if (!snumused || !snumused(i)) {
7842 free_service_byindex(i);
7843 }
7844 }
7845}
7846
7847/**
7848 * Kill all except autoloaded and usershare services - convenience wrapper
7849 */
7850void lp_kill_all_services(void)
7851{
7852 lp_killunused(NULL);
7853}
7854
7855/***************************************************************************
7856 Unload a service.
7857***************************************************************************/
7858
7859void lp_killservice(int iServiceIn)
7860{
7861 if (VALID(iServiceIn)) {
7862 free_service_byindex(iServiceIn);
7863 }
7864}
7865
7866/***************************************************************************
7867 Save the curent values of all global and sDefault parameters into the
7868 defaults union. This allows swat and testparm to show only the
7869 changed (ie. non-default) parameters.
7870***************************************************************************/
7871
7872static void lp_save_defaults(void)
7873{
7874 int i;
7875 for (i = 0; parm_table[i].label; i++) {
7876 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7877 continue;
7878 switch (parm_table[i].type) {
7879 case P_LIST:
7880 str_list_copy(
7881 NULL, &(parm_table[i].def.lvalue),
7882 *(const char ***)parm_table[i].ptr);
7883 break;
7884 case P_STRING:
7885 case P_USTRING:
7886 if (parm_table[i].ptr) {
7887 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7888 } else {
7889 parm_table[i].def.svalue = NULL;
7890 }
7891 break;
7892 case P_BOOL:
7893 case P_BOOLREV:
7894 parm_table[i].def.bvalue =
7895 *(bool *)parm_table[i].ptr;
7896 break;
7897 case P_CHAR:
7898 parm_table[i].def.cvalue =
7899 *(char *)parm_table[i].ptr;
7900 break;
7901 case P_INTEGER:
7902 case P_OCTAL:
7903 case P_ENUM:
7904 parm_table[i].def.ivalue =
7905 *(int *)parm_table[i].ptr;
7906 break;
7907 case P_SEP:
7908 break;
7909 }
7910 }
7911 defaults_saved = True;
7912}
7913
7914/*******************************************************************
7915 Set the server type we will announce as via nmbd.
7916********************************************************************/
7917
7918static const struct srv_role_tab {
7919 uint32 role;
7920 const char *role_str;
7921} srv_role_tab [] = {
7922 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7923 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7924 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7925 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7926 { 0, NULL }
7927};
7928
7929const char* server_role_str(uint32 role)
7930{
7931 int i = 0;
7932 for (i=0; srv_role_tab[i].role_str; i++) {
7933 if (role == srv_role_tab[i].role) {
7934 return srv_role_tab[i].role_str;
7935 }
7936 }
7937 return NULL;
7938}
7939
7940static void set_server_role(void)
7941{
7942 server_role = ROLE_STANDALONE;
7943
7944 switch (lp_security()) {
7945 case SEC_SHARE:
7946 if (lp_domain_logons())
7947 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7948 break;
7949 case SEC_SERVER:
7950 if (lp_domain_logons())
7951 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7952 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7953 server_role = ROLE_STANDALONE;
7954 break;
7955 case SEC_DOMAIN:
7956 if (lp_domain_logons()) {
7957 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7958 server_role = ROLE_DOMAIN_BDC;
7959 break;
7960 }
7961 server_role = ROLE_DOMAIN_MEMBER;
7962 break;
7963 case SEC_ADS:
7964 if (lp_domain_logons()) {
7965 server_role = ROLE_DOMAIN_PDC;
7966 break;
7967 }
7968 server_role = ROLE_DOMAIN_MEMBER;
7969 break;
7970 case SEC_USER:
7971 if (lp_domain_logons()) {
7972
7973 if (Globals.iDomainMaster) /* auto or yes */
7974 server_role = ROLE_DOMAIN_PDC;
7975 else
7976 server_role = ROLE_DOMAIN_BDC;
7977 }
7978 break;
7979 default:
7980 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7981 break;
7982 }
7983
7984 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
7985}
7986
7987/***********************************************************
7988 If we should send plaintext/LANMAN passwords in the clinet
7989************************************************************/
7990
7991static void set_allowed_client_auth(void)
7992{
7993 if (Globals.bClientNTLMv2Auth) {
7994 Globals.bClientLanManAuth = False;
7995 }
7996 if (!Globals.bClientLanManAuth) {
7997 Globals.bClientPlaintextAuth = False;
7998 }
7999}
8000
8001/***************************************************************************
8002 JRA.
8003 The following code allows smbd to read a user defined share file.
8004 Yes, this is my intent. Yes, I'm comfortable with that...
8005
8006 THE FOLLOWING IS SECURITY CRITICAL CODE.
8007
8008 It washes your clothes, it cleans your house, it guards you while you sleep...
8009 Do not f%^k with it....
8010***************************************************************************/
8011
8012#define MAX_USERSHARE_FILE_SIZE (10*1024)
8013
8014/***************************************************************************
8015 Check allowed stat state of a usershare file.
8016 Ensure we print out who is dicking with us so the admin can
8017 get their sorry ass fired.
8018***************************************************************************/
8019
8020static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8021{
8022 if (!S_ISREG(psbuf->st_mode)) {
8023 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8024 "not a regular file\n",
8025 fname, (unsigned int)psbuf->st_uid ));
8026 return False;
8027 }
8028
8029 /* Ensure this doesn't have the other write bit set. */
8030 if (psbuf->st_mode & S_IWOTH) {
8031 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8032 "public write. Refusing to allow as a usershare file.\n",
8033 fname, (unsigned int)psbuf->st_uid ));
8034 return False;
8035 }
8036
8037 /* Should be 10k or less. */
8038 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8039 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8040 "too large (%u) to be a user share file.\n",
8041 fname, (unsigned int)psbuf->st_uid,
8042 (unsigned int)psbuf->st_size ));
8043 return False;
8044 }
8045
8046 return True;
8047}
8048
8049/***************************************************************************
8050 Parse the contents of a usershare file.
8051***************************************************************************/
8052
8053enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8054 SMB_STRUCT_STAT *psbuf,
8055 const char *servicename,
8056 int snum,
8057 char **lines,
8058 int numlines,
8059 char **pp_sharepath,
8060 char **pp_comment,
8061 SEC_DESC **ppsd,
8062 bool *pallow_guest)
8063{
8064 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8065 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8066 int us_vers;
8067 SMB_STRUCT_DIR *dp;
8068 SMB_STRUCT_STAT sbuf;
8069 char *sharepath = NULL;
8070 char *comment = NULL;
8071
8072 *pp_sharepath = NULL;
8073 *pp_comment = NULL;
8074
8075 *pallow_guest = False;
8076
8077 if (numlines < 4) {
8078 return USERSHARE_MALFORMED_FILE;
8079 }
8080
8081 if (strcmp(lines[0], "#VERSION 1") == 0) {
8082 us_vers = 1;
8083 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8084 us_vers = 2;
8085 if (numlines < 5) {
8086 return USERSHARE_MALFORMED_FILE;
8087 }
8088 } else {
8089 return USERSHARE_BAD_VERSION;
8090 }
8091
8092 if (strncmp(lines[1], "path=", 5) != 0) {
8093 return USERSHARE_MALFORMED_PATH;
8094 }
8095
8096 sharepath = talloc_strdup(ctx, &lines[1][5]);
8097 if (!sharepath) {
8098 return USERSHARE_POSIX_ERR;
8099 }
8100 trim_string(sharepath, " ", " ");
8101
8102 if (strncmp(lines[2], "comment=", 8) != 0) {
8103 return USERSHARE_MALFORMED_COMMENT_DEF;
8104 }
8105
8106 comment = talloc_strdup(ctx, &lines[2][8]);
8107 if (!comment) {
8108 return USERSHARE_POSIX_ERR;
8109 }
8110 trim_string(comment, " ", " ");
8111 trim_char(comment, '"', '"');
8112
8113 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8114 return USERSHARE_MALFORMED_ACL_DEF;
8115 }
8116
8117 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8118 return USERSHARE_ACL_ERR;
8119 }
8120
8121 if (us_vers == 2) {
8122 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8123 return USERSHARE_MALFORMED_ACL_DEF;
8124 }
8125 if (lines[4][9] == 'y') {
8126 *pallow_guest = True;
8127 }
8128 }
8129
8130 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8131 /* Path didn't change, no checks needed. */
8132 *pp_sharepath = sharepath;
8133 *pp_comment = comment;
8134 return USERSHARE_OK;
8135 }
8136
8137 /* The path *must* be absolute. */
8138 if (sharepath[0] != '/') {
8139 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8140 servicename, sharepath));
8141 return USERSHARE_PATH_NOT_ABSOLUTE;
8142 }
8143
8144 /* If there is a usershare prefix deny list ensure one of these paths
8145 doesn't match the start of the user given path. */
8146 if (prefixdenylist) {
8147 int i;
8148 for ( i=0; prefixdenylist[i]; i++ ) {
8149 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8150 servicename, i, prefixdenylist[i], sharepath ));
8151 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8152 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8153 "usershare prefix deny list entries.\n",
8154 servicename, sharepath));
8155 return USERSHARE_PATH_IS_DENIED;
8156 }
8157 }
8158 }
8159
8160 /* If there is a usershare prefix allow list ensure one of these paths
8161 does match the start of the user given path. */
8162
8163 if (prefixallowlist) {
8164 int i;
8165 for ( i=0; prefixallowlist[i]; i++ ) {
8166 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8167 servicename, i, prefixallowlist[i], sharepath ));
8168 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8169 break;
8170 }
8171 }
8172 if (prefixallowlist[i] == NULL) {
8173 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8174 "usershare prefix allow list entries.\n",
8175 servicename, sharepath));
8176 return USERSHARE_PATH_NOT_ALLOWED;
8177 }
8178 }
8179
8180 /* Ensure this is pointing to a directory. */
8181 dp = sys_opendir(sharepath);
8182
8183 if (!dp) {
8184 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8185 servicename, sharepath));
8186 return USERSHARE_PATH_NOT_DIRECTORY;
8187 }
8188
8189 /* Ensure the owner of the usershare file has permission to share
8190 this directory. */
8191
8192 if (sys_stat(sharepath, &sbuf) == -1) {
8193 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8194 servicename, sharepath, strerror(errno) ));
8195 sys_closedir(dp);
8196 return USERSHARE_POSIX_ERR;
8197 }
8198
8199 sys_closedir(dp);
8200
8201 if (!S_ISDIR(sbuf.st_mode)) {
8202 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8203 servicename, sharepath ));
8204 return USERSHARE_PATH_NOT_DIRECTORY;
8205 }
8206
8207 /* Check if sharing is restricted to owner-only. */
8208 /* psbuf is the stat of the usershare definition file,
8209 sbuf is the stat of the target directory to be shared. */
8210
8211 if (lp_usershare_owner_only()) {
8212 /* root can share anything. */
8213 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8214 return USERSHARE_PATH_NOT_ALLOWED;
8215 }
8216 }
8217
8218 *pp_sharepath = sharepath;
8219 *pp_comment = comment;
8220 return USERSHARE_OK;
8221}
8222
8223/***************************************************************************
8224 Deal with a usershare file.
8225 Returns:
8226 >= 0 - snum
8227 -1 - Bad name, invalid contents.
8228 - service name already existed and not a usershare, problem
8229 with permissions to share directory etc.
8230***************************************************************************/
8231
8232static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8233{
8234 SMB_STRUCT_STAT sbuf;
8235 SMB_STRUCT_STAT lsbuf;
8236 char *fname = NULL;
8237 char *sharepath = NULL;
8238 char *comment = NULL;
8239 fstring service_name;
8240 char **lines = NULL;
8241 int numlines = 0;
8242 int fd = -1;
8243 int iService = -1;
8244 TALLOC_CTX *ctx = NULL;
8245 SEC_DESC *psd = NULL;
8246 bool guest_ok = False;
8247
8248 /* Ensure share name doesn't contain invalid characters. */
8249 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8250 DEBUG(0,("process_usershare_file: share name %s contains "
8251 "invalid characters (any of %s)\n",
8252 file_name, INVALID_SHARENAME_CHARS ));
8253 return -1;
8254 }
8255
8256 fstrcpy(service_name, file_name);
8257
8258 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8259 }
8260
8261 /* Minimize the race condition by doing an lstat before we
8262 open and fstat. Ensure this isn't a symlink link. */
8263
8264 if (sys_lstat(fname, &lsbuf) != 0) {
8265 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8266 fname, strerror(errno) ));
8267 SAFE_FREE(fname);
8268 return -1;
8269 }
8270
8271 /* This must be a regular file, not a symlink, directory or
8272 other strange filetype. */
8273 if (!check_usershare_stat(fname, &lsbuf)) {
8274 SAFE_FREE(fname);
8275 return -1;
8276 }
8277
8278 {
8279 char *canon_name = canonicalize_servicename(service_name);
8280 TDB_DATA data = dbwrap_fetch_bystring(
8281 ServiceHash, canon_name, canon_name);
8282
8283 iService = -1;
8284
8285 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8286 iService = *(int *)data.dptr;
8287 }
8288 TALLOC_FREE(canon_name);
8289 }
8290
8291 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8292 /* Nothing changed - Mark valid and return. */
8293 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8294 service_name ));
8295 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8296 SAFE_FREE(fname);
8297 return iService;
8298 }
8299
8300 /* Try and open the file read only - no symlinks allowed. */
8301#ifdef O_NOFOLLOW
8302 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8303#else
8304 fd = sys_open(fname, O_RDONLY, 0);
8305#endif
8306
8307 if (fd == -1) {
8308 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8309 fname, strerror(errno) ));
8310 SAFE_FREE(fname);
8311 return -1;
8312 }
8313
8314 /* Now fstat to be *SURE* it's a regular file. */
8315 if (sys_fstat(fd, &sbuf) != 0) {
8316 close(fd);
8317 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8318 fname, strerror(errno) ));
8319 SAFE_FREE(fname);
8320 return -1;
8321 }
8322
8323 /* Is it the same dev/inode as was lstated ? */
8324 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8325 close(fd);
8326 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8327 "Symlink spoofing going on ?\n", fname ));
8328 SAFE_FREE(fname);
8329 return -1;
8330 }
8331
8332 /* This must be a regular file, not a symlink, directory or
8333 other strange filetype. */
8334 if (!check_usershare_stat(fname, &sbuf)) {
8335 SAFE_FREE(fname);
8336 return -1;
8337 }
8338
8339 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8340
8341 close(fd);
8342 if (lines == NULL) {
8343 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8344 fname, (unsigned int)sbuf.st_uid ));
8345 SAFE_FREE(fname);
8346 return -1;
8347 }
8348
8349 SAFE_FREE(fname);
8350
8351 /* Should we allow printers to be shared... ? */
8352 ctx = talloc_init("usershare_sd_xctx");
8353 if (!ctx) {
8354 file_lines_free(lines);
8355 return 1;
8356 }
8357
8358 if (parse_usershare_file(ctx, &sbuf, service_name,
8359 iService, lines, numlines, &sharepath,
8360 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8361 talloc_destroy(ctx);
8362 file_lines_free(lines);
8363 return -1;
8364 }
8365
8366 file_lines_free(lines);
8367
8368 /* Everything ok - add the service possibly using a template. */
8369 if (iService < 0) {
8370 const struct service *sp = &sDefault;
8371 if (snum_template != -1) {
8372 sp = ServicePtrs[snum_template];
8373 }
8374
8375 if ((iService = add_a_service(sp, service_name)) < 0) {
8376 DEBUG(0, ("process_usershare_file: Failed to add "
8377 "new service %s\n", service_name));
8378 talloc_destroy(ctx);
8379 return -1;
8380 }
8381
8382 /* Read only is controlled by usershare ACL below. */
8383 ServicePtrs[iService]->bRead_only = False;
8384 }
8385
8386 /* Write the ACL of the new/modified share. */
8387 if (!set_share_security(service_name, psd)) {
8388 DEBUG(0, ("process_usershare_file: Failed to set share "
8389 "security for user share %s\n",
8390 service_name ));
8391 lp_remove_service(iService);
8392 talloc_destroy(ctx);
8393 return -1;
8394 }
8395
8396 /* If from a template it may be marked invalid. */
8397 ServicePtrs[iService]->valid = True;
8398
8399 /* Set the service as a valid usershare. */
8400 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8401
8402 /* Set guest access. */
8403 if (lp_usershare_allow_guests()) {
8404 ServicePtrs[iService]->bGuest_ok = guest_ok;
8405 }
8406
8407 /* And note when it was loaded. */
8408 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8409 string_set(&ServicePtrs[iService]->szPath, sharepath);
8410 string_set(&ServicePtrs[iService]->comment, comment);
8411
8412 talloc_destroy(ctx);
8413
8414 return iService;
8415}
8416
8417/***************************************************************************
8418 Checks if a usershare entry has been modified since last load.
8419***************************************************************************/
8420
8421static bool usershare_exists(int iService, time_t *last_mod)
8422{
8423 SMB_STRUCT_STAT lsbuf;
8424 const char *usersharepath = Globals.szUsersharePath;
8425 char *fname;
8426
8427 if (asprintf(&fname, "%s/%s",
8428 usersharepath,
8429 ServicePtrs[iService]->szService) < 0) {
8430 return false;
8431 }
8432
8433 if (sys_lstat(fname, &lsbuf) != 0) {
8434 SAFE_FREE(fname);
8435 return false;
8436 }
8437
8438 if (!S_ISREG(lsbuf.st_mode)) {
8439 SAFE_FREE(fname);
8440 return false;
8441 }
8442
8443 SAFE_FREE(fname);
8444 *last_mod = lsbuf.st_mtime;
8445 return true;
8446}
8447
8448/***************************************************************************
8449 Load a usershare service by name. Returns a valid servicenumber or -1.
8450***************************************************************************/
8451
8452int load_usershare_service(const char *servicename)
8453{
8454 SMB_STRUCT_STAT sbuf;
8455 const char *usersharepath = Globals.szUsersharePath;
8456 int max_user_shares = Globals.iUsershareMaxShares;
8457 int snum_template = -1;
8458
8459 if (*usersharepath == 0 || max_user_shares == 0) {
8460 return -1;
8461 }
8462
8463 if (sys_stat(usersharepath, &sbuf) != 0) {
8464 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8465 usersharepath, strerror(errno) ));
8466 return -1;
8467 }
8468
8469 if (!S_ISDIR(sbuf.st_mode)) {
8470 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8471 usersharepath ));
8472 return -1;
8473 }
8474
8475 /*
8476 * This directory must be owned by root, and have the 't' bit set.
8477 * It also must not be writable by "other".
8478 */
8479
8480#ifdef S_ISVTX
8481 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8482#else
8483 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8484#endif
8485 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8486 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8487 usersharepath ));
8488 return -1;
8489 }
8490
8491 /* Ensure the template share exists if it's set. */
8492 if (Globals.szUsershareTemplateShare[0]) {
8493 /* We can't use lp_servicenumber here as we are recommending that
8494 template shares have -valid=False set. */
8495 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8496 if (ServicePtrs[snum_template]->szService &&
8497 strequal(ServicePtrs[snum_template]->szService,
8498 Globals.szUsershareTemplateShare)) {
8499 break;
8500 }
8501 }
8502
8503 if (snum_template == -1) {
8504 DEBUG(0,("load_usershare_service: usershare template share %s "
8505 "does not exist.\n",
8506 Globals.szUsershareTemplateShare ));
8507 return -1;
8508 }
8509 }
8510
8511 return process_usershare_file(usersharepath, servicename, snum_template);
8512}
8513
8514/***************************************************************************
8515 Load all user defined shares from the user share directory.
8516 We only do this if we're enumerating the share list.
8517 This is the function that can delete usershares that have
8518 been removed.
8519***************************************************************************/
8520
8521int load_usershare_shares(void)
8522{
8523 SMB_STRUCT_DIR *dp;
8524 SMB_STRUCT_STAT sbuf;
8525 SMB_STRUCT_DIRENT *de;
8526 int num_usershares = 0;
8527 int max_user_shares = Globals.iUsershareMaxShares;
8528 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8529 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8530 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8531 int iService;
8532 int snum_template = -1;
8533 const char *usersharepath = Globals.szUsersharePath;
8534 int ret = lp_numservices();
8535
8536 if (max_user_shares == 0 || *usersharepath == '\0') {
8537 return lp_numservices();
8538 }
8539
8540 if (sys_stat(usersharepath, &sbuf) != 0) {
8541 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8542 usersharepath, strerror(errno) ));
8543 return ret;
8544 }
8545
8546 /*
8547 * This directory must be owned by root, and have the 't' bit set.
8548 * It also must not be writable by "other".
8549 */
8550
8551#ifdef S_ISVTX
8552 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8553#else
8554 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8555#endif
8556 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8557 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8558 usersharepath ));
8559 return ret;
8560 }
8561
8562 /* Ensure the template share exists if it's set. */
8563 if (Globals.szUsershareTemplateShare[0]) {
8564 /* We can't use lp_servicenumber here as we are recommending that
8565 template shares have -valid=False set. */
8566 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8567 if (ServicePtrs[snum_template]->szService &&
8568 strequal(ServicePtrs[snum_template]->szService,
8569 Globals.szUsershareTemplateShare)) {
8570 break;
8571 }
8572 }
8573
8574 if (snum_template == -1) {
8575 DEBUG(0,("load_usershare_shares: usershare template share %s "
8576 "does not exist.\n",
8577 Globals.szUsershareTemplateShare ));
8578 return ret;
8579 }
8580 }
8581
8582 /* Mark all existing usershares as pending delete. */
8583 for (iService = iNumServices - 1; iService >= 0; iService--) {
8584 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8585 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8586 }
8587 }
8588
8589 dp = sys_opendir(usersharepath);
8590 if (!dp) {
8591 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8592 usersharepath, strerror(errno) ));
8593 return ret;
8594 }
8595
8596 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8597 (de = sys_readdir(dp));
8598 num_dir_entries++ ) {
8599 int r;
8600 const char *n = de->d_name;
8601
8602 /* Ignore . and .. */
8603 if (*n == '.') {
8604 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8605 continue;
8606 }
8607 }
8608
8609 if (n[0] == ':') {
8610 /* Temporary file used when creating a share. */
8611 num_tmp_dir_entries++;
8612 }
8613
8614 /* Allow 20% tmp entries. */
8615 if (num_tmp_dir_entries > allowed_tmp_entries) {
8616 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8617 "in directory %s\n",
8618 num_tmp_dir_entries, usersharepath));
8619 break;
8620 }
8621
8622 r = process_usershare_file(usersharepath, n, snum_template);
8623 if (r == 0) {
8624 /* Update the services count. */
8625 num_usershares++;
8626 if (num_usershares >= max_user_shares) {
8627 DEBUG(0,("load_usershare_shares: max user shares reached "
8628 "on file %s in directory %s\n",
8629 n, usersharepath ));
8630 break;
8631 }
8632 } else if (r == -1) {
8633 num_bad_dir_entries++;
8634 }
8635
8636 /* Allow 20% bad entries. */
8637 if (num_bad_dir_entries > allowed_bad_entries) {
8638 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8639 "in directory %s\n",
8640 num_bad_dir_entries, usersharepath));
8641 break;
8642 }
8643
8644 /* Allow 20% bad entries. */
8645 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8646 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8647 "in directory %s\n",
8648 num_dir_entries, usersharepath));
8649 break;
8650 }
8651 }
8652
8653 sys_closedir(dp);
8654
8655 /* Sweep through and delete any non-refreshed usershares that are
8656 not currently in use. */
8657 for (iService = iNumServices - 1; iService >= 0; iService--) {
8658 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8659 if (conn_snum_used(iService)) {
8660 continue;
8661 }
8662 /* Remove from the share ACL db. */
8663 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8664 lp_servicename(iService) ));
8665 delete_share_security(lp_servicename(iService));
8666 free_service_byindex(iService);
8667 }
8668 }
8669
8670 return lp_numservices();
8671}
8672
8673/********************************************************
8674 Destroy global resources allocated in this file
8675********************************************************/
8676
8677void gfree_loadparm(void)
8678{
8679 struct file_lists *f;
8680 struct file_lists *next;
8681 int i;
8682
8683 /* Free the file lists */
8684
8685 f = file_lists;
8686 while( f ) {
8687 next = f->next;
8688 SAFE_FREE( f->name );
8689 SAFE_FREE( f->subfname );
8690 SAFE_FREE( f );
8691 f = next;
8692 }
8693 file_lists = NULL;
8694
8695 /* Free resources allocated to services */
8696
8697 for ( i = 0; i < iNumServices; i++ ) {
8698 if ( VALID(i) ) {
8699 free_service_byindex(i);
8700 }
8701 }
8702
8703 SAFE_FREE( ServicePtrs );
8704 iNumServices = 0;
8705
8706 /* Now release all resources allocated to global
8707 parameters and the default service */
8708
8709 for (i = 0; parm_table[i].label; i++)
8710 {
8711 if ( parm_table[i].type == P_STRING
8712 || parm_table[i].type == P_USTRING )
8713 {
8714 string_free( (char**)parm_table[i].ptr );
8715 }
8716 else if (parm_table[i].type == P_LIST) {
8717 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8718 }
8719 }
8720}
8721
8722
8723/***************************************************************************
8724 Allow client apps to specify that they are a client
8725***************************************************************************/
8726void lp_set_in_client(bool b)
8727{
8728 in_client = b;
8729}
8730
8731
8732/***************************************************************************
8733 Determine if we're running in a client app
8734***************************************************************************/
8735bool lp_is_in_client(void)
8736{
8737 return in_client;
8738}
8739
8740
8741
8742
8743/***************************************************************************
8744 Load the services array from the services file. Return True on success,
8745 False on failure.
8746***************************************************************************/
8747
8748bool lp_load_ex(const char *pszFname,
8749 bool global_only,
8750 bool save_defaults,
8751 bool add_ipc,
8752 bool initialize_globals,
8753 bool allow_include_registry,
8754 bool allow_registry_shares)
8755{
8756 char *n2 = NULL;
8757 bool bRetval;
8758 param_opt_struct *data, *pdata;
8759
8760 bRetval = False;
8761
8762 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8763
8764 bInGlobalSection = True;
8765 bGlobalOnly = global_only;
8766 bAllowIncludeRegistry = allow_include_registry;
8767
8768 init_globals(! initialize_globals);
8769 debug_init();
8770
8771 if (save_defaults) {
8772 init_locals();
8773 lp_save_defaults();
8774 }
8775
8776 /* We get sections first, so have to start 'behind' to make up */
8777 iServiceIndex = -1;
8778
8779 if (Globals.param_opt != NULL) {
8780 data = Globals.param_opt;
8781 while (data) {
8782 string_free(&data->key);
8783 string_free(&data->value);
8784 TALLOC_FREE(data->list);
8785 pdata = data->next;
8786 SAFE_FREE(data);
8787 data = pdata;
8788 }
8789 Globals.param_opt = NULL;
8790 }
8791
8792 if (lp_config_backend_is_file()) {
8793 n2 = alloc_sub_basic(get_current_username(),
8794 current_user_info.domain,
8795 pszFname);
8796 if (!n2) {
8797 smb_panic("lp_load_ex: out of memory");
8798 }
8799
8800 add_to_file_list(pszFname, n2);
8801
8802 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8803 SAFE_FREE(n2);
8804
8805 /* finish up the last section */
8806 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8807 if (bRetval) {
8808 if (iServiceIndex >= 0) {
8809 bRetval = service_ok(iServiceIndex);
8810 }
8811 }
8812
8813 if (lp_config_backend_is_registry()) {
8814 /* config backend changed to registry in config file */
8815 /*
8816 * We need to use this extra global variable here to
8817 * survive restart: init_globals uses this as a default
8818 * for ConfigBackend. Otherwise, init_globals would
8819 * send us into an endless loop here.
8820 */
8821 config_backend = CONFIG_BACKEND_REGISTRY;
8822 /* start over */
8823 DEBUG(1, ("lp_load_ex: changing to config backend "
8824 "registry\n"));
8825 init_globals(false);
8826 lp_kill_all_services();
8827 return lp_load_ex(pszFname, global_only, save_defaults,
8828 add_ipc, initialize_globals,
8829 allow_include_registry,
8830 allow_registry_shares);
8831 }
8832 } else if (lp_config_backend_is_registry()) {
8833 bRetval = process_registry_globals();
8834 } else {
8835 DEBUG(0, ("Illegal config backend given: %d\n",
8836 lp_config_backend()));
8837 bRetval = false;
8838 }
8839
8840 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8841 bRetval = process_registry_shares();
8842 }
8843
8844 lp_add_auto_services(lp_auto_services());
8845
8846 if (add_ipc) {
8847 /* When 'restrict anonymous = 2' guest connections to ipc$
8848 are denied */
8849 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8850 if ( lp_enable_asu_support() ) {
8851 lp_add_ipc("ADMIN$", false);
8852 }
8853 }
8854
8855 set_server_role();
8856 set_default_server_announce_type();
8857 set_allowed_client_auth();
8858
8859 bLoaded = True;
8860
8861 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8862 /* if bWINSsupport is true and we are in the client */
8863 if (lp_is_in_client() && Globals.bWINSsupport) {
8864 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8865 }
8866
8867 init_iconv();
8868
8869 bAllowIncludeRegistry = true;
8870
8871 return (bRetval);
8872}
8873
8874bool lp_load(const char *pszFname,
8875 bool global_only,
8876 bool save_defaults,
8877 bool add_ipc,
8878 bool initialize_globals)
8879{
8880 return lp_load_ex(pszFname,
8881 global_only,
8882 save_defaults,
8883 add_ipc,
8884 initialize_globals,
8885 true, false);
8886}
8887
8888bool lp_load_initial_only(const char *pszFname)
8889{
8890 return lp_load_ex(pszFname,
8891 true,
8892 false,
8893 false,
8894 true,
8895 false,
8896 false);
8897}
8898
8899bool lp_load_with_registry_shares(const char *pszFname,
8900 bool global_only,
8901 bool save_defaults,
8902 bool add_ipc,
8903 bool initialize_globals)
8904{
8905 return lp_load_ex(pszFname,
8906 global_only,
8907 save_defaults,
8908 add_ipc,
8909 initialize_globals,
8910 true,
8911 true);
8912}
8913
8914/***************************************************************************
8915 Return the max number of services.
8916***************************************************************************/
8917
8918int lp_numservices(void)
8919{
8920 return (iNumServices);
8921}
8922
8923/***************************************************************************
8924Display the contents of the services array in human-readable form.
8925***************************************************************************/
8926
8927void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8928{
8929 int iService;
8930
8931 if (show_defaults)
8932 defaults_saved = False;
8933
8934 dump_globals(f);
8935
8936 dump_a_service(&sDefault, f);
8937
8938 for (iService = 0; iService < maxtoprint; iService++) {
8939 fprintf(f,"\n");
8940 lp_dump_one(f, show_defaults, iService);
8941 }
8942}
8943
8944/***************************************************************************
8945Display the contents of one service in human-readable form.
8946***************************************************************************/
8947
8948void lp_dump_one(FILE * f, bool show_defaults, int snum)
8949{
8950 if (VALID(snum)) {
8951 if (ServicePtrs[snum]->szService[0] == '\0')
8952 return;
8953 dump_a_service(ServicePtrs[snum], f);
8954 }
8955}
8956
8957/***************************************************************************
8958Return the number of the service with the given name, or -1 if it doesn't
8959exist. Note that this is a DIFFERENT ANIMAL from the internal function
8960getservicebyname()! This works ONLY if all services have been loaded, and
8961does not copy the found service.
8962***************************************************************************/
8963
8964int lp_servicenumber(const char *pszServiceName)
8965{
8966 int iService;
8967 fstring serviceName;
8968
8969 if (!pszServiceName) {
8970 return GLOBAL_SECTION_SNUM;
8971 }
8972
8973 for (iService = iNumServices - 1; iService >= 0; iService--) {
8974 if (VALID(iService) && ServicePtrs[iService]->szService) {
8975 /*
8976 * The substitution here is used to support %U is
8977 * service names
8978 */
8979 fstrcpy(serviceName, ServicePtrs[iService]->szService);
8980 standard_sub_basic(get_current_username(),
8981 current_user_info.domain,
8982 serviceName,sizeof(serviceName));
8983 if (strequal(serviceName, pszServiceName)) {
8984 break;
8985 }
8986 }
8987 }
8988
8989 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
8990 time_t last_mod;
8991
8992 if (!usershare_exists(iService, &last_mod)) {
8993 /* Remove the share security tdb entry for it. */
8994 delete_share_security(lp_servicename(iService));
8995 /* Remove it from the array. */
8996 free_service_byindex(iService);
8997 /* Doesn't exist anymore. */
8998 return GLOBAL_SECTION_SNUM;
8999 }
9000
9001 /* Has it been modified ? If so delete and reload. */
9002 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9003 /* Remove it from the array. */
9004 free_service_byindex(iService);
9005 /* and now reload it. */
9006 iService = load_usershare_service(pszServiceName);
9007 }
9008 }
9009
9010 if (iService < 0) {
9011 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9012 return GLOBAL_SECTION_SNUM;
9013 }
9014
9015 return (iService);
9016}
9017
9018bool share_defined(const char *service_name)
9019{
9020 return (lp_servicenumber(service_name) != -1);
9021}
9022
9023struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9024 const char *sharename)
9025{
9026 struct share_params *result;
9027 char *sname;
9028 int snum;
9029
9030 if (!(sname = SMB_STRDUP(sharename))) {
9031 return NULL;
9032 }
9033
9034 snum = find_service(sname);
9035 SAFE_FREE(sname);
9036
9037 if (snum < 0) {
9038 return NULL;
9039 }
9040
9041 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9042 DEBUG(0, ("talloc failed\n"));
9043 return NULL;
9044 }
9045
9046 result->service = snum;
9047 return result;
9048}
9049
9050struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9051{
9052 struct share_iterator *result;
9053
9054 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9055 DEBUG(0, ("talloc failed\n"));
9056 return NULL;
9057 }
9058
9059 result->next_id = 0;
9060 return result;
9061}
9062
9063struct share_params *next_share(struct share_iterator *list)
9064{
9065 struct share_params *result;
9066
9067 while (!lp_snum_ok(list->next_id) &&
9068 (list->next_id < lp_numservices())) {
9069 list->next_id += 1;
9070 }
9071
9072 if (list->next_id >= lp_numservices()) {
9073 return NULL;
9074 }
9075
9076 if (!(result = TALLOC_P(list, struct share_params))) {
9077 DEBUG(0, ("talloc failed\n"));
9078 return NULL;
9079 }
9080
9081 result->service = list->next_id;
9082 list->next_id += 1;
9083 return result;
9084}
9085
9086struct share_params *next_printer(struct share_iterator *list)
9087{
9088 struct share_params *result;
9089
9090 while ((result = next_share(list)) != NULL) {
9091 if (lp_print_ok(result->service)) {
9092 break;
9093 }
9094 }
9095 return result;
9096}
9097
9098/*
9099 * This is a hack for a transition period until we transformed all code from
9100 * service numbers to struct share_params.
9101 */
9102
9103struct share_params *snum2params_static(int snum)
9104{
9105 static struct share_params result;
9106 result.service = snum;
9107 return &result;
9108}
9109
9110/*******************************************************************
9111 A useful volume label function.
9112********************************************************************/
9113
9114const char *volume_label(int snum)
9115{
9116 char *ret;
9117 const char *label = lp_volume(snum);
9118 if (!*label) {
9119 label = lp_servicename(snum);
9120 }
9121
9122 /* This returns a 33 byte guarenteed null terminated string. */
9123 ret = talloc_strndup(talloc_tos(), label, 32);
9124 if (!ret) {
9125 return "";
9126 }
9127 return ret;
9128}
9129
9130/*******************************************************************
9131 Set the server type we will announce as via nmbd.
9132********************************************************************/
9133
9134static void set_default_server_announce_type(void)
9135{
9136 default_server_announce = 0;
9137 default_server_announce |= SV_TYPE_WORKSTATION;
9138 default_server_announce |= SV_TYPE_SERVER;
9139 default_server_announce |= SV_TYPE_SERVER_UNIX;
9140
9141 /* note that the flag should be set only if we have a
9142 printer service but nmbd doesn't actually load the
9143 services so we can't tell --jerry */
9144
9145 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9146
9147 switch (lp_announce_as()) {
9148 case ANNOUNCE_AS_NT_SERVER:
9149 default_server_announce |= SV_TYPE_SERVER_NT;
9150 /* fall through... */
9151 case ANNOUNCE_AS_NT_WORKSTATION:
9152 default_server_announce |= SV_TYPE_NT;
9153 break;
9154 case ANNOUNCE_AS_WIN95:
9155 default_server_announce |= SV_TYPE_WIN95_PLUS;
9156 break;
9157 case ANNOUNCE_AS_WFW:
9158 default_server_announce |= SV_TYPE_WFW;
9159 break;
9160 default:
9161 break;
9162 }
9163
9164 switch (lp_server_role()) {
9165 case ROLE_DOMAIN_MEMBER:
9166 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9167 break;
9168 case ROLE_DOMAIN_PDC:
9169 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9170 break;
9171 case ROLE_DOMAIN_BDC:
9172 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9173 break;
9174 case ROLE_STANDALONE:
9175 default:
9176 break;
9177 }
9178 if (lp_time_server())
9179 default_server_announce |= SV_TYPE_TIME_SOURCE;
9180
9181 if (lp_host_msdfs())
9182 default_server_announce |= SV_TYPE_DFS_SERVER;
9183}
9184
9185/***********************************************************
9186 returns role of Samba server
9187************************************************************/
9188
9189int lp_server_role(void)
9190{
9191 return server_role;
9192}
9193
9194/***********************************************************
9195 If we are PDC then prefer us as DMB
9196************************************************************/
9197
9198bool lp_domain_master(void)
9199{
9200 if (Globals.iDomainMaster == Auto)
9201 return (lp_server_role() == ROLE_DOMAIN_PDC);
9202
9203 return (bool)Globals.iDomainMaster;
9204}
9205
9206/***********************************************************
9207 If we are DMB then prefer us as LMB
9208************************************************************/
9209
9210bool lp_preferred_master(void)
9211{
9212 if (Globals.iPreferredMaster == Auto)
9213 return (lp_local_master() && lp_domain_master());
9214
9215 return (bool)Globals.iPreferredMaster;
9216}
9217
9218/*******************************************************************
9219 Remove a service.
9220********************************************************************/
9221
9222void lp_remove_service(int snum)
9223{
9224 ServicePtrs[snum]->valid = False;
9225 invalid_services[num_invalid_services++] = snum;
9226}
9227
9228/*******************************************************************
9229 Copy a service.
9230********************************************************************/
9231
9232void lp_copy_service(int snum, const char *new_name)
9233{
9234 do_section(new_name, NULL);
9235 if (snum >= 0) {
9236 snum = lp_servicenumber(new_name);
9237 if (snum >= 0)
9238 lp_do_parameter(snum, "copy", lp_servicename(snum));
9239 }
9240}
9241
9242
9243/*******************************************************************
9244 Get the default server type we will announce as via nmbd.
9245********************************************************************/
9246
9247int lp_default_server_announce(void)
9248{
9249 return default_server_announce;
9250}
9251
9252/*******************************************************************
9253 Split the announce version into major and minor numbers.
9254********************************************************************/
9255
9256int lp_major_announce_version(void)
9257{
9258 static bool got_major = False;
9259 static int major_version = DEFAULT_MAJOR_VERSION;
9260 char *vers;
9261 char *p;
9262
9263 if (got_major)
9264 return major_version;
9265
9266 got_major = True;
9267 if ((vers = lp_announce_version()) == NULL)
9268 return major_version;
9269
9270 if ((p = strchr_m(vers, '.')) == 0)
9271 return major_version;
9272
9273 *p = '\0';
9274 major_version = atoi(vers);
9275 return major_version;
9276}
9277
9278int lp_minor_announce_version(void)
9279{
9280 static bool got_minor = False;
9281 static int minor_version = DEFAULT_MINOR_VERSION;
9282 char *vers;
9283 char *p;
9284
9285 if (got_minor)
9286 return minor_version;
9287
9288 got_minor = True;
9289 if ((vers = lp_announce_version()) == NULL)
9290 return minor_version;
9291
9292 if ((p = strchr_m(vers, '.')) == 0)
9293 return minor_version;
9294
9295 p++;
9296 minor_version = atoi(p);
9297 return minor_version;
9298}
9299
9300/***********************************************************
9301 Set the global name resolution order (used in smbclient).
9302************************************************************/
9303
9304void lp_set_name_resolve_order(const char *new_order)
9305{
9306 string_set(&Globals.szNameResolveOrder, new_order);
9307}
9308
9309const char *lp_printername(int snum)
9310{
9311 const char *ret = _lp_printername(snum);
9312 if (ret == NULL || (ret != NULL && *ret == '\0'))
9313 ret = lp_const_servicename(snum);
9314
9315 return ret;
9316}
9317
9318
9319/***********************************************************
9320 Allow daemons such as winbindd to fix their logfile name.
9321************************************************************/
9322
9323void lp_set_logfile(const char *name)
9324{
9325 string_set(&Globals.szLogFile, name);
9326 debug_set_logfile(name);
9327}
9328
9329/*******************************************************************
9330 Return the max print jobs per queue.
9331********************************************************************/
9332
9333int lp_maxprintjobs(int snum)
9334{
9335 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9336 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9337 maxjobs = PRINT_MAX_JOBID - 1;
9338
9339 return maxjobs;
9340}
9341
9342const char *lp_printcapname(void)
9343{
9344 if ((Globals.szPrintcapname != NULL) &&
9345 (Globals.szPrintcapname[0] != '\0'))
9346 return Globals.szPrintcapname;
9347
9348 if (sDefault.iPrinting == PRINT_CUPS) {
9349#ifdef HAVE_CUPS
9350 return "cups";
9351#else
9352 return "lpstat";
9353#endif
9354 }
9355
9356 if (sDefault.iPrinting == PRINT_BSD)
9357 return "/etc/printcap";
9358
9359 return PRINTCAP_NAME;
9360}
9361
9362/*******************************************************************
9363 Ensure we don't use sendfile if server smb signing is active.
9364********************************************************************/
9365
9366static uint32 spoolss_state;
9367
9368bool lp_disable_spoolss( void )
9369{
9370 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9371 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9372
9373 return spoolss_state == SVCCTL_STOPPED ? True : False;
9374}
9375
9376void lp_set_spoolss_state( uint32 state )
9377{
9378 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9379
9380 spoolss_state = state;
9381}
9382
9383uint32 lp_get_spoolss_state( void )
9384{
9385 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9386}
9387
9388/*******************************************************************
9389 Ensure we don't use sendfile if server smb signing is active.
9390********************************************************************/
9391
9392bool lp_use_sendfile(int snum)
9393{
9394 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9395 if (Protocol < PROTOCOL_NT1) {
9396 return False;
9397 }
9398 return (_lp_use_sendfile(snum) &&
9399 (get_remote_arch() != RA_WIN95) &&
9400 !srv_is_signing_active());
9401}
9402
9403/*******************************************************************
9404 Turn off sendfile if we find the underlying OS doesn't support it.
9405********************************************************************/
9406
9407void set_use_sendfile(int snum, bool val)
9408{
9409 if (LP_SNUM_OK(snum))
9410 ServicePtrs[snum]->bUseSendfile = val;
9411 else
9412 sDefault.bUseSendfile = val;
9413}
9414
9415/*******************************************************************
9416 Turn off storing DOS attributes if this share doesn't support it.
9417********************************************************************/
9418
9419void set_store_dos_attributes(int snum, bool val)
9420{
9421 if (!LP_SNUM_OK(snum))
9422 return;
9423 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9424}
9425
9426void lp_set_mangling_method(const char *new_method)
9427{
9428 string_set(&Globals.szManglingMethod, new_method);
9429}
9430
9431/*******************************************************************
9432 Global state for POSIX pathname processing.
9433********************************************************************/
9434
9435static bool posix_pathnames;
9436
9437bool lp_posix_pathnames(void)
9438{
9439 return posix_pathnames;
9440}
9441
9442/*******************************************************************
9443 Change everything needed to ensure POSIX pathname processing (currently
9444 not much).
9445********************************************************************/
9446
9447void lp_set_posix_pathnames(void)
9448{
9449 posix_pathnames = True;
9450}
9451
9452/*******************************************************************
9453 Global state for POSIX lock processing - CIFS unix extensions.
9454********************************************************************/
9455
9456bool posix_default_lock_was_set;
9457static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9458
9459enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9460{
9461 if (posix_default_lock_was_set) {
9462 return posix_cifsx_locktype;
9463 } else {
9464 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9465 }
9466}
9467
9468/*******************************************************************
9469********************************************************************/
9470
9471void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9472{
9473 posix_default_lock_was_set = True;
9474 posix_cifsx_locktype = val;
9475}
9476
9477int lp_min_receive_file_size(void)
9478{
9479 if (Globals.iminreceivefile < 0) {
9480 return 0;
9481 }
9482 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9483}
Note: See TracBrowser for help on using the repository browser.