source: branches/samba-3.3.x/source/param/loadparm.c@ 403

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

Update 3.3. to 3.3.8 (security update)

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