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

Last change on this file since 312 was 308, checked in by Silvan Scherrer, 16 years ago

attemp to fix ticket 100 in the 3.3 tree

File size: 254.5 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 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5920
5921 if (i < 0)
5922 return (False);
5923
5924 if (!(*(ServicePtrs[iDefaultService]->szPath))
5925 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5926 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5927 }
5928
5929 if (!(*(ServicePtrs[i]->comment))) {
5930 char *comment = NULL;
5931 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5932 return false;
5933 }
5934 string_set(&ServicePtrs[i]->comment, comment);
5935 SAFE_FREE(comment);
5936 }
5937
5938 /* set the browseable flag from the global default */
5939
5940 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5941
5942 ServicePtrs[i]->autoloaded = True;
5943
5944 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5945 user, ServicePtrs[i]->szPath ));
5946
5947 return (True);
5948}
5949
5950/***************************************************************************
5951 Add a new service, based on an old one.
5952***************************************************************************/
5953
5954int lp_add_service(const char *pszService, int iDefaultService)
5955{
5956 if (iDefaultService < 0) {
5957 return add_a_service(&sDefault, pszService);
5958 }
5959
5960 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5961}
5962
5963/***************************************************************************
5964 Add the IPC service.
5965***************************************************************************/
5966
5967static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5968{
5969 char *comment = NULL;
5970 int i = add_a_service(&sDefault, ipc_name);
5971
5972 if (i < 0)
5973 return (False);
5974
5975 if (asprintf(&comment, "IPC Service (%s)",
5976 Globals.szServerString) < 0) {
5977 return (False);
5978 }
5979
5980 string_set(&ServicePtrs[i]->szPath, tmpdir());
5981 string_set(&ServicePtrs[i]->szUsername, "");
5982 string_set(&ServicePtrs[i]->comment, comment);
5983 string_set(&ServicePtrs[i]->fstype, "IPC");
5984 ServicePtrs[i]->iMaxConnections = 0;
5985 ServicePtrs[i]->bAvailable = True;
5986 ServicePtrs[i]->bRead_only = True;
5987 ServicePtrs[i]->bGuest_only = False;
5988 ServicePtrs[i]->bAdministrative_share = True;
5989 ServicePtrs[i]->bGuest_ok = guest_ok;
5990 ServicePtrs[i]->bPrint_ok = False;
5991 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5992
5993 DEBUG(3, ("adding IPC service\n"));
5994
5995 SAFE_FREE(comment);
5996 return (True);
5997}
5998
5999/***************************************************************************
6000 Add a new printer service, with defaults coming from service iFrom.
6001***************************************************************************/
6002
6003bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6004{
6005 const char *comment = "From Printcap";
6006 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6007
6008 if (i < 0)
6009 return (False);
6010
6011 /* note that we do NOT default the availability flag to True - */
6012 /* we take it from the default service passed. This allows all */
6013 /* dynamic printers to be disabled by disabling the [printers] */
6014 /* entry (if/when the 'available' keyword is implemented!). */
6015
6016 /* the printer name is set to the service name. */
6017 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6018 string_set(&ServicePtrs[i]->comment, comment);
6019
6020 /* set the browseable flag from the gloabl default */
6021 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6022
6023 /* Printers cannot be read_only. */
6024 ServicePtrs[i]->bRead_only = False;
6025 /* No share modes on printer services. */
6026 ServicePtrs[i]->bShareModes = False;
6027 /* No oplocks on printer services. */
6028 ServicePtrs[i]->bOpLocks = False;
6029 /* Printer services must be printable. */
6030 ServicePtrs[i]->bPrint_ok = True;
6031
6032 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6033
6034 return (True);
6035}
6036
6037
6038/***************************************************************************
6039 Check whether the given parameter name is valid.
6040 Parametric options (names containing a colon) are considered valid.
6041***************************************************************************/
6042
6043bool lp_parameter_is_valid(const char *pszParmName)
6044{
6045 return ((map_parameter(pszParmName) != -1) ||
6046 (strchr(pszParmName, ':') != NULL));
6047}
6048
6049/***************************************************************************
6050 Check whether the given name is the name of a global parameter.
6051 Returns True for strings belonging to parameters of class
6052 P_GLOBAL, False for all other strings, also for parametric options
6053 and strings not belonging to any option.
6054***************************************************************************/
6055
6056bool lp_parameter_is_global(const char *pszParmName)
6057{
6058 int num = map_parameter(pszParmName);
6059
6060 if (num >= 0) {
6061 return (parm_table[num].p_class == P_GLOBAL);
6062 }
6063
6064 return False;
6065}
6066
6067/**************************************************************************
6068 Check whether the given name is the canonical name of a parameter.
6069 Returns False if it is not a valid parameter Name.
6070 For parametric options, True is returned.
6071**************************************************************************/
6072
6073bool lp_parameter_is_canonical(const char *parm_name)
6074{
6075 if (!lp_parameter_is_valid(parm_name)) {
6076 return False;
6077 }
6078
6079 return (map_parameter(parm_name) ==
6080 map_parameter_canonical(parm_name, NULL));
6081}
6082
6083/**************************************************************************
6084 Determine the canonical name for a parameter.
6085 Indicate when it is an inverse (boolean) synonym instead of a
6086 "usual" synonym.
6087**************************************************************************/
6088
6089bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6090 bool *inverse)
6091{
6092 int num;
6093
6094 if (!lp_parameter_is_valid(parm_name)) {
6095 *canon_parm = NULL;
6096 return False;
6097 }
6098
6099 num = map_parameter_canonical(parm_name, inverse);
6100 if (num < 0) {
6101 /* parametric option */
6102 *canon_parm = parm_name;
6103 } else {
6104 *canon_parm = parm_table[num].label;
6105 }
6106
6107 return True;
6108
6109}
6110
6111/**************************************************************************
6112 Determine the canonical name for a parameter.
6113 Turn the value given into the inverse boolean expression when
6114 the synonym is an invers boolean synonym.
6115
6116 Return True if parm_name is a valid parameter name and
6117 in case it is an invers boolean synonym, if the val string could
6118 successfully be converted to the reverse bool.
6119 Return false in all other cases.
6120**************************************************************************/
6121
6122bool lp_canonicalize_parameter_with_value(const char *parm_name,
6123 const char *val,
6124 const char **canon_parm,
6125 const char **canon_val)
6126{
6127 int num;
6128 bool inverse;
6129
6130 if (!lp_parameter_is_valid(parm_name)) {
6131 *canon_parm = NULL;
6132 *canon_val = NULL;
6133 return False;
6134 }
6135
6136 num = map_parameter_canonical(parm_name, &inverse);
6137 if (num < 0) {
6138 /* parametric option */
6139 *canon_parm = parm_name;
6140 *canon_val = val;
6141 } else {
6142 *canon_parm = parm_table[num].label;
6143 if (inverse) {
6144 if (!lp_invert_boolean(val, canon_val)) {
6145 *canon_val = NULL;
6146 return False;
6147 }
6148 } else {
6149 *canon_val = val;
6150 }
6151 }
6152
6153 return True;
6154}
6155
6156/***************************************************************************
6157 Map a parameter's string representation to something we can use.
6158 Returns False if the parameter string is not recognised, else TRUE.
6159***************************************************************************/
6160
6161static int map_parameter(const char *pszParmName)
6162{
6163 int iIndex;
6164
6165 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6166 return (-1);
6167
6168 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6169 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6170 return (iIndex);
6171
6172 /* Warn only if it isn't parametric option */
6173 if (strchr(pszParmName, ':') == NULL)
6174 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6175 /* We do return 'fail' for parametric options as well because they are
6176 stored in different storage
6177 */
6178 return (-1);
6179}
6180
6181/***************************************************************************
6182 Map a parameter's string representation to the index of the canonical
6183 form of the parameter (it might be a synonym).
6184 Returns -1 if the parameter string is not recognised.
6185***************************************************************************/
6186
6187static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6188{
6189 int parm_num, canon_num;
6190 bool loc_inverse = False;
6191
6192 parm_num = map_parameter(pszParmName);
6193 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6194 /* invalid, parametric or no canidate for synonyms ... */
6195 goto done;
6196 }
6197
6198 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6199 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6200 parm_num = canon_num;
6201 goto done;
6202 }
6203 }
6204
6205done:
6206 if (inverse != NULL) {
6207 *inverse = loc_inverse;
6208 }
6209 return parm_num;
6210}
6211
6212/***************************************************************************
6213 return true if parameter number parm1 is a synonym of parameter
6214 number parm2 (parm2 being the principal name).
6215 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6216 False otherwise.
6217***************************************************************************/
6218
6219static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6220{
6221 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6222 (parm_table[parm1].flags & FLAG_HIDE) &&
6223 !(parm_table[parm2].flags & FLAG_HIDE))
6224 {
6225 if (inverse != NULL) {
6226 if ((parm_table[parm1].type == P_BOOLREV) &&
6227 (parm_table[parm2].type == P_BOOL))
6228 {
6229 *inverse = True;
6230 } else {
6231 *inverse = False;
6232 }
6233 }
6234 return True;
6235 }
6236 return False;
6237}
6238
6239/***************************************************************************
6240 Show one parameter's name, type, [values,] and flags.
6241 (helper functions for show_parameter_list)
6242***************************************************************************/
6243
6244static void show_parameter(int parmIndex)
6245{
6246 int enumIndex, flagIndex;
6247 int parmIndex2;
6248 bool hadFlag;
6249 bool hadSyn;
6250 bool inverse;
6251 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6252 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6253 "P_ENUM", "P_SEP"};
6254 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6255 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6256 FLAG_HIDE, FLAG_DOS_STRING};
6257 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6258 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6259 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6260
6261 printf("%s=%s", parm_table[parmIndex].label,
6262 type[parm_table[parmIndex].type]);
6263 if (parm_table[parmIndex].type == P_ENUM) {
6264 printf(",");
6265 for (enumIndex=0;
6266 parm_table[parmIndex].enum_list[enumIndex].name;
6267 enumIndex++)
6268 {
6269 printf("%s%s",
6270 enumIndex ? "|" : "",
6271 parm_table[parmIndex].enum_list[enumIndex].name);
6272 }
6273 }
6274 printf(",");
6275 hadFlag = False;
6276 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6277 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6278 printf("%s%s",
6279 hadFlag ? "|" : "",
6280 flag_names[flagIndex]);
6281 hadFlag = True;
6282 }
6283 }
6284
6285 /* output synonyms */
6286 hadSyn = False;
6287 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6288 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6289 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6290 parm_table[parmIndex2].label);
6291 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6292 if (!hadSyn) {
6293 printf(" (synonyms: ");
6294 hadSyn = True;
6295 } else {
6296 printf(", ");
6297 }
6298 printf("%s%s", parm_table[parmIndex2].label,
6299 inverse ? "[i]" : "");
6300 }
6301 }
6302 if (hadSyn) {
6303 printf(")");
6304 }
6305
6306 printf("\n");
6307}
6308
6309/***************************************************************************
6310 Show all parameter's name, type, [values,] and flags.
6311***************************************************************************/
6312
6313void show_parameter_list(void)
6314{
6315 int classIndex, parmIndex;
6316 const char *section_names[] = { "local", "global", NULL};
6317
6318 for (classIndex=0; section_names[classIndex]; classIndex++) {
6319 printf("[%s]\n", section_names[classIndex]);
6320 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6321 if (parm_table[parmIndex].p_class == classIndex) {
6322 show_parameter(parmIndex);
6323 }
6324 }
6325 }
6326}
6327
6328/***************************************************************************
6329 Set a boolean variable from the text value stored in the passed string.
6330 Returns True in success, False if the passed string does not correctly
6331 represent a boolean.
6332***************************************************************************/
6333
6334static bool set_boolean(bool *pb, const char *pszParmValue)
6335{
6336 bool bRetval;
6337 bool value;
6338
6339 bRetval = True;
6340 value = False;
6341 if (strwicmp(pszParmValue, "yes") == 0 ||
6342 strwicmp(pszParmValue, "true") == 0 ||
6343 strwicmp(pszParmValue, "1") == 0)
6344 value = True;
6345 else if (strwicmp(pszParmValue, "no") == 0 ||
6346 strwicmp(pszParmValue, "False") == 0 ||
6347 strwicmp(pszParmValue, "0") == 0)
6348 value = False;
6349 else {
6350 DEBUG(2,
6351 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6352 pszParmValue));
6353 bRetval = False;
6354 }
6355
6356 if ((pb != NULL) && (bRetval != False)) {
6357 *pb = value;
6358 }
6359
6360 return (bRetval);
6361}
6362
6363
6364/***************************************************************************
6365 Check if a given string correctly represents a boolean value.
6366***************************************************************************/
6367
6368bool lp_string_is_valid_boolean(const char *parm_value)
6369{
6370 return set_boolean(NULL, parm_value);
6371}
6372
6373/***************************************************************************
6374 Get the standard string representation of a boolean value ("yes" or "no")
6375***************************************************************************/
6376
6377static const char *get_boolean(bool bool_value)
6378{
6379 static const char *yes_str = "yes";
6380 static const char *no_str = "no";
6381
6382 return (bool_value ? yes_str : no_str);
6383}
6384
6385/***************************************************************************
6386 Provide the string of the negated boolean value associated to the boolean
6387 given as a string. Returns False if the passed string does not correctly
6388 represent a boolean.
6389***************************************************************************/
6390
6391bool lp_invert_boolean(const char *str, const char **inverse_str)
6392{
6393 bool val;
6394
6395 if (!set_boolean(&val, str)) {
6396 return False;
6397 }
6398
6399 *inverse_str = get_boolean(!val);
6400 return True;
6401}
6402
6403/***************************************************************************
6404 Provide the canonical string representation of a boolean value given
6405 as a string. Return True on success, False if the string given does
6406 not correctly represent a boolean.
6407***************************************************************************/
6408
6409bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6410{
6411 bool val;
6412
6413 if (!set_boolean(&val, str)) {
6414 return False;
6415 }
6416
6417 *canon_str = get_boolean(val);
6418 return True;
6419}
6420
6421/***************************************************************************
6422Find a service by name. Otherwise works like get_service.
6423***************************************************************************/
6424
6425static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6426{
6427 int iService = -1;
6428 char *canon_name;
6429 TDB_DATA data;
6430
6431 if (ServiceHash == NULL) {
6432 return -1;
6433 }
6434
6435 canon_name = canonicalize_servicename(pszServiceName);
6436
6437 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6438
6439 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6440 iService = *(int *)data.dptr;
6441 }
6442
6443 TALLOC_FREE(canon_name);
6444
6445 if ((iService != -1) && (LP_SNUM_OK(iService))
6446 && (pserviceDest != NULL)) {
6447 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6448 }
6449
6450 return (iService);
6451}
6452
6453/***************************************************************************
6454 Copy a service structure to another.
6455 If pcopymapDest is NULL then copy all fields
6456***************************************************************************/
6457
6458static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6459 struct bitmap *pcopymapDest)
6460{
6461 int i;
6462 bool bcopyall = (pcopymapDest == NULL);
6463 struct param_opt_struct *data, *pdata, *paramo;
6464 bool not_added;
6465
6466 for (i = 0; parm_table[i].label; i++)
6467 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6468 (bcopyall || bitmap_query(pcopymapDest,i))) {
6469 void *def_ptr = parm_table[i].ptr;
6470 void *src_ptr =
6471 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6472 &sDefault);
6473 void *dest_ptr =
6474 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6475 &sDefault);
6476
6477 switch (parm_table[i].type) {
6478 case P_BOOL:
6479 case P_BOOLREV:
6480 *(bool *)dest_ptr = *(bool *)src_ptr;
6481 break;
6482
6483 case P_INTEGER:
6484 case P_ENUM:
6485 case P_OCTAL:
6486 *(int *)dest_ptr = *(int *)src_ptr;
6487 break;
6488
6489 case P_CHAR:
6490 *(char *)dest_ptr = *(char *)src_ptr;
6491 break;
6492
6493 case P_STRING:
6494 string_set((char **)dest_ptr,
6495 *(char **)src_ptr);
6496 break;
6497
6498 case P_USTRING:
6499 string_set((char **)dest_ptr,
6500 *(char **)src_ptr);
6501 strupper_m(*(char **)dest_ptr);
6502 break;
6503 case P_LIST:
6504 TALLOC_FREE(*((char ***)dest_ptr));
6505 str_list_copy(NULL, (char ***)dest_ptr,
6506 *(const char ***)src_ptr);
6507 break;
6508 default:
6509 break;
6510 }
6511 }
6512
6513 if (bcopyall) {
6514 init_copymap(pserviceDest);
6515 if (pserviceSource->copymap)
6516 bitmap_copy(pserviceDest->copymap,
6517 pserviceSource->copymap);
6518 }
6519
6520 data = pserviceSource->param_opt;
6521 while (data) {
6522 not_added = True;
6523 pdata = pserviceDest->param_opt;
6524 /* Traverse destination */
6525 while (pdata) {
6526 /* If we already have same option, override it */
6527 if (strwicmp(pdata->key, data->key) == 0) {
6528 string_free(&pdata->value);
6529 TALLOC_FREE(data->list);
6530 pdata->value = SMB_STRDUP(data->value);
6531 not_added = False;
6532 break;
6533 }
6534 pdata = pdata->next;
6535 }
6536 if (not_added) {
6537 paramo = SMB_XMALLOC_P(struct param_opt_struct);
6538 paramo->key = SMB_STRDUP(data->key);
6539 paramo->value = SMB_STRDUP(data->value);
6540 paramo->list = NULL;
6541 DLIST_ADD(pserviceDest->param_opt, paramo);
6542 }
6543 data = data->next;
6544 }
6545}
6546
6547/***************************************************************************
6548Check a service for consistency. Return False if the service is in any way
6549incomplete or faulty, else True.
6550***************************************************************************/
6551
6552bool service_ok(int iService)
6553{
6554 bool bRetval;
6555
6556 bRetval = True;
6557 if (ServicePtrs[iService]->szService[0] == '\0') {
6558 DEBUG(0, ("The following message indicates an internal error:\n"));
6559 DEBUG(0, ("No service name in service entry.\n"));
6560 bRetval = False;
6561 }
6562
6563 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6564 /* I can't see why you'd want a non-printable printer service... */
6565 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6566 if (!ServicePtrs[iService]->bPrint_ok) {
6567 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6568 ServicePtrs[iService]->szService));
6569 ServicePtrs[iService]->bPrint_ok = True;
6570 }
6571 /* [printers] service must also be non-browsable. */
6572 if (ServicePtrs[iService]->bBrowseable)
6573 ServicePtrs[iService]->bBrowseable = False;
6574 }
6575
6576 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6577 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6578 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6579 ) {
6580 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6581 ServicePtrs[iService]->szService));
6582 ServicePtrs[iService]->bAvailable = False;
6583 }
6584
6585 /* If a service is flagged unavailable, log the fact at level 1. */
6586 if (!ServicePtrs[iService]->bAvailable)
6587 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6588 ServicePtrs[iService]->szService));
6589
6590 return (bRetval);
6591}
6592
6593static struct smbconf_ctx *lp_smbconf_ctx(void)
6594{
6595 WERROR werr;
6596 static struct smbconf_ctx *conf_ctx = NULL;
6597
6598 if (conf_ctx == NULL) {
6599 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6600 if (!W_ERROR_IS_OK(werr)) {
6601 DEBUG(1, ("error initializing registry configuration: "
6602 "%s\n", dos_errstr(werr)));
6603 conf_ctx = NULL;
6604 }
6605 }
6606
6607 return conf_ctx;
6608}
6609
6610static bool process_registry_service(struct smbconf_service *service)
6611{
6612 uint32_t count;
6613 bool ret;
6614
6615 if (service == NULL) {
6616 return false;
6617 }
6618
6619 ret = do_section(service->name, NULL);
6620 if (ret != true) {
6621 return false;
6622 }
6623 for (count = 0; count < service->num_params; count++) {
6624 ret = do_parameter(service->param_names[count],
6625 service->param_values[count],
6626 NULL);
6627 if (ret != true) {
6628 return false;
6629 }
6630 }
6631 if (iServiceIndex >= 0) {
6632 return service_ok(iServiceIndex);
6633 }
6634 return true;
6635}
6636
6637/*
6638 * process_registry_globals
6639 */
6640static bool process_registry_globals(void)
6641{
6642 WERROR werr;
6643 struct smbconf_service *service = NULL;
6644 TALLOC_CTX *mem_ctx = talloc_stackframe();
6645 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6646 bool ret = false;
6647
6648 if (conf_ctx == NULL) {
6649 goto done;
6650 }
6651
6652 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6653
6654 ret = do_parameter("registry shares", "yes", NULL);
6655 if (!ret) {
6656 goto done;
6657 }
6658
6659 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6660 /* nothing to read from the registry yet but make sure lp_load
6661 * doesn't return false */
6662 ret = true;
6663 goto done;
6664 }
6665
6666 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6667 if (!W_ERROR_IS_OK(werr)) {
6668 goto done;
6669 }
6670
6671 ret = process_registry_service(service);
6672 if (!ret) {
6673 goto done;
6674 }
6675
6676 /* store the csn */
6677 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6678
6679done:
6680 TALLOC_FREE(mem_ctx);
6681 return ret;
6682}
6683
6684static bool process_registry_shares(void)
6685{
6686 WERROR werr;
6687 uint32_t count;
6688 struct smbconf_service **service = NULL;
6689 uint32_t num_shares = 0;
6690 TALLOC_CTX *mem_ctx = talloc_stackframe();
6691 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6692 bool ret = false;
6693
6694 if (conf_ctx == NULL) {
6695 goto done;
6696 }
6697
6698 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6699 if (!W_ERROR_IS_OK(werr)) {
6700 goto done;
6701 }
6702
6703 ret = true;
6704
6705 for (count = 0; count < num_shares; count++) {
6706 if (strequal(service[count]->name, GLOBAL_NAME)) {
6707 continue;
6708 }
6709 ret = process_registry_service(service[count]);
6710 if (!ret) {
6711 goto done;
6712 }
6713 }
6714
6715 /* store the csn */
6716 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6717
6718done:
6719 TALLOC_FREE(mem_ctx);
6720 return ret;
6721}
6722
6723#define MAX_INCLUDE_DEPTH 100
6724
6725static uint8_t include_depth;
6726
6727static struct file_lists {
6728 struct file_lists *next;
6729 char *name;
6730 char *subfname;
6731 time_t modtime;
6732} *file_lists = NULL;
6733
6734/*******************************************************************
6735 Keep a linked list of all config files so we know when one has changed
6736 it's date and needs to be reloaded.
6737********************************************************************/
6738
6739static void add_to_file_list(const char *fname, const char *subfname)
6740{
6741 struct file_lists *f = file_lists;
6742
6743 while (f) {
6744 if (f->name && !strcmp(f->name, fname))
6745 break;
6746 f = f->next;
6747 }
6748
6749 if (!f) {
6750 f = SMB_MALLOC_P(struct file_lists);
6751 if (!f)
6752 return;
6753 f->next = file_lists;
6754 f->name = SMB_STRDUP(fname);
6755 if (!f->name) {
6756 SAFE_FREE(f);
6757 return;
6758 }
6759 f->subfname = SMB_STRDUP(subfname);
6760 if (!f->subfname) {
6761 SAFE_FREE(f);
6762 return;
6763 }
6764 file_lists = f;
6765 f->modtime = file_modtime(subfname);
6766 } else {
6767 time_t t = file_modtime(subfname);
6768 if (t)
6769 f->modtime = t;
6770 }
6771}
6772
6773/**
6774 * Utility function for outsiders to check if we're running on registry.
6775 */
6776bool lp_config_backend_is_registry(void)
6777{
6778 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6779}
6780
6781/**
6782 * Utility function to check if the config backend is FILE.
6783 */
6784bool lp_config_backend_is_file(void)
6785{
6786 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6787}
6788
6789/*******************************************************************
6790 Check if a config file has changed date.
6791********************************************************************/
6792
6793bool lp_file_list_changed(void)
6794{
6795 struct file_lists *f = file_lists;
6796
6797 DEBUG(6, ("lp_file_list_changed()\n"));
6798
6799 while (f) {
6800 char *n2 = NULL;
6801 time_t mod_time;
6802
6803 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
6804 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6805
6806 if (conf_ctx == NULL) {
6807 return false;
6808 }
6809 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
6810 NULL))
6811 {
6812 DEBUGADD(6, ("registry config changed\n"));
6813 return true;
6814 }
6815 } else {
6816 n2 = alloc_sub_basic(get_current_username(),
6817 current_user_info.domain,
6818 f->name);
6819 if (!n2) {
6820 return false;
6821 }
6822 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6823 f->name, n2, ctime(&f->modtime)));
6824
6825 mod_time = file_modtime(n2);
6826
6827 if (mod_time &&
6828 ((f->modtime != mod_time) ||
6829 (f->subfname == NULL) ||
6830 (strcmp(n2, f->subfname) != 0)))
6831 {
6832 DEBUGADD(6,
6833 ("file %s modified: %s\n", n2,
6834 ctime(&mod_time)));
6835 f->modtime = mod_time;
6836 SAFE_FREE(f->subfname);
6837 f->subfname = n2; /* Passing ownership of
6838 return from alloc_sub_basic
6839 above. */
6840 return true;
6841 }
6842 SAFE_FREE(n2);
6843 }
6844 f = f->next;
6845 }
6846 return (False);
6847}
6848
6849
6850/***************************************************************************
6851 Run standard_sub_basic on netbios name... needed because global_myname
6852 is not accessed through any lp_ macro.
6853 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6854***************************************************************************/
6855
6856static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6857{
6858 bool ret;
6859 char *netbios_name = alloc_sub_basic(get_current_username(),
6860 current_user_info.domain,
6861 pszParmValue);
6862
6863 ret = set_global_myname(netbios_name);
6864 SAFE_FREE(netbios_name);
6865 string_set(&Globals.szNetbiosName,global_myname());
6866
6867 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6868 global_myname()));
6869
6870 return ret;
6871}
6872
6873static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6874{
6875 if (strcmp(*ptr, pszParmValue) != 0) {
6876 string_set(ptr, pszParmValue);
6877 init_iconv();
6878 }
6879 return True;
6880}
6881
6882
6883
6884static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6885{
6886 bool ret;
6887
6888 ret = set_global_myworkgroup(pszParmValue);
6889 string_set(&Globals.szWorkgroup,lp_workgroup());
6890
6891 return ret;
6892}
6893
6894static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6895{
6896 bool ret;
6897
6898 ret = set_global_scope(pszParmValue);
6899 string_set(&Globals.szNetbiosScope,global_scope());
6900
6901 return ret;
6902}
6903
6904static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6905{
6906 TALLOC_FREE(Globals.szNetbiosAliases);
6907 Globals.szNetbiosAliases = str_list_make(talloc_autofree_context(), pszParmValue, NULL);
6908 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6909}
6910
6911/***************************************************************************
6912 Handle the include operation.
6913***************************************************************************/
6914static bool bAllowIncludeRegistry = true;
6915
6916static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6917{
6918 char *fname;
6919
6920 if (include_depth >= MAX_INCLUDE_DEPTH) {
6921 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
6922 include_depth));
6923 return false;
6924 }
6925
6926 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6927 if (!bAllowIncludeRegistry) {
6928 return true;
6929 }
6930 if (bInGlobalSection) {
6931 bool ret;
6932 include_depth++;
6933 ret = process_registry_globals();
6934 include_depth--;
6935 return ret;
6936 } else {
6937 DEBUG(1, ("\"include = registry\" only effective "
6938 "in %s section\n", GLOBAL_NAME));
6939 return false;
6940 }
6941 }
6942
6943 fname = alloc_sub_basic(get_current_username(),
6944 current_user_info.domain,
6945 pszParmValue);
6946
6947 add_to_file_list(pszParmValue, fname);
6948
6949 string_set(ptr, fname);
6950
6951 if (file_exist(fname, NULL)) {
6952 bool ret;
6953 include_depth++;
6954 ret = pm_process(fname, do_section, do_parameter, NULL);
6955 include_depth--;
6956 SAFE_FREE(fname);
6957 return ret;
6958 }
6959
6960 DEBUG(2, ("Can't find include file %s\n", fname));
6961 SAFE_FREE(fname);
6962 return true;
6963}
6964
6965/***************************************************************************
6966 Handle the interpretation of the copy parameter.
6967***************************************************************************/
6968
6969static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6970{
6971 bool bRetval;
6972 int iTemp;
6973 struct service serviceTemp;
6974
6975 string_set(ptr, pszParmValue);
6976
6977 init_service(&serviceTemp);
6978
6979 bRetval = False;
6980
6981 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6982
6983 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6984 if (iTemp == iServiceIndex) {
6985 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6986 } else {
6987 copy_service(ServicePtrs[iServiceIndex],
6988 &serviceTemp,
6989 ServicePtrs[iServiceIndex]->copymap);
6990 bRetval = True;
6991 }
6992 } else {
6993 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6994 bRetval = False;
6995 }
6996
6997 free_service(&serviceTemp);
6998 return (bRetval);
6999}
7000
7001static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7002{
7003 Globals.ldap_debug_level = lp_int(pszParmValue);
7004 init_ldap_debugging();
7005 return true;
7006}
7007
7008/***************************************************************************
7009 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7010 parameters is:
7011
7012 [global]
7013
7014 idmap uid = 1000-1999
7015 idmap gid = 700-899
7016
7017 We only do simple parsing checks here. The strings are parsed into useful
7018 structures in the idmap daemon code.
7019
7020***************************************************************************/
7021
7022/* Some lp_ routines to return idmap [ug]id information */
7023
7024static uid_t idmap_uid_low, idmap_uid_high;
7025static gid_t idmap_gid_low, idmap_gid_high;
7026
7027bool lp_idmap_uid(uid_t *low, uid_t *high)
7028{
7029 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7030 return False;
7031
7032 if (low)
7033 *low = idmap_uid_low;
7034
7035 if (high)
7036 *high = idmap_uid_high;
7037
7038 return True;
7039}
7040
7041bool lp_idmap_gid(gid_t *low, gid_t *high)
7042{
7043 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7044 return False;
7045
7046 if (low)
7047 *low = idmap_gid_low;
7048
7049 if (high)
7050 *high = idmap_gid_high;
7051
7052 return True;
7053}
7054
7055/* Do some simple checks on "idmap [ug]id" parameter values */
7056
7057static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7058{
7059 uint32 low, high;
7060
7061 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7062 return False;
7063
7064 /* Parse OK */
7065
7066 string_set(ptr, pszParmValue);
7067
7068 idmap_uid_low = low;
7069 idmap_uid_high = high;
7070
7071 return True;
7072}
7073
7074static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7075{
7076 uint32 low, high;
7077
7078 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7079 return False;
7080
7081 /* Parse OK */
7082
7083 string_set(ptr, pszParmValue);
7084
7085 idmap_gid_low = low;
7086 idmap_gid_high = high;
7087
7088 return True;
7089}
7090
7091/***************************************************************************
7092 Handle the DEBUG level list.
7093***************************************************************************/
7094
7095static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7096{
7097 string_set(ptr, pszParmValueIn);
7098 return debug_parse_levels(pszParmValueIn);
7099}
7100
7101/***************************************************************************
7102 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7103***************************************************************************/
7104
7105static const char *append_ldap_suffix( const char *str )
7106{
7107 const char *suffix_string;
7108
7109
7110 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7111 Globals.szLdapSuffix );
7112 if ( !suffix_string ) {
7113 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7114 return "";
7115 }
7116
7117 return suffix_string;
7118}
7119
7120const char *lp_ldap_machine_suffix(void)
7121{
7122 if (Globals.szLdapMachineSuffix[0])
7123 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7124
7125 return lp_string(Globals.szLdapSuffix);
7126}
7127
7128const char *lp_ldap_user_suffix(void)
7129{
7130 if (Globals.szLdapUserSuffix[0])
7131 return append_ldap_suffix(Globals.szLdapUserSuffix);
7132
7133 return lp_string(Globals.szLdapSuffix);
7134}
7135
7136const char *lp_ldap_group_suffix(void)
7137{
7138 if (Globals.szLdapGroupSuffix[0])
7139 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7140
7141 return lp_string(Globals.szLdapSuffix);
7142}
7143
7144const char *lp_ldap_idmap_suffix(void)
7145{
7146 if (Globals.szLdapIdmapSuffix[0])
7147 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7148
7149 return lp_string(Globals.szLdapSuffix);
7150}
7151
7152/****************************************************************************
7153 set the value for a P_ENUM
7154 ***************************************************************************/
7155
7156static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7157 int *ptr )
7158{
7159 int i;
7160
7161 for (i = 0; parm->enum_list[i].name; i++) {
7162 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7163 *ptr = parm->enum_list[i].value;
7164 return;
7165 }
7166 }
7167 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7168 pszParmValue, parm->label));
7169}
7170
7171/***************************************************************************
7172***************************************************************************/
7173
7174static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7175{
7176 static int parm_num = -1;
7177 struct service *s;
7178
7179 if ( parm_num == -1 )
7180 parm_num = map_parameter( "printing" );
7181
7182 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7183
7184 if ( snum < 0 )
7185 s = &sDefault;
7186 else
7187 s = ServicePtrs[snum];
7188
7189 init_printer_values( s );
7190
7191 return True;
7192}
7193
7194
7195/***************************************************************************
7196 Initialise a copymap.
7197***************************************************************************/
7198
7199static void init_copymap(struct service *pservice)
7200{
7201 int i;
7202 if (pservice->copymap) {
7203 bitmap_free(pservice->copymap);
7204 }
7205 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7206 if (!pservice->copymap)
7207 DEBUG(0,
7208 ("Couldn't allocate copymap!! (size %d)\n",
7209 (int)NUMPARAMETERS));
7210 else
7211 for (i = 0; i < NUMPARAMETERS; i++)
7212 bitmap_set(pservice->copymap, i);
7213}
7214
7215/***************************************************************************
7216 Return the local pointer to a parameter given the service number and the
7217 pointer into the default structure.
7218***************************************************************************/
7219
7220void *lp_local_ptr(int snum, void *ptr)
7221{
7222 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7223}
7224
7225/***************************************************************************
7226 Process a parameter for a particular service number. If snum < 0
7227 then assume we are in the globals.
7228***************************************************************************/
7229
7230bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7231{
7232 int parmnum, i;
7233 void *parm_ptr = NULL; /* where we are going to store the result */
7234 void *def_ptr = NULL;
7235 struct param_opt_struct *paramo, *data;
7236 bool not_added;
7237
7238 parmnum = map_parameter(pszParmName);
7239
7240 if (parmnum < 0) {
7241 TALLOC_CTX *frame;
7242
7243 if (strchr(pszParmName, ':') == NULL) {
7244 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7245 pszParmName));
7246 return (True);
7247 }
7248
7249 /*
7250 * We've got a parametric option
7251 */
7252
7253 frame = talloc_stackframe();
7254
7255 not_added = True;
7256 data = (snum < 0)
7257 ? Globals.param_opt : ServicePtrs[snum]->param_opt;
7258 /* Traverse destination */
7259 while (data) {
7260 /* If we already have same option, override it */
7261 if (strwicmp(data->key, pszParmName) == 0) {
7262 string_free(&data->value);
7263 TALLOC_FREE(data->list);
7264 data->value = SMB_STRDUP(pszParmValue);
7265 not_added = False;
7266 break;
7267 }
7268 data = data->next;
7269 }
7270 if (not_added) {
7271 paramo = SMB_XMALLOC_P(struct param_opt_struct);
7272 paramo->key = SMB_STRDUP(pszParmName);
7273 paramo->value = SMB_STRDUP(pszParmValue);
7274 paramo->list = NULL;
7275 if (snum < 0) {
7276 DLIST_ADD(Globals.param_opt, paramo);
7277 } else {
7278 DLIST_ADD(ServicePtrs[snum]->param_opt,
7279 paramo);
7280 }
7281 }
7282
7283 TALLOC_FREE(frame);
7284 return (True);
7285 }
7286
7287 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7288 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7289 pszParmName));
7290 }
7291
7292 def_ptr = parm_table[parmnum].ptr;
7293
7294 /* we might point at a service, the default service or a global */
7295 if (snum < 0) {
7296 parm_ptr = def_ptr;
7297 } else {
7298 if (parm_table[parmnum].p_class == P_GLOBAL) {
7299 DEBUG(0,
7300 ("Global parameter %s found in service section!\n",
7301 pszParmName));
7302 return (True);
7303 }
7304 parm_ptr =
7305 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7306 &sDefault);
7307 }
7308
7309 if (snum >= 0) {
7310 if (!ServicePtrs[snum]->copymap)
7311 init_copymap(ServicePtrs[snum]);
7312
7313 /* this handles the aliases - set the copymap for other entries with
7314 the same data pointer */
7315 for (i = 0; parm_table[i].label; i++)
7316 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7317 bitmap_clear(ServicePtrs[snum]->copymap, i);
7318 }
7319
7320 /* if it is a special case then go ahead */
7321 if (parm_table[parmnum].special) {
7322 return parm_table[parmnum].special(snum, pszParmValue,
7323 (char **)parm_ptr);
7324 }
7325
7326 /* now switch on the type of variable it is */
7327 switch (parm_table[parmnum].type)
7328 {
7329 case P_BOOL:
7330 *(bool *)parm_ptr = lp_bool(pszParmValue);
7331 break;
7332
7333 case P_BOOLREV:
7334 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7335 break;
7336
7337 case P_INTEGER:
7338 *(int *)parm_ptr = lp_int(pszParmValue);
7339 break;
7340
7341 case P_CHAR:
7342 *(char *)parm_ptr = *pszParmValue;
7343 break;
7344
7345 case P_OCTAL:
7346 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7347 if ( i != 1 ) {
7348 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7349 }
7350 break;
7351
7352 case P_LIST:
7353 TALLOC_FREE(*((char ***)parm_ptr));
7354 *(char ***)parm_ptr = str_list_make(
7355 talloc_autofree_context(), pszParmValue, NULL);
7356 break;
7357
7358 case P_STRING:
7359 string_set((char **)parm_ptr, pszParmValue);
7360 break;
7361
7362 case P_USTRING:
7363 string_set((char **)parm_ptr, pszParmValue);
7364 strupper_m(*(char **)parm_ptr);
7365 break;
7366
7367 case P_ENUM:
7368 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7369 break;
7370 case P_SEP:
7371 break;
7372 }
7373
7374 return (True);
7375}
7376
7377/***************************************************************************
7378 Process a parameter.
7379***************************************************************************/
7380
7381static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7382 void *userdata)
7383{
7384 if (!bInGlobalSection && bGlobalOnly)
7385 return (True);
7386
7387 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7388
7389 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7390 pszParmName, pszParmValue));
7391}
7392
7393/***************************************************************************
7394 Print a parameter of the specified type.
7395***************************************************************************/
7396
7397static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7398{
7399 int i;
7400 switch (p->type)
7401 {
7402 case P_ENUM:
7403 for (i = 0; p->enum_list[i].name; i++) {
7404 if (*(int *)ptr == p->enum_list[i].value) {
7405 fprintf(f, "%s",
7406 p->enum_list[i].name);
7407 break;
7408 }
7409 }
7410 break;
7411
7412 case P_BOOL:
7413 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7414 break;
7415
7416 case P_BOOLREV:
7417 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7418 break;
7419
7420 case P_INTEGER:
7421 fprintf(f, "%d", *(int *)ptr);
7422 break;
7423
7424 case P_CHAR:
7425 fprintf(f, "%c", *(char *)ptr);
7426 break;
7427
7428 case P_OCTAL: {
7429 char *o = octal_string(*(int *)ptr);
7430 fprintf(f, "%s", o);
7431 TALLOC_FREE(o);
7432 break;
7433 }
7434
7435 case P_LIST:
7436 if ((char ***)ptr && *(char ***)ptr) {
7437 char **list = *(char ***)ptr;
7438 for (; *list; list++) {
7439 /* surround strings with whitespace in double quotes */
7440 if ( strchr_m( *list, ' ' ) )
7441 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7442 else
7443 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7444 }
7445 }
7446 break;
7447
7448 case P_STRING:
7449 case P_USTRING:
7450 if (*(char **)ptr) {
7451 fprintf(f, "%s", *(char **)ptr);
7452 }
7453 break;
7454 case P_SEP:
7455 break;
7456 }
7457}
7458
7459/***************************************************************************
7460 Check if two parameters are equal.
7461***************************************************************************/
7462
7463static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7464{
7465 switch (type) {
7466 case P_BOOL:
7467 case P_BOOLREV:
7468 return (*((bool *)ptr1) == *((bool *)ptr2));
7469
7470 case P_INTEGER:
7471 case P_ENUM:
7472 case P_OCTAL:
7473 return (*((int *)ptr1) == *((int *)ptr2));
7474
7475 case P_CHAR:
7476 return (*((char *)ptr1) == *((char *)ptr2));
7477
7478 case P_LIST:
7479 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7480
7481 case P_STRING:
7482 case P_USTRING:
7483 {
7484 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7485 if (p1 && !*p1)
7486 p1 = NULL;
7487 if (p2 && !*p2)
7488 p2 = NULL;
7489 return (p1 == p2 || strequal(p1, p2));
7490 }
7491 case P_SEP:
7492 break;
7493 }
7494 return (False);
7495}
7496
7497/***************************************************************************
7498 Initialize any local varients in the sDefault table.
7499***************************************************************************/
7500
7501void init_locals(void)
7502{
7503 /* None as yet. */
7504}
7505
7506/***************************************************************************
7507 Process a new section (service). At this stage all sections are services.
7508 Later we'll have special sections that permit server parameters to be set.
7509 Returns True on success, False on failure.
7510***************************************************************************/
7511
7512static bool do_section(const char *pszSectionName, void *userdata)
7513{
7514 bool bRetval;
7515 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7516 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7517 bRetval = False;
7518
7519 /* if we were in a global section then do the local inits */
7520 if (bInGlobalSection && !isglobal)
7521 init_locals();
7522
7523 /* if we've just struck a global section, note the fact. */
7524 bInGlobalSection = isglobal;
7525
7526 /* check for multiple global sections */
7527 if (bInGlobalSection) {
7528 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7529 return (True);
7530 }
7531
7532 if (!bInGlobalSection && bGlobalOnly)
7533 return (True);
7534
7535 /* if we have a current service, tidy it up before moving on */
7536 bRetval = True;
7537
7538 if (iServiceIndex >= 0)
7539 bRetval = service_ok(iServiceIndex);
7540
7541 /* if all is still well, move to the next record in the services array */
7542 if (bRetval) {
7543 /* We put this here to avoid an odd message order if messages are */
7544 /* issued by the post-processing of a previous section. */
7545 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7546
7547 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7548 < 0) {
7549 DEBUG(0, ("Failed to add a new service\n"));
7550 return (False);
7551 }
7552 }
7553
7554 return (bRetval);
7555}
7556
7557
7558/***************************************************************************
7559 Determine if a partcular base parameter is currentl set to the default value.
7560***************************************************************************/
7561
7562static bool is_default(int i)
7563{
7564 if (!defaults_saved)
7565 return False;
7566 switch (parm_table[i].type) {
7567 case P_LIST:
7568 return str_list_compare (parm_table[i].def.lvalue,
7569 *(char ***)parm_table[i].ptr);
7570 case P_STRING:
7571 case P_USTRING:
7572 return strequal(parm_table[i].def.svalue,
7573 *(char **)parm_table[i].ptr);
7574 case P_BOOL:
7575 case P_BOOLREV:
7576 return parm_table[i].def.bvalue ==
7577 *(bool *)parm_table[i].ptr;
7578 case P_CHAR:
7579 return parm_table[i].def.cvalue ==
7580 *(char *)parm_table[i].ptr;
7581 case P_INTEGER:
7582 case P_OCTAL:
7583 case P_ENUM:
7584 return parm_table[i].def.ivalue ==
7585 *(int *)parm_table[i].ptr;
7586 case P_SEP:
7587 break;
7588 }
7589 return False;
7590}
7591
7592/***************************************************************************
7593Display the contents of the global structure.
7594***************************************************************************/
7595
7596static void dump_globals(FILE *f)
7597{
7598 int i;
7599 struct param_opt_struct *data;
7600
7601 fprintf(f, "[global]\n");
7602
7603 for (i = 0; parm_table[i].label; i++)
7604 if (parm_table[i].p_class == P_GLOBAL &&
7605 parm_table[i].ptr &&
7606 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7607 if (defaults_saved && is_default(i))
7608 continue;
7609 fprintf(f, "\t%s = ", parm_table[i].label);
7610 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7611 fprintf(f, "\n");
7612 }
7613 if (Globals.param_opt != NULL) {
7614 data = Globals.param_opt;
7615 while(data) {
7616 fprintf(f, "\t%s = %s\n", data->key, data->value);
7617 data = data->next;
7618 }
7619 }
7620
7621}
7622
7623/***************************************************************************
7624 Return True if a local parameter is currently set to the global default.
7625***************************************************************************/
7626
7627bool lp_is_default(int snum, struct parm_struct *parm)
7628{
7629 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7630
7631 return equal_parameter(parm->type,
7632 ((char *)ServicePtrs[snum]) + pdiff,
7633 ((char *)&sDefault) + pdiff);
7634}
7635
7636/***************************************************************************
7637 Display the contents of a single services record.
7638***************************************************************************/
7639
7640static void dump_a_service(struct service *pService, FILE * f)
7641{
7642 int i;
7643 struct param_opt_struct *data;
7644
7645 if (pService != &sDefault)
7646 fprintf(f, "[%s]\n", pService->szService);
7647
7648 for (i = 0; parm_table[i].label; i++) {
7649
7650 if (parm_table[i].p_class == P_LOCAL &&
7651 parm_table[i].ptr &&
7652 (*parm_table[i].label != '-') &&
7653 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7654 {
7655
7656 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7657
7658 if (pService == &sDefault) {
7659 if (defaults_saved && is_default(i))
7660 continue;
7661 } else {
7662 if (equal_parameter(parm_table[i].type,
7663 ((char *)pService) +
7664 pdiff,
7665 ((char *)&sDefault) +
7666 pdiff))
7667 continue;
7668 }
7669
7670 fprintf(f, "\t%s = ", parm_table[i].label);
7671 print_parameter(&parm_table[i],
7672 ((char *)pService) + pdiff, f);
7673 fprintf(f, "\n");
7674 }
7675 }
7676
7677 if (pService->param_opt != NULL) {
7678 data = pService->param_opt;
7679 while(data) {
7680 fprintf(f, "\t%s = %s\n", data->key, data->value);
7681 data = data->next;
7682 }
7683 }
7684}
7685
7686/***************************************************************************
7687 Display the contents of a parameter of a single services record.
7688***************************************************************************/
7689
7690bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7691{
7692 int i;
7693 bool result = False;
7694 parm_class p_class;
7695 unsigned flag = 0;
7696 fstring local_parm_name;
7697 char *parm_opt;
7698 const char *parm_opt_value;
7699
7700 /* check for parametrical option */
7701 fstrcpy( local_parm_name, parm_name);
7702 parm_opt = strchr( local_parm_name, ':');
7703
7704 if (parm_opt) {
7705 *parm_opt = '\0';
7706 parm_opt++;
7707 if (strlen(parm_opt)) {
7708 parm_opt_value = lp_parm_const_string( snum,
7709 local_parm_name, parm_opt, NULL);
7710 if (parm_opt_value) {
7711 printf( "%s\n", parm_opt_value);
7712 result = True;
7713 }
7714 }
7715 return result;
7716 }
7717
7718 /* check for a key and print the value */
7719 if (isGlobal) {
7720 p_class = P_GLOBAL;
7721 flag = FLAG_GLOBAL;
7722 } else
7723 p_class = P_LOCAL;
7724
7725 for (i = 0; parm_table[i].label; i++) {
7726 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7727 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7728 parm_table[i].ptr &&
7729 (*parm_table[i].label != '-') &&
7730 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7731 {
7732 void *ptr;
7733
7734 if (isGlobal) {
7735 ptr = parm_table[i].ptr;
7736 } else {
7737 struct service *pService = ServicePtrs[snum];
7738 ptr = ((char *)pService) +
7739 PTR_DIFF(parm_table[i].ptr, &sDefault);
7740 }
7741
7742 print_parameter(&parm_table[i],
7743 ptr, f);
7744 fprintf(f, "\n");
7745 result = True;
7746 break;
7747 }
7748 }
7749
7750 return result;
7751}
7752
7753/***************************************************************************
7754 Return info about the requested parameter (given as a string).
7755 Return NULL when the string is not a valid parameter name.
7756***************************************************************************/
7757
7758struct parm_struct *lp_get_parameter(const char *param_name)
7759{
7760 int num = map_parameter(param_name);
7761
7762 if (num < 0) {
7763 return NULL;
7764 }
7765
7766 return &parm_table[num];
7767}
7768
7769/***************************************************************************
7770 Return info about the next parameter in a service.
7771 snum==GLOBAL_SECTION_SNUM gives the globals.
7772 Return NULL when out of parameters.
7773***************************************************************************/
7774
7775struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7776{
7777 if (snum < 0) {
7778 /* do the globals */
7779 for (; parm_table[*i].label; (*i)++) {
7780 if (parm_table[*i].p_class == P_SEPARATOR)
7781 return &parm_table[(*i)++];
7782
7783 if (!parm_table[*i].ptr
7784 || (*parm_table[*i].label == '-'))
7785 continue;
7786
7787 if ((*i) > 0
7788 && (parm_table[*i].ptr ==
7789 parm_table[(*i) - 1].ptr))
7790 continue;
7791
7792 if (is_default(*i) && !allparameters)
7793 continue;
7794
7795 return &parm_table[(*i)++];
7796 }
7797 } else {
7798 struct service *pService = ServicePtrs[snum];
7799
7800 for (; parm_table[*i].label; (*i)++) {
7801 if (parm_table[*i].p_class == P_SEPARATOR)
7802 return &parm_table[(*i)++];
7803
7804 if (parm_table[*i].p_class == P_LOCAL &&
7805 parm_table[*i].ptr &&
7806 (*parm_table[*i].label != '-') &&
7807 ((*i) == 0 ||
7808 (parm_table[*i].ptr !=
7809 parm_table[(*i) - 1].ptr)))
7810 {
7811 int pdiff =
7812 PTR_DIFF(parm_table[*i].ptr,
7813 &sDefault);
7814
7815 if (allparameters ||
7816 !equal_parameter(parm_table[*i].type,
7817 ((char *)pService) +
7818 pdiff,
7819 ((char *)&sDefault) +
7820 pdiff))
7821 {
7822 return &parm_table[(*i)++];
7823 }
7824 }
7825 }
7826 }
7827
7828 return NULL;
7829}
7830
7831
7832#if 0
7833/***************************************************************************
7834 Display the contents of a single copy structure.
7835***************************************************************************/
7836static void dump_copy_map(bool *pcopymap)
7837{
7838 int i;
7839 if (!pcopymap)
7840 return;
7841
7842 printf("\n\tNon-Copied parameters:\n");
7843
7844 for (i = 0; parm_table[i].label; i++)
7845 if (parm_table[i].p_class == P_LOCAL &&
7846 parm_table[i].ptr && !pcopymap[i] &&
7847 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7848 {
7849 printf("\t\t%s\n", parm_table[i].label);
7850 }
7851}
7852#endif
7853
7854/***************************************************************************
7855 Return TRUE if the passed service number is within range.
7856***************************************************************************/
7857
7858bool lp_snum_ok(int iService)
7859{
7860 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7861}
7862
7863/***************************************************************************
7864 Auto-load some home services.
7865***************************************************************************/
7866
7867static void lp_add_auto_services(char *str)
7868{
7869 char *s;
7870 char *p;
7871 int homes;
7872 char *saveptr;
7873
7874 if (!str)
7875 return;
7876
7877 s = SMB_STRDUP(str);
7878 if (!s)
7879 return;
7880
7881 homes = lp_servicenumber(HOMES_NAME);
7882
7883 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7884 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7885 char *home;
7886
7887 if (lp_servicenumber(p) >= 0)
7888 continue;
7889
7890 home = get_user_home_dir(talloc_tos(), p);
7891
7892 if (home && homes >= 0)
7893 lp_add_home(p, homes, p, home);
7894
7895 TALLOC_FREE(home);
7896 }
7897 SAFE_FREE(s);
7898}
7899
7900/***************************************************************************
7901 Auto-load one printer.
7902***************************************************************************/
7903
7904void lp_add_one_printer(const char *name, const char *comment, void *pdata)
7905{
7906 int printers = lp_servicenumber(PRINTERS_NAME);
7907 int i;
7908
7909 if (lp_servicenumber(name) < 0) {
7910 lp_add_printer(name, printers);
7911 if ((i = lp_servicenumber(name)) >= 0) {
7912 string_set(&ServicePtrs[i]->comment, comment);
7913 ServicePtrs[i]->autoloaded = True;
7914 }
7915 }
7916}
7917
7918/***************************************************************************
7919 Have we loaded a services file yet?
7920***************************************************************************/
7921
7922bool lp_loaded(void)
7923{
7924 return (bLoaded);
7925}
7926
7927/***************************************************************************
7928 Unload unused services.
7929***************************************************************************/
7930
7931void lp_killunused(bool (*snumused) (int))
7932{
7933 int i;
7934 for (i = 0; i < iNumServices; i++) {
7935 if (!VALID(i))
7936 continue;
7937
7938 /* don't kill autoloaded or usershare services */
7939 if ( ServicePtrs[i]->autoloaded ||
7940 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7941 continue;
7942 }
7943
7944 if (!snumused || !snumused(i)) {
7945 free_service_byindex(i);
7946 }
7947 }
7948}
7949
7950/**
7951 * Kill all except autoloaded and usershare services - convenience wrapper
7952 */
7953void lp_kill_all_services(void)
7954{
7955 lp_killunused(NULL);
7956}
7957
7958/***************************************************************************
7959 Unload a service.
7960***************************************************************************/
7961
7962void lp_killservice(int iServiceIn)
7963{
7964 if (VALID(iServiceIn)) {
7965 free_service_byindex(iServiceIn);
7966 }
7967}
7968
7969/***************************************************************************
7970 Save the curent values of all global and sDefault parameters into the
7971 defaults union. This allows swat and testparm to show only the
7972 changed (ie. non-default) parameters.
7973***************************************************************************/
7974
7975static void lp_save_defaults(void)
7976{
7977 int i;
7978 for (i = 0; parm_table[i].label; i++) {
7979 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7980 continue;
7981 switch (parm_table[i].type) {
7982 case P_LIST:
7983 str_list_copy(
7984 NULL, &(parm_table[i].def.lvalue),
7985 *(const char ***)parm_table[i].ptr);
7986 break;
7987 case P_STRING:
7988 case P_USTRING:
7989 if (parm_table[i].ptr) {
7990 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7991 } else {
7992 parm_table[i].def.svalue = NULL;
7993 }
7994 break;
7995 case P_BOOL:
7996 case P_BOOLREV:
7997 parm_table[i].def.bvalue =
7998 *(bool *)parm_table[i].ptr;
7999 break;
8000 case P_CHAR:
8001 parm_table[i].def.cvalue =
8002 *(char *)parm_table[i].ptr;
8003 break;
8004 case P_INTEGER:
8005 case P_OCTAL:
8006 case P_ENUM:
8007 parm_table[i].def.ivalue =
8008 *(int *)parm_table[i].ptr;
8009 break;
8010 case P_SEP:
8011 break;
8012 }
8013 }
8014 defaults_saved = True;
8015}
8016
8017/*******************************************************************
8018 Set the server type we will announce as via nmbd.
8019********************************************************************/
8020
8021static const struct srv_role_tab {
8022 uint32 role;
8023 const char *role_str;
8024} srv_role_tab [] = {
8025 { ROLE_STANDALONE, "ROLE_STANDALONE" },
8026 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8027 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8028 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8029 { 0, NULL }
8030};
8031
8032const char* server_role_str(uint32 role)
8033{
8034 int i = 0;
8035 for (i=0; srv_role_tab[i].role_str; i++) {
8036 if (role == srv_role_tab[i].role) {
8037 return srv_role_tab[i].role_str;
8038 }
8039 }
8040 return NULL;
8041}
8042
8043static void set_server_role(void)
8044{
8045 server_role = ROLE_STANDALONE;
8046
8047 switch (lp_security()) {
8048 case SEC_SHARE:
8049 if (lp_domain_logons())
8050 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8051 break;
8052 case SEC_SERVER:
8053 if (lp_domain_logons())
8054 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8055 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8056 server_role = ROLE_STANDALONE;
8057 break;
8058 case SEC_DOMAIN:
8059 if (lp_domain_logons()) {
8060 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8061 server_role = ROLE_DOMAIN_BDC;
8062 break;
8063 }
8064 server_role = ROLE_DOMAIN_MEMBER;
8065 break;
8066 case SEC_ADS:
8067 if (lp_domain_logons()) {
8068 server_role = ROLE_DOMAIN_PDC;
8069 break;
8070 }
8071 server_role = ROLE_DOMAIN_MEMBER;
8072 break;
8073 case SEC_USER:
8074 if (lp_domain_logons()) {
8075
8076 if (Globals.iDomainMaster) /* auto or yes */
8077 server_role = ROLE_DOMAIN_PDC;
8078 else
8079 server_role = ROLE_DOMAIN_BDC;
8080 }
8081 break;
8082 default:
8083 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8084 break;
8085 }
8086
8087 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8088}
8089
8090/***********************************************************
8091 If we should send plaintext/LANMAN passwords in the clinet
8092************************************************************/
8093
8094static void set_allowed_client_auth(void)
8095{
8096 if (Globals.bClientNTLMv2Auth) {
8097 Globals.bClientLanManAuth = False;
8098 }
8099 if (!Globals.bClientLanManAuth) {
8100 Globals.bClientPlaintextAuth = False;
8101 }
8102}
8103
8104/***************************************************************************
8105 JRA.
8106 The following code allows smbd to read a user defined share file.
8107 Yes, this is my intent. Yes, I'm comfortable with that...
8108
8109 THE FOLLOWING IS SECURITY CRITICAL CODE.
8110
8111 It washes your clothes, it cleans your house, it guards you while you sleep...
8112 Do not f%^k with it....
8113***************************************************************************/
8114
8115#define MAX_USERSHARE_FILE_SIZE (10*1024)
8116
8117/***************************************************************************
8118 Check allowed stat state of a usershare file.
8119 Ensure we print out who is dicking with us so the admin can
8120 get their sorry ass fired.
8121***************************************************************************/
8122
8123static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8124{
8125 if (!S_ISREG(psbuf->st_mode)) {
8126 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8127 "not a regular file\n",
8128 fname, (unsigned int)psbuf->st_uid ));
8129 return False;
8130 }
8131
8132 /* Ensure this doesn't have the other write bit set. */
8133 if (psbuf->st_mode & S_IWOTH) {
8134 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8135 "public write. Refusing to allow as a usershare file.\n",
8136 fname, (unsigned int)psbuf->st_uid ));
8137 return False;
8138 }
8139
8140 /* Should be 10k or less. */
8141 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8142 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8143 "too large (%u) to be a user share file.\n",
8144 fname, (unsigned int)psbuf->st_uid,
8145 (unsigned int)psbuf->st_size ));
8146 return False;
8147 }
8148
8149 return True;
8150}
8151
8152/***************************************************************************
8153 Parse the contents of a usershare file.
8154***************************************************************************/
8155
8156enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8157 SMB_STRUCT_STAT *psbuf,
8158 const char *servicename,
8159 int snum,
8160 char **lines,
8161 int numlines,
8162 char **pp_sharepath,
8163 char **pp_comment,
8164 SEC_DESC **ppsd,
8165 bool *pallow_guest)
8166{
8167 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8168 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8169 int us_vers;
8170 SMB_STRUCT_DIR *dp;
8171 SMB_STRUCT_STAT sbuf;
8172 char *sharepath = NULL;
8173 char *comment = NULL;
8174
8175 *pp_sharepath = NULL;
8176 *pp_comment = NULL;
8177
8178 *pallow_guest = False;
8179
8180 if (numlines < 4) {
8181 return USERSHARE_MALFORMED_FILE;
8182 }
8183
8184 if (strcmp(lines[0], "#VERSION 1") == 0) {
8185 us_vers = 1;
8186 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8187 us_vers = 2;
8188 if (numlines < 5) {
8189 return USERSHARE_MALFORMED_FILE;
8190 }
8191 } else {
8192 return USERSHARE_BAD_VERSION;
8193 }
8194
8195 if (strncmp(lines[1], "path=", 5) != 0) {
8196 return USERSHARE_MALFORMED_PATH;
8197 }
8198
8199 sharepath = talloc_strdup(ctx, &lines[1][5]);
8200 if (!sharepath) {
8201 return USERSHARE_POSIX_ERR;
8202 }
8203 trim_string(sharepath, " ", " ");
8204
8205 if (strncmp(lines[2], "comment=", 8) != 0) {
8206 return USERSHARE_MALFORMED_COMMENT_DEF;
8207 }
8208
8209 comment = talloc_strdup(ctx, &lines[2][8]);
8210 if (!comment) {
8211 return USERSHARE_POSIX_ERR;
8212 }
8213 trim_string(comment, " ", " ");
8214 trim_char(comment, '"', '"');
8215
8216 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8217 return USERSHARE_MALFORMED_ACL_DEF;
8218 }
8219
8220 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8221 return USERSHARE_ACL_ERR;
8222 }
8223
8224 if (us_vers == 2) {
8225 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8226 return USERSHARE_MALFORMED_ACL_DEF;
8227 }
8228 if (lines[4][9] == 'y') {
8229 *pallow_guest = True;
8230 }
8231 }
8232
8233 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8234 /* Path didn't change, no checks needed. */
8235 *pp_sharepath = sharepath;
8236 *pp_comment = comment;
8237 return USERSHARE_OK;
8238 }
8239
8240 /* The path *must* be absolute. */
8241 if (sharepath[0] != '/') {
8242 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8243 servicename, sharepath));
8244 return USERSHARE_PATH_NOT_ABSOLUTE;
8245 }
8246
8247 /* If there is a usershare prefix deny list ensure one of these paths
8248 doesn't match the start of the user given path. */
8249 if (prefixdenylist) {
8250 int i;
8251 for ( i=0; prefixdenylist[i]; i++ ) {
8252 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8253 servicename, i, prefixdenylist[i], sharepath ));
8254 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8255 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8256 "usershare prefix deny list entries.\n",
8257 servicename, sharepath));
8258 return USERSHARE_PATH_IS_DENIED;
8259 }
8260 }
8261 }
8262
8263 /* If there is a usershare prefix allow list ensure one of these paths
8264 does match the start of the user given path. */
8265
8266 if (prefixallowlist) {
8267 int i;
8268 for ( i=0; prefixallowlist[i]; i++ ) {
8269 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8270 servicename, i, prefixallowlist[i], sharepath ));
8271 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8272 break;
8273 }
8274 }
8275 if (prefixallowlist[i] == NULL) {
8276 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8277 "usershare prefix allow list entries.\n",
8278 servicename, sharepath));
8279 return USERSHARE_PATH_NOT_ALLOWED;
8280 }
8281 }
8282
8283 /* Ensure this is pointing to a directory. */
8284 dp = sys_opendir(sharepath);
8285
8286 if (!dp) {
8287 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8288 servicename, sharepath));
8289 return USERSHARE_PATH_NOT_DIRECTORY;
8290 }
8291
8292 /* Ensure the owner of the usershare file has permission to share
8293 this directory. */
8294
8295 if (sys_stat(sharepath, &sbuf) == -1) {
8296 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8297 servicename, sharepath, strerror(errno) ));
8298 sys_closedir(dp);
8299 return USERSHARE_POSIX_ERR;
8300 }
8301
8302 sys_closedir(dp);
8303
8304 if (!S_ISDIR(sbuf.st_mode)) {
8305 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8306 servicename, sharepath ));
8307 return USERSHARE_PATH_NOT_DIRECTORY;
8308 }
8309
8310 /* Check if sharing is restricted to owner-only. */
8311 /* psbuf is the stat of the usershare definition file,
8312 sbuf is the stat of the target directory to be shared. */
8313
8314 if (lp_usershare_owner_only()) {
8315 /* root can share anything. */
8316 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8317 return USERSHARE_PATH_NOT_ALLOWED;
8318 }
8319 }
8320
8321 *pp_sharepath = sharepath;
8322 *pp_comment = comment;
8323 return USERSHARE_OK;
8324}
8325
8326/***************************************************************************
8327 Deal with a usershare file.
8328 Returns:
8329 >= 0 - snum
8330 -1 - Bad name, invalid contents.
8331 - service name already existed and not a usershare, problem
8332 with permissions to share directory etc.
8333***************************************************************************/
8334
8335static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8336{
8337 SMB_STRUCT_STAT sbuf;
8338 SMB_STRUCT_STAT lsbuf;
8339 char *fname = NULL;
8340 char *sharepath = NULL;
8341 char *comment = NULL;
8342 fstring service_name;
8343 char **lines = NULL;
8344 int numlines = 0;
8345 int fd = -1;
8346 int iService = -1;
8347 TALLOC_CTX *ctx = NULL;
8348 SEC_DESC *psd = NULL;
8349 bool guest_ok = False;
8350
8351 /* Ensure share name doesn't contain invalid characters. */
8352 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8353 DEBUG(0,("process_usershare_file: share name %s contains "
8354 "invalid characters (any of %s)\n",
8355 file_name, INVALID_SHARENAME_CHARS ));
8356 return -1;
8357 }
8358
8359 fstrcpy(service_name, file_name);
8360
8361 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8362 }
8363
8364 /* Minimize the race condition by doing an lstat before we
8365 open and fstat. Ensure this isn't a symlink link. */
8366
8367 if (sys_lstat(fname, &lsbuf) != 0) {
8368 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8369 fname, strerror(errno) ));
8370 SAFE_FREE(fname);
8371 return -1;
8372 }
8373
8374 /* This must be a regular file, not a symlink, directory or
8375 other strange filetype. */
8376 if (!check_usershare_stat(fname, &lsbuf)) {
8377 SAFE_FREE(fname);
8378 return -1;
8379 }
8380
8381 {
8382 char *canon_name = canonicalize_servicename(service_name);
8383 TDB_DATA data = dbwrap_fetch_bystring(
8384 ServiceHash, canon_name, canon_name);
8385
8386 iService = -1;
8387
8388 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8389 iService = *(int *)data.dptr;
8390 }
8391 TALLOC_FREE(canon_name);
8392 }
8393
8394 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8395 /* Nothing changed - Mark valid and return. */
8396 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8397 service_name ));
8398 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8399 SAFE_FREE(fname);
8400 return iService;
8401 }
8402
8403 /* Try and open the file read only - no symlinks allowed. */
8404#ifdef O_NOFOLLOW
8405 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8406#else
8407 fd = sys_open(fname, O_RDONLY, 0);
8408#endif
8409
8410 if (fd == -1) {
8411 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8412 fname, strerror(errno) ));
8413 SAFE_FREE(fname);
8414 return -1;
8415 }
8416
8417 /* Now fstat to be *SURE* it's a regular file. */
8418 if (sys_fstat(fd, &sbuf) != 0) {
8419 close(fd);
8420 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8421 fname, strerror(errno) ));
8422 SAFE_FREE(fname);
8423 return -1;
8424 }
8425
8426 /* Is it the same dev/inode as was lstated ? */
8427 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8428 close(fd);
8429 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8430 "Symlink spoofing going on ?\n", fname ));
8431 SAFE_FREE(fname);
8432 return -1;
8433 }
8434
8435 /* This must be a regular file, not a symlink, directory or
8436 other strange filetype. */
8437 if (!check_usershare_stat(fname, &sbuf)) {
8438 SAFE_FREE(fname);
8439 return -1;
8440 }
8441
8442 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8443
8444 close(fd);
8445 if (lines == NULL) {
8446 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8447 fname, (unsigned int)sbuf.st_uid ));
8448 SAFE_FREE(fname);
8449 return -1;
8450 }
8451
8452 SAFE_FREE(fname);
8453
8454 /* Should we allow printers to be shared... ? */
8455 ctx = talloc_init("usershare_sd_xctx");
8456 if (!ctx) {
8457 file_lines_free(lines);
8458 return 1;
8459 }
8460
8461 if (parse_usershare_file(ctx, &sbuf, service_name,
8462 iService, lines, numlines, &sharepath,
8463 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8464 talloc_destroy(ctx);
8465 file_lines_free(lines);
8466 return -1;
8467 }
8468
8469 file_lines_free(lines);
8470
8471 /* Everything ok - add the service possibly using a template. */
8472 if (iService < 0) {
8473 const struct service *sp = &sDefault;
8474 if (snum_template != -1) {
8475 sp = ServicePtrs[snum_template];
8476 }
8477
8478 if ((iService = add_a_service(sp, service_name)) < 0) {
8479 DEBUG(0, ("process_usershare_file: Failed to add "
8480 "new service %s\n", service_name));
8481 talloc_destroy(ctx);
8482 return -1;
8483 }
8484
8485 /* Read only is controlled by usershare ACL below. */
8486 ServicePtrs[iService]->bRead_only = False;
8487 }
8488
8489 /* Write the ACL of the new/modified share. */
8490 if (!set_share_security(service_name, psd)) {
8491 DEBUG(0, ("process_usershare_file: Failed to set share "
8492 "security for user share %s\n",
8493 service_name ));
8494 lp_remove_service(iService);
8495 talloc_destroy(ctx);
8496 return -1;
8497 }
8498
8499 /* If from a template it may be marked invalid. */
8500 ServicePtrs[iService]->valid = True;
8501
8502 /* Set the service as a valid usershare. */
8503 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8504
8505 /* Set guest access. */
8506 if (lp_usershare_allow_guests()) {
8507 ServicePtrs[iService]->bGuest_ok = guest_ok;
8508 }
8509
8510 /* And note when it was loaded. */
8511 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8512 string_set(&ServicePtrs[iService]->szPath, sharepath);
8513 string_set(&ServicePtrs[iService]->comment, comment);
8514
8515 talloc_destroy(ctx);
8516
8517 return iService;
8518}
8519
8520/***************************************************************************
8521 Checks if a usershare entry has been modified since last load.
8522***************************************************************************/
8523
8524static bool usershare_exists(int iService, time_t *last_mod)
8525{
8526 SMB_STRUCT_STAT lsbuf;
8527 const char *usersharepath = Globals.szUsersharePath;
8528 char *fname;
8529
8530 if (asprintf(&fname, "%s/%s",
8531 usersharepath,
8532 ServicePtrs[iService]->szService) < 0) {
8533 return false;
8534 }
8535
8536 if (sys_lstat(fname, &lsbuf) != 0) {
8537 SAFE_FREE(fname);
8538 return false;
8539 }
8540
8541 if (!S_ISREG(lsbuf.st_mode)) {
8542 SAFE_FREE(fname);
8543 return false;
8544 }
8545
8546 SAFE_FREE(fname);
8547 *last_mod = lsbuf.st_mtime;
8548 return true;
8549}
8550
8551/***************************************************************************
8552 Load a usershare service by name. Returns a valid servicenumber or -1.
8553***************************************************************************/
8554
8555int load_usershare_service(const char *servicename)
8556{
8557 SMB_STRUCT_STAT sbuf;
8558 const char *usersharepath = Globals.szUsersharePath;
8559 int max_user_shares = Globals.iUsershareMaxShares;
8560 int snum_template = -1;
8561
8562 if (*usersharepath == 0 || max_user_shares == 0) {
8563 return -1;
8564 }
8565
8566 if (sys_stat(usersharepath, &sbuf) != 0) {
8567 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8568 usersharepath, strerror(errno) ));
8569 return -1;
8570 }
8571
8572 if (!S_ISDIR(sbuf.st_mode)) {
8573 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8574 usersharepath ));
8575 return -1;
8576 }
8577
8578 /*
8579 * This directory must be owned by root, and have the 't' bit set.
8580 * It also must not be writable by "other".
8581 */
8582
8583#ifdef S_ISVTX
8584 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8585#else
8586 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8587#endif
8588 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8589 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8590 usersharepath ));
8591 return -1;
8592 }
8593
8594 /* Ensure the template share exists if it's set. */
8595 if (Globals.szUsershareTemplateShare[0]) {
8596 /* We can't use lp_servicenumber here as we are recommending that
8597 template shares have -valid=False set. */
8598 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8599 if (ServicePtrs[snum_template]->szService &&
8600 strequal(ServicePtrs[snum_template]->szService,
8601 Globals.szUsershareTemplateShare)) {
8602 break;
8603 }
8604 }
8605
8606 if (snum_template == -1) {
8607 DEBUG(0,("load_usershare_service: usershare template share %s "
8608 "does not exist.\n",
8609 Globals.szUsershareTemplateShare ));
8610 return -1;
8611 }
8612 }
8613
8614 return process_usershare_file(usersharepath, servicename, snum_template);
8615}
8616
8617/***************************************************************************
8618 Load all user defined shares from the user share directory.
8619 We only do this if we're enumerating the share list.
8620 This is the function that can delete usershares that have
8621 been removed.
8622***************************************************************************/
8623
8624int load_usershare_shares(void)
8625{
8626 SMB_STRUCT_DIR *dp;
8627 SMB_STRUCT_STAT sbuf;
8628 SMB_STRUCT_DIRENT *de;
8629 int num_usershares = 0;
8630 int max_user_shares = Globals.iUsershareMaxShares;
8631 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8632 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8633 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8634 int iService;
8635 int snum_template = -1;
8636 const char *usersharepath = Globals.szUsersharePath;
8637 int ret = lp_numservices();
8638
8639 if (max_user_shares == 0 || *usersharepath == '\0') {
8640 return lp_numservices();
8641 }
8642
8643 if (sys_stat(usersharepath, &sbuf) != 0) {
8644 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8645 usersharepath, strerror(errno) ));
8646 return ret;
8647 }
8648
8649 /*
8650 * This directory must be owned by root, and have the 't' bit set.
8651 * It also must not be writable by "other".
8652 */
8653
8654#ifdef S_ISVTX
8655 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8656#else
8657 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8658#endif
8659 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8660 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8661 usersharepath ));
8662 return ret;
8663 }
8664
8665 /* Ensure the template share exists if it's set. */
8666 if (Globals.szUsershareTemplateShare[0]) {
8667 /* We can't use lp_servicenumber here as we are recommending that
8668 template shares have -valid=False set. */
8669 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8670 if (ServicePtrs[snum_template]->szService &&
8671 strequal(ServicePtrs[snum_template]->szService,
8672 Globals.szUsershareTemplateShare)) {
8673 break;
8674 }
8675 }
8676
8677 if (snum_template == -1) {
8678 DEBUG(0,("load_usershare_shares: usershare template share %s "
8679 "does not exist.\n",
8680 Globals.szUsershareTemplateShare ));
8681 return ret;
8682 }
8683 }
8684
8685 /* Mark all existing usershares as pending delete. */
8686 for (iService = iNumServices - 1; iService >= 0; iService--) {
8687 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8688 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8689 }
8690 }
8691
8692 dp = sys_opendir(usersharepath);
8693 if (!dp) {
8694 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8695 usersharepath, strerror(errno) ));
8696 return ret;
8697 }
8698
8699 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8700 (de = sys_readdir(dp));
8701 num_dir_entries++ ) {
8702 int r;
8703 const char *n = de->d_name;
8704
8705 /* Ignore . and .. */
8706 if (*n == '.') {
8707 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8708 continue;
8709 }
8710 }
8711
8712 if (n[0] == ':') {
8713 /* Temporary file used when creating a share. */
8714 num_tmp_dir_entries++;
8715 }
8716
8717 /* Allow 20% tmp entries. */
8718 if (num_tmp_dir_entries > allowed_tmp_entries) {
8719 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8720 "in directory %s\n",
8721 num_tmp_dir_entries, usersharepath));
8722 break;
8723 }
8724
8725 r = process_usershare_file(usersharepath, n, snum_template);
8726 if (r == 0) {
8727 /* Update the services count. */
8728 num_usershares++;
8729 if (num_usershares >= max_user_shares) {
8730 DEBUG(0,("load_usershare_shares: max user shares reached "
8731 "on file %s in directory %s\n",
8732 n, usersharepath ));
8733 break;
8734 }
8735 } else if (r == -1) {
8736 num_bad_dir_entries++;
8737 }
8738
8739 /* Allow 20% bad entries. */
8740 if (num_bad_dir_entries > allowed_bad_entries) {
8741 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8742 "in directory %s\n",
8743 num_bad_dir_entries, usersharepath));
8744 break;
8745 }
8746
8747 /* Allow 20% bad entries. */
8748 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8749 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8750 "in directory %s\n",
8751 num_dir_entries, usersharepath));
8752 break;
8753 }
8754 }
8755
8756 sys_closedir(dp);
8757
8758 /* Sweep through and delete any non-refreshed usershares that are
8759 not currently in use. */
8760 for (iService = iNumServices - 1; iService >= 0; iService--) {
8761 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8762 if (conn_snum_used(iService)) {
8763 continue;
8764 }
8765 /* Remove from the share ACL db. */
8766 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8767 lp_servicename(iService) ));
8768 delete_share_security(lp_servicename(iService));
8769 free_service_byindex(iService);
8770 }
8771 }
8772
8773 return lp_numservices();
8774}
8775
8776/********************************************************
8777 Destroy global resources allocated in this file
8778********************************************************/
8779
8780void gfree_loadparm(void)
8781{
8782 struct file_lists *f;
8783 struct file_lists *next;
8784 int i;
8785
8786 /* Free the file lists */
8787
8788 f = file_lists;
8789 while( f ) {
8790 next = f->next;
8791 SAFE_FREE( f->name );
8792 SAFE_FREE( f->subfname );
8793 SAFE_FREE( f );
8794 f = next;
8795 }
8796 file_lists = NULL;
8797
8798 /* Free resources allocated to services */
8799
8800 for ( i = 0; i < iNumServices; i++ ) {
8801 if ( VALID(i) ) {
8802 free_service_byindex(i);
8803 }
8804 }
8805
8806 SAFE_FREE( ServicePtrs );
8807 iNumServices = 0;
8808
8809 /* Now release all resources allocated to global
8810 parameters and the default service */
8811
8812 for (i = 0; parm_table[i].label; i++)
8813 {
8814 if ( parm_table[i].type == P_STRING
8815 || parm_table[i].type == P_USTRING )
8816 {
8817 string_free( (char**)parm_table[i].ptr );
8818 }
8819 else if (parm_table[i].type == P_LIST) {
8820 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8821 }
8822 }
8823}
8824
8825
8826/***************************************************************************
8827 Allow client apps to specify that they are a client
8828***************************************************************************/
8829void lp_set_in_client(bool b)
8830{
8831 in_client = b;
8832}
8833
8834
8835/***************************************************************************
8836 Determine if we're running in a client app
8837***************************************************************************/
8838bool lp_is_in_client(void)
8839{
8840 return in_client;
8841}
8842
8843
8844
8845
8846/***************************************************************************
8847 Load the services array from the services file. Return True on success,
8848 False on failure.
8849***************************************************************************/
8850
8851bool lp_load_ex(const char *pszFname,
8852 bool global_only,
8853 bool save_defaults,
8854 bool add_ipc,
8855 bool initialize_globals,
8856 bool allow_include_registry,
8857 bool allow_registry_shares)
8858{
8859 char *n2 = NULL;
8860 bool bRetval;
8861 struct param_opt_struct *data, *pdata;
8862
8863 bRetval = False;
8864
8865 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8866
8867 bInGlobalSection = True;
8868 bGlobalOnly = global_only;
8869 bAllowIncludeRegistry = allow_include_registry;
8870
8871 init_globals(! initialize_globals);
8872 debug_init();
8873
8874 if (save_defaults) {
8875 init_locals();
8876 lp_save_defaults();
8877 }
8878
8879 /* We get sections first, so have to start 'behind' to make up */
8880 iServiceIndex = -1;
8881
8882 if (Globals.param_opt != NULL) {
8883 data = Globals.param_opt;
8884 while (data) {
8885 string_free(&data->key);
8886 string_free(&data->value);
8887 TALLOC_FREE(data->list);
8888 pdata = data->next;
8889 SAFE_FREE(data);
8890 data = pdata;
8891 }
8892 Globals.param_opt = NULL;
8893 }
8894
8895 if (lp_config_backend_is_file()) {
8896 n2 = alloc_sub_basic(get_current_username(),
8897 current_user_info.domain,
8898 pszFname);
8899 if (!n2) {
8900 smb_panic("lp_load_ex: out of memory");
8901 }
8902
8903 add_to_file_list(pszFname, n2);
8904
8905 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8906 SAFE_FREE(n2);
8907
8908 /* finish up the last section */
8909 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8910 if (bRetval) {
8911 if (iServiceIndex >= 0) {
8912 bRetval = service_ok(iServiceIndex);
8913 }
8914 }
8915
8916 if (lp_config_backend_is_registry()) {
8917 /* config backend changed to registry in config file */
8918 /*
8919 * We need to use this extra global variable here to
8920 * survive restart: init_globals uses this as a default
8921 * for ConfigBackend. Otherwise, init_globals would
8922 * send us into an endless loop here.
8923 */
8924 config_backend = CONFIG_BACKEND_REGISTRY;
8925 /* start over */
8926 DEBUG(1, ("lp_load_ex: changing to config backend "
8927 "registry\n"));
8928 init_globals(false);
8929 lp_kill_all_services();
8930 return lp_load_ex(pszFname, global_only, save_defaults,
8931 add_ipc, initialize_globals,
8932 allow_include_registry,
8933 allow_registry_shares);
8934 }
8935 } else if (lp_config_backend_is_registry()) {
8936 bRetval = process_registry_globals();
8937 } else {
8938 DEBUG(0, ("Illegal config backend given: %d\n",
8939 lp_config_backend()));
8940 bRetval = false;
8941 }
8942
8943 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8944 bRetval = process_registry_shares();
8945 }
8946
8947 lp_add_auto_services(lp_auto_services());
8948
8949 if (add_ipc) {
8950 /* When 'restrict anonymous = 2' guest connections to ipc$
8951 are denied */
8952 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8953 if ( lp_enable_asu_support() ) {
8954 lp_add_ipc("ADMIN$", false);
8955 }
8956 }
8957
8958 set_server_role();
8959 set_default_server_announce_type();
8960 set_allowed_client_auth();
8961
8962 bLoaded = True;
8963
8964 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8965 /* if bWINSsupport is true and we are in the client */
8966 if (lp_is_in_client() && Globals.bWINSsupport) {
8967 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8968 }
8969
8970 init_iconv();
8971
8972 bAllowIncludeRegistry = true;
8973
8974 return (bRetval);
8975}
8976
8977bool lp_load(const char *pszFname,
8978 bool global_only,
8979 bool save_defaults,
8980 bool add_ipc,
8981 bool initialize_globals)
8982{
8983 return lp_load_ex(pszFname,
8984 global_only,
8985 save_defaults,
8986 add_ipc,
8987 initialize_globals,
8988 true, false);
8989}
8990
8991bool lp_load_initial_only(const char *pszFname)
8992{
8993 return lp_load_ex(pszFname,
8994 true,
8995 false,
8996 false,
8997 true,
8998 false,
8999 false);
9000}
9001
9002bool lp_load_with_registry_shares(const char *pszFname,
9003 bool global_only,
9004 bool save_defaults,
9005 bool add_ipc,
9006 bool initialize_globals)
9007{
9008 return lp_load_ex(pszFname,
9009 global_only,
9010 save_defaults,
9011 add_ipc,
9012 initialize_globals,
9013 true,
9014 true);
9015}
9016
9017/***************************************************************************
9018 Return the max number of services.
9019***************************************************************************/
9020
9021int lp_numservices(void)
9022{
9023 return (iNumServices);
9024}
9025
9026/***************************************************************************
9027Display the contents of the services array in human-readable form.
9028***************************************************************************/
9029
9030void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9031{
9032 int iService;
9033
9034 if (show_defaults)
9035 defaults_saved = False;
9036
9037 dump_globals(f);
9038
9039 dump_a_service(&sDefault, f);
9040
9041 for (iService = 0; iService < maxtoprint; iService++) {
9042 fprintf(f,"\n");
9043 lp_dump_one(f, show_defaults, iService);
9044 }
9045}
9046
9047/***************************************************************************
9048Display the contents of one service in human-readable form.
9049***************************************************************************/
9050
9051void lp_dump_one(FILE * f, bool show_defaults, int snum)
9052{
9053 if (VALID(snum)) {
9054 if (ServicePtrs[snum]->szService[0] == '\0')
9055 return;
9056 dump_a_service(ServicePtrs[snum], f);
9057 }
9058}
9059
9060/***************************************************************************
9061Return the number of the service with the given name, or -1 if it doesn't
9062exist. Note that this is a DIFFERENT ANIMAL from the internal function
9063getservicebyname()! This works ONLY if all services have been loaded, and
9064does not copy the found service.
9065***************************************************************************/
9066
9067int lp_servicenumber(const char *pszServiceName)
9068{
9069 int iService;
9070 fstring serviceName;
9071
9072 if (!pszServiceName) {
9073 return GLOBAL_SECTION_SNUM;
9074 }
9075
9076 for (iService = iNumServices - 1; iService >= 0; iService--) {
9077 if (VALID(iService) && ServicePtrs[iService]->szService) {
9078 /*
9079 * The substitution here is used to support %U is
9080 * service names
9081 */
9082 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9083 standard_sub_basic(get_current_username(),
9084 current_user_info.domain,
9085 serviceName,sizeof(serviceName));
9086 if (strequal(serviceName, pszServiceName)) {
9087 break;
9088 }
9089 }
9090 }
9091
9092 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9093 time_t last_mod;
9094
9095 if (!usershare_exists(iService, &last_mod)) {
9096 /* Remove the share security tdb entry for it. */
9097 delete_share_security(lp_servicename(iService));
9098 /* Remove it from the array. */
9099 free_service_byindex(iService);
9100 /* Doesn't exist anymore. */
9101 return GLOBAL_SECTION_SNUM;
9102 }
9103
9104 /* Has it been modified ? If so delete and reload. */
9105 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9106 /* Remove it from the array. */
9107 free_service_byindex(iService);
9108 /* and now reload it. */
9109 iService = load_usershare_service(pszServiceName);
9110 }
9111 }
9112
9113 if (iService < 0) {
9114 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9115 return GLOBAL_SECTION_SNUM;
9116 }
9117
9118 return (iService);
9119}
9120
9121bool share_defined(const char *service_name)
9122{
9123 return (lp_servicenumber(service_name) != -1);
9124}
9125
9126struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9127 const char *sharename)
9128{
9129 struct share_params *result;
9130 char *sname;
9131 int snum;
9132
9133 if (!(sname = SMB_STRDUP(sharename))) {
9134 return NULL;
9135 }
9136
9137 snum = find_service(sname);
9138 SAFE_FREE(sname);
9139
9140 if (snum < 0) {
9141 return NULL;
9142 }
9143
9144 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9145 DEBUG(0, ("talloc failed\n"));
9146 return NULL;
9147 }
9148
9149 result->service = snum;
9150 return result;
9151}
9152
9153struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9154{
9155 struct share_iterator *result;
9156
9157 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9158 DEBUG(0, ("talloc failed\n"));
9159 return NULL;
9160 }
9161
9162 result->next_id = 0;
9163 return result;
9164}
9165
9166struct share_params *next_share(struct share_iterator *list)
9167{
9168 struct share_params *result;
9169
9170 while (!lp_snum_ok(list->next_id) &&
9171 (list->next_id < lp_numservices())) {
9172 list->next_id += 1;
9173 }
9174
9175 if (list->next_id >= lp_numservices()) {
9176 return NULL;
9177 }
9178
9179 if (!(result = TALLOC_P(list, struct share_params))) {
9180 DEBUG(0, ("talloc failed\n"));
9181 return NULL;
9182 }
9183
9184 result->service = list->next_id;
9185 list->next_id += 1;
9186 return result;
9187}
9188
9189struct share_params *next_printer(struct share_iterator *list)
9190{
9191 struct share_params *result;
9192
9193 while ((result = next_share(list)) != NULL) {
9194 if (lp_print_ok(result->service)) {
9195 break;
9196 }
9197 }
9198 return result;
9199}
9200
9201/*
9202 * This is a hack for a transition period until we transformed all code from
9203 * service numbers to struct share_params.
9204 */
9205
9206struct share_params *snum2params_static(int snum)
9207{
9208 static struct share_params result;
9209 result.service = snum;
9210 return &result;
9211}
9212
9213/*******************************************************************
9214 A useful volume label function.
9215********************************************************************/
9216
9217const char *volume_label(int snum)
9218{
9219 char *ret;
9220 const char *label = lp_volume(snum);
9221 if (!*label) {
9222 label = lp_servicename(snum);
9223 }
9224
9225 /* This returns a 33 byte guarenteed null terminated string. */
9226 ret = talloc_strndup(talloc_tos(), label, 32);
9227 if (!ret) {
9228 return "";
9229 }
9230 return ret;
9231}
9232
9233/*******************************************************************
9234 Set the server type we will announce as via nmbd.
9235********************************************************************/
9236
9237static void set_default_server_announce_type(void)
9238{
9239 default_server_announce = 0;
9240 default_server_announce |= SV_TYPE_WORKSTATION;
9241 default_server_announce |= SV_TYPE_SERVER;
9242 default_server_announce |= SV_TYPE_SERVER_UNIX;
9243
9244 /* note that the flag should be set only if we have a
9245 printer service but nmbd doesn't actually load the
9246 services so we can't tell --jerry */
9247
9248 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9249
9250 switch (lp_announce_as()) {
9251 case ANNOUNCE_AS_NT_SERVER:
9252 default_server_announce |= SV_TYPE_SERVER_NT;
9253 /* fall through... */
9254 case ANNOUNCE_AS_NT_WORKSTATION:
9255 default_server_announce |= SV_TYPE_NT;
9256 break;
9257 case ANNOUNCE_AS_WIN95:
9258 default_server_announce |= SV_TYPE_WIN95_PLUS;
9259 break;
9260 case ANNOUNCE_AS_WFW:
9261 default_server_announce |= SV_TYPE_WFW;
9262 break;
9263 default:
9264 break;
9265 }
9266
9267 switch (lp_server_role()) {
9268 case ROLE_DOMAIN_MEMBER:
9269 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9270 break;
9271 case ROLE_DOMAIN_PDC:
9272 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9273 break;
9274 case ROLE_DOMAIN_BDC:
9275 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9276 break;
9277 case ROLE_STANDALONE:
9278 default:
9279 break;
9280 }
9281 if (lp_time_server())
9282 default_server_announce |= SV_TYPE_TIME_SOURCE;
9283
9284 if (lp_host_msdfs())
9285 default_server_announce |= SV_TYPE_DFS_SERVER;
9286}
9287
9288/***********************************************************
9289 returns role of Samba server
9290************************************************************/
9291
9292int lp_server_role(void)
9293{
9294 return server_role;
9295}
9296
9297/***********************************************************
9298 If we are PDC then prefer us as DMB
9299************************************************************/
9300
9301bool lp_domain_master(void)
9302{
9303 if (Globals.iDomainMaster == Auto)
9304 return (lp_server_role() == ROLE_DOMAIN_PDC);
9305
9306 return (bool)Globals.iDomainMaster;
9307}
9308
9309/***********************************************************
9310 If we are DMB then prefer us as LMB
9311************************************************************/
9312
9313bool lp_preferred_master(void)
9314{
9315 if (Globals.iPreferredMaster == Auto)
9316 return (lp_local_master() && lp_domain_master());
9317
9318 return (bool)Globals.iPreferredMaster;
9319}
9320
9321/*******************************************************************
9322 Remove a service.
9323********************************************************************/
9324
9325void lp_remove_service(int snum)
9326{
9327 ServicePtrs[snum]->valid = False;
9328 invalid_services[num_invalid_services++] = snum;
9329}
9330
9331/*******************************************************************
9332 Copy a service.
9333********************************************************************/
9334
9335void lp_copy_service(int snum, const char *new_name)
9336{
9337 do_section(new_name, NULL);
9338 if (snum >= 0) {
9339 snum = lp_servicenumber(new_name);
9340 if (snum >= 0)
9341 lp_do_parameter(snum, "copy", lp_servicename(snum));
9342 }
9343}
9344
9345
9346/*******************************************************************
9347 Get the default server type we will announce as via nmbd.
9348********************************************************************/
9349
9350int lp_default_server_announce(void)
9351{
9352 return default_server_announce;
9353}
9354
9355/*******************************************************************
9356 Split the announce version into major and minor numbers.
9357********************************************************************/
9358
9359int lp_major_announce_version(void)
9360{
9361 static bool got_major = False;
9362 static int major_version = DEFAULT_MAJOR_VERSION;
9363 char *vers;
9364 char *p;
9365
9366 if (got_major)
9367 return major_version;
9368
9369 got_major = True;
9370 if ((vers = lp_announce_version()) == NULL)
9371 return major_version;
9372
9373 if ((p = strchr_m(vers, '.')) == 0)
9374 return major_version;
9375
9376 *p = '\0';
9377 major_version = atoi(vers);
9378 return major_version;
9379}
9380
9381int lp_minor_announce_version(void)
9382{
9383 static bool got_minor = False;
9384 static int minor_version = DEFAULT_MINOR_VERSION;
9385 char *vers;
9386 char *p;
9387
9388 if (got_minor)
9389 return minor_version;
9390
9391 got_minor = True;
9392 if ((vers = lp_announce_version()) == NULL)
9393 return minor_version;
9394
9395 if ((p = strchr_m(vers, '.')) == 0)
9396 return minor_version;
9397
9398 p++;
9399 minor_version = atoi(p);
9400 return minor_version;
9401}
9402
9403/***********************************************************
9404 Set the global name resolution order (used in smbclient).
9405************************************************************/
9406
9407void lp_set_name_resolve_order(const char *new_order)
9408{
9409 string_set(&Globals.szNameResolveOrder, new_order);
9410}
9411
9412const char *lp_printername(int snum)
9413{
9414 const char *ret = _lp_printername(snum);
9415 if (ret == NULL || (ret != NULL && *ret == '\0'))
9416 ret = lp_const_servicename(snum);
9417
9418 return ret;
9419}
9420
9421
9422/***********************************************************
9423 Allow daemons such as winbindd to fix their logfile name.
9424************************************************************/
9425
9426void lp_set_logfile(const char *name)
9427{
9428 string_set(&Globals.szLogFile, name);
9429 debug_set_logfile(name);
9430}
9431
9432/*******************************************************************
9433 Return the max print jobs per queue.
9434********************************************************************/
9435
9436int lp_maxprintjobs(int snum)
9437{
9438 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9439 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9440 maxjobs = PRINT_MAX_JOBID - 1;
9441
9442 return maxjobs;
9443}
9444
9445const char *lp_printcapname(void)
9446{
9447 if ((Globals.szPrintcapname != NULL) &&
9448 (Globals.szPrintcapname[0] != '\0'))
9449 return Globals.szPrintcapname;
9450
9451 if (sDefault.iPrinting == PRINT_CUPS) {
9452#ifdef HAVE_CUPS
9453 return "cups";
9454#else
9455 return "lpstat";
9456#endif
9457 }
9458
9459 if (sDefault.iPrinting == PRINT_BSD)
9460 return "/etc/printcap";
9461
9462 return PRINTCAP_NAME;
9463}
9464
9465/*******************************************************************
9466 Ensure we don't use sendfile if server smb signing is active.
9467********************************************************************/
9468
9469static uint32 spoolss_state;
9470
9471bool lp_disable_spoolss( void )
9472{
9473 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9474 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9475
9476 return spoolss_state == SVCCTL_STOPPED ? True : False;
9477}
9478
9479void lp_set_spoolss_state( uint32 state )
9480{
9481 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9482
9483 spoolss_state = state;
9484}
9485
9486uint32 lp_get_spoolss_state( void )
9487{
9488 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9489}
9490
9491/*******************************************************************
9492 Ensure we don't use sendfile if server smb signing is active.
9493********************************************************************/
9494
9495bool lp_use_sendfile(int snum)
9496{
9497 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9498 if (Protocol < PROTOCOL_NT1) {
9499 return False;
9500 }
9501 return (_lp_use_sendfile(snum) &&
9502 (get_remote_arch() != RA_WIN95) &&
9503 !srv_is_signing_active());
9504}
9505
9506/*******************************************************************
9507 Turn off sendfile if we find the underlying OS doesn't support it.
9508********************************************************************/
9509
9510void set_use_sendfile(int snum, bool val)
9511{
9512 if (LP_SNUM_OK(snum))
9513 ServicePtrs[snum]->bUseSendfile = val;
9514 else
9515 sDefault.bUseSendfile = val;
9516}
9517
9518/*******************************************************************
9519 Turn off storing DOS attributes if this share doesn't support it.
9520********************************************************************/
9521
9522void set_store_dos_attributes(int snum, bool val)
9523{
9524 if (!LP_SNUM_OK(snum))
9525 return;
9526 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9527}
9528
9529void lp_set_mangling_method(const char *new_method)
9530{
9531 string_set(&Globals.szManglingMethod, new_method);
9532}
9533
9534/*******************************************************************
9535 Global state for POSIX pathname processing.
9536********************************************************************/
9537
9538static bool posix_pathnames;
9539
9540bool lp_posix_pathnames(void)
9541{
9542 return posix_pathnames;
9543}
9544
9545/*******************************************************************
9546 Change everything needed to ensure POSIX pathname processing (currently
9547 not much).
9548********************************************************************/
9549
9550void lp_set_posix_pathnames(void)
9551{
9552 posix_pathnames = True;
9553}
9554
9555/*******************************************************************
9556 Global state for POSIX lock processing - CIFS unix extensions.
9557********************************************************************/
9558
9559bool posix_default_lock_was_set;
9560static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9561
9562enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9563{
9564 if (posix_default_lock_was_set) {
9565 return posix_cifsx_locktype;
9566 } else {
9567 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9568 }
9569}
9570
9571/*******************************************************************
9572********************************************************************/
9573
9574void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9575{
9576 posix_default_lock_was_set = True;
9577 posix_cifsx_locktype = val;
9578}
9579
9580int lp_min_receive_file_size(void)
9581{
9582 if (Globals.iminreceivefile < 0) {
9583 return 0;
9584 }
9585 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9586}
9587
9588/*******************************************************************
9589 If socket address is an empty character string, it is necessary to
9590 define it as "0.0.0.0".
9591********************************************************************/
9592
9593const char *lp_socket_address(void)
9594{
9595 char *sock_addr = Globals.szSocketAddress;
9596
9597 if (sock_addr[0] == '\0'){
9598 string_set(&Globals.szSocketAddress, "0.0.0.0");
9599 }
9600 return Globals.szSocketAddress;
9601}
Note: See TracBrowser for help on using the repository browser.