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

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

Update 3.2 branch to 3.2.6

File size: 251.4 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_nis_home_map_name, &Globals.szNISHomeMapName)
4999static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5000FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5001/* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5002 * lp_passdb_backend() should be replace by the this macro again after
5003 * some releases.
5004 * */
5005const char *lp_passdb_backend(void)
5006{
5007 char *delim, *quote;
5008
5009 delim = strchr( Globals.szPassdbBackend, ' ');
5010 /* no space at all */
5011 if (delim == NULL) {
5012 goto out;
5013 }
5014
5015 quote = strchr(Globals.szPassdbBackend, '"');
5016 /* no quote char or non in the first part */
5017 if (quote == NULL || quote > delim) {
5018 *delim = '\0';
5019 goto warn;
5020 }
5021
5022 quote = strchr(quote+1, '"');
5023 if (quote == NULL) {
5024 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5025 goto out;
5026 } else if (*(quote+1) == '\0') {
5027 /* space, fitting quote char, and one backend only */
5028 goto out;
5029 } else {
5030 /* terminate string after the fitting quote char */
5031 *(quote+1) = '\0';
5032 }
5033
5034warn:
5035 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5036 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5037 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5038 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5039
5040out:
5041 return Globals.szPassdbBackend;
5042}
5043FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5044FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5045FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5046FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5047FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5048
5049FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5050FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5051FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5052FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5053FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5054FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5055
5056FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5057
5058FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5059FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5060FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5061
5062FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5063
5064FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5065FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5066FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5067FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5068FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5069FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5070FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5071FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5072FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5073FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5074FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5075FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5076FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5077FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5078FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5079
5080FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
5081FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
5082FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5083FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5084FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5085FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5086FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5087
5088FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5089FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5090FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5091FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5092FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5093FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5094FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5095FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5096FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5097FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5098FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5099FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5100FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5101FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5102FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5103FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5104FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5105
5106FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5107
5108FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5109FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5110FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5111FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5112FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5113FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5114FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5115FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5116FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5117FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5118FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5119FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5120FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5121FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5122FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5123FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5124FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5125FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5126FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5127FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5128FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5129FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5130FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5131FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5132FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5133FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5134FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5135FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5136FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5137FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5138FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5139FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5140static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5141FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5142FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5143FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5144FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5145FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5146FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5147FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5148FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5149FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5150FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5151FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5152FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5153FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5154FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5155FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5156FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5157FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5158FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5159FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5160FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5161FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5162FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5163FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5164FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5165FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5166FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5167FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5168FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5169FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5170FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5171FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5172FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5173FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5174FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5175FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5176FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5177FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5178FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5179FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5180FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5181FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5182FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5183FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5184FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5185FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5186FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5187FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5188FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5189FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5190FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5191FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5192FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5193FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5194static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5195FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5196FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5197FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5198FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5199FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5200FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5201FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5202FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5203FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5204
5205FN_LOCAL_STRING(lp_preexec, szPreExec)
5206FN_LOCAL_STRING(lp_postexec, szPostExec)
5207FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5208FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5209FN_LOCAL_STRING(lp_servicename, szService)
5210FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5211FN_LOCAL_STRING(lp_pathname, szPath)
5212FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5213FN_LOCAL_STRING(lp_username, szUsername)
5214FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5215FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5216FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5217FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5218FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5219FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5220FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5221FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5222FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5223FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5224FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5225FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5226FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5227FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5228FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5229FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5230FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5231static FN_LOCAL_STRING(_lp_printername, szPrintername)
5232FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5233FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5234FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5235FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5236FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5237FN_LOCAL_STRING(lp_comment, comment)
5238FN_LOCAL_STRING(lp_force_user, force_user)
5239FN_LOCAL_STRING(lp_force_group, force_group)
5240FN_LOCAL_LIST(lp_readlist, readlist)
5241FN_LOCAL_LIST(lp_writelist, writelist)
5242FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5243FN_LOCAL_STRING(lp_fstype, fstype)
5244FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5245FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5246static FN_LOCAL_STRING(lp_volume, volume)
5247FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5248FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5249FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5250FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5251FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5252FN_LOCAL_STRING(lp_dfree_command, szDfree)
5253FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5254FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5255FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5256FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5257FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5258FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5259FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5260FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5261FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5262FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5263FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5264FN_LOCAL_BOOL(lp_readonly, bRead_only)
5265FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5266FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5267FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5268FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5269FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5270FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5271FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5272FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5273FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5274FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5275FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5276FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5277FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5278FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5279FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5280FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5281FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5282FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5283FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5284FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5285FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5286FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5287FN_LOCAL_BOOL(lp_map_system, bMap_system)
5288FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5289FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5290FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5291FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5292FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5293FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5294FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5295FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5296FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5297FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5298FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5299FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5300FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5301FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5302FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5303FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5304FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5305FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5306FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5307FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5308FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5309FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5310FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5311FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5312FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5313FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5314FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5315FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5316FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5317FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5318FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5319FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5320FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5321FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5322FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5323FN_LOCAL_INTEGER(lp_printing, iPrinting)
5324FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5325FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5326FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5327FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5328FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5329FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5330FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5331FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5332FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5333FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5334FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5335FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5336FN_LOCAL_CHAR(lp_magicchar, magic_char)
5337FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5338FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5339FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5340FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5341FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5342FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5343FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5344
5345/* local prototypes */
5346
5347static int map_parameter(const char *pszParmName);
5348static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5349static bool set_boolean(bool *pb, const char *pszParmValue);
5350static const char *get_boolean(bool bool_value);
5351static int getservicebyname(const char *pszServiceName,
5352 struct service *pserviceDest);
5353static void copy_service(struct service *pserviceDest,
5354 struct service *pserviceSource,
5355 struct bitmap *pcopymapDest);
5356static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5357 void *userdata);
5358static bool do_section(const char *pszSectionName, void *userdata);
5359static void init_copymap(struct service *pservice);
5360static bool hash_a_service(const char *name, int number);
5361static void free_service_byindex(int iService);
5362static char * canonicalize_servicename(const char *name);
5363static void show_parameter(int parmIndex);
5364static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5365
5366/* This is a helper function for parametrical options support. */
5367/* It returns a pointer to parametrical option value if it exists or NULL otherwise */
5368/* Actual parametrical functions are quite simple */
5369static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
5370{
5371 bool global_section = False;
5372 char* param_key;
5373 param_opt_struct *data;
5374
5375 if (snum >= iNumServices) return NULL;
5376
5377 if (snum < 0) {
5378 data = Globals.param_opt;
5379 global_section = True;
5380 } else {
5381 data = ServicePtrs[snum]->param_opt;
5382 }
5383
5384 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5385 DEBUG(0,("asprintf failed!\n"));
5386 return NULL;
5387 }
5388
5389 while (data) {
5390 if (strcmp(data->key, param_key) == 0) {
5391 string_free(&param_key);
5392 return data;
5393 }
5394 data = data->next;
5395 }
5396
5397 if (!global_section) {
5398 /* Try to fetch the same option but from globals */
5399 /* but only if we are not already working with Globals */
5400 data = Globals.param_opt;
5401 while (data) {
5402 if (strcmp(data->key, param_key) == 0) {
5403 string_free(&param_key);
5404 return data;
5405 }
5406 data = data->next;
5407 }
5408 }
5409
5410 string_free(&param_key);
5411
5412 return NULL;
5413}
5414
5415
5416#define MISSING_PARAMETER(name) \
5417 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5418
5419/*******************************************************************
5420convenience routine to return int parameters.
5421********************************************************************/
5422static int lp_int(const char *s)
5423{
5424
5425 if (!s || !*s) {
5426 MISSING_PARAMETER(lp_int);
5427 return (-1);
5428 }
5429
5430 return (int)strtol(s, NULL, 0);
5431}
5432
5433/*******************************************************************
5434convenience routine to return unsigned long parameters.
5435********************************************************************/
5436static unsigned long lp_ulong(const char *s)
5437{
5438
5439 if (!s || !*s) {
5440 MISSING_PARAMETER(lp_ulong);
5441 return (0);
5442 }
5443
5444 return strtoul(s, NULL, 0);
5445}
5446
5447/*******************************************************************
5448convenience routine to return boolean parameters.
5449********************************************************************/
5450static bool lp_bool(const char *s)
5451{
5452 bool ret = False;
5453
5454 if (!s || !*s) {
5455 MISSING_PARAMETER(lp_bool);
5456 return False;
5457 }
5458
5459 if (!set_boolean(&ret,s)) {
5460 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5461 return False;
5462 }
5463
5464 return ret;
5465}
5466
5467/*******************************************************************
5468convenience routine to return enum parameters.
5469********************************************************************/
5470static int lp_enum(const char *s,const struct enum_list *_enum)
5471{
5472 int i;
5473
5474 if (!s || !*s || !_enum) {
5475 MISSING_PARAMETER(lp_enum);
5476 return (-1);
5477 }
5478
5479 for (i=0; _enum[i].name; i++) {
5480 if (strequal(_enum[i].name,s))
5481 return _enum[i].value;
5482 }
5483
5484 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5485 return (-1);
5486}
5487
5488#undef MISSING_PARAMETER
5489
5490/* DO NOT USE lp_parm_string ANYMORE!!!!
5491 * use lp_parm_const_string or lp_parm_talloc_string
5492 *
5493 * lp_parm_string is only used to let old modules find this symbol
5494 */
5495#undef lp_parm_string
5496 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5497 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5498{
5499 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5500}
5501
5502/* Return parametric option from a given service. Type is a part of option before ':' */
5503/* Parametric option has following syntax: 'Type: option = value' */
5504/* the returned value is talloced on the talloc_tos() */
5505char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5506{
5507 param_opt_struct *data = get_parametrics(snum, type, option);
5508
5509 if (data == NULL||data->value==NULL) {
5510 if (def) {
5511 return lp_string(def);
5512 } else {
5513 return NULL;
5514 }
5515 }
5516
5517 return lp_string(data->value);
5518}
5519
5520/* Return parametric option from a given service. Type is a part of option before ':' */
5521/* Parametric option has following syntax: 'Type: option = value' */
5522const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5523{
5524 param_opt_struct *data = get_parametrics(snum, type, option);
5525
5526 if (data == NULL||data->value==NULL)
5527 return def;
5528
5529 return data->value;
5530}
5531
5532/* Return parametric option from a given service. Type is a part of option before ':' */
5533/* Parametric option has following syntax: 'Type: option = value' */
5534
5535const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5536{
5537 param_opt_struct *data = get_parametrics(snum, type, option);
5538
5539 if (data == NULL||data->value==NULL)
5540 return (const char **)def;
5541
5542 if (data->list==NULL) {
5543 data->list = str_list_make(NULL, data->value, NULL);
5544 }
5545
5546 return (const char **)data->list;
5547}
5548
5549/* Return parametric option from a given service. Type is a part of option before ':' */
5550/* Parametric option has following syntax: 'Type: option = value' */
5551
5552int lp_parm_int(int snum, const char *type, const char *option, int def)
5553{
5554 param_opt_struct *data = get_parametrics(snum, type, option);
5555
5556 if (data && data->value && *data->value)
5557 return lp_int(data->value);
5558
5559 return def;
5560}
5561
5562/* Return parametric option from a given service. Type is a part of option before ':' */
5563/* Parametric option has following syntax: 'Type: option = value' */
5564
5565unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5566{
5567 param_opt_struct *data = get_parametrics(snum, type, option);
5568
5569 if (data && data->value && *data->value)
5570 return lp_ulong(data->value);
5571
5572 return def;
5573}
5574
5575/* Return parametric option from a given service. Type is a part of option before ':' */
5576/* Parametric option has following syntax: 'Type: option = value' */
5577
5578bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5579{
5580 param_opt_struct *data = get_parametrics(snum, type, option);
5581
5582 if (data && data->value && *data->value)
5583 return lp_bool(data->value);
5584
5585 return def;
5586}
5587
5588/* Return parametric option from a given service. Type is a part of option before ':' */
5589/* Parametric option has following syntax: 'Type: option = value' */
5590
5591int lp_parm_enum(int snum, const char *type, const char *option,
5592 const struct enum_list *_enum, int def)
5593{
5594 param_opt_struct *data = get_parametrics(snum, type, option);
5595
5596 if (data && data->value && *data->value && _enum)
5597 return lp_enum(data->value, _enum);
5598
5599 return def;
5600}
5601
5602
5603/***************************************************************************
5604 Initialise a service to the defaults.
5605***************************************************************************/
5606
5607static void init_service(struct service *pservice)
5608{
5609 memset((char *)pservice, '\0', sizeof(struct service));
5610 copy_service(pservice, &sDefault, NULL);
5611}
5612
5613/***************************************************************************
5614 Free the dynamically allocated parts of a service struct.
5615***************************************************************************/
5616
5617static void free_service(struct service *pservice)
5618{
5619 int i;
5620 param_opt_struct *data, *pdata;
5621 if (!pservice)
5622 return;
5623
5624 if (pservice->szService)
5625 DEBUG(5, ("free_service: Freeing service %s\n",
5626 pservice->szService));
5627
5628 string_free(&pservice->szService);
5629 bitmap_free(pservice->copymap);
5630
5631 for (i = 0; parm_table[i].label; i++) {
5632 if ((parm_table[i].type == P_STRING ||
5633 parm_table[i].type == P_USTRING) &&
5634 parm_table[i].p_class == P_LOCAL)
5635 string_free((char **)
5636 (((char *)pservice) +
5637 PTR_DIFF(parm_table[i].ptr, &sDefault)));
5638 else if (parm_table[i].type == P_LIST &&
5639 parm_table[i].p_class == P_LOCAL)
5640 TALLOC_FREE(*((char ***)
5641 (((char *)pservice) +
5642 PTR_DIFF(parm_table[i].ptr,
5643 &sDefault))));
5644 }
5645
5646 data = pservice->param_opt;
5647 if (data)
5648 DEBUG(5,("Freeing parametrics:\n"));
5649 while (data) {
5650 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5651 string_free(&data->key);
5652 string_free(&data->value);
5653 TALLOC_FREE(data->list);
5654 pdata = data->next;
5655 SAFE_FREE(data);
5656 data = pdata;
5657 }
5658
5659 ZERO_STRUCTP(pservice);
5660}
5661
5662
5663/***************************************************************************
5664 remove a service indexed in the ServicePtrs array from the ServiceHash
5665 and free the dynamically allocated parts
5666***************************************************************************/
5667
5668static void free_service_byindex(int idx)
5669{
5670 if ( !LP_SNUM_OK(idx) )
5671 return;
5672
5673 ServicePtrs[idx]->valid = False;
5674 invalid_services[num_invalid_services++] = idx;
5675
5676 /* we have to cleanup the hash record */
5677
5678 if (ServicePtrs[idx]->szService) {
5679 char *canon_name = canonicalize_servicename(
5680 ServicePtrs[idx]->szService );
5681
5682 dbwrap_delete_bystring(ServiceHash, canon_name );
5683 TALLOC_FREE(canon_name);
5684 }
5685
5686 free_service(ServicePtrs[idx]);
5687}
5688
5689/***************************************************************************
5690 Add a new service to the services array initialising it with the given
5691 service.
5692***************************************************************************/
5693
5694static int add_a_service(const struct service *pservice, const char *name)
5695{
5696 int i;
5697 struct service tservice;
5698 int num_to_alloc = iNumServices + 1;
5699 param_opt_struct *data, *pdata;
5700
5701 tservice = *pservice;
5702
5703 /* it might already exist */
5704 if (name) {
5705 i = getservicebyname(name, NULL);
5706 if (i >= 0) {
5707 /* Clean all parametric options for service */
5708 /* They will be added during parsing again */
5709 data = ServicePtrs[i]->param_opt;
5710 while (data) {
5711 string_free(&data->key);
5712 string_free(&data->value);
5713 TALLOC_FREE(data->list);
5714 pdata = data->next;
5715 SAFE_FREE(data);
5716 data = pdata;
5717 }
5718 ServicePtrs[i]->param_opt = NULL;
5719 return (i);
5720 }
5721 }
5722
5723 /* find an invalid one */
5724 i = iNumServices;
5725 if (num_invalid_services > 0) {
5726 i = invalid_services[--num_invalid_services];
5727 }
5728
5729 /* if not, then create one */
5730 if (i == iNumServices) {
5731 struct service **tsp;
5732 int *tinvalid;
5733
5734 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5735 if (tsp == NULL) {
5736 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5737 return (-1);
5738 }
5739 ServicePtrs = tsp;
5740 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5741 if (!ServicePtrs[iNumServices]) {
5742 DEBUG(0,("add_a_service: out of memory!\n"));
5743 return (-1);
5744 }
5745 iNumServices++;
5746
5747 /* enlarge invalid_services here for now... */
5748 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5749 num_to_alloc);
5750 if (tinvalid == NULL) {
5751 DEBUG(0,("add_a_service: failed to enlarge "
5752 "invalid_services!\n"));
5753 return (-1);
5754 }
5755 invalid_services = tinvalid;
5756 } else {
5757 free_service_byindex(i);
5758 }
5759
5760 ServicePtrs[i]->valid = True;
5761
5762 init_service(ServicePtrs[i]);
5763 copy_service(ServicePtrs[i], &tservice, NULL);
5764 if (name)
5765 string_set(&ServicePtrs[i]->szService, name);
5766
5767 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5768 i, ServicePtrs[i]->szService));
5769
5770 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5771 return (-1);
5772 }
5773
5774 return (i);
5775}
5776
5777/***************************************************************************
5778 Convert a string to uppercase and remove whitespaces.
5779***************************************************************************/
5780
5781static char *canonicalize_servicename(const char *src)
5782{
5783 char *result;
5784
5785 if ( !src ) {
5786 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5787 return NULL;
5788 }
5789
5790 result = talloc_strdup(talloc_tos(), src);
5791 SMB_ASSERT(result != NULL);
5792
5793 strlower_m(result);
5794 return result;
5795}
5796
5797/***************************************************************************
5798 Add a name/index pair for the services array to the hash table.
5799***************************************************************************/
5800
5801static bool hash_a_service(const char *name, int idx)
5802{
5803 char *canon_name;
5804
5805 if ( !ServiceHash ) {
5806 DEBUG(10,("hash_a_service: creating servicehash\n"));
5807 ServiceHash = db_open_rbt(NULL);
5808 if ( !ServiceHash ) {
5809 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5810 return False;
5811 }
5812 }
5813
5814 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5815 idx, name));
5816
5817 canon_name = canonicalize_servicename( name );
5818
5819 dbwrap_store_bystring(ServiceHash, canon_name,
5820 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5821 TDB_REPLACE);
5822
5823 TALLOC_FREE(canon_name);
5824
5825 return True;
5826}
5827
5828/***************************************************************************
5829 Add a new home service, with the specified home directory, defaults coming
5830 from service ifrom.
5831***************************************************************************/
5832
5833bool lp_add_home(const char *pszHomename, int iDefaultService,
5834 const char *user, const char *pszHomedir)
5835{
5836 int i;
5837
5838 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5839
5840 if (i < 0)
5841 return (False);
5842
5843 if (!(*(ServicePtrs[iDefaultService]->szPath))
5844 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5845 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5846 }
5847
5848 if (!(*(ServicePtrs[i]->comment))) {
5849 char *comment = NULL;
5850 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5851 return false;
5852 }
5853 string_set(&ServicePtrs[i]->comment, comment);
5854 SAFE_FREE(comment);
5855 }
5856
5857 /* set the browseable flag from the global default */
5858
5859 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5860
5861 ServicePtrs[i]->autoloaded = True;
5862
5863 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5864 user, ServicePtrs[i]->szPath ));
5865
5866 return (True);
5867}
5868
5869/***************************************************************************
5870 Add a new service, based on an old one.
5871***************************************************************************/
5872
5873int lp_add_service(const char *pszService, int iDefaultService)
5874{
5875 if (iDefaultService < 0) {
5876 return add_a_service(&sDefault, pszService);
5877 }
5878
5879 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5880}
5881
5882/***************************************************************************
5883 Add the IPC service.
5884***************************************************************************/
5885
5886static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5887{
5888 char *comment = NULL;
5889 int i = add_a_service(&sDefault, ipc_name);
5890
5891 if (i < 0)
5892 return (False);
5893
5894 if (asprintf(&comment, "IPC Service (%s)",
5895 Globals.szServerString) < 0) {
5896 return (False);
5897 }
5898
5899 string_set(&ServicePtrs[i]->szPath, tmpdir());
5900 string_set(&ServicePtrs[i]->szUsername, "");
5901 string_set(&ServicePtrs[i]->comment, comment);
5902 string_set(&ServicePtrs[i]->fstype, "IPC");
5903 ServicePtrs[i]->iMaxConnections = 0;
5904 ServicePtrs[i]->bAvailable = True;
5905 ServicePtrs[i]->bRead_only = True;
5906 ServicePtrs[i]->bGuest_only = False;
5907 ServicePtrs[i]->bAdministrative_share = True;
5908 ServicePtrs[i]->bGuest_ok = guest_ok;
5909 ServicePtrs[i]->bPrint_ok = False;
5910 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5911
5912 DEBUG(3, ("adding IPC service\n"));
5913
5914 SAFE_FREE(comment);
5915 return (True);
5916}
5917
5918/***************************************************************************
5919 Add a new printer service, with defaults coming from service iFrom.
5920***************************************************************************/
5921
5922bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5923{
5924 const char *comment = "From Printcap";
5925 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5926
5927 if (i < 0)
5928 return (False);
5929
5930 /* note that we do NOT default the availability flag to True - */
5931 /* we take it from the default service passed. This allows all */
5932 /* dynamic printers to be disabled by disabling the [printers] */
5933 /* entry (if/when the 'available' keyword is implemented!). */
5934
5935 /* the printer name is set to the service name. */
5936 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5937 string_set(&ServicePtrs[i]->comment, comment);
5938
5939 /* set the browseable flag from the gloabl default */
5940 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5941
5942 /* Printers cannot be read_only. */
5943 ServicePtrs[i]->bRead_only = False;
5944 /* No share modes on printer services. */
5945 ServicePtrs[i]->bShareModes = False;
5946 /* No oplocks on printer services. */
5947 ServicePtrs[i]->bOpLocks = False;
5948 /* Printer services must be printable. */
5949 ServicePtrs[i]->bPrint_ok = True;
5950
5951 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5952
5953 return (True);
5954}
5955
5956
5957/***************************************************************************
5958 Check whether the given parameter name is valid.
5959 Parametric options (names containing a colon) are considered valid.
5960***************************************************************************/
5961
5962bool lp_parameter_is_valid(const char *pszParmName)
5963{
5964 return ((map_parameter(pszParmName) != -1) ||
5965 (strchr(pszParmName, ':') != NULL));
5966}
5967
5968/***************************************************************************
5969 Check whether the given name is the name of a global parameter.
5970 Returns True for strings belonging to parameters of class
5971 P_GLOBAL, False for all other strings, also for parametric options
5972 and strings not belonging to any option.
5973***************************************************************************/
5974
5975bool lp_parameter_is_global(const char *pszParmName)
5976{
5977 int num = map_parameter(pszParmName);
5978
5979 if (num >= 0) {
5980 return (parm_table[num].p_class == P_GLOBAL);
5981 }
5982
5983 return False;
5984}
5985
5986/**************************************************************************
5987 Check whether the given name is the canonical name of a parameter.
5988 Returns False if it is not a valid parameter Name.
5989 For parametric options, True is returned.
5990**************************************************************************/
5991
5992bool lp_parameter_is_canonical(const char *parm_name)
5993{
5994 if (!lp_parameter_is_valid(parm_name)) {
5995 return False;
5996 }
5997
5998 return (map_parameter(parm_name) ==
5999 map_parameter_canonical(parm_name, NULL));
6000}
6001
6002/**************************************************************************
6003 Determine the canonical name for a parameter.
6004 Indicate when it is an inverse (boolean) synonym instead of a
6005 "usual" synonym.
6006**************************************************************************/
6007
6008bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6009 bool *inverse)
6010{
6011 int num;
6012
6013 if (!lp_parameter_is_valid(parm_name)) {
6014 *canon_parm = NULL;
6015 return False;
6016 }
6017
6018 num = map_parameter_canonical(parm_name, inverse);
6019 if (num < 0) {
6020 /* parametric option */
6021 *canon_parm = parm_name;
6022 } else {
6023 *canon_parm = parm_table[num].label;
6024 }
6025
6026 return True;
6027
6028}
6029
6030/**************************************************************************
6031 Determine the canonical name for a parameter.
6032 Turn the value given into the inverse boolean expression when
6033 the synonym is an invers boolean synonym.
6034
6035 Return True if parm_name is a valid parameter name and
6036 in case it is an invers boolean synonym, if the val string could
6037 successfully be converted to the reverse bool.
6038 Return false in all other cases.
6039**************************************************************************/
6040
6041bool lp_canonicalize_parameter_with_value(const char *parm_name,
6042 const char *val,
6043 const char **canon_parm,
6044 const char **canon_val)
6045{
6046 int num;
6047 bool inverse;
6048
6049 if (!lp_parameter_is_valid(parm_name)) {
6050 *canon_parm = NULL;
6051 *canon_val = NULL;
6052 return False;
6053 }
6054
6055 num = map_parameter_canonical(parm_name, &inverse);
6056 if (num < 0) {
6057 /* parametric option */
6058 *canon_parm = parm_name;
6059 *canon_val = val;
6060 } else {
6061 *canon_parm = parm_table[num].label;
6062 if (inverse) {
6063 if (!lp_invert_boolean(val, canon_val)) {
6064 *canon_val = NULL;
6065 return False;
6066 }
6067 } else {
6068 *canon_val = val;
6069 }
6070 }
6071
6072 return True;
6073}
6074
6075/***************************************************************************
6076 Map a parameter's string representation to something we can use.
6077 Returns False if the parameter string is not recognised, else TRUE.
6078***************************************************************************/
6079
6080static int map_parameter(const char *pszParmName)
6081{
6082 int iIndex;
6083
6084 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6085 return (-1);
6086
6087 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6088 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6089 return (iIndex);
6090
6091 /* Warn only if it isn't parametric option */
6092 if (strchr(pszParmName, ':') == NULL)
6093 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6094 /* We do return 'fail' for parametric options as well because they are
6095 stored in different storage
6096 */
6097 return (-1);
6098}
6099
6100/***************************************************************************
6101 Map a parameter's string representation to the index of the canonical
6102 form of the parameter (it might be a synonym).
6103 Returns -1 if the parameter string is not recognised.
6104***************************************************************************/
6105
6106static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6107{
6108 int parm_num, canon_num;
6109 bool loc_inverse = False;
6110
6111 parm_num = map_parameter(pszParmName);
6112 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6113 /* invalid, parametric or no canidate for synonyms ... */
6114 goto done;
6115 }
6116
6117 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6118 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6119 parm_num = canon_num;
6120 goto done;
6121 }
6122 }
6123
6124done:
6125 if (inverse != NULL) {
6126 *inverse = loc_inverse;
6127 }
6128 return parm_num;
6129}
6130
6131/***************************************************************************
6132 return true if parameter number parm1 is a synonym of parameter
6133 number parm2 (parm2 being the principal name).
6134 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6135 False otherwise.
6136***************************************************************************/
6137
6138static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6139{
6140 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6141 (parm_table[parm1].flags & FLAG_HIDE) &&
6142 !(parm_table[parm2].flags & FLAG_HIDE))
6143 {
6144 if (inverse != NULL) {
6145 if ((parm_table[parm1].type == P_BOOLREV) &&
6146 (parm_table[parm2].type == P_BOOL))
6147 {
6148 *inverse = True;
6149 } else {
6150 *inverse = False;
6151 }
6152 }
6153 return True;
6154 }
6155 return False;
6156}
6157
6158/***************************************************************************
6159 Show one parameter's name, type, [values,] and flags.
6160 (helper functions for show_parameter_list)
6161***************************************************************************/
6162
6163static void show_parameter(int parmIndex)
6164{
6165 int enumIndex, flagIndex;
6166 int parmIndex2;
6167 bool hadFlag;
6168 bool hadSyn;
6169 bool inverse;
6170 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6171 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6172 "P_ENUM", "P_SEP"};
6173 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6174 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6175 FLAG_HIDE, FLAG_DOS_STRING};
6176 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6177 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6178 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6179
6180 printf("%s=%s", parm_table[parmIndex].label,
6181 type[parm_table[parmIndex].type]);
6182 if (parm_table[parmIndex].type == P_ENUM) {
6183 printf(",");
6184 for (enumIndex=0;
6185 parm_table[parmIndex].enum_list[enumIndex].name;
6186 enumIndex++)
6187 {
6188 printf("%s%s",
6189 enumIndex ? "|" : "",
6190 parm_table[parmIndex].enum_list[enumIndex].name);
6191 }
6192 }
6193 printf(",");
6194 hadFlag = False;
6195 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6196 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6197 printf("%s%s",
6198 hadFlag ? "|" : "",
6199 flag_names[flagIndex]);
6200 hadFlag = True;
6201 }
6202 }
6203
6204 /* output synonyms */
6205 hadSyn = False;
6206 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6207 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6208 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6209 parm_table[parmIndex2].label);
6210 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6211 if (!hadSyn) {
6212 printf(" (synonyms: ");
6213 hadSyn = True;
6214 } else {
6215 printf(", ");
6216 }
6217 printf("%s%s", parm_table[parmIndex2].label,
6218 inverse ? "[i]" : "");
6219 }
6220 }
6221 if (hadSyn) {
6222 printf(")");
6223 }
6224
6225 printf("\n");
6226}
6227
6228/***************************************************************************
6229 Show all parameter's name, type, [values,] and flags.
6230***************************************************************************/
6231
6232void show_parameter_list(void)
6233{
6234 int classIndex, parmIndex;
6235 const char *section_names[] = { "local", "global", NULL};
6236
6237 for (classIndex=0; section_names[classIndex]; classIndex++) {
6238 printf("[%s]\n", section_names[classIndex]);
6239 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6240 if (parm_table[parmIndex].p_class == classIndex) {
6241 show_parameter(parmIndex);
6242 }
6243 }
6244 }
6245}
6246
6247/***************************************************************************
6248 Set a boolean variable from the text value stored in the passed string.
6249 Returns True in success, False if the passed string does not correctly
6250 represent a boolean.
6251***************************************************************************/
6252
6253static bool set_boolean(bool *pb, const char *pszParmValue)
6254{
6255 bool bRetval;
6256 bool value;
6257
6258 bRetval = True;
6259 value = False;
6260 if (strwicmp(pszParmValue, "yes") == 0 ||
6261 strwicmp(pszParmValue, "true") == 0 ||
6262 strwicmp(pszParmValue, "1") == 0)
6263 value = True;
6264 else if (strwicmp(pszParmValue, "no") == 0 ||
6265 strwicmp(pszParmValue, "False") == 0 ||
6266 strwicmp(pszParmValue, "0") == 0)
6267 value = False;
6268 else {
6269 DEBUG(2,
6270 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6271 pszParmValue));
6272 bRetval = False;
6273 }
6274
6275 if ((pb != NULL) && (bRetval != False)) {
6276 *pb = value;
6277 }
6278
6279 return (bRetval);
6280}
6281
6282
6283/***************************************************************************
6284 Check if a given string correctly represents a boolean value.
6285***************************************************************************/
6286
6287bool lp_string_is_valid_boolean(const char *parm_value)
6288{
6289 return set_boolean(NULL, parm_value);
6290}
6291
6292/***************************************************************************
6293 Get the standard string representation of a boolean value ("yes" or "no")
6294***************************************************************************/
6295
6296static const char *get_boolean(bool bool_value)
6297{
6298 static const char *yes_str = "yes";
6299 static const char *no_str = "no";
6300
6301 return (bool_value ? yes_str : no_str);
6302}
6303
6304/***************************************************************************
6305 Provide the string of the negated boolean value associated to the boolean
6306 given as a string. Returns False if the passed string does not correctly
6307 represent a boolean.
6308***************************************************************************/
6309
6310bool lp_invert_boolean(const char *str, const char **inverse_str)
6311{
6312 bool val;
6313
6314 if (!set_boolean(&val, str)) {
6315 return False;
6316 }
6317
6318 *inverse_str = get_boolean(!val);
6319 return True;
6320}
6321
6322/***************************************************************************
6323 Provide the canonical string representation of a boolean value given
6324 as a string. Return True on success, False if the string given does
6325 not correctly represent a boolean.
6326***************************************************************************/
6327
6328bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6329{
6330 bool val;
6331
6332 if (!set_boolean(&val, str)) {
6333 return False;
6334 }
6335
6336 *canon_str = get_boolean(val);
6337 return True;
6338}
6339
6340/***************************************************************************
6341Find a service by name. Otherwise works like get_service.
6342***************************************************************************/
6343
6344static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6345{
6346 int iService = -1;
6347 char *canon_name;
6348 TDB_DATA data;
6349
6350 if (ServiceHash == NULL) {
6351 return -1;
6352 }
6353
6354 canon_name = canonicalize_servicename(pszServiceName);
6355
6356 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6357
6358 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6359 iService = *(int *)data.dptr;
6360 }
6361
6362 TALLOC_FREE(canon_name);
6363
6364 if ((iService != -1) && (LP_SNUM_OK(iService))
6365 && (pserviceDest != NULL)) {
6366 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6367 }
6368
6369 return (iService);
6370}
6371
6372/***************************************************************************
6373 Copy a service structure to another.
6374 If pcopymapDest is NULL then copy all fields
6375***************************************************************************/
6376
6377static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6378 struct bitmap *pcopymapDest)
6379{
6380 int i;
6381 bool bcopyall = (pcopymapDest == NULL);
6382 param_opt_struct *data, *pdata, *paramo;
6383 bool not_added;
6384
6385 for (i = 0; parm_table[i].label; i++)
6386 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6387 (bcopyall || bitmap_query(pcopymapDest,i))) {
6388 void *def_ptr = parm_table[i].ptr;
6389 void *src_ptr =
6390 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6391 &sDefault);
6392 void *dest_ptr =
6393 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6394 &sDefault);
6395
6396 switch (parm_table[i].type) {
6397 case P_BOOL:
6398 case P_BOOLREV:
6399 *(bool *)dest_ptr = *(bool *)src_ptr;
6400 break;
6401
6402 case P_INTEGER:
6403 case P_ENUM:
6404 case P_OCTAL:
6405 *(int *)dest_ptr = *(int *)src_ptr;
6406 break;
6407
6408 case P_CHAR:
6409 *(char *)dest_ptr = *(char *)src_ptr;
6410 break;
6411
6412 case P_STRING:
6413 string_set((char **)dest_ptr,
6414 *(char **)src_ptr);
6415 break;
6416
6417 case P_USTRING:
6418 string_set((char **)dest_ptr,
6419 *(char **)src_ptr);
6420 strupper_m(*(char **)dest_ptr);
6421 break;
6422 case P_LIST:
6423 TALLOC_FREE(*((char ***)dest_ptr));
6424 str_list_copy(NULL, (char ***)dest_ptr,
6425 *(const char ***)src_ptr);
6426 break;
6427 default:
6428 break;
6429 }
6430 }
6431
6432 if (bcopyall) {
6433 init_copymap(pserviceDest);
6434 if (pserviceSource->copymap)
6435 bitmap_copy(pserviceDest->copymap,
6436 pserviceSource->copymap);
6437 }
6438
6439 data = pserviceSource->param_opt;
6440 while (data) {
6441 not_added = True;
6442 pdata = pserviceDest->param_opt;
6443 /* Traverse destination */
6444 while (pdata) {
6445 /* If we already have same option, override it */
6446 if (strcmp(pdata->key, data->key) == 0) {
6447 string_free(&pdata->value);
6448 TALLOC_FREE(data->list);
6449 pdata->value = SMB_STRDUP(data->value);
6450 not_added = False;
6451 break;
6452 }
6453 pdata = pdata->next;
6454 }
6455 if (not_added) {
6456 paramo = SMB_XMALLOC_P(param_opt_struct);
6457 paramo->key = SMB_STRDUP(data->key);
6458 paramo->value = SMB_STRDUP(data->value);
6459 paramo->list = NULL;
6460 DLIST_ADD(pserviceDest->param_opt, paramo);
6461 }
6462 data = data->next;
6463 }
6464}
6465
6466/***************************************************************************
6467Check a service for consistency. Return False if the service is in any way
6468incomplete or faulty, else True.
6469***************************************************************************/
6470
6471bool service_ok(int iService)
6472{
6473 bool bRetval;
6474
6475 bRetval = True;
6476 if (ServicePtrs[iService]->szService[0] == '\0') {
6477 DEBUG(0, ("The following message indicates an internal error:\n"));
6478 DEBUG(0, ("No service name in service entry.\n"));
6479 bRetval = False;
6480 }
6481
6482 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6483 /* I can't see why you'd want a non-printable printer service... */
6484 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6485 if (!ServicePtrs[iService]->bPrint_ok) {
6486 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6487 ServicePtrs[iService]->szService));
6488 ServicePtrs[iService]->bPrint_ok = True;
6489 }
6490 /* [printers] service must also be non-browsable. */
6491 if (ServicePtrs[iService]->bBrowseable)
6492 ServicePtrs[iService]->bBrowseable = False;
6493 }
6494
6495 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6496 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6497 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6498 ) {
6499 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6500 ServicePtrs[iService]->szService));
6501 ServicePtrs[iService]->bAvailable = False;
6502 }
6503
6504 /* If a service is flagged unavailable, log the fact at level 1. */
6505 if (!ServicePtrs[iService]->bAvailable)
6506 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6507 ServicePtrs[iService]->szService));
6508
6509 return (bRetval);
6510}
6511
6512static struct smbconf_ctx *lp_smbconf_ctx(void)
6513{
6514 WERROR werr;
6515 static struct smbconf_ctx *conf_ctx = NULL;
6516
6517 if (conf_ctx == NULL) {
6518 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6519 if (!W_ERROR_IS_OK(werr)) {
6520 DEBUG(1, ("error initializing registry configuration: "
6521 "%s\n", dos_errstr(werr)));
6522 conf_ctx = NULL;
6523 }
6524 }
6525
6526 return conf_ctx;
6527}
6528
6529static bool process_registry_service(struct smbconf_service *service)
6530{
6531 uint32_t count;
6532 bool ret;
6533
6534 if (service == NULL) {
6535 return false;
6536 }
6537
6538 ret = do_section(service->name, NULL);
6539 if (ret != true) {
6540 return false;
6541 }
6542 for (count = 0; count < service->num_params; count++) {
6543 ret = do_parameter(service->param_names[count],
6544 service->param_values[count],
6545 NULL);
6546 if (ret != true) {
6547 return false;
6548 }
6549 }
6550 return true;
6551}
6552
6553/*
6554 * process_registry_globals
6555 */
6556static bool process_registry_globals(void)
6557{
6558 WERROR werr;
6559 struct smbconf_service *service = NULL;
6560 TALLOC_CTX *mem_ctx = talloc_stackframe();
6561 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6562 bool ret = false;
6563
6564 if (conf_ctx == NULL) {
6565 goto done;
6566 }
6567
6568 ret = do_parameter("registry shares", "yes", NULL);
6569 if (!ret) {
6570 goto done;
6571 }
6572
6573 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6574 /* nothing to read from the registry yet but make sure lp_load
6575 * doesn't return false */
6576 ret = true;
6577 goto done;
6578 }
6579
6580 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6581 if (!W_ERROR_IS_OK(werr)) {
6582 goto done;
6583 }
6584
6585 ret = process_registry_service(service);
6586 if (!ret) {
6587 goto done;
6588 }
6589
6590 /* store the csn */
6591 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6592
6593done:
6594 TALLOC_FREE(mem_ctx);
6595 return ret;
6596}
6597
6598static bool process_registry_shares(void)
6599{
6600 WERROR werr;
6601 uint32_t count;
6602 struct smbconf_service **service = NULL;
6603 uint32_t num_shares = 0;
6604 TALLOC_CTX *mem_ctx = talloc_stackframe();
6605 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6606 bool ret = false;
6607
6608 if (conf_ctx == NULL) {
6609 goto done;
6610 }
6611
6612 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6613 if (!W_ERROR_IS_OK(werr)) {
6614 goto done;
6615 }
6616
6617 ret = true;
6618
6619 for (count = 0; count < num_shares; count++) {
6620 if (strequal(service[count]->name, GLOBAL_NAME)) {
6621 continue;
6622 }
6623 ret = process_registry_service(service[count]);
6624 if (!ret) {
6625 goto done;
6626 }
6627 }
6628
6629 /* store the csn */
6630 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6631
6632done:
6633 TALLOC_FREE(mem_ctx);
6634 return ret;
6635}
6636
6637static struct file_lists {
6638 struct file_lists *next;
6639 char *name;
6640 char *subfname;
6641 time_t modtime;
6642} *file_lists = NULL;
6643
6644/*******************************************************************
6645 Keep a linked list of all config files so we know when one has changed
6646 it's date and needs to be reloaded.
6647********************************************************************/
6648
6649static void add_to_file_list(const char *fname, const char *subfname)
6650{
6651 struct file_lists *f = file_lists;
6652
6653 while (f) {
6654 if (f->name && !strcmp(f->name, fname))
6655 break;
6656 f = f->next;
6657 }
6658
6659 if (!f) {
6660 f = SMB_MALLOC_P(struct file_lists);
6661 if (!f)
6662 return;
6663 f->next = file_lists;
6664 f->name = SMB_STRDUP(fname);
6665 if (!f->name) {
6666 SAFE_FREE(f);
6667 return;
6668 }
6669 f->subfname = SMB_STRDUP(subfname);
6670 if (!f->subfname) {
6671 SAFE_FREE(f);
6672 return;
6673 }
6674 file_lists = f;
6675 f->modtime = file_modtime(subfname);
6676 } else {
6677 time_t t = file_modtime(subfname);
6678 if (t)
6679 f->modtime = t;
6680 }
6681}
6682
6683/**
6684 * Utility function for outsiders to check if we're running on registry.
6685 */
6686bool lp_config_backend_is_registry(void)
6687{
6688 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6689}
6690
6691/**
6692 * Utility function to check if the config backend is FILE.
6693 */
6694bool lp_config_backend_is_file(void)
6695{
6696 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6697}
6698
6699/*******************************************************************
6700 Check if a config file has changed date.
6701********************************************************************/
6702
6703bool lp_file_list_changed(void)
6704{
6705 struct file_lists *f = file_lists;
6706
6707 DEBUG(6, ("lp_file_list_changed()\n"));
6708
6709 if (lp_config_backend_is_registry()) {
6710 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6711
6712 if (conf_ctx == NULL) {
6713 return false;
6714 }
6715 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6716 DEBUGADD(6, ("registry config changed\n"));
6717 return true;
6718 }
6719 }
6720
6721 while (f) {
6722 char *n2 = NULL;
6723 time_t mod_time;
6724
6725 n2 = alloc_sub_basic(get_current_username(),
6726 current_user_info.domain,
6727 f->name);
6728 if (!n2) {
6729 return false;
6730 }
6731 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6732 f->name, n2, ctime(&f->modtime)));
6733
6734 mod_time = file_modtime(n2);
6735
6736 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6737 DEBUGADD(6,
6738 ("file %s modified: %s\n", n2,
6739 ctime(&mod_time)));
6740 f->modtime = mod_time;
6741 SAFE_FREE(f->subfname);
6742 f->subfname = n2; /* Passing ownership of
6743 return from alloc_sub_basic
6744 above. */
6745 return true;
6746 }
6747 SAFE_FREE(n2);
6748 f = f->next;
6749 }
6750 return (False);
6751}
6752
6753
6754/***************************************************************************
6755 Run standard_sub_basic on netbios name... needed because global_myname
6756 is not accessed through any lp_ macro.
6757 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6758***************************************************************************/
6759
6760static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6761{
6762 bool ret;
6763 char *netbios_name = alloc_sub_basic(get_current_username(),
6764 current_user_info.domain,
6765 pszParmValue);
6766
6767 ret = set_global_myname(netbios_name);
6768 SAFE_FREE(netbios_name);
6769 string_set(&Globals.szNetbiosName,global_myname());
6770
6771 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6772 global_myname()));
6773
6774 return ret;
6775}
6776
6777static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6778{
6779 if (strcmp(*ptr, pszParmValue) != 0) {
6780 string_set(ptr, pszParmValue);
6781 init_iconv();
6782 }
6783 return True;
6784}
6785
6786
6787
6788static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6789{
6790 bool ret;
6791
6792 ret = set_global_myworkgroup(pszParmValue);
6793 string_set(&Globals.szWorkgroup,lp_workgroup());
6794
6795 return ret;
6796}
6797
6798static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6799{
6800 bool ret;
6801
6802 ret = set_global_scope(pszParmValue);
6803 string_set(&Globals.szNetbiosScope,global_scope());
6804
6805 return ret;
6806}
6807
6808static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6809{
6810 TALLOC_FREE(Globals.szNetbiosAliases);
6811 Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6812 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6813}
6814
6815/***************************************************************************
6816 Handle the include operation.
6817***************************************************************************/
6818static bool bAllowIncludeRegistry = true;
6819
6820static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6821{
6822 char *fname;
6823
6824 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6825 if (!bAllowIncludeRegistry) {
6826 return true;
6827 }
6828 if (bInGlobalSection) {
6829 return process_registry_globals();
6830 } else {
6831 DEBUG(1, ("\"include = registry\" only effective "
6832 "in %s section\n", GLOBAL_NAME));
6833 return false;
6834 }
6835 }
6836
6837 fname = alloc_sub_basic(get_current_username(),
6838 current_user_info.domain,
6839 pszParmValue);
6840
6841 add_to_file_list(pszParmValue, fname);
6842
6843 string_set(ptr, fname);
6844
6845 if (file_exist(fname, NULL)) {
6846 bool ret = pm_process(fname, do_section, do_parameter, NULL);
6847 SAFE_FREE(fname);
6848 return ret;
6849 }
6850
6851 DEBUG(2, ("Can't find include file %s\n", fname));
6852 SAFE_FREE(fname);
6853 return false;
6854}
6855
6856/***************************************************************************
6857 Handle the interpretation of the copy parameter.
6858***************************************************************************/
6859
6860static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6861{
6862 bool bRetval;
6863 int iTemp;
6864 struct service serviceTemp;
6865
6866 string_set(ptr, pszParmValue);
6867
6868 init_service(&serviceTemp);
6869
6870 bRetval = False;
6871
6872 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6873
6874 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6875 if (iTemp == iServiceIndex) {
6876 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6877 } else {
6878 copy_service(ServicePtrs[iServiceIndex],
6879 &serviceTemp,
6880 ServicePtrs[iServiceIndex]->copymap);
6881 bRetval = True;
6882 }
6883 } else {
6884 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6885 bRetval = False;
6886 }
6887
6888 free_service(&serviceTemp);
6889 return (bRetval);
6890}
6891
6892static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6893{
6894 Globals.ldap_debug_level = lp_int(pszParmValue);
6895 init_ldap_debugging();
6896 return true;
6897}
6898
6899/***************************************************************************
6900 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6901 parameters is:
6902
6903 [global]
6904
6905 idmap uid = 1000-1999
6906 idmap gid = 700-899
6907
6908 We only do simple parsing checks here. The strings are parsed into useful
6909 structures in the idmap daemon code.
6910
6911***************************************************************************/
6912
6913/* Some lp_ routines to return idmap [ug]id information */
6914
6915static uid_t idmap_uid_low, idmap_uid_high;
6916static gid_t idmap_gid_low, idmap_gid_high;
6917
6918bool lp_idmap_uid(uid_t *low, uid_t *high)
6919{
6920 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6921 return False;
6922
6923 if (low)
6924 *low = idmap_uid_low;
6925
6926 if (high)
6927 *high = idmap_uid_high;
6928
6929 return True;
6930}
6931
6932bool lp_idmap_gid(gid_t *low, gid_t *high)
6933{
6934 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6935 return False;
6936
6937 if (low)
6938 *low = idmap_gid_low;
6939
6940 if (high)
6941 *high = idmap_gid_high;
6942
6943 return True;
6944}
6945
6946/* Do some simple checks on "idmap [ug]id" parameter values */
6947
6948static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6949{
6950 uint32 low, high;
6951
6952 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6953 return False;
6954
6955 /* Parse OK */
6956
6957 string_set(ptr, pszParmValue);
6958
6959 idmap_uid_low = low;
6960 idmap_uid_high = high;
6961
6962 return True;
6963}
6964
6965static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6966{
6967 uint32 low, high;
6968
6969 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6970 return False;
6971
6972 /* Parse OK */
6973
6974 string_set(ptr, pszParmValue);
6975
6976 idmap_gid_low = low;
6977 idmap_gid_high = high;
6978
6979 return True;
6980}
6981
6982/***************************************************************************
6983 Handle the DEBUG level list.
6984***************************************************************************/
6985
6986static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
6987{
6988 string_set(ptr, pszParmValueIn);
6989 return debug_parse_levels(pszParmValueIn);
6990}
6991
6992/***************************************************************************
6993 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
6994***************************************************************************/
6995
6996static const char *append_ldap_suffix( const char *str )
6997{
6998 const char *suffix_string;
6999
7000
7001 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7002 Globals.szLdapSuffix );
7003 if ( !suffix_string ) {
7004 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7005 return "";
7006 }
7007
7008 return suffix_string;
7009}
7010
7011const char *lp_ldap_machine_suffix(void)
7012{
7013 if (Globals.szLdapMachineSuffix[0])
7014 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7015
7016 return lp_string(Globals.szLdapSuffix);
7017}
7018
7019const char *lp_ldap_user_suffix(void)
7020{
7021 if (Globals.szLdapUserSuffix[0])
7022 return append_ldap_suffix(Globals.szLdapUserSuffix);
7023
7024 return lp_string(Globals.szLdapSuffix);
7025}
7026
7027const char *lp_ldap_group_suffix(void)
7028{
7029 if (Globals.szLdapGroupSuffix[0])
7030 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7031
7032 return lp_string(Globals.szLdapSuffix);
7033}
7034
7035const char *lp_ldap_idmap_suffix(void)
7036{
7037 if (Globals.szLdapIdmapSuffix[0])
7038 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7039
7040 return lp_string(Globals.szLdapSuffix);
7041}
7042
7043/****************************************************************************
7044 set the value for a P_ENUM
7045 ***************************************************************************/
7046
7047static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7048 int *ptr )
7049{
7050 int i;
7051
7052 for (i = 0; parm->enum_list[i].name; i++) {
7053 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7054 *ptr = parm->enum_list[i].value;
7055 break;
7056 }
7057 }
7058}
7059
7060/***************************************************************************
7061***************************************************************************/
7062
7063static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7064{
7065 static int parm_num = -1;
7066 struct service *s;
7067
7068 if ( parm_num == -1 )
7069 parm_num = map_parameter( "printing" );
7070
7071 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7072
7073 if ( snum < 0 )
7074 s = &sDefault;
7075 else
7076 s = ServicePtrs[snum];
7077
7078 init_printer_values( s );
7079
7080 return True;
7081}
7082
7083
7084/***************************************************************************
7085 Initialise a copymap.
7086***************************************************************************/
7087
7088static void init_copymap(struct service *pservice)
7089{
7090 int i;
7091 if (pservice->copymap) {
7092 bitmap_free(pservice->copymap);
7093 }
7094 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7095 if (!pservice->copymap)
7096 DEBUG(0,
7097 ("Couldn't allocate copymap!! (size %d)\n",
7098 (int)NUMPARAMETERS));
7099 else
7100 for (i = 0; i < NUMPARAMETERS; i++)
7101 bitmap_set(pservice->copymap, i);
7102}
7103
7104/***************************************************************************
7105 Return the local pointer to a parameter given the service number and the
7106 pointer into the default structure.
7107***************************************************************************/
7108
7109void *lp_local_ptr(int snum, void *ptr)
7110{
7111 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7112}
7113
7114/***************************************************************************
7115 Process a parameter for a particular service number. If snum < 0
7116 then assume we are in the globals.
7117***************************************************************************/
7118
7119bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7120{
7121 int parmnum, i, slen;
7122 void *parm_ptr = NULL; /* where we are going to store the result */
7123 void *def_ptr = NULL;
7124 char *param_key = NULL;
7125 char *sep;
7126 param_opt_struct *paramo, *data;
7127 bool not_added;
7128
7129 parmnum = map_parameter(pszParmName);
7130
7131 if (parmnum < 0) {
7132 if ((sep=strchr(pszParmName, ':')) != NULL) {
7133 TALLOC_CTX *frame = talloc_stackframe();
7134
7135 *sep = '\0';
7136 param_key = talloc_asprintf(frame, "%s:", pszParmName);
7137 if (!param_key) {
7138 TALLOC_FREE(frame);
7139 return false;
7140 }
7141 slen = strlen(param_key);
7142 param_key = talloc_asprintf_append(param_key, sep+1);
7143 if (!param_key) {
7144 TALLOC_FREE(frame);
7145 return false;
7146 }
7147 trim_char(param_key+slen, ' ', ' ');
7148 not_added = True;
7149 data = (snum < 0) ? Globals.param_opt :
7150 ServicePtrs[snum]->param_opt;
7151 /* Traverse destination */
7152 while (data) {
7153 /* If we already have same option, override it */
7154 if (strcmp(data->key, param_key) == 0) {
7155 string_free(&data->value);
7156 TALLOC_FREE(data->list);
7157 data->value = SMB_STRDUP(pszParmValue);
7158 not_added = False;
7159 break;
7160 }
7161 data = data->next;
7162 }
7163 if (not_added) {
7164 paramo = SMB_XMALLOC_P(param_opt_struct);
7165 paramo->key = SMB_STRDUP(param_key);
7166 paramo->value = SMB_STRDUP(pszParmValue);
7167 paramo->list = NULL;
7168 if (snum < 0) {
7169 DLIST_ADD(Globals.param_opt, paramo);
7170 } else {
7171 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
7172 }
7173 }
7174
7175 *sep = ':';
7176 TALLOC_FREE(frame);
7177 return (True);
7178 }
7179 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7180 return (True);
7181 }
7182
7183 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7184 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7185 pszParmName));
7186 }
7187
7188 def_ptr = parm_table[parmnum].ptr;
7189
7190 /* we might point at a service, the default service or a global */
7191 if (snum < 0) {
7192 parm_ptr = def_ptr;
7193 } else {
7194 if (parm_table[parmnum].p_class == P_GLOBAL) {
7195 DEBUG(0,
7196 ("Global parameter %s found in service section!\n",
7197 pszParmName));
7198 return (True);
7199 }
7200 parm_ptr =
7201 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7202 &sDefault);
7203 }
7204
7205 if (snum >= 0) {
7206 if (!ServicePtrs[snum]->copymap)
7207 init_copymap(ServicePtrs[snum]);
7208
7209 /* this handles the aliases - set the copymap for other entries with
7210 the same data pointer */
7211 for (i = 0; parm_table[i].label; i++)
7212 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7213 bitmap_clear(ServicePtrs[snum]->copymap, i);
7214 }
7215
7216 /* if it is a special case then go ahead */
7217 if (parm_table[parmnum].special) {
7218 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
7219 return (True);
7220 }
7221
7222 /* now switch on the type of variable it is */
7223 switch (parm_table[parmnum].type)
7224 {
7225 case P_BOOL:
7226 *(bool *)parm_ptr = lp_bool(pszParmValue);
7227 break;
7228
7229 case P_BOOLREV:
7230 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7231 break;
7232
7233 case P_INTEGER:
7234 *(int *)parm_ptr = lp_int(pszParmValue);
7235 break;
7236
7237 case P_CHAR:
7238 *(char *)parm_ptr = *pszParmValue;
7239 break;
7240
7241 case P_OCTAL:
7242 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7243 if ( i != 1 ) {
7244 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7245 }
7246 break;
7247
7248 case P_LIST:
7249 TALLOC_FREE(*((char ***)parm_ptr));
7250 *(char ***)parm_ptr = str_list_make(
7251 NULL, pszParmValue, NULL);
7252 break;
7253
7254 case P_STRING:
7255 string_set((char **)parm_ptr, pszParmValue);
7256 break;
7257
7258 case P_USTRING:
7259 string_set((char **)parm_ptr, pszParmValue);
7260 strupper_m(*(char **)parm_ptr);
7261 break;
7262
7263 case P_ENUM:
7264 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7265 break;
7266 case P_SEP:
7267 break;
7268 }
7269
7270 return (True);
7271}
7272
7273/***************************************************************************
7274 Process a parameter.
7275***************************************************************************/
7276
7277static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7278 void *userdata)
7279{
7280 if (!bInGlobalSection && bGlobalOnly)
7281 return (True);
7282
7283 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7284
7285 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7286 pszParmName, pszParmValue));
7287}
7288
7289/***************************************************************************
7290 Print a parameter of the specified type.
7291***************************************************************************/
7292
7293static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7294{
7295 int i;
7296 switch (p->type)
7297 {
7298 case P_ENUM:
7299 for (i = 0; p->enum_list[i].name; i++) {
7300 if (*(int *)ptr == p->enum_list[i].value) {
7301 fprintf(f, "%s",
7302 p->enum_list[i].name);
7303 break;
7304 }
7305 }
7306 break;
7307
7308 case P_BOOL:
7309 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7310 break;
7311
7312 case P_BOOLREV:
7313 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7314 break;
7315
7316 case P_INTEGER:
7317 fprintf(f, "%d", *(int *)ptr);
7318 break;
7319
7320 case P_CHAR:
7321 fprintf(f, "%c", *(char *)ptr);
7322 break;
7323
7324 case P_OCTAL: {
7325 char *o = octal_string(*(int *)ptr);
7326 fprintf(f, "%s", o);
7327 TALLOC_FREE(o);
7328 break;
7329 }
7330
7331 case P_LIST:
7332 if ((char ***)ptr && *(char ***)ptr) {
7333 char **list = *(char ***)ptr;
7334 for (; *list; list++) {
7335 /* surround strings with whitespace in double quotes */
7336 if ( strchr_m( *list, ' ' ) )
7337 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7338 else
7339 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7340 }
7341 }
7342 break;
7343
7344 case P_STRING:
7345 case P_USTRING:
7346 if (*(char **)ptr) {
7347 fprintf(f, "%s", *(char **)ptr);
7348 }
7349 break;
7350 case P_SEP:
7351 break;
7352 }
7353}
7354
7355/***************************************************************************
7356 Check if two parameters are equal.
7357***************************************************************************/
7358
7359static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7360{
7361 switch (type) {
7362 case P_BOOL:
7363 case P_BOOLREV:
7364 return (*((bool *)ptr1) == *((bool *)ptr2));
7365
7366 case P_INTEGER:
7367 case P_ENUM:
7368 case P_OCTAL:
7369 return (*((int *)ptr1) == *((int *)ptr2));
7370
7371 case P_CHAR:
7372 return (*((char *)ptr1) == *((char *)ptr2));
7373
7374 case P_LIST:
7375 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7376
7377 case P_STRING:
7378 case P_USTRING:
7379 {
7380 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7381 if (p1 && !*p1)
7382 p1 = NULL;
7383 if (p2 && !*p2)
7384 p2 = NULL;
7385 return (p1 == p2 || strequal(p1, p2));
7386 }
7387 case P_SEP:
7388 break;
7389 }
7390 return (False);
7391}
7392
7393/***************************************************************************
7394 Initialize any local varients in the sDefault table.
7395***************************************************************************/
7396
7397void init_locals(void)
7398{
7399 /* None as yet. */
7400}
7401
7402/***************************************************************************
7403 Process a new section (service). At this stage all sections are services.
7404 Later we'll have special sections that permit server parameters to be set.
7405 Returns True on success, False on failure.
7406***************************************************************************/
7407
7408static bool do_section(const char *pszSectionName, void *userdata)
7409{
7410 bool bRetval;
7411 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7412 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7413 bRetval = False;
7414
7415 /* if we were in a global section then do the local inits */
7416 if (bInGlobalSection && !isglobal)
7417 init_locals();
7418
7419 /* if we've just struck a global section, note the fact. */
7420 bInGlobalSection = isglobal;
7421
7422 /* check for multiple global sections */
7423 if (bInGlobalSection) {
7424 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7425 return (True);
7426 }
7427
7428 if (!bInGlobalSection && bGlobalOnly)
7429 return (True);
7430
7431 /* if we have a current service, tidy it up before moving on */
7432 bRetval = True;
7433
7434 if (iServiceIndex >= 0)
7435 bRetval = service_ok(iServiceIndex);
7436
7437 /* if all is still well, move to the next record in the services array */
7438 if (bRetval) {
7439 /* We put this here to avoid an odd message order if messages are */
7440 /* issued by the post-processing of a previous section. */
7441 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7442
7443 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7444 < 0) {
7445 DEBUG(0, ("Failed to add a new service\n"));
7446 return (False);
7447 }
7448 }
7449
7450 return (bRetval);
7451}
7452
7453
7454/***************************************************************************
7455 Determine if a partcular base parameter is currentl set to the default value.
7456***************************************************************************/
7457
7458static bool is_default(int i)
7459{
7460 if (!defaults_saved)
7461 return False;
7462 switch (parm_table[i].type) {
7463 case P_LIST:
7464 return str_list_compare (parm_table[i].def.lvalue,
7465 *(char ***)parm_table[i].ptr);
7466 case P_STRING:
7467 case P_USTRING:
7468 return strequal(parm_table[i].def.svalue,
7469 *(char **)parm_table[i].ptr);
7470 case P_BOOL:
7471 case P_BOOLREV:
7472 return parm_table[i].def.bvalue ==
7473 *(bool *)parm_table[i].ptr;
7474 case P_CHAR:
7475 return parm_table[i].def.cvalue ==
7476 *(char *)parm_table[i].ptr;
7477 case P_INTEGER:
7478 case P_OCTAL:
7479 case P_ENUM:
7480 return parm_table[i].def.ivalue ==
7481 *(int *)parm_table[i].ptr;
7482 case P_SEP:
7483 break;
7484 }
7485 return False;
7486}
7487
7488/***************************************************************************
7489Display the contents of the global structure.
7490***************************************************************************/
7491
7492static void dump_globals(FILE *f)
7493{
7494 int i;
7495 param_opt_struct *data;
7496
7497 fprintf(f, "[global]\n");
7498
7499 for (i = 0; parm_table[i].label; i++)
7500 if (parm_table[i].p_class == P_GLOBAL &&
7501 parm_table[i].ptr &&
7502 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7503 if (defaults_saved && is_default(i))
7504 continue;
7505 fprintf(f, "\t%s = ", parm_table[i].label);
7506 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7507 fprintf(f, "\n");
7508 }
7509 if (Globals.param_opt != NULL) {
7510 data = Globals.param_opt;
7511 while(data) {
7512 fprintf(f, "\t%s = %s\n", data->key, data->value);
7513 data = data->next;
7514 }
7515 }
7516
7517}
7518
7519/***************************************************************************
7520 Return True if a local parameter is currently set to the global default.
7521***************************************************************************/
7522
7523bool lp_is_default(int snum, struct parm_struct *parm)
7524{
7525 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7526
7527 return equal_parameter(parm->type,
7528 ((char *)ServicePtrs[snum]) + pdiff,
7529 ((char *)&sDefault) + pdiff);
7530}
7531
7532/***************************************************************************
7533 Display the contents of a single services record.
7534***************************************************************************/
7535
7536static void dump_a_service(struct service *pService, FILE * f)
7537{
7538 int i;
7539 param_opt_struct *data;
7540
7541 if (pService != &sDefault)
7542 fprintf(f, "[%s]\n", pService->szService);
7543
7544 for (i = 0; parm_table[i].label; i++) {
7545
7546 if (parm_table[i].p_class == P_LOCAL &&
7547 parm_table[i].ptr &&
7548 (*parm_table[i].label != '-') &&
7549 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7550 {
7551
7552 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7553
7554 if (pService == &sDefault) {
7555 if (defaults_saved && is_default(i))
7556 continue;
7557 } else {
7558 if (equal_parameter(parm_table[i].type,
7559 ((char *)pService) +
7560 pdiff,
7561 ((char *)&sDefault) +
7562 pdiff))
7563 continue;
7564 }
7565
7566 fprintf(f, "\t%s = ", parm_table[i].label);
7567 print_parameter(&parm_table[i],
7568 ((char *)pService) + pdiff, f);
7569 fprintf(f, "\n");
7570 }
7571 }
7572
7573 if (pService->param_opt != NULL) {
7574 data = pService->param_opt;
7575 while(data) {
7576 fprintf(f, "\t%s = %s\n", data->key, data->value);
7577 data = data->next;
7578 }
7579 }
7580}
7581
7582/***************************************************************************
7583 Display the contents of a parameter of a single services record.
7584***************************************************************************/
7585
7586bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7587{
7588 int i;
7589 bool result = False;
7590 parm_class p_class;
7591 unsigned flag = 0;
7592 fstring local_parm_name;
7593 char *parm_opt;
7594 const char *parm_opt_value;
7595
7596 /* check for parametrical option */
7597 fstrcpy( local_parm_name, parm_name);
7598 parm_opt = strchr( local_parm_name, ':');
7599
7600 if (parm_opt) {
7601 *parm_opt = '\0';
7602 parm_opt++;
7603 if (strlen(parm_opt)) {
7604 parm_opt_value = lp_parm_const_string( snum,
7605 local_parm_name, parm_opt, NULL);
7606 if (parm_opt_value) {
7607 printf( "%s\n", parm_opt_value);
7608 result = True;
7609 }
7610 }
7611 return result;
7612 }
7613
7614 /* check for a key and print the value */
7615 if (isGlobal) {
7616 p_class = P_GLOBAL;
7617 flag = FLAG_GLOBAL;
7618 } else
7619 p_class = P_LOCAL;
7620
7621 for (i = 0; parm_table[i].label; i++) {
7622 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7623 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7624 parm_table[i].ptr &&
7625 (*parm_table[i].label != '-') &&
7626 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7627 {
7628 void *ptr;
7629
7630 if (isGlobal) {
7631 ptr = parm_table[i].ptr;
7632 } else {
7633 struct service *pService = ServicePtrs[snum];
7634 ptr = ((char *)pService) +
7635 PTR_DIFF(parm_table[i].ptr, &sDefault);
7636 }
7637
7638 print_parameter(&parm_table[i],
7639 ptr, f);
7640 fprintf(f, "\n");
7641 result = True;
7642 break;
7643 }
7644 }
7645
7646 return result;
7647}
7648
7649/***************************************************************************
7650 Return info about the requested parameter (given as a string).
7651 Return NULL when the string is not a valid parameter name.
7652***************************************************************************/
7653
7654struct parm_struct *lp_get_parameter(const char *param_name)
7655{
7656 int num = map_parameter(param_name);
7657
7658 if (num < 0) {
7659 return NULL;
7660 }
7661
7662 return &parm_table[num];
7663}
7664
7665/***************************************************************************
7666 Return info about the next parameter in a service.
7667 snum==GLOBAL_SECTION_SNUM gives the globals.
7668 Return NULL when out of parameters.
7669***************************************************************************/
7670
7671struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7672{
7673 if (snum < 0) {
7674 /* do the globals */
7675 for (; parm_table[*i].label; (*i)++) {
7676 if (parm_table[*i].p_class == P_SEPARATOR)
7677 return &parm_table[(*i)++];
7678
7679 if (!parm_table[*i].ptr
7680 || (*parm_table[*i].label == '-'))
7681 continue;
7682
7683 if ((*i) > 0
7684 && (parm_table[*i].ptr ==
7685 parm_table[(*i) - 1].ptr))
7686 continue;
7687
7688 if (is_default(*i) && !allparameters)
7689 continue;
7690
7691 return &parm_table[(*i)++];
7692 }
7693 } else {
7694 struct service *pService = ServicePtrs[snum];
7695
7696 for (; parm_table[*i].label; (*i)++) {
7697 if (parm_table[*i].p_class == P_SEPARATOR)
7698 return &parm_table[(*i)++];
7699
7700 if (parm_table[*i].p_class == P_LOCAL &&
7701 parm_table[*i].ptr &&
7702 (*parm_table[*i].label != '-') &&
7703 ((*i) == 0 ||
7704 (parm_table[*i].ptr !=
7705 parm_table[(*i) - 1].ptr)))
7706 {
7707 int pdiff =
7708 PTR_DIFF(parm_table[*i].ptr,
7709 &sDefault);
7710
7711 if (allparameters ||
7712 !equal_parameter(parm_table[*i].type,
7713 ((char *)pService) +
7714 pdiff,
7715 ((char *)&sDefault) +
7716 pdiff))
7717 {
7718 return &parm_table[(*i)++];
7719 }
7720 }
7721 }
7722 }
7723
7724 return NULL;
7725}
7726
7727
7728#if 0
7729/***************************************************************************
7730 Display the contents of a single copy structure.
7731***************************************************************************/
7732static void dump_copy_map(bool *pcopymap)
7733{
7734 int i;
7735 if (!pcopymap)
7736 return;
7737
7738 printf("\n\tNon-Copied parameters:\n");
7739
7740 for (i = 0; parm_table[i].label; i++)
7741 if (parm_table[i].p_class == P_LOCAL &&
7742 parm_table[i].ptr && !pcopymap[i] &&
7743 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7744 {
7745 printf("\t\t%s\n", parm_table[i].label);
7746 }
7747}
7748#endif
7749
7750/***************************************************************************
7751 Return TRUE if the passed service number is within range.
7752***************************************************************************/
7753
7754bool lp_snum_ok(int iService)
7755{
7756 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7757}
7758
7759/***************************************************************************
7760 Auto-load some home services.
7761***************************************************************************/
7762
7763static void lp_add_auto_services(char *str)
7764{
7765 char *s;
7766 char *p;
7767 int homes;
7768 char *saveptr;
7769
7770 if (!str)
7771 return;
7772
7773 s = SMB_STRDUP(str);
7774 if (!s)
7775 return;
7776
7777 homes = lp_servicenumber(HOMES_NAME);
7778
7779 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7780 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7781 char *home;
7782
7783 if (lp_servicenumber(p) >= 0)
7784 continue;
7785
7786 home = get_user_home_dir(talloc_tos(), p);
7787
7788 if (home && homes >= 0)
7789 lp_add_home(p, homes, p, home);
7790
7791 TALLOC_FREE(home);
7792 }
7793 SAFE_FREE(s);
7794}
7795
7796/***************************************************************************
7797 Auto-load one printer.
7798***************************************************************************/
7799
7800void lp_add_one_printer(const char *name, const char *comment, void *pdata)
7801{
7802 int printers = lp_servicenumber(PRINTERS_NAME);
7803 int i;
7804
7805 if (lp_servicenumber(name) < 0) {
7806 lp_add_printer(name, printers);
7807 if ((i = lp_servicenumber(name)) >= 0) {
7808 string_set(&ServicePtrs[i]->comment, comment);
7809 ServicePtrs[i]->autoloaded = True;
7810 }
7811 }
7812}
7813
7814/***************************************************************************
7815 Have we loaded a services file yet?
7816***************************************************************************/
7817
7818bool lp_loaded(void)
7819{
7820 return (bLoaded);
7821}
7822
7823/***************************************************************************
7824 Unload unused services.
7825***************************************************************************/
7826
7827void lp_killunused(bool (*snumused) (int))
7828{
7829 int i;
7830 for (i = 0; i < iNumServices; i++) {
7831 if (!VALID(i))
7832 continue;
7833
7834 /* don't kill autoloaded or usershare services */
7835 if ( ServicePtrs[i]->autoloaded ||
7836 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7837 continue;
7838 }
7839
7840 if (!snumused || !snumused(i)) {
7841 free_service_byindex(i);
7842 }
7843 }
7844}
7845
7846/**
7847 * Kill all except autoloaded and usershare services - convenience wrapper
7848 */
7849void lp_kill_all_services(void)
7850{
7851 lp_killunused(NULL);
7852}
7853
7854/***************************************************************************
7855 Unload a service.
7856***************************************************************************/
7857
7858void lp_killservice(int iServiceIn)
7859{
7860 if (VALID(iServiceIn)) {
7861 free_service_byindex(iServiceIn);
7862 }
7863}
7864
7865/***************************************************************************
7866 Save the curent values of all global and sDefault parameters into the
7867 defaults union. This allows swat and testparm to show only the
7868 changed (ie. non-default) parameters.
7869***************************************************************************/
7870
7871static void lp_save_defaults(void)
7872{
7873 int i;
7874 for (i = 0; parm_table[i].label; i++) {
7875 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7876 continue;
7877 switch (parm_table[i].type) {
7878 case P_LIST:
7879 str_list_copy(
7880 NULL, &(parm_table[i].def.lvalue),
7881 *(const char ***)parm_table[i].ptr);
7882 break;
7883 case P_STRING:
7884 case P_USTRING:
7885 if (parm_table[i].ptr) {
7886 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7887 } else {
7888 parm_table[i].def.svalue = NULL;
7889 }
7890 break;
7891 case P_BOOL:
7892 case P_BOOLREV:
7893 parm_table[i].def.bvalue =
7894 *(bool *)parm_table[i].ptr;
7895 break;
7896 case P_CHAR:
7897 parm_table[i].def.cvalue =
7898 *(char *)parm_table[i].ptr;
7899 break;
7900 case P_INTEGER:
7901 case P_OCTAL:
7902 case P_ENUM:
7903 parm_table[i].def.ivalue =
7904 *(int *)parm_table[i].ptr;
7905 break;
7906 case P_SEP:
7907 break;
7908 }
7909 }
7910 defaults_saved = True;
7911}
7912
7913/*******************************************************************
7914 Set the server type we will announce as via nmbd.
7915********************************************************************/
7916
7917static const struct srv_role_tab {
7918 uint32 role;
7919 const char *role_str;
7920} srv_role_tab [] = {
7921 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7922 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7923 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7924 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7925 { 0, NULL }
7926};
7927
7928const char* server_role_str(uint32 role)
7929{
7930 int i = 0;
7931 for (i=0; srv_role_tab[i].role_str; i++) {
7932 if (role == srv_role_tab[i].role) {
7933 return srv_role_tab[i].role_str;
7934 }
7935 }
7936 return NULL;
7937}
7938
7939static void set_server_role(void)
7940{
7941 server_role = ROLE_STANDALONE;
7942
7943 switch (lp_security()) {
7944 case SEC_SHARE:
7945 if (lp_domain_logons())
7946 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7947 break;
7948 case SEC_SERVER:
7949 if (lp_domain_logons())
7950 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7951 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7952 server_role = ROLE_STANDALONE;
7953 break;
7954 case SEC_DOMAIN:
7955 if (lp_domain_logons()) {
7956 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7957 server_role = ROLE_DOMAIN_BDC;
7958 break;
7959 }
7960 server_role = ROLE_DOMAIN_MEMBER;
7961 break;
7962 case SEC_ADS:
7963 if (lp_domain_logons()) {
7964 server_role = ROLE_DOMAIN_PDC;
7965 break;
7966 }
7967 server_role = ROLE_DOMAIN_MEMBER;
7968 break;
7969 case SEC_USER:
7970 if (lp_domain_logons()) {
7971
7972 if (Globals.iDomainMaster) /* auto or yes */
7973 server_role = ROLE_DOMAIN_PDC;
7974 else
7975 server_role = ROLE_DOMAIN_BDC;
7976 }
7977 break;
7978 default:
7979 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7980 break;
7981 }
7982
7983 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
7984}
7985
7986/***********************************************************
7987 If we should send plaintext/LANMAN passwords in the clinet
7988************************************************************/
7989
7990static void set_allowed_client_auth(void)
7991{
7992 if (Globals.bClientNTLMv2Auth) {
7993 Globals.bClientLanManAuth = False;
7994 }
7995 if (!Globals.bClientLanManAuth) {
7996 Globals.bClientPlaintextAuth = False;
7997 }
7998}
7999
8000/***************************************************************************
8001 JRA.
8002 The following code allows smbd to read a user defined share file.
8003 Yes, this is my intent. Yes, I'm comfortable with that...
8004
8005 THE FOLLOWING IS SECURITY CRITICAL CODE.
8006
8007 It washes your clothes, it cleans your house, it guards you while you sleep...
8008 Do not f%^k with it....
8009***************************************************************************/
8010
8011#define MAX_USERSHARE_FILE_SIZE (10*1024)
8012
8013/***************************************************************************
8014 Check allowed stat state of a usershare file.
8015 Ensure we print out who is dicking with us so the admin can
8016 get their sorry ass fired.
8017***************************************************************************/
8018
8019static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8020{
8021 if (!S_ISREG(psbuf->st_mode)) {
8022 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8023 "not a regular file\n",
8024 fname, (unsigned int)psbuf->st_uid ));
8025 return False;
8026 }
8027
8028 /* Ensure this doesn't have the other write bit set. */
8029 if (psbuf->st_mode & S_IWOTH) {
8030 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8031 "public write. Refusing to allow as a usershare file.\n",
8032 fname, (unsigned int)psbuf->st_uid ));
8033 return False;
8034 }
8035
8036 /* Should be 10k or less. */
8037 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8038 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8039 "too large (%u) to be a user share file.\n",
8040 fname, (unsigned int)psbuf->st_uid,
8041 (unsigned int)psbuf->st_size ));
8042 return False;
8043 }
8044
8045 return True;
8046}
8047
8048/***************************************************************************
8049 Parse the contents of a usershare file.
8050***************************************************************************/
8051
8052enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8053 SMB_STRUCT_STAT *psbuf,
8054 const char *servicename,
8055 int snum,
8056 char **lines,
8057 int numlines,
8058 char **pp_sharepath,
8059 char **pp_comment,
8060 SEC_DESC **ppsd,
8061 bool *pallow_guest)
8062{
8063 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8064 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8065 int us_vers;
8066 SMB_STRUCT_DIR *dp;
8067 SMB_STRUCT_STAT sbuf;
8068 char *sharepath = NULL;
8069 char *comment = NULL;
8070
8071 *pp_sharepath = NULL;
8072 *pp_comment = NULL;
8073
8074 *pallow_guest = False;
8075
8076 if (numlines < 4) {
8077 return USERSHARE_MALFORMED_FILE;
8078 }
8079
8080 if (strcmp(lines[0], "#VERSION 1") == 0) {
8081 us_vers = 1;
8082 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8083 us_vers = 2;
8084 if (numlines < 5) {
8085 return USERSHARE_MALFORMED_FILE;
8086 }
8087 } else {
8088 return USERSHARE_BAD_VERSION;
8089 }
8090
8091 if (strncmp(lines[1], "path=", 5) != 0) {
8092 return USERSHARE_MALFORMED_PATH;
8093 }
8094
8095 sharepath = talloc_strdup(ctx, &lines[1][5]);
8096 if (!sharepath) {
8097 return USERSHARE_POSIX_ERR;
8098 }
8099 trim_string(sharepath, " ", " ");
8100
8101 if (strncmp(lines[2], "comment=", 8) != 0) {
8102 return USERSHARE_MALFORMED_COMMENT_DEF;
8103 }
8104
8105 comment = talloc_strdup(ctx, &lines[2][8]);
8106 if (!comment) {
8107 return USERSHARE_POSIX_ERR;
8108 }
8109 trim_string(comment, " ", " ");
8110 trim_char(comment, '"', '"');
8111
8112 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8113 return USERSHARE_MALFORMED_ACL_DEF;
8114 }
8115
8116 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8117 return USERSHARE_ACL_ERR;
8118 }
8119
8120 if (us_vers == 2) {
8121 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8122 return USERSHARE_MALFORMED_ACL_DEF;
8123 }
8124 if (lines[4][9] == 'y') {
8125 *pallow_guest = True;
8126 }
8127 }
8128
8129 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8130 /* Path didn't change, no checks needed. */
8131 *pp_sharepath = sharepath;
8132 *pp_comment = comment;
8133 return USERSHARE_OK;
8134 }
8135
8136 /* The path *must* be absolute. */
8137 if (sharepath[0] != '/') {
8138 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8139 servicename, sharepath));
8140 return USERSHARE_PATH_NOT_ABSOLUTE;
8141 }
8142
8143 /* If there is a usershare prefix deny list ensure one of these paths
8144 doesn't match the start of the user given path. */
8145 if (prefixdenylist) {
8146 int i;
8147 for ( i=0; prefixdenylist[i]; i++ ) {
8148 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8149 servicename, i, prefixdenylist[i], sharepath ));
8150 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8151 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8152 "usershare prefix deny list entries.\n",
8153 servicename, sharepath));
8154 return USERSHARE_PATH_IS_DENIED;
8155 }
8156 }
8157 }
8158
8159 /* If there is a usershare prefix allow list ensure one of these paths
8160 does match the start of the user given path. */
8161
8162 if (prefixallowlist) {
8163 int i;
8164 for ( i=0; prefixallowlist[i]; i++ ) {
8165 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8166 servicename, i, prefixallowlist[i], sharepath ));
8167 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8168 break;
8169 }
8170 }
8171 if (prefixallowlist[i] == NULL) {
8172 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8173 "usershare prefix allow list entries.\n",
8174 servicename, sharepath));
8175 return USERSHARE_PATH_NOT_ALLOWED;
8176 }
8177 }
8178
8179 /* Ensure this is pointing to a directory. */
8180 dp = sys_opendir(sharepath);
8181
8182 if (!dp) {
8183 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8184 servicename, sharepath));
8185 return USERSHARE_PATH_NOT_DIRECTORY;
8186 }
8187
8188 /* Ensure the owner of the usershare file has permission to share
8189 this directory. */
8190
8191 if (sys_stat(sharepath, &sbuf) == -1) {
8192 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8193 servicename, sharepath, strerror(errno) ));
8194 sys_closedir(dp);
8195 return USERSHARE_POSIX_ERR;
8196 }
8197
8198 sys_closedir(dp);
8199
8200 if (!S_ISDIR(sbuf.st_mode)) {
8201 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8202 servicename, sharepath ));
8203 return USERSHARE_PATH_NOT_DIRECTORY;
8204 }
8205
8206 /* Check if sharing is restricted to owner-only. */
8207 /* psbuf is the stat of the usershare definition file,
8208 sbuf is the stat of the target directory to be shared. */
8209
8210 if (lp_usershare_owner_only()) {
8211 /* root can share anything. */
8212 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8213 return USERSHARE_PATH_NOT_ALLOWED;
8214 }
8215 }
8216
8217 *pp_sharepath = sharepath;
8218 *pp_comment = comment;
8219 return USERSHARE_OK;
8220}
8221
8222/***************************************************************************
8223 Deal with a usershare file.
8224 Returns:
8225 >= 0 - snum
8226 -1 - Bad name, invalid contents.
8227 - service name already existed and not a usershare, problem
8228 with permissions to share directory etc.
8229***************************************************************************/
8230
8231static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8232{
8233 SMB_STRUCT_STAT sbuf;
8234 SMB_STRUCT_STAT lsbuf;
8235 char *fname = NULL;
8236 char *sharepath = NULL;
8237 char *comment = NULL;
8238 fstring service_name;
8239 char **lines = NULL;
8240 int numlines = 0;
8241 int fd = -1;
8242 int iService = -1;
8243 TALLOC_CTX *ctx = NULL;
8244 SEC_DESC *psd = NULL;
8245 bool guest_ok = False;
8246
8247 /* Ensure share name doesn't contain invalid characters. */
8248 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8249 DEBUG(0,("process_usershare_file: share name %s contains "
8250 "invalid characters (any of %s)\n",
8251 file_name, INVALID_SHARENAME_CHARS ));
8252 return -1;
8253 }
8254
8255 fstrcpy(service_name, file_name);
8256
8257 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8258 }
8259
8260 /* Minimize the race condition by doing an lstat before we
8261 open and fstat. Ensure this isn't a symlink link. */
8262
8263 if (sys_lstat(fname, &lsbuf) != 0) {
8264 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8265 fname, strerror(errno) ));
8266 SAFE_FREE(fname);
8267 return -1;
8268 }
8269
8270 /* This must be a regular file, not a symlink, directory or
8271 other strange filetype. */
8272 if (!check_usershare_stat(fname, &lsbuf)) {
8273 SAFE_FREE(fname);
8274 return -1;
8275 }
8276
8277 {
8278 char *canon_name = canonicalize_servicename(service_name);
8279 TDB_DATA data = dbwrap_fetch_bystring(
8280 ServiceHash, canon_name, canon_name);
8281
8282 iService = -1;
8283
8284 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8285 iService = *(int *)data.dptr;
8286 }
8287 TALLOC_FREE(canon_name);
8288 }
8289
8290 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8291 /* Nothing changed - Mark valid and return. */
8292 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8293 service_name ));
8294 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8295 SAFE_FREE(fname);
8296 return iService;
8297 }
8298
8299 /* Try and open the file read only - no symlinks allowed. */
8300#ifdef O_NOFOLLOW
8301 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8302#else
8303 fd = sys_open(fname, O_RDONLY, 0);
8304#endif
8305
8306 if (fd == -1) {
8307 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8308 fname, strerror(errno) ));
8309 SAFE_FREE(fname);
8310 return -1;
8311 }
8312
8313 /* Now fstat to be *SURE* it's a regular file. */
8314 if (sys_fstat(fd, &sbuf) != 0) {
8315 close(fd);
8316 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8317 fname, strerror(errno) ));
8318 SAFE_FREE(fname);
8319 return -1;
8320 }
8321
8322 /* Is it the same dev/inode as was lstated ? */
8323 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8324 close(fd);
8325 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8326 "Symlink spoofing going on ?\n", fname ));
8327 SAFE_FREE(fname);
8328 return -1;
8329 }
8330
8331 /* This must be a regular file, not a symlink, directory or
8332 other strange filetype. */
8333 if (!check_usershare_stat(fname, &sbuf)) {
8334 SAFE_FREE(fname);
8335 return -1;
8336 }
8337
8338 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8339
8340 close(fd);
8341 if (lines == NULL) {
8342 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8343 fname, (unsigned int)sbuf.st_uid ));
8344 SAFE_FREE(fname);
8345 return -1;
8346 }
8347
8348 SAFE_FREE(fname);
8349
8350 /* Should we allow printers to be shared... ? */
8351 ctx = talloc_init("usershare_sd_xctx");
8352 if (!ctx) {
8353 file_lines_free(lines);
8354 return 1;
8355 }
8356
8357 if (parse_usershare_file(ctx, &sbuf, service_name,
8358 iService, lines, numlines, &sharepath,
8359 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8360 talloc_destroy(ctx);
8361 file_lines_free(lines);
8362 return -1;
8363 }
8364
8365 file_lines_free(lines);
8366
8367 /* Everything ok - add the service possibly using a template. */
8368 if (iService < 0) {
8369 const struct service *sp = &sDefault;
8370 if (snum_template != -1) {
8371 sp = ServicePtrs[snum_template];
8372 }
8373
8374 if ((iService = add_a_service(sp, service_name)) < 0) {
8375 DEBUG(0, ("process_usershare_file: Failed to add "
8376 "new service %s\n", service_name));
8377 talloc_destroy(ctx);
8378 return -1;
8379 }
8380
8381 /* Read only is controlled by usershare ACL below. */
8382 ServicePtrs[iService]->bRead_only = False;
8383 }
8384
8385 /* Write the ACL of the new/modified share. */
8386 if (!set_share_security(service_name, psd)) {
8387 DEBUG(0, ("process_usershare_file: Failed to set share "
8388 "security for user share %s\n",
8389 service_name ));
8390 lp_remove_service(iService);
8391 talloc_destroy(ctx);
8392 return -1;
8393 }
8394
8395 /* If from a template it may be marked invalid. */
8396 ServicePtrs[iService]->valid = True;
8397
8398 /* Set the service as a valid usershare. */
8399 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8400
8401 /* Set guest access. */
8402 if (lp_usershare_allow_guests()) {
8403 ServicePtrs[iService]->bGuest_ok = guest_ok;
8404 }
8405
8406 /* And note when it was loaded. */
8407 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8408 string_set(&ServicePtrs[iService]->szPath, sharepath);
8409 string_set(&ServicePtrs[iService]->comment, comment);
8410
8411 talloc_destroy(ctx);
8412
8413 return iService;
8414}
8415
8416/***************************************************************************
8417 Checks if a usershare entry has been modified since last load.
8418***************************************************************************/
8419
8420static bool usershare_exists(int iService, time_t *last_mod)
8421{
8422 SMB_STRUCT_STAT lsbuf;
8423 const char *usersharepath = Globals.szUsersharePath;
8424 char *fname;
8425
8426 if (asprintf(&fname, "%s/%s",
8427 usersharepath,
8428 ServicePtrs[iService]->szService) < 0) {
8429 return false;
8430 }
8431
8432 if (sys_lstat(fname, &lsbuf) != 0) {
8433 SAFE_FREE(fname);
8434 return false;
8435 }
8436
8437 if (!S_ISREG(lsbuf.st_mode)) {
8438 SAFE_FREE(fname);
8439 return false;
8440 }
8441
8442 SAFE_FREE(fname);
8443 *last_mod = lsbuf.st_mtime;
8444 return true;
8445}
8446
8447/***************************************************************************
8448 Load a usershare service by name. Returns a valid servicenumber or -1.
8449***************************************************************************/
8450
8451int load_usershare_service(const char *servicename)
8452{
8453 SMB_STRUCT_STAT sbuf;
8454 const char *usersharepath = Globals.szUsersharePath;
8455 int max_user_shares = Globals.iUsershareMaxShares;
8456 int snum_template = -1;
8457
8458 if (*usersharepath == 0 || max_user_shares == 0) {
8459 return -1;
8460 }
8461
8462 if (sys_stat(usersharepath, &sbuf) != 0) {
8463 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8464 usersharepath, strerror(errno) ));
8465 return -1;
8466 }
8467
8468 if (!S_ISDIR(sbuf.st_mode)) {
8469 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8470 usersharepath ));
8471 return -1;
8472 }
8473
8474 /*
8475 * This directory must be owned by root, and have the 't' bit set.
8476 * It also must not be writable by "other".
8477 */
8478
8479#ifdef S_ISVTX
8480 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8481#else
8482 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8483#endif
8484 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8485 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8486 usersharepath ));
8487 return -1;
8488 }
8489
8490 /* Ensure the template share exists if it's set. */
8491 if (Globals.szUsershareTemplateShare[0]) {
8492 /* We can't use lp_servicenumber here as we are recommending that
8493 template shares have -valid=False set. */
8494 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8495 if (ServicePtrs[snum_template]->szService &&
8496 strequal(ServicePtrs[snum_template]->szService,
8497 Globals.szUsershareTemplateShare)) {
8498 break;
8499 }
8500 }
8501
8502 if (snum_template == -1) {
8503 DEBUG(0,("load_usershare_service: usershare template share %s "
8504 "does not exist.\n",
8505 Globals.szUsershareTemplateShare ));
8506 return -1;
8507 }
8508 }
8509
8510 return process_usershare_file(usersharepath, servicename, snum_template);
8511}
8512
8513/***************************************************************************
8514 Load all user defined shares from the user share directory.
8515 We only do this if we're enumerating the share list.
8516 This is the function that can delete usershares that have
8517 been removed.
8518***************************************************************************/
8519
8520int load_usershare_shares(void)
8521{
8522 SMB_STRUCT_DIR *dp;
8523 SMB_STRUCT_STAT sbuf;
8524 SMB_STRUCT_DIRENT *de;
8525 int num_usershares = 0;
8526 int max_user_shares = Globals.iUsershareMaxShares;
8527 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8528 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8529 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8530 int iService;
8531 int snum_template = -1;
8532 const char *usersharepath = Globals.szUsersharePath;
8533 int ret = lp_numservices();
8534
8535 if (max_user_shares == 0 || *usersharepath == '\0') {
8536 return lp_numservices();
8537 }
8538
8539 if (sys_stat(usersharepath, &sbuf) != 0) {
8540 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8541 usersharepath, strerror(errno) ));
8542 return ret;
8543 }
8544
8545 /*
8546 * This directory must be owned by root, and have the 't' bit set.
8547 * It also must not be writable by "other".
8548 */
8549
8550#ifdef S_ISVTX
8551 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8552#else
8553 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8554#endif
8555 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8556 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8557 usersharepath ));
8558 return ret;
8559 }
8560
8561 /* Ensure the template share exists if it's set. */
8562 if (Globals.szUsershareTemplateShare[0]) {
8563 /* We can't use lp_servicenumber here as we are recommending that
8564 template shares have -valid=False set. */
8565 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8566 if (ServicePtrs[snum_template]->szService &&
8567 strequal(ServicePtrs[snum_template]->szService,
8568 Globals.szUsershareTemplateShare)) {
8569 break;
8570 }
8571 }
8572
8573 if (snum_template == -1) {
8574 DEBUG(0,("load_usershare_shares: usershare template share %s "
8575 "does not exist.\n",
8576 Globals.szUsershareTemplateShare ));
8577 return ret;
8578 }
8579 }
8580
8581 /* Mark all existing usershares as pending delete. */
8582 for (iService = iNumServices - 1; iService >= 0; iService--) {
8583 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8584 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8585 }
8586 }
8587
8588 dp = sys_opendir(usersharepath);
8589 if (!dp) {
8590 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8591 usersharepath, strerror(errno) ));
8592 return ret;
8593 }
8594
8595 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8596 (de = sys_readdir(dp));
8597 num_dir_entries++ ) {
8598 int r;
8599 const char *n = de->d_name;
8600
8601 /* Ignore . and .. */
8602 if (*n == '.') {
8603 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8604 continue;
8605 }
8606 }
8607
8608 if (n[0] == ':') {
8609 /* Temporary file used when creating a share. */
8610 num_tmp_dir_entries++;
8611 }
8612
8613 /* Allow 20% tmp entries. */
8614 if (num_tmp_dir_entries > allowed_tmp_entries) {
8615 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8616 "in directory %s\n",
8617 num_tmp_dir_entries, usersharepath));
8618 break;
8619 }
8620
8621 r = process_usershare_file(usersharepath, n, snum_template);
8622 if (r == 0) {
8623 /* Update the services count. */
8624 num_usershares++;
8625 if (num_usershares >= max_user_shares) {
8626 DEBUG(0,("load_usershare_shares: max user shares reached "
8627 "on file %s in directory %s\n",
8628 n, usersharepath ));
8629 break;
8630 }
8631 } else if (r == -1) {
8632 num_bad_dir_entries++;
8633 }
8634
8635 /* Allow 20% bad entries. */
8636 if (num_bad_dir_entries > allowed_bad_entries) {
8637 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8638 "in directory %s\n",
8639 num_bad_dir_entries, usersharepath));
8640 break;
8641 }
8642
8643 /* Allow 20% bad entries. */
8644 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8645 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8646 "in directory %s\n",
8647 num_dir_entries, usersharepath));
8648 break;
8649 }
8650 }
8651
8652 sys_closedir(dp);
8653
8654 /* Sweep through and delete any non-refreshed usershares that are
8655 not currently in use. */
8656 for (iService = iNumServices - 1; iService >= 0; iService--) {
8657 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8658 if (conn_snum_used(iService)) {
8659 continue;
8660 }
8661 /* Remove from the share ACL db. */
8662 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8663 lp_servicename(iService) ));
8664 delete_share_security(lp_servicename(iService));
8665 free_service_byindex(iService);
8666 }
8667 }
8668
8669 return lp_numservices();
8670}
8671
8672/********************************************************
8673 Destroy global resources allocated in this file
8674********************************************************/
8675
8676void gfree_loadparm(void)
8677{
8678 struct file_lists *f;
8679 struct file_lists *next;
8680 int i;
8681
8682 /* Free the file lists */
8683
8684 f = file_lists;
8685 while( f ) {
8686 next = f->next;
8687 SAFE_FREE( f->name );
8688 SAFE_FREE( f->subfname );
8689 SAFE_FREE( f );
8690 f = next;
8691 }
8692 file_lists = NULL;
8693
8694 /* Free resources allocated to services */
8695
8696 for ( i = 0; i < iNumServices; i++ ) {
8697 if ( VALID(i) ) {
8698 free_service_byindex(i);
8699 }
8700 }
8701
8702 SAFE_FREE( ServicePtrs );
8703 iNumServices = 0;
8704
8705 /* Now release all resources allocated to global
8706 parameters and the default service */
8707
8708 for (i = 0; parm_table[i].label; i++)
8709 {
8710 if ( parm_table[i].type == P_STRING
8711 || parm_table[i].type == P_USTRING )
8712 {
8713 string_free( (char**)parm_table[i].ptr );
8714 }
8715 else if (parm_table[i].type == P_LIST) {
8716 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8717 }
8718 }
8719}
8720
8721
8722/***************************************************************************
8723 Allow client apps to specify that they are a client
8724***************************************************************************/
8725void lp_set_in_client(bool b)
8726{
8727 in_client = b;
8728}
8729
8730
8731/***************************************************************************
8732 Determine if we're running in a client app
8733***************************************************************************/
8734bool lp_is_in_client(void)
8735{
8736 return in_client;
8737}
8738
8739
8740
8741
8742/***************************************************************************
8743 Load the services array from the services file. Return True on success,
8744 False on failure.
8745***************************************************************************/
8746
8747bool lp_load_ex(const char *pszFname,
8748 bool global_only,
8749 bool save_defaults,
8750 bool add_ipc,
8751 bool initialize_globals,
8752 bool allow_include_registry,
8753 bool allow_registry_shares)
8754{
8755 char *n2 = NULL;
8756 bool bRetval;
8757 param_opt_struct *data, *pdata;
8758
8759 bRetval = False;
8760
8761 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8762
8763 bInGlobalSection = True;
8764 bGlobalOnly = global_only;
8765 bAllowIncludeRegistry = allow_include_registry;
8766
8767 init_globals(! initialize_globals);
8768 debug_init();
8769
8770 if (save_defaults) {
8771 init_locals();
8772 lp_save_defaults();
8773 }
8774
8775 /* We get sections first, so have to start 'behind' to make up */
8776 iServiceIndex = -1;
8777
8778 if (Globals.param_opt != NULL) {
8779 data = Globals.param_opt;
8780 while (data) {
8781 string_free(&data->key);
8782 string_free(&data->value);
8783 TALLOC_FREE(data->list);
8784 pdata = data->next;
8785 SAFE_FREE(data);
8786 data = pdata;
8787 }
8788 Globals.param_opt = NULL;
8789 }
8790
8791 if (lp_config_backend_is_file()) {
8792 n2 = alloc_sub_basic(get_current_username(),
8793 current_user_info.domain,
8794 pszFname);
8795 if (!n2) {
8796 smb_panic("lp_load_ex: out of memory");
8797 }
8798
8799 add_to_file_list(pszFname, n2);
8800
8801 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8802 SAFE_FREE(n2);
8803
8804 /* finish up the last section */
8805 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8806 if (bRetval) {
8807 if (iServiceIndex >= 0) {
8808 bRetval = service_ok(iServiceIndex);
8809 }
8810 }
8811
8812 if (lp_config_backend_is_registry()) {
8813 /* config backend changed to registry in config file */
8814 /*
8815 * We need to use this extra global variable here to
8816 * survive restart: init_globals uses this as a default
8817 * for ConfigBackend. Otherwise, init_globals would
8818 * send us into an endless loop here.
8819 */
8820 config_backend = CONFIG_BACKEND_REGISTRY;
8821 /* start over */
8822 DEBUG(1, ("lp_load_ex: changing to config backend "
8823 "registry\n"));
8824 init_globals(false);
8825 lp_kill_all_services();
8826 return lp_load_ex(pszFname, global_only, save_defaults,
8827 add_ipc, initialize_globals,
8828 allow_include_registry,
8829 allow_registry_shares);
8830 }
8831 } else if (lp_config_backend_is_registry()) {
8832 bRetval = process_registry_globals();
8833 } else {
8834 DEBUG(0, ("Illegal config backend given: %d\n",
8835 lp_config_backend()));
8836 bRetval = false;
8837 }
8838
8839 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8840 bRetval = process_registry_shares();
8841 }
8842
8843 lp_add_auto_services(lp_auto_services());
8844
8845 if (add_ipc) {
8846 /* When 'restrict anonymous = 2' guest connections to ipc$
8847 are denied */
8848 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8849 if ( lp_enable_asu_support() ) {
8850 lp_add_ipc("ADMIN$", false);
8851 }
8852 }
8853
8854 set_server_role();
8855 set_default_server_announce_type();
8856 set_allowed_client_auth();
8857
8858 bLoaded = True;
8859
8860 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8861 /* if bWINSsupport is true and we are in the client */
8862 if (lp_is_in_client() && Globals.bWINSsupport) {
8863 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8864 }
8865
8866 init_iconv();
8867
8868 bAllowIncludeRegistry = true;
8869
8870 return (bRetval);
8871}
8872
8873bool lp_load(const char *pszFname,
8874 bool global_only,
8875 bool save_defaults,
8876 bool add_ipc,
8877 bool initialize_globals)
8878{
8879 return lp_load_ex(pszFname,
8880 global_only,
8881 save_defaults,
8882 add_ipc,
8883 initialize_globals,
8884 true, false);
8885}
8886
8887bool lp_load_initial_only(const char *pszFname)
8888{
8889 return lp_load_ex(pszFname,
8890 true,
8891 false,
8892 false,
8893 true,
8894 false,
8895 false);
8896}
8897
8898bool lp_load_with_registry_shares(const char *pszFname,
8899 bool global_only,
8900 bool save_defaults,
8901 bool add_ipc,
8902 bool initialize_globals)
8903{
8904 return lp_load_ex(pszFname,
8905 global_only,
8906 save_defaults,
8907 add_ipc,
8908 initialize_globals,
8909 true,
8910 true);
8911}
8912
8913/***************************************************************************
8914 Return the max number of services.
8915***************************************************************************/
8916
8917int lp_numservices(void)
8918{
8919 return (iNumServices);
8920}
8921
8922/***************************************************************************
8923Display the contents of the services array in human-readable form.
8924***************************************************************************/
8925
8926void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8927{
8928 int iService;
8929
8930 if (show_defaults)
8931 defaults_saved = False;
8932
8933 dump_globals(f);
8934
8935 dump_a_service(&sDefault, f);
8936
8937 for (iService = 0; iService < maxtoprint; iService++) {
8938 fprintf(f,"\n");
8939 lp_dump_one(f, show_defaults, iService);
8940 }
8941}
8942
8943/***************************************************************************
8944Display the contents of one service in human-readable form.
8945***************************************************************************/
8946
8947void lp_dump_one(FILE * f, bool show_defaults, int snum)
8948{
8949 if (VALID(snum)) {
8950 if (ServicePtrs[snum]->szService[0] == '\0')
8951 return;
8952 dump_a_service(ServicePtrs[snum], f);
8953 }
8954}
8955
8956/***************************************************************************
8957Return the number of the service with the given name, or -1 if it doesn't
8958exist. Note that this is a DIFFERENT ANIMAL from the internal function
8959getservicebyname()! This works ONLY if all services have been loaded, and
8960does not copy the found service.
8961***************************************************************************/
8962
8963int lp_servicenumber(const char *pszServiceName)
8964{
8965 int iService;
8966 fstring serviceName;
8967
8968 if (!pszServiceName) {
8969 return GLOBAL_SECTION_SNUM;
8970 }
8971
8972 for (iService = iNumServices - 1; iService >= 0; iService--) {
8973 if (VALID(iService) && ServicePtrs[iService]->szService) {
8974 /*
8975 * The substitution here is used to support %U is
8976 * service names
8977 */
8978 fstrcpy(serviceName, ServicePtrs[iService]->szService);
8979 standard_sub_basic(get_current_username(),
8980 current_user_info.domain,
8981 serviceName,sizeof(serviceName));
8982 if (strequal(serviceName, pszServiceName)) {
8983 break;
8984 }
8985 }
8986 }
8987
8988 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
8989 time_t last_mod;
8990
8991 if (!usershare_exists(iService, &last_mod)) {
8992 /* Remove the share security tdb entry for it. */
8993 delete_share_security(lp_servicename(iService));
8994 /* Remove it from the array. */
8995 free_service_byindex(iService);
8996 /* Doesn't exist anymore. */
8997 return GLOBAL_SECTION_SNUM;
8998 }
8999
9000 /* Has it been modified ? If so delete and reload. */
9001 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9002 /* Remove it from the array. */
9003 free_service_byindex(iService);
9004 /* and now reload it. */
9005 iService = load_usershare_service(pszServiceName);
9006 }
9007 }
9008
9009 if (iService < 0) {
9010 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9011 return GLOBAL_SECTION_SNUM;
9012 }
9013
9014 return (iService);
9015}
9016
9017bool share_defined(const char *service_name)
9018{
9019 return (lp_servicenumber(service_name) != -1);
9020}
9021
9022struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9023 const char *sharename)
9024{
9025 struct share_params *result;
9026 char *sname;
9027 int snum;
9028
9029 if (!(sname = SMB_STRDUP(sharename))) {
9030 return NULL;
9031 }
9032
9033 snum = find_service(sname);
9034 SAFE_FREE(sname);
9035
9036 if (snum < 0) {
9037 return NULL;
9038 }
9039
9040 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9041 DEBUG(0, ("talloc failed\n"));
9042 return NULL;
9043 }
9044
9045 result->service = snum;
9046 return result;
9047}
9048
9049struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9050{
9051 struct share_iterator *result;
9052
9053 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9054 DEBUG(0, ("talloc failed\n"));
9055 return NULL;
9056 }
9057
9058 result->next_id = 0;
9059 return result;
9060}
9061
9062struct share_params *next_share(struct share_iterator *list)
9063{
9064 struct share_params *result;
9065
9066 while (!lp_snum_ok(list->next_id) &&
9067 (list->next_id < lp_numservices())) {
9068 list->next_id += 1;
9069 }
9070
9071 if (list->next_id >= lp_numservices()) {
9072 return NULL;
9073 }
9074
9075 if (!(result = TALLOC_P(list, struct share_params))) {
9076 DEBUG(0, ("talloc failed\n"));
9077 return NULL;
9078 }
9079
9080 result->service = list->next_id;
9081 list->next_id += 1;
9082 return result;
9083}
9084
9085struct share_params *next_printer(struct share_iterator *list)
9086{
9087 struct share_params *result;
9088
9089 while ((result = next_share(list)) != NULL) {
9090 if (lp_print_ok(result->service)) {
9091 break;
9092 }
9093 }
9094 return result;
9095}
9096
9097/*
9098 * This is a hack for a transition period until we transformed all code from
9099 * service numbers to struct share_params.
9100 */
9101
9102struct share_params *snum2params_static(int snum)
9103{
9104 static struct share_params result;
9105 result.service = snum;
9106 return &result;
9107}
9108
9109/*******************************************************************
9110 A useful volume label function.
9111********************************************************************/
9112
9113const char *volume_label(int snum)
9114{
9115 char *ret;
9116 const char *label = lp_volume(snum);
9117 if (!*label) {
9118 label = lp_servicename(snum);
9119 }
9120
9121 /* This returns a 33 byte guarenteed null terminated string. */
9122 ret = talloc_strndup(talloc_tos(), label, 32);
9123 if (!ret) {
9124 return "";
9125 }
9126 return ret;
9127}
9128
9129/*******************************************************************
9130 Set the server type we will announce as via nmbd.
9131********************************************************************/
9132
9133static void set_default_server_announce_type(void)
9134{
9135 default_server_announce = 0;
9136 default_server_announce |= SV_TYPE_WORKSTATION;
9137 default_server_announce |= SV_TYPE_SERVER;
9138 default_server_announce |= SV_TYPE_SERVER_UNIX;
9139
9140 /* note that the flag should be set only if we have a
9141 printer service but nmbd doesn't actually load the
9142 services so we can't tell --jerry */
9143
9144 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9145
9146 switch (lp_announce_as()) {
9147 case ANNOUNCE_AS_NT_SERVER:
9148 default_server_announce |= SV_TYPE_SERVER_NT;
9149 /* fall through... */
9150 case ANNOUNCE_AS_NT_WORKSTATION:
9151 default_server_announce |= SV_TYPE_NT;
9152 break;
9153 case ANNOUNCE_AS_WIN95:
9154 default_server_announce |= SV_TYPE_WIN95_PLUS;
9155 break;
9156 case ANNOUNCE_AS_WFW:
9157 default_server_announce |= SV_TYPE_WFW;
9158 break;
9159 default:
9160 break;
9161 }
9162
9163 switch (lp_server_role()) {
9164 case ROLE_DOMAIN_MEMBER:
9165 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9166 break;
9167 case ROLE_DOMAIN_PDC:
9168 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9169 break;
9170 case ROLE_DOMAIN_BDC:
9171 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9172 break;
9173 case ROLE_STANDALONE:
9174 default:
9175 break;
9176 }
9177 if (lp_time_server())
9178 default_server_announce |= SV_TYPE_TIME_SOURCE;
9179
9180 if (lp_host_msdfs())
9181 default_server_announce |= SV_TYPE_DFS_SERVER;
9182}
9183
9184/***********************************************************
9185 returns role of Samba server
9186************************************************************/
9187
9188int lp_server_role(void)
9189{
9190 return server_role;
9191}
9192
9193/***********************************************************
9194 If we are PDC then prefer us as DMB
9195************************************************************/
9196
9197bool lp_domain_master(void)
9198{
9199 if (Globals.iDomainMaster == Auto)
9200 return (lp_server_role() == ROLE_DOMAIN_PDC);
9201
9202 return (bool)Globals.iDomainMaster;
9203}
9204
9205/***********************************************************
9206 If we are DMB then prefer us as LMB
9207************************************************************/
9208
9209bool lp_preferred_master(void)
9210{
9211 if (Globals.iPreferredMaster == Auto)
9212 return (lp_local_master() && lp_domain_master());
9213
9214 return (bool)Globals.iPreferredMaster;
9215}
9216
9217/*******************************************************************
9218 Remove a service.
9219********************************************************************/
9220
9221void lp_remove_service(int snum)
9222{
9223 ServicePtrs[snum]->valid = False;
9224 invalid_services[num_invalid_services++] = snum;
9225}
9226
9227/*******************************************************************
9228 Copy a service.
9229********************************************************************/
9230
9231void lp_copy_service(int snum, const char *new_name)
9232{
9233 do_section(new_name, NULL);
9234 if (snum >= 0) {
9235 snum = lp_servicenumber(new_name);
9236 if (snum >= 0)
9237 lp_do_parameter(snum, "copy", lp_servicename(snum));
9238 }
9239}
9240
9241
9242/*******************************************************************
9243 Get the default server type we will announce as via nmbd.
9244********************************************************************/
9245
9246int lp_default_server_announce(void)
9247{
9248 return default_server_announce;
9249}
9250
9251/*******************************************************************
9252 Split the announce version into major and minor numbers.
9253********************************************************************/
9254
9255int lp_major_announce_version(void)
9256{
9257 static bool got_major = False;
9258 static int major_version = DEFAULT_MAJOR_VERSION;
9259 char *vers;
9260 char *p;
9261
9262 if (got_major)
9263 return major_version;
9264
9265 got_major = True;
9266 if ((vers = lp_announce_version()) == NULL)
9267 return major_version;
9268
9269 if ((p = strchr_m(vers, '.')) == 0)
9270 return major_version;
9271
9272 *p = '\0';
9273 major_version = atoi(vers);
9274 return major_version;
9275}
9276
9277int lp_minor_announce_version(void)
9278{
9279 static bool got_minor = False;
9280 static int minor_version = DEFAULT_MINOR_VERSION;
9281 char *vers;
9282 char *p;
9283
9284 if (got_minor)
9285 return minor_version;
9286
9287 got_minor = True;
9288 if ((vers = lp_announce_version()) == NULL)
9289 return minor_version;
9290
9291 if ((p = strchr_m(vers, '.')) == 0)
9292 return minor_version;
9293
9294 p++;
9295 minor_version = atoi(p);
9296 return minor_version;
9297}
9298
9299/***********************************************************
9300 Set the global name resolution order (used in smbclient).
9301************************************************************/
9302
9303void lp_set_name_resolve_order(const char *new_order)
9304{
9305 string_set(&Globals.szNameResolveOrder, new_order);
9306}
9307
9308const char *lp_printername(int snum)
9309{
9310 const char *ret = _lp_printername(snum);
9311 if (ret == NULL || (ret != NULL && *ret == '\0'))
9312 ret = lp_const_servicename(snum);
9313
9314 return ret;
9315}
9316
9317
9318/***********************************************************
9319 Allow daemons such as winbindd to fix their logfile name.
9320************************************************************/
9321
9322void lp_set_logfile(const char *name)
9323{
9324 string_set(&Globals.szLogFile, name);
9325 debug_set_logfile(name);
9326}
9327
9328/*******************************************************************
9329 Return the max print jobs per queue.
9330********************************************************************/
9331
9332int lp_maxprintjobs(int snum)
9333{
9334 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9335 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9336 maxjobs = PRINT_MAX_JOBID - 1;
9337
9338 return maxjobs;
9339}
9340
9341const char *lp_printcapname(void)
9342{
9343 if ((Globals.szPrintcapname != NULL) &&
9344 (Globals.szPrintcapname[0] != '\0'))
9345 return Globals.szPrintcapname;
9346
9347 if (sDefault.iPrinting == PRINT_CUPS) {
9348#ifdef HAVE_CUPS
9349 return "cups";
9350#else
9351 return "lpstat";
9352#endif
9353 }
9354
9355 if (sDefault.iPrinting == PRINT_BSD)
9356 return "/etc/printcap";
9357
9358 return PRINTCAP_NAME;
9359}
9360
9361/*******************************************************************
9362 Ensure we don't use sendfile if server smb signing is active.
9363********************************************************************/
9364
9365static uint32 spoolss_state;
9366
9367bool lp_disable_spoolss( void )
9368{
9369 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9370 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9371
9372 return spoolss_state == SVCCTL_STOPPED ? True : False;
9373}
9374
9375void lp_set_spoolss_state( uint32 state )
9376{
9377 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9378
9379 spoolss_state = state;
9380}
9381
9382uint32 lp_get_spoolss_state( void )
9383{
9384 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9385}
9386
9387/*******************************************************************
9388 Ensure we don't use sendfile if server smb signing is active.
9389********************************************************************/
9390
9391bool lp_use_sendfile(int snum)
9392{
9393 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9394 if (Protocol < PROTOCOL_NT1) {
9395 return False;
9396 }
9397 return (_lp_use_sendfile(snum) &&
9398 (get_remote_arch() != RA_WIN95) &&
9399 !srv_is_signing_active());
9400}
9401
9402/*******************************************************************
9403 Turn off sendfile if we find the underlying OS doesn't support it.
9404********************************************************************/
9405
9406void set_use_sendfile(int snum, bool val)
9407{
9408 if (LP_SNUM_OK(snum))
9409 ServicePtrs[snum]->bUseSendfile = val;
9410 else
9411 sDefault.bUseSendfile = val;
9412}
9413
9414/*******************************************************************
9415 Turn off storing DOS attributes if this share doesn't support it.
9416********************************************************************/
9417
9418void set_store_dos_attributes(int snum, bool val)
9419{
9420 if (!LP_SNUM_OK(snum))
9421 return;
9422 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9423}
9424
9425void lp_set_mangling_method(const char *new_method)
9426{
9427 string_set(&Globals.szManglingMethod, new_method);
9428}
9429
9430/*******************************************************************
9431 Global state for POSIX pathname processing.
9432********************************************************************/
9433
9434static bool posix_pathnames;
9435
9436bool lp_posix_pathnames(void)
9437{
9438 return posix_pathnames;
9439}
9440
9441/*******************************************************************
9442 Change everything needed to ensure POSIX pathname processing (currently
9443 not much).
9444********************************************************************/
9445
9446void lp_set_posix_pathnames(void)
9447{
9448 posix_pathnames = True;
9449}
9450
9451/*******************************************************************
9452 Global state for POSIX lock processing - CIFS unix extensions.
9453********************************************************************/
9454
9455bool posix_default_lock_was_set;
9456static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9457
9458enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9459{
9460 if (posix_default_lock_was_set) {
9461 return posix_cifsx_locktype;
9462 } else {
9463 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9464 }
9465}
9466
9467/*******************************************************************
9468********************************************************************/
9469
9470void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9471{
9472 posix_default_lock_was_set = True;
9473 posix_cifsx_locktype = val;
9474}
9475
9476int lp_min_receive_file_size(void)
9477{
9478 if (Globals.iminreceivefile < 0) {
9479 return 0;
9480 }
9481 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9482}
9483
9484/*******************************************************************
9485 If socket address is an empty character string, it is necessary to
9486 define it as "0.0.0.0".
9487********************************************************************/
9488
9489const char *lp_socket_address(void)
9490{
9491 char *sock_addr = Globals.szSocketAddress;
9492
9493 if (sock_addr[0] == '\0'){
9494 string_set(&Globals.szSocketAddress, "0.0.0.0");
9495 }
9496 return Globals.szSocketAddress;
9497}
Note: See TracBrowser for help on using the repository browser.