source: trunk/server/source3/param/loadparm.c@ 454

Last change on this file since 454 was 454, checked in by Silvan Scherrer, 15 years ago

Samba Server 3.5: merged changes from 3.3

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