s3: loadparm: Clean-up list of parameters.
[Samba.git] / source / param / loadparm.c
blob8b320f1c9b24036b9e7a81ffe337c3419d68ef15
1 /*
2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
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
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.
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.
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/>.
29 * Load parameters.
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.
35 * To add a parameter:
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
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!
54 #include "includes.h"
55 #include "printing.h"
57 bool bLoaded = False;
59 extern enum protocol_types Protocol;
60 extern userdom_struct current_user_info;
62 #ifndef GLOBAL_NAME
63 #define GLOBAL_NAME "global"
64 #endif
66 #ifndef PRINTERS_NAME
67 #define PRINTERS_NAME "printers"
68 #endif
70 #ifndef HOMES_NAME
71 #define HOMES_NAME "homes"
72 #endif
74 /* the special value for the include parameter
75 * to be interpreted not as a file name but to
76 * trigger loading of the global smb.conf options
77 * from registry. */
78 #ifndef INCLUDE_REGISTRY_NAME
79 #define INCLUDE_REGISTRY_NAME "registry"
80 #endif
82 static bool in_client = False; /* Not in the client by default */
83 static struct smbconf_csn conf_last_csn;
85 #define CONFIG_BACKEND_FILE 0
86 #define CONFIG_BACKEND_REGISTRY 1
88 static int config_backend = CONFIG_BACKEND_FILE;
90 /* some helpful bits */
91 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
92 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
94 #define USERSHARE_VALID 1
95 #define USERSHARE_PENDING_DELETE 2
97 extern int extra_time_offset;
99 static bool defaults_saved = False;
101 struct param_opt_struct {
102 struct param_opt_struct *prev, *next;
103 char *key;
104 char *value;
105 char **list;
109 * This structure describes global (ie., server-wide) parameters.
111 struct global {
112 int ConfigBackend;
113 char *smb_ports;
114 char *dos_charset;
115 char *unix_charset;
116 char *display_charset;
117 char *szPrintcapname;
118 char *szAddPortCommand;
119 char *szEnumPortsCommand;
120 char *szAddPrinterCommand;
121 char *szDeletePrinterCommand;
122 char *szOs2DriverMap;
123 char *szLockDir;
124 char *szPidDir;
125 char *szRootdir;
126 char *szDefaultService;
127 char *szGetQuota;
128 char *szSetQuota;
129 char *szMsgCommand;
130 char *szServerString;
131 char *szAutoServices;
132 char *szPasswdProgram;
133 char *szPasswdChat;
134 char *szLogFile;
135 char *szConfigFile;
136 char *szSMBPasswdFile;
137 char *szPrivateDir;
138 char *szPassdbBackend;
139 char **szPreloadModules;
140 char *szPasswordServer;
141 char *szSocketOptions;
142 char *szRealm;
143 char *szAfsUsernameMap;
144 int iAfsTokenLifetime;
145 char *szLogNtTokenCommand;
146 char *szUsernameMap;
147 char *szLogonScript;
148 char *szLogonPath;
149 char *szLogonDrive;
150 char *szLogonHome;
151 char **szWINSservers;
152 char **szInterfaces;
153 char *szRemoteAnnounce;
154 char *szRemoteBrowseSync;
155 char *szSocketAddress;
156 char *szNISHomeMapName;
157 char *szAnnounceVersion; /* This is initialised in init_globals */
158 char *szWorkgroup;
159 char *szNetbiosName;
160 char **szNetbiosAliases;
161 char *szNetbiosScope;
162 char *szNameResolveOrder;
163 char *szPanicAction;
164 char *szAddUserScript;
165 char *szRenameUserScript;
166 char *szDelUserScript;
167 char *szAddGroupScript;
168 char *szDelGroupScript;
169 char *szAddUserToGroupScript;
170 char *szDelUserFromGroupScript;
171 char *szSetPrimaryGroupScript;
172 char *szAddMachineScript;
173 char *szShutdownScript;
174 char *szAbortShutdownScript;
175 char *szUsernameMapScript;
176 char *szCheckPasswordScript;
177 char *szWINSHook;
178 char *szUtmpDir;
179 char *szWtmpDir;
180 bool bUtmp;
181 char *szIdmapUID;
182 char *szIdmapGID;
183 bool bPassdbExpandExplicit;
184 int AlgorithmicRidBase;
185 char *szTemplateHomedir;
186 char *szTemplateShell;
187 char *szWinbindSeparator;
188 bool bWinbindEnumUsers;
189 bool bWinbindEnumGroups;
190 bool bWinbindUseDefaultDomain;
191 bool bWinbindTrustedDomainsOnly;
192 bool bWinbindNestedGroups;
193 int winbind_expand_groups;
194 bool bWinbindRefreshTickets;
195 bool bWinbindOfflineLogon;
196 bool bWinbindNormalizeNames;
197 bool bWinbindRpcOnly;
198 char *szIdmapBackend;
199 char *szIdmapAllocBackend;
200 char *szAddShareCommand;
201 char *szChangeShareCommand;
202 char *szDeleteShareCommand;
203 char **szEventLogs;
204 char *szGuestaccount;
205 char *szManglingMethod;
206 char **szServicesList;
207 char *szUsersharePath;
208 char *szUsershareTemplateShare;
209 char **szUsersharePrefixAllowList;
210 char **szUsersharePrefixDenyList;
211 int mangle_prefix;
212 int max_log_size;
213 char *szLogLevel;
214 int max_xmit;
215 int max_mux;
216 int max_open_files;
217 int open_files_db_hash_size;
218 int pwordlevel;
219 int unamelevel;
220 int deadtime;
221 bool getwd_cache;
222 int maxprotocol;
223 int minprotocol;
224 int security;
225 char **AuthMethods;
226 bool paranoid_server_security;
227 int maxdisksize;
228 int lpqcachetime;
229 int iMaxSmbdProcesses;
230 bool bDisableSpoolss;
231 int syslog;
232 int os_level;
233 bool enhanced_browsing;
234 int max_ttl;
235 int max_wins_ttl;
236 int min_wins_ttl;
237 int lm_announce;
238 int lm_interval;
239 int announce_as; /* This is initialised in init_globals */
240 int machine_password_timeout;
241 int map_to_guest;
242 int oplock_break_wait_time;
243 int winbind_cache_time;
244 int winbind_reconnect_delay;
245 int winbind_max_idle_children;
246 char **szWinbindNssInfo;
247 int iLockSpinTime;
248 char *szLdapMachineSuffix;
249 char *szLdapUserSuffix;
250 char *szLdapIdmapSuffix;
251 char *szLdapGroupSuffix;
252 int ldap_ssl;
253 char *szLdapSuffix;
254 char *szLdapAdminDn;
255 int ldap_debug_level;
256 int ldap_debug_threshold;
257 int iAclCompat;
258 char *szCupsServer;
259 char *szIPrintServer;
260 char *ctdbdSocket;
261 char **szClusterAddresses;
262 bool clustering;
263 int ldap_passwd_sync;
264 int ldap_replication_sleep;
265 int ldap_timeout; /* This is initialised in init_globals */
266 int ldap_connection_timeout;
267 int ldap_page_size;
268 bool ldap_delete_dn;
269 bool bMsAddPrinterWizard;
270 bool bDNSproxy;
271 bool bWINSsupport;
272 bool bWINSproxy;
273 bool bLocalMaster;
274 int iPreferredMaster;
275 int iDomainMaster;
276 bool bDomainLogons;
277 char **szInitLogonDelayedHosts;
278 int InitLogonDelay;
279 bool bEncryptPasswords;
280 bool bUpdateEncrypt;
281 int clientSchannel;
282 int serverSchannel;
283 bool bNullPasswords;
284 bool bObeyPamRestrictions;
285 bool bLoadPrinters;
286 int PrintcapCacheTime;
287 bool bLargeReadwrite;
288 bool bReadRaw;
289 bool bWriteRaw;
290 bool bSyslogOnly;
291 bool bBrowseList;
292 bool bNISHomeMap;
293 bool bTimeServer;
294 bool bBindInterfacesOnly;
295 bool bPamPasswordChange;
296 bool bUnixPasswdSync;
297 bool bPasswdChatDebug;
298 int iPasswdChatTimeout;
299 bool bTimestampLogs;
300 bool bNTSmbSupport;
301 bool bNTPipeSupport;
302 bool bNTStatusSupport;
303 bool bStatCache;
304 int iMaxStatCacheSize;
305 bool bKernelOplocks;
306 bool bAllowTrustedDomains;
307 bool bLanmanAuth;
308 bool bNTLMAuth;
309 bool bUseSpnego;
310 bool bClientLanManAuth;
311 bool bClientNTLMv2Auth;
312 bool bClientPlaintextAuth;
313 bool bClientUseSpnego;
314 bool bDebugPrefixTimestamp;
315 bool bDebugHiresTimestamp;
316 bool bDebugPid;
317 bool bDebugUid;
318 bool bDebugClass;
319 bool bEnableCoreFiles;
320 bool bHostMSDfs;
321 bool bUseMmap;
322 bool bHostnameLookups;
323 bool bUnixExtensions;
324 bool bDisableNetbios;
325 bool bUseKerberosKeytab;
326 bool bDeferSharingViolations;
327 bool bEnablePrivileges;
328 bool bASUSupport;
329 bool bUsershareOwnerOnly;
330 bool bUsershareAllowGuests;
331 bool bRegistryShares;
332 int restrict_anonymous;
333 int name_cache_timeout;
334 int client_signing;
335 int server_signing;
336 int client_ldap_sasl_wrapping;
337 int iUsershareMaxShares;
338 int iIdmapCacheTime;
339 int iIdmapNegativeCacheTime;
340 bool bResetOnZeroVC;
341 int iKeepalive;
342 int iminreceivefile;
343 struct param_opt_struct *param_opt;
344 int cups_connection_timeout;
347 static struct global Globals;
350 * This structure describes a single service.
352 struct service {
353 bool valid;
354 bool autoloaded;
355 int usershare;
356 time_t usershare_last_mod;
357 char *szService;
358 char *szPath;
359 char *szUsername;
360 char **szInvalidUsers;
361 char **szValidUsers;
362 char **szAdminUsers;
363 char *szCopy;
364 char *szInclude;
365 char *szPreExec;
366 char *szPostExec;
367 char *szRootPreExec;
368 char *szRootPostExec;
369 char *szCupsOptions;
370 char *szPrintcommand;
371 char *szLpqcommand;
372 char *szLprmcommand;
373 char *szLppausecommand;
374 char *szLpresumecommand;
375 char *szQueuepausecommand;
376 char *szQueueresumecommand;
377 char *szPrintername;
378 char *szPrintjobUsername;
379 char *szDontdescend;
380 char **szHostsallow;
381 char **szHostsdeny;
382 char *szMagicScript;
383 char *szMagicOutput;
384 char *szVetoFiles;
385 char *szHideFiles;
386 char *szVetoOplockFiles;
387 char *comment;
388 char *force_user;
389 char *force_group;
390 char **readlist;
391 char **writelist;
392 char **printer_admin;
393 char *volume;
394 char *fstype;
395 char **szVfsObjects;
396 char *szMSDfsProxy;
397 char *szAioWriteBehind;
398 char *szDfree;
399 int iMinPrintSpace;
400 int iMaxPrintJobs;
401 int iMaxReportedPrintJobs;
402 int iWriteCacheSize;
403 int iCreate_mask;
404 int iCreate_force_mode;
405 int iSecurity_mask;
406 int iSecurity_force_mode;
407 int iDir_mask;
408 int iDir_force_mode;
409 int iDir_Security_mask;
410 int iDir_Security_force_mode;
411 int iMaxConnections;
412 int iDefaultCase;
413 int iPrinting;
414 int iOplockContentionLimit;
415 int iCSCPolicy;
416 int iBlock_size;
417 int iDfreeCacheTime;
418 bool bPreexecClose;
419 bool bRootpreexecClose;
420 int iCaseSensitive;
421 bool bCasePreserve;
422 bool bShortCasePreserve;
423 bool bHideDotFiles;
424 bool bHideSpecialFiles;
425 bool bHideUnReadable;
426 bool bHideUnWriteableFiles;
427 bool bBrowseable;
428 bool bAvailable;
429 bool bRead_only;
430 bool bNo_set_dir;
431 bool bGuest_only;
432 bool bAdministrative_share;
433 bool bGuest_ok;
434 bool bPrint_ok;
435 bool bMap_system;
436 bool bMap_hidden;
437 bool bMap_archive;
438 bool bStoreDosAttributes;
439 bool bDmapiSupport;
440 bool bLocking;
441 int iStrictLocking;
442 bool bPosixLocking;
443 bool bShareModes;
444 bool bOpLocks;
445 bool bLevel2OpLocks;
446 bool bOnlyUser;
447 bool bMangledNames;
448 bool bWidelinks;
449 bool bSymlinks;
450 bool bSyncAlways;
451 bool bStrictAllocate;
452 bool bStrictSync;
453 char magic_char;
454 struct bitmap *copymap;
455 bool bDeleteReadonly;
456 bool bFakeOplocks;
457 bool bDeleteVetoFiles;
458 bool bDosFilemode;
459 bool bDosFiletimes;
460 bool bDosFiletimeResolution;
461 bool bFakeDirCreateTimes;
462 bool bBlockingLocks;
463 bool bInheritPerms;
464 bool bInheritACLS;
465 bool bInheritOwner;
466 bool bMSDfsRoot;
467 bool bUseClientDriver;
468 bool bDefaultDevmode;
469 bool bForcePrintername;
470 bool bNTAclSupport;
471 bool bForceUnknownAclUser;
472 bool bUseSendfile;
473 bool bProfileAcls;
474 bool bMap_acl_inherit;
475 bool bAfs_Share;
476 bool bEASupport;
477 bool bAclCheckPermissions;
478 bool bAclMapFullControl;
479 bool bAclGroupControl;
480 bool bChangeNotify;
481 bool bKernelChangeNotify;
482 int iallocation_roundup_size;
483 int iAioReadSize;
484 int iAioWriteSize;
485 int iMap_readonly;
486 int iDirectoryNameCacheSize;
487 int ismb_encrypt;
488 struct param_opt_struct *param_opt;
490 char dummy[3]; /* for alignment */
494 /* This is a default service used to prime a services structure */
495 static struct service sDefault = {
496 True, /* valid */
497 False, /* not autoloaded */
498 0, /* not a usershare */
499 (time_t)0, /* No last mod time */
500 NULL, /* szService */
501 NULL, /* szPath */
502 NULL, /* szUsername */
503 NULL, /* szInvalidUsers */
504 NULL, /* szValidUsers */
505 NULL, /* szAdminUsers */
506 NULL, /* szCopy */
507 NULL, /* szInclude */
508 NULL, /* szPreExec */
509 NULL, /* szPostExec */
510 NULL, /* szRootPreExec */
511 NULL, /* szRootPostExec */
512 NULL, /* szCupsOptions */
513 NULL, /* szPrintcommand */
514 NULL, /* szLpqcommand */
515 NULL, /* szLprmcommand */
516 NULL, /* szLppausecommand */
517 NULL, /* szLpresumecommand */
518 NULL, /* szQueuepausecommand */
519 NULL, /* szQueueresumecommand */
520 NULL, /* szPrintername */
521 NULL, /* szPrintjobUsername */
522 NULL, /* szDontdescend */
523 NULL, /* szHostsallow */
524 NULL, /* szHostsdeny */
525 NULL, /* szMagicScript */
526 NULL, /* szMagicOutput */
527 NULL, /* szVetoFiles */
528 NULL, /* szHideFiles */
529 NULL, /* szVetoOplockFiles */
530 NULL, /* comment */
531 NULL, /* force user */
532 NULL, /* force group */
533 NULL, /* readlist */
534 NULL, /* writelist */
535 NULL, /* printer admin */
536 NULL, /* volume */
537 NULL, /* fstype */
538 NULL, /* vfs objects */
539 NULL, /* szMSDfsProxy */
540 NULL, /* szAioWriteBehind */
541 NULL, /* szDfree */
542 0, /* iMinPrintSpace */
543 1000, /* iMaxPrintJobs */
544 0, /* iMaxReportedPrintJobs */
545 0, /* iWriteCacheSize */
546 0744, /* iCreate_mask */
547 0000, /* iCreate_force_mode */
548 0777, /* iSecurity_mask */
549 0, /* iSecurity_force_mode */
550 0755, /* iDir_mask */
551 0000, /* iDir_force_mode */
552 0777, /* iDir_Security_mask */
553 0, /* iDir_Security_force_mode */
554 0, /* iMaxConnections */
555 CASE_LOWER, /* iDefaultCase */
556 DEFAULT_PRINTING, /* iPrinting */
557 2, /* iOplockContentionLimit */
558 0, /* iCSCPolicy */
559 1024, /* iBlock_size */
560 0, /* iDfreeCacheTime */
561 False, /* bPreexecClose */
562 False, /* bRootpreexecClose */
563 Auto, /* case sensitive */
564 True, /* case preserve */
565 True, /* short case preserve */
566 True, /* bHideDotFiles */
567 False, /* bHideSpecialFiles */
568 False, /* bHideUnReadable */
569 False, /* bHideUnWriteableFiles */
570 True, /* bBrowseable */
571 True, /* bAvailable */
572 True, /* bRead_only */
573 True, /* bNo_set_dir */
574 False, /* bGuest_only */
575 False, /* bAdministrative_share */
576 False, /* bGuest_ok */
577 False, /* bPrint_ok */
578 False, /* bMap_system */
579 False, /* bMap_hidden */
580 True, /* bMap_archive */
581 False, /* bStoreDosAttributes */
582 False, /* bDmapiSupport */
583 True, /* bLocking */
584 Auto, /* iStrictLocking */
585 True, /* bPosixLocking */
586 True, /* bShareModes */
587 True, /* bOpLocks */
588 True, /* bLevel2OpLocks */
589 False, /* bOnlyUser */
590 True, /* bMangledNames */
591 True, /* bWidelinks */
592 True, /* bSymlinks */
593 False, /* bSyncAlways */
594 False, /* bStrictAllocate */
595 False, /* bStrictSync */
596 '~', /* magic char */
597 NULL, /* copymap */
598 False, /* bDeleteReadonly */
599 False, /* bFakeOplocks */
600 False, /* bDeleteVetoFiles */
601 False, /* bDosFilemode */
602 True, /* bDosFiletimes */
603 False, /* bDosFiletimeResolution */
604 False, /* bFakeDirCreateTimes */
605 True, /* bBlockingLocks */
606 False, /* bInheritPerms */
607 False, /* bInheritACLS */
608 False, /* bInheritOwner */
609 False, /* bMSDfsRoot */
610 False, /* bUseClientDriver */
611 True, /* bDefaultDevmode */
612 False, /* bForcePrintername */
613 True, /* bNTAclSupport */
614 False, /* bForceUnknownAclUser */
615 False, /* bUseSendfile */
616 False, /* bProfileAcls */
617 False, /* bMap_acl_inherit */
618 False, /* bAfs_Share */
619 False, /* bEASupport */
620 True, /* bAclCheckPermissions */
621 True, /* bAclMapFullControl */
622 False, /* bAclGroupControl */
623 True, /* bChangeNotify */
624 True, /* bKernelChangeNotify */
625 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
626 0, /* iAioReadSize */
627 0, /* iAioWriteSize */
628 MAP_READONLY_YES, /* iMap_readonly */
629 #ifdef BROKEN_DIRECTORY_HANDLING
630 0, /* iDirectoryNameCacheSize */
631 #else
632 100, /* iDirectoryNameCacheSize */
633 #endif
634 Auto, /* ismb_encrypt */
635 NULL, /* Parametric options */
637 "" /* dummy */
640 /* local variables */
641 static struct service **ServicePtrs = NULL;
642 static int iNumServices = 0;
643 static int iServiceIndex = 0;
644 static struct db_context *ServiceHash;
645 static int *invalid_services = NULL;
646 static int num_invalid_services = 0;
647 static bool bInGlobalSection = True;
648 static bool bGlobalOnly = False;
649 static int server_role;
650 static int default_server_announce;
652 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
654 /* prototypes for the special type handlers */
655 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
656 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
657 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
658 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
659 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
660 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
661 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
662 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
663 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
664 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
665 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
666 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
668 static void set_server_role(void);
669 static void set_default_server_announce_type(void);
670 static void set_allowed_client_auth(void);
672 static const struct enum_list enum_protocol[] = {
673 {PROTOCOL_NT1, "NT1"},
674 {PROTOCOL_LANMAN2, "LANMAN2"},
675 {PROTOCOL_LANMAN1, "LANMAN1"},
676 {PROTOCOL_CORE, "CORE"},
677 {PROTOCOL_COREPLUS, "COREPLUS"},
678 {PROTOCOL_COREPLUS, "CORE+"},
679 {-1, NULL}
682 static const struct enum_list enum_security[] = {
683 {SEC_SHARE, "SHARE"},
684 {SEC_USER, "USER"},
685 {SEC_SERVER, "SERVER"},
686 {SEC_DOMAIN, "DOMAIN"},
687 #ifdef HAVE_ADS
688 {SEC_ADS, "ADS"},
689 #endif
690 {-1, NULL}
693 static const struct enum_list enum_printing[] = {
694 {PRINT_SYSV, "sysv"},
695 {PRINT_AIX, "aix"},
696 {PRINT_HPUX, "hpux"},
697 {PRINT_BSD, "bsd"},
698 {PRINT_QNX, "qnx"},
699 {PRINT_PLP, "plp"},
700 {PRINT_LPRNG, "lprng"},
701 {PRINT_CUPS, "cups"},
702 {PRINT_IPRINT, "iprint"},
703 {PRINT_LPRNT, "nt"},
704 {PRINT_LPROS2, "os2"},
705 #ifdef DEVELOPER
706 {PRINT_TEST, "test"},
707 {PRINT_VLP, "vlp"},
708 #endif /* DEVELOPER */
709 {-1, NULL}
712 static const struct enum_list enum_ldap_sasl_wrapping[] = {
713 {0, "plain"},
714 {ADS_AUTH_SASL_SIGN, "sign"},
715 {ADS_AUTH_SASL_SEAL, "seal"},
716 {-1, NULL}
719 static const struct enum_list enum_ldap_ssl[] = {
720 {LDAP_SSL_OFF, "no"},
721 {LDAP_SSL_OFF, "off"},
722 {LDAP_SSL_START_TLS, "start tls"},
723 {LDAP_SSL_START_TLS, "start_tls"},
724 {-1, NULL}
727 static const struct enum_list enum_ldap_passwd_sync[] = {
728 {LDAP_PASSWD_SYNC_OFF, "no"},
729 {LDAP_PASSWD_SYNC_OFF, "off"},
730 {LDAP_PASSWD_SYNC_ON, "yes"},
731 {LDAP_PASSWD_SYNC_ON, "on"},
732 {LDAP_PASSWD_SYNC_ONLY, "only"},
733 {-1, NULL}
736 /* Types of machine we can announce as. */
737 #define ANNOUNCE_AS_NT_SERVER 1
738 #define ANNOUNCE_AS_WIN95 2
739 #define ANNOUNCE_AS_WFW 3
740 #define ANNOUNCE_AS_NT_WORKSTATION 4
742 static const struct enum_list enum_announce_as[] = {
743 {ANNOUNCE_AS_NT_SERVER, "NT"},
744 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
745 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
746 {ANNOUNCE_AS_WIN95, "win95"},
747 {ANNOUNCE_AS_WFW, "WfW"},
748 {-1, NULL}
751 static const struct enum_list enum_map_readonly[] = {
752 {MAP_READONLY_NO, "no"},
753 {MAP_READONLY_NO, "false"},
754 {MAP_READONLY_NO, "0"},
755 {MAP_READONLY_YES, "yes"},
756 {MAP_READONLY_YES, "true"},
757 {MAP_READONLY_YES, "1"},
758 {MAP_READONLY_PERMISSIONS, "permissions"},
759 {MAP_READONLY_PERMISSIONS, "perms"},
760 {-1, NULL}
763 static const struct enum_list enum_case[] = {
764 {CASE_LOWER, "lower"},
765 {CASE_UPPER, "upper"},
766 {-1, NULL}
769 static const struct enum_list enum_bool_auto[] = {
770 {False, "No"},
771 {False, "False"},
772 {False, "0"},
773 {True, "Yes"},
774 {True, "True"},
775 {True, "1"},
776 {Auto, "Auto"},
777 {-1, NULL}
780 /* Client-side offline caching policy types */
781 #define CSC_POLICY_MANUAL 0
782 #define CSC_POLICY_DOCUMENTS 1
783 #define CSC_POLICY_PROGRAMS 2
784 #define CSC_POLICY_DISABLE 3
786 static const struct enum_list enum_csc_policy[] = {
787 {CSC_POLICY_MANUAL, "manual"},
788 {CSC_POLICY_DOCUMENTS, "documents"},
789 {CSC_POLICY_PROGRAMS, "programs"},
790 {CSC_POLICY_DISABLE, "disable"},
791 {-1, NULL}
794 /* SMB signing types. */
795 static const struct enum_list enum_smb_signing_vals[] = {
796 {False, "No"},
797 {False, "False"},
798 {False, "0"},
799 {False, "Off"},
800 {False, "disabled"},
801 {True, "Yes"},
802 {True, "True"},
803 {True, "1"},
804 {True, "On"},
805 {True, "enabled"},
806 {Auto, "auto"},
807 {Required, "required"},
808 {Required, "mandatory"},
809 {Required, "force"},
810 {Required, "forced"},
811 {Required, "enforced"},
812 {-1, NULL}
815 /* ACL compatibility options. */
816 static const struct enum_list enum_acl_compat_vals[] = {
817 { ACL_COMPAT_AUTO, "auto" },
818 { ACL_COMPAT_WINNT, "winnt" },
819 { ACL_COMPAT_WIN2K, "win2k" },
820 { -1, NULL}
824 Do you want session setups at user level security with a invalid
825 password to be rejected or allowed in as guest? WinNT rejects them
826 but it can be a pain as it means "net view" needs to use a password
828 You have 3 choices in the setting of map_to_guest:
830 "Never" means session setups with an invalid password
831 are rejected. This is the default.
833 "Bad User" means session setups with an invalid password
834 are rejected, unless the username does not exist, in which case it
835 is treated as a guest login
837 "Bad Password" means session setups with an invalid password
838 are treated as a guest login
840 Note that map_to_guest only has an effect in user or server
841 level security.
844 static const struct enum_list enum_map_to_guest[] = {
845 {NEVER_MAP_TO_GUEST, "Never"},
846 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
847 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
848 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
849 {-1, NULL}
852 /* Config backend options */
854 static const struct enum_list enum_config_backend[] = {
855 {CONFIG_BACKEND_FILE, "file"},
856 {CONFIG_BACKEND_REGISTRY, "registry"},
857 {-1, NULL}
860 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
862 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
863 * screen in SWAT. This is used to exclude parameters as well as to squash all
864 * parameters that have been duplicated by pseudonyms.
866 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
867 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
868 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
869 * respective views.
871 * NOTE2: Handling of duplicated (synonym) paramters:
872 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
873 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
874 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
875 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
878 static struct parm_struct parm_table[] = {
879 {N_("Base Options"), P_SEP, P_SEPARATOR},
882 .label = "dos charset",
883 .type = P_STRING,
884 .p_class = P_GLOBAL,
885 .ptr = &Globals.dos_charset,
886 .special = handle_charset,
887 .enum_list = NULL,
888 .flags = FLAG_ADVANCED
891 .label = "unix charset",
892 .type = P_STRING,
893 .p_class = P_GLOBAL,
894 .ptr = &Globals.unix_charset,
895 .special = handle_charset,
896 .enum_list = NULL,
897 .flags = FLAG_ADVANCED
900 .label = "display charset",
901 .type = P_STRING,
902 .p_class = P_GLOBAL,
903 .ptr = &Globals.display_charset,
904 .special = handle_charset,
905 .enum_list = NULL,
906 .flags = FLAG_ADVANCED
909 .label = "comment",
910 .type = P_STRING,
911 .p_class = P_LOCAL,
912 .ptr = &sDefault.comment,
913 .special = NULL,
914 .enum_list = NULL,
915 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
918 .label = "path",
919 .type = P_STRING,
920 .p_class = P_LOCAL,
921 .ptr = &sDefault.szPath,
922 .special = NULL,
923 .enum_list = NULL,
924 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
927 .label = "directory",
928 .type = P_STRING,
929 .p_class = P_LOCAL,
930 .ptr = &sDefault.szPath,
931 .special = NULL,
932 .enum_list = NULL,
933 .flags = FLAG_HIDE,
936 .label = "workgroup",
937 .type = P_USTRING,
938 .p_class = P_GLOBAL,
939 .ptr = &Globals.szWorkgroup,
940 .special = handle_workgroup,
941 .enum_list = NULL,
942 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
944 #ifdef WITH_ADS
946 .label = "realm",
947 .type = P_USTRING,
948 .p_class = P_GLOBAL,
949 .ptr = &Globals.szRealm,
950 .special = NULL,
951 .enum_list = NULL,
952 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
954 #endif
956 .label = "netbios name",
957 .type = P_USTRING,
958 .p_class = P_GLOBAL,
959 .ptr = &Globals.szNetbiosName,
960 .special = handle_netbios_name,
961 .enum_list = NULL,
962 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
965 .label = "netbios aliases",
966 .type = P_LIST,
967 .p_class = P_GLOBAL,
968 .ptr = &Globals.szNetbiosAliases,
969 .special = handle_netbios_aliases,
970 .enum_list = NULL,
971 .flags = FLAG_ADVANCED,
974 .label = "netbios scope",
975 .type = P_USTRING,
976 .p_class = P_GLOBAL,
977 .ptr = &Globals.szNetbiosScope,
978 .special = handle_netbios_scope,
979 .enum_list = NULL,
980 .flags = FLAG_ADVANCED,
983 .label = "server string",
984 .type = P_STRING,
985 .p_class = P_GLOBAL,
986 .ptr = &Globals.szServerString,
987 .special = NULL,
988 .enum_list = NULL,
989 .flags = FLAG_BASIC | FLAG_ADVANCED,
992 .label = "interfaces",
993 .type = P_LIST,
994 .p_class = P_GLOBAL,
995 .ptr = &Globals.szInterfaces,
996 .special = NULL,
997 .enum_list = NULL,
998 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1001 .label = "bind interfaces only",
1002 .type = P_BOOL,
1003 .p_class = P_GLOBAL,
1004 .ptr = &Globals.bBindInterfacesOnly,
1005 .special = NULL,
1006 .enum_list = NULL,
1007 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1010 .label = "config backend",
1011 .type = P_ENUM,
1012 .p_class = P_GLOBAL,
1013 .ptr = &Globals.ConfigBackend,
1014 .special = NULL,
1015 .enum_list = enum_config_backend,
1016 .flags = FLAG_ADVANCED,
1019 {N_("Security Options"), P_SEP, P_SEPARATOR},
1022 .label = "security",
1023 .type = P_ENUM,
1024 .p_class = P_GLOBAL,
1025 .ptr = &Globals.security,
1026 .special = NULL,
1027 .enum_list = enum_security,
1028 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1031 .label = "auth methods",
1032 .type = P_LIST,
1033 .p_class = P_GLOBAL,
1034 .ptr = &Globals.AuthMethods,
1035 .special = NULL,
1036 .enum_list = NULL,
1037 .flags = FLAG_ADVANCED,
1040 .label = "encrypt passwords",
1041 .type = P_BOOL,
1042 .p_class = P_GLOBAL,
1043 .ptr = &Globals.bEncryptPasswords,
1044 .special = NULL,
1045 .enum_list = NULL,
1046 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1049 .label = "update encrypted",
1050 .type = P_BOOL,
1051 .p_class = P_GLOBAL,
1052 .ptr = &Globals.bUpdateEncrypt,
1053 .special = NULL,
1054 .enum_list = NULL,
1055 .flags = FLAG_ADVANCED,
1058 .label = "client schannel",
1059 .type = P_ENUM,
1060 .p_class = P_GLOBAL,
1061 .ptr = &Globals.clientSchannel,
1062 .special = NULL,
1063 .enum_list = enum_bool_auto,
1064 .flags = FLAG_BASIC | FLAG_ADVANCED,
1067 .label = "server schannel",
1068 .type = P_ENUM,
1069 .p_class = P_GLOBAL,
1070 .ptr = &Globals.serverSchannel,
1071 .special = NULL,
1072 .enum_list = enum_bool_auto,
1073 .flags = FLAG_BASIC | FLAG_ADVANCED,
1076 .label = "allow trusted domains",
1077 .type = P_BOOL,
1078 .p_class = P_GLOBAL,
1079 .ptr = &Globals.bAllowTrustedDomains,
1080 .special = NULL,
1081 .enum_list = NULL,
1082 .flags = FLAG_ADVANCED,
1085 .label = "map to guest",
1086 .type = P_ENUM,
1087 .p_class = P_GLOBAL,
1088 .ptr = &Globals.map_to_guest,
1089 .special = NULL,
1090 .enum_list = enum_map_to_guest,
1091 .flags = FLAG_ADVANCED,
1094 .label = "null passwords",
1095 .type = P_BOOL,
1096 .p_class = P_GLOBAL,
1097 .ptr = &Globals.bNullPasswords,
1098 .special = NULL,
1099 .enum_list = NULL,
1100 .flags = FLAG_ADVANCED,
1103 .label = "obey pam restrictions",
1104 .type = P_BOOL,
1105 .p_class = P_GLOBAL,
1106 .ptr = &Globals.bObeyPamRestrictions,
1107 .special = NULL,
1108 .enum_list = NULL,
1109 .flags = FLAG_ADVANCED,
1112 .label = "password server",
1113 .type = P_STRING,
1114 .p_class = P_GLOBAL,
1115 .ptr = &Globals.szPasswordServer,
1116 .special = NULL,
1117 .enum_list = NULL,
1118 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1121 .label = "smb passwd file",
1122 .type = P_STRING,
1123 .p_class = P_GLOBAL,
1124 .ptr = &Globals.szSMBPasswdFile,
1125 .special = NULL,
1126 .enum_list = NULL,
1127 .flags = FLAG_ADVANCED,
1130 .label = "private dir",
1131 .type = P_STRING,
1132 .p_class = P_GLOBAL,
1133 .ptr = &Globals.szPrivateDir,
1134 .special = NULL,
1135 .enum_list = NULL,
1136 .flags = FLAG_ADVANCED,
1139 .label = "passdb backend",
1140 .type = P_STRING,
1141 .p_class = P_GLOBAL,
1142 .ptr = &Globals.szPassdbBackend,
1143 .special = NULL,
1144 .enum_list = NULL,
1145 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1148 .label = "algorithmic rid base",
1149 .type = P_INTEGER,
1150 .p_class = P_GLOBAL,
1151 .ptr = &Globals.AlgorithmicRidBase,
1152 .special = NULL,
1153 .enum_list = NULL,
1154 .flags = FLAG_ADVANCED,
1157 .label = "root directory",
1158 .type = P_STRING,
1159 .p_class = P_GLOBAL,
1160 .ptr = &Globals.szRootdir,
1161 .special = NULL,
1162 .enum_list = NULL,
1163 .flags = FLAG_ADVANCED,
1166 .label = "root dir",
1167 .type = P_STRING,
1168 .p_class = P_GLOBAL,
1169 .ptr = &Globals.szRootdir,
1170 .special = NULL,
1171 .enum_list = NULL,
1172 .flags = FLAG_HIDE,
1175 .label = "root",
1176 .type = P_STRING,
1177 .p_class = P_GLOBAL,
1178 .ptr = &Globals.szRootdir,
1179 .special = NULL,
1180 .enum_list = NULL,
1181 .flags = FLAG_HIDE,
1184 .label = "guest account",
1185 .type = P_STRING,
1186 .p_class = P_GLOBAL,
1187 .ptr = &Globals.szGuestaccount,
1188 .special = NULL,
1189 .enum_list = NULL,
1190 .flags = FLAG_BASIC | FLAG_ADVANCED,
1193 .label = "enable privileges",
1194 .type = P_BOOL,
1195 .p_class = P_GLOBAL,
1196 .ptr = &Globals.bEnablePrivileges,
1197 .special = NULL,
1198 .enum_list = NULL,
1199 .flags = FLAG_ADVANCED,
1203 .label = "pam password change",
1204 .type = P_BOOL,
1205 .p_class = P_GLOBAL,
1206 .ptr = &Globals.bPamPasswordChange,
1207 .special = NULL,
1208 .enum_list = NULL,
1209 .flags = FLAG_ADVANCED,
1212 .label = "passwd program",
1213 .type = P_STRING,
1214 .p_class = P_GLOBAL,
1215 .ptr = &Globals.szPasswdProgram,
1216 .special = NULL,
1217 .enum_list = NULL,
1218 .flags = FLAG_ADVANCED,
1221 .label = "passwd chat",
1222 .type = P_STRING,
1223 .p_class = P_GLOBAL,
1224 .ptr = &Globals.szPasswdChat,
1225 .special = NULL,
1226 .enum_list = NULL,
1227 .flags = FLAG_ADVANCED,
1230 .label = "passwd chat debug",
1231 .type = P_BOOL,
1232 .p_class = P_GLOBAL,
1233 .ptr = &Globals.bPasswdChatDebug,
1234 .special = NULL,
1235 .enum_list = NULL,
1236 .flags = FLAG_ADVANCED,
1239 .label = "passwd chat timeout",
1240 .type = P_INTEGER,
1241 .p_class = P_GLOBAL,
1242 .ptr = &Globals.iPasswdChatTimeout,
1243 .special = NULL,
1244 .enum_list = NULL,
1245 .flags = FLAG_ADVANCED,
1248 .label = "check password script",
1249 .type = P_STRING,
1250 .p_class = P_GLOBAL,
1251 .ptr = &Globals.szCheckPasswordScript,
1252 .special = NULL,
1253 .enum_list = NULL,
1254 .flags = FLAG_ADVANCED,
1257 .label = "username map",
1258 .type = P_STRING,
1259 .p_class = P_GLOBAL,
1260 .ptr = &Globals.szUsernameMap,
1261 .special = NULL,
1262 .enum_list = NULL,
1263 .flags = FLAG_ADVANCED,
1266 .label = "password level",
1267 .type = P_INTEGER,
1268 .p_class = P_GLOBAL,
1269 .ptr = &Globals.pwordlevel,
1270 .special = NULL,
1271 .enum_list = NULL,
1272 .flags = FLAG_ADVANCED,
1275 .label = "username level",
1276 .type = P_INTEGER,
1277 .p_class = P_GLOBAL,
1278 .ptr = &Globals.unamelevel,
1279 .special = NULL,
1280 .enum_list = NULL,
1281 .flags = FLAG_ADVANCED,
1284 .label = "unix password sync",
1285 .type = P_BOOL,
1286 .p_class = P_GLOBAL,
1287 .ptr = &Globals.bUnixPasswdSync,
1288 .special = NULL,
1289 .enum_list = NULL,
1290 .flags = FLAG_ADVANCED,
1293 .label = "restrict anonymous",
1294 .type = P_INTEGER,
1295 .p_class = P_GLOBAL,
1296 .ptr = &Globals.restrict_anonymous,
1297 .special = NULL,
1298 .enum_list = NULL,
1299 .flags = FLAG_ADVANCED,
1302 .label = "lanman auth",
1303 .type = P_BOOL,
1304 .p_class = P_GLOBAL,
1305 .ptr = &Globals.bLanmanAuth,
1306 .special = NULL,
1307 .enum_list = NULL,
1308 .flags = FLAG_ADVANCED,
1311 .label = "ntlm auth",
1312 .type = P_BOOL,
1313 .p_class = P_GLOBAL,
1314 .ptr = &Globals.bNTLMAuth,
1315 .special = NULL,
1316 .enum_list = NULL,
1317 .flags = FLAG_ADVANCED,
1320 .label = "client NTLMv2 auth",
1321 .type = P_BOOL,
1322 .p_class = P_GLOBAL,
1323 .ptr = &Globals.bClientNTLMv2Auth,
1324 .special = NULL,
1325 .enum_list = NULL,
1326 .flags = FLAG_ADVANCED,
1329 .label = "client lanman auth",
1330 .type = P_BOOL,
1331 .p_class = P_GLOBAL,
1332 .ptr = &Globals.bClientLanManAuth,
1333 .special = NULL,
1334 .enum_list = NULL,
1335 .flags = FLAG_ADVANCED,
1338 .label = "client plaintext auth",
1339 .type = P_BOOL,
1340 .p_class = P_GLOBAL,
1341 .ptr = &Globals.bClientPlaintextAuth,
1342 .special = NULL,
1343 .enum_list = NULL,
1344 .flags = FLAG_ADVANCED,
1347 .label = "username",
1348 .type = P_STRING,
1349 .p_class = P_LOCAL,
1350 .ptr = &sDefault.szUsername,
1351 .special = NULL,
1352 .enum_list = NULL,
1353 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1356 .label = "user",
1357 .type = P_STRING,
1358 .p_class = P_LOCAL,
1359 .ptr = &sDefault.szUsername,
1360 .special = NULL,
1361 .enum_list = NULL,
1362 .flags = FLAG_HIDE,
1365 .label = "users",
1366 .type = P_STRING,
1367 .p_class = P_LOCAL,
1368 .ptr = &sDefault.szUsername,
1369 .special = NULL,
1370 .enum_list = NULL,
1371 .flags = FLAG_HIDE,
1374 .label = "invalid users",
1375 .type = P_LIST,
1376 .p_class = P_LOCAL,
1377 .ptr = &sDefault.szInvalidUsers,
1378 .special = NULL,
1379 .enum_list = NULL,
1380 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1383 .label = "valid users",
1384 .type = P_LIST,
1385 .p_class = P_LOCAL,
1386 .ptr = &sDefault.szValidUsers,
1387 .special = NULL,
1388 .enum_list = NULL,
1389 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1392 .label = "admin users",
1393 .type = P_LIST,
1394 .p_class = P_LOCAL,
1395 .ptr = &sDefault.szAdminUsers,
1396 .special = NULL,
1397 .enum_list = NULL,
1398 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1401 .label = "read list",
1402 .type = P_LIST,
1403 .p_class = P_LOCAL,
1404 .ptr = &sDefault.readlist,
1405 .special = NULL,
1406 .enum_list = NULL,
1407 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1410 .label = "write list",
1411 .type = P_LIST,
1412 .p_class = P_LOCAL,
1413 .ptr = &sDefault.writelist,
1414 .special = NULL,
1415 .enum_list = NULL,
1416 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1419 .label = "printer admin",
1420 .type = P_LIST,
1421 .p_class = P_LOCAL,
1422 .ptr = &sDefault.printer_admin,
1423 .special = NULL,
1424 .enum_list = NULL,
1425 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1428 .label = "force user",
1429 .type = P_STRING,
1430 .p_class = P_LOCAL,
1431 .ptr = &sDefault.force_user,
1432 .special = NULL,
1433 .enum_list = NULL,
1434 .flags = FLAG_ADVANCED | FLAG_SHARE,
1437 .label = "force group",
1438 .type = P_STRING,
1439 .p_class = P_LOCAL,
1440 .ptr = &sDefault.force_group,
1441 .special = NULL,
1442 .enum_list = NULL,
1443 .flags = FLAG_ADVANCED | FLAG_SHARE,
1446 .label = "group",
1447 .type = P_STRING,
1448 .p_class = P_LOCAL,
1449 .ptr = &sDefault.force_group,
1450 .special = NULL,
1451 .enum_list = NULL,
1452 .flags = FLAG_ADVANCED,
1455 .label = "read only",
1456 .type = P_BOOL,
1457 .p_class = P_LOCAL,
1458 .ptr = &sDefault.bRead_only,
1459 .special = NULL,
1460 .enum_list = NULL,
1461 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1464 .label = "write ok",
1465 .type = P_BOOLREV,
1466 .p_class = P_LOCAL,
1467 .ptr = &sDefault.bRead_only,
1468 .special = NULL,
1469 .enum_list = NULL,
1470 .flags = FLAG_HIDE,
1473 .label = "writeable",
1474 .type = P_BOOLREV,
1475 .p_class = P_LOCAL,
1476 .ptr = &sDefault.bRead_only,
1477 .special = NULL,
1478 .enum_list = NULL,
1479 .flags = FLAG_HIDE,
1482 .label = "writable",
1483 .type = P_BOOLREV,
1484 .p_class = P_LOCAL,
1485 .ptr = &sDefault.bRead_only,
1486 .special = NULL,
1487 .enum_list = NULL,
1488 .flags = FLAG_HIDE,
1491 .label = "acl check permissions",
1492 .type = P_BOOL,
1493 .p_class = P_LOCAL,
1494 .ptr = &sDefault.bAclCheckPermissions,
1495 .special = NULL,
1496 .enum_list = NULL,
1497 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1500 .label = "acl group control",
1501 .type = P_BOOL,
1502 .p_class = P_LOCAL,
1503 .ptr = &sDefault.bAclGroupControl,
1504 .special = NULL,
1505 .enum_list = NULL,
1506 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1509 .label = "acl map full control",
1510 .type = P_BOOL,
1511 .p_class = P_LOCAL,
1512 .ptr = &sDefault.bAclMapFullControl,
1513 .special = NULL,
1514 .enum_list = NULL,
1515 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1518 .label = "create mask",
1519 .type = P_OCTAL,
1520 .p_class = P_LOCAL,
1521 .ptr = &sDefault.iCreate_mask,
1522 .special = NULL,
1523 .enum_list = NULL,
1524 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1527 .label = "create mode",
1528 .type = P_OCTAL,
1529 .p_class = P_LOCAL,
1530 .ptr = &sDefault.iCreate_mask,
1531 .special = NULL,
1532 .enum_list = NULL,
1533 .flags = FLAG_HIDE,
1536 .label = "force create mode",
1537 .type = P_OCTAL,
1538 .p_class = P_LOCAL,
1539 .ptr = &sDefault.iCreate_force_mode,
1540 .special = NULL,
1541 .enum_list = NULL,
1542 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1545 .label = "security mask",
1546 .type = P_OCTAL,
1547 .p_class = P_LOCAL,
1548 .ptr = &sDefault.iSecurity_mask,
1549 .special = NULL,
1550 .enum_list = NULL,
1551 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1554 .label = "force security mode",
1555 .type = P_OCTAL,
1556 .p_class = P_LOCAL,
1557 .ptr = &sDefault.iSecurity_force_mode,
1558 .special = NULL,
1559 .enum_list = NULL,
1560 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1563 .label = "directory mask",
1564 .type = P_OCTAL,
1565 .p_class = P_LOCAL,
1566 .ptr = &sDefault.iDir_mask,
1567 .special = NULL,
1568 .enum_list = NULL,
1569 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1572 .label = "directory mode",
1573 .type = P_OCTAL,
1574 .p_class = P_LOCAL,
1575 .ptr = &sDefault.iDir_mask,
1576 .special = NULL,
1577 .enum_list = NULL,
1578 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1581 .label = "force directory mode",
1582 .type = P_OCTAL,
1583 .p_class = P_LOCAL,
1584 .ptr = &sDefault.iDir_force_mode,
1585 .special = NULL,
1586 .enum_list = NULL,
1587 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1590 .label = "directory security mask",
1591 .type = P_OCTAL,
1592 .p_class = P_LOCAL,
1593 .ptr = &sDefault.iDir_Security_mask,
1594 .special = NULL,
1595 .enum_list = NULL,
1596 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1599 .label = "force directory security mode",
1600 .type = P_OCTAL,
1601 .p_class = P_LOCAL,
1602 .ptr = &sDefault.iDir_Security_force_mode,
1603 .special = NULL,
1604 .enum_list = NULL,
1605 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1608 .label = "force unknown acl user",
1609 .type = P_BOOL,
1610 .p_class = P_LOCAL,
1611 .ptr = &sDefault.bForceUnknownAclUser,
1612 .special = NULL,
1613 .enum_list = NULL,
1614 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1617 .label = "inherit permissions",
1618 .type = P_BOOL,
1619 .p_class = P_LOCAL,
1620 .ptr = &sDefault.bInheritPerms,
1621 .special = NULL,
1622 .enum_list = NULL,
1623 .flags = FLAG_ADVANCED | FLAG_SHARE,
1626 .label = "inherit acls",
1627 .type = P_BOOL,
1628 .p_class = P_LOCAL,
1629 .ptr = &sDefault.bInheritACLS,
1630 .special = NULL,
1631 .enum_list = NULL,
1632 .flags = FLAG_ADVANCED | FLAG_SHARE,
1635 .label = "inherit owner",
1636 .type = P_BOOL,
1637 .p_class = P_LOCAL,
1638 .ptr = &sDefault.bInheritOwner,
1639 .special = NULL,
1640 .enum_list = NULL,
1641 .flags = FLAG_ADVANCED | FLAG_SHARE,
1644 .label = "guest only",
1645 .type = P_BOOL,
1646 .p_class = P_LOCAL,
1647 .ptr = &sDefault.bGuest_only,
1648 .special = NULL,
1649 .enum_list = NULL,
1650 .flags = FLAG_ADVANCED | FLAG_SHARE,
1653 .label = "only guest",
1654 .type = P_BOOL,
1655 .p_class = P_LOCAL,
1656 .ptr = &sDefault.bGuest_only,
1657 .special = NULL,
1658 .enum_list = NULL,
1659 .flags = FLAG_HIDE,
1662 .label = "administrative share",
1663 .type = P_BOOL,
1664 .p_class = P_LOCAL,
1665 .ptr = &sDefault.bAdministrative_share,
1666 .special = NULL,
1667 .enum_list = NULL,
1668 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1672 .label = "guest ok",
1673 .type = P_BOOL,
1674 .p_class = P_LOCAL,
1675 .ptr = &sDefault.bGuest_ok,
1676 .special = NULL,
1677 .enum_list = NULL,
1678 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1681 .label = "public",
1682 .type = P_BOOL,
1683 .p_class = P_LOCAL,
1684 .ptr = &sDefault.bGuest_ok,
1685 .special = NULL,
1686 .enum_list = NULL,
1687 .flags = FLAG_HIDE,
1690 .label = "only user",
1691 .type = P_BOOL,
1692 .p_class = P_LOCAL,
1693 .ptr = &sDefault.bOnlyUser,
1694 .special = NULL,
1695 .enum_list = NULL,
1696 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1699 .label = "hosts allow",
1700 .type = P_LIST,
1701 .p_class = P_LOCAL,
1702 .ptr = &sDefault.szHostsallow,
1703 .special = NULL,
1704 .enum_list = NULL,
1705 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1708 .label = "allow hosts",
1709 .type = P_LIST,
1710 .p_class = P_LOCAL,
1711 .ptr = &sDefault.szHostsallow,
1712 .special = NULL,
1713 .enum_list = NULL,
1714 .flags = FLAG_HIDE,
1717 .label = "hosts deny",
1718 .type = P_LIST,
1719 .p_class = P_LOCAL,
1720 .ptr = &sDefault.szHostsdeny,
1721 .special = NULL,
1722 .enum_list = NULL,
1723 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1726 .label = "deny hosts",
1727 .type = P_LIST,
1728 .p_class = P_LOCAL,
1729 .ptr = &sDefault.szHostsdeny,
1730 .special = NULL,
1731 .enum_list = NULL,
1732 .flags = FLAG_HIDE,
1735 .label = "preload modules",
1736 .type = P_LIST,
1737 .p_class = P_GLOBAL,
1738 .ptr = &Globals.szPreloadModules,
1739 .special = NULL,
1740 .enum_list = NULL,
1741 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1744 .label = "use kerberos keytab",
1745 .type = P_BOOL,
1746 .p_class = P_GLOBAL,
1747 .ptr = &Globals.bUseKerberosKeytab,
1748 .special = NULL,
1749 .enum_list = NULL,
1750 .flags = FLAG_ADVANCED,
1753 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1756 .label = "log level",
1757 .type = P_STRING,
1758 .p_class = P_GLOBAL,
1759 .ptr = &Globals.szLogLevel,
1760 .special = handle_debug_list,
1761 .enum_list = NULL,
1762 .flags = FLAG_ADVANCED,
1765 .label = "debuglevel",
1766 .type = P_STRING,
1767 .p_class = P_GLOBAL,
1768 .ptr = &Globals.szLogLevel,
1769 .special = handle_debug_list,
1770 .enum_list = NULL,
1771 .flags = FLAG_HIDE,
1774 .label = "syslog",
1775 .type = P_INTEGER,
1776 .p_class = P_GLOBAL,
1777 .ptr = &Globals.syslog,
1778 .special = NULL,
1779 .enum_list = NULL,
1780 .flags = FLAG_ADVANCED,
1783 .label = "syslog only",
1784 .type = P_BOOL,
1785 .p_class = P_GLOBAL,
1786 .ptr = &Globals.bSyslogOnly,
1787 .special = NULL,
1788 .enum_list = NULL,
1789 .flags = FLAG_ADVANCED,
1792 .label = "log file",
1793 .type = P_STRING,
1794 .p_class = P_GLOBAL,
1795 .ptr = &Globals.szLogFile,
1796 .special = NULL,
1797 .enum_list = NULL,
1798 .flags = FLAG_ADVANCED,
1801 .label = "max log size",
1802 .type = P_INTEGER,
1803 .p_class = P_GLOBAL,
1804 .ptr = &Globals.max_log_size,
1805 .special = NULL,
1806 .enum_list = NULL,
1807 .flags = FLAG_ADVANCED,
1810 .label = "debug timestamp",
1811 .type = P_BOOL,
1812 .p_class = P_GLOBAL,
1813 .ptr = &Globals.bTimestampLogs,
1814 .special = NULL,
1815 .enum_list = NULL,
1816 .flags = FLAG_ADVANCED,
1819 .label = "timestamp logs",
1820 .type = P_BOOL,
1821 .p_class = P_GLOBAL,
1822 .ptr = &Globals.bTimestampLogs,
1823 .special = NULL,
1824 .enum_list = NULL,
1825 .flags = FLAG_ADVANCED,
1828 .label = "debug prefix timestamp",
1829 .type = P_BOOL,
1830 .p_class = P_GLOBAL,
1831 .ptr = &Globals.bDebugPrefixTimestamp,
1832 .special = NULL,
1833 .enum_list = NULL,
1834 .flags = FLAG_ADVANCED,
1837 .label = "debug hires timestamp",
1838 .type = P_BOOL,
1839 .p_class = P_GLOBAL,
1840 .ptr = &Globals.bDebugHiresTimestamp,
1841 .special = NULL,
1842 .enum_list = NULL,
1843 .flags = FLAG_ADVANCED,
1846 .label = "debug pid",
1847 .type = P_BOOL,
1848 .p_class = P_GLOBAL,
1849 .ptr = &Globals.bDebugPid,
1850 .special = NULL,
1851 .enum_list = NULL,
1852 .flags = FLAG_ADVANCED,
1855 .label = "debug uid",
1856 .type = P_BOOL,
1857 .p_class = P_GLOBAL,
1858 .ptr = &Globals.bDebugUid,
1859 .special = NULL,
1860 .enum_list = NULL,
1861 .flags = FLAG_ADVANCED,
1864 .label = "debug class",
1865 .type = P_BOOL,
1866 .p_class = P_GLOBAL,
1867 .ptr = &Globals.bDebugClass,
1868 .special = NULL,
1869 .enum_list = NULL,
1870 .flags = FLAG_ADVANCED,
1873 .label = "enable core files",
1874 .type = P_BOOL,
1875 .p_class = P_GLOBAL,
1876 .ptr = &Globals.bEnableCoreFiles,
1877 .special = NULL,
1878 .enum_list = NULL,
1879 .flags = FLAG_ADVANCED,
1882 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1885 .label = "allocation roundup size",
1886 .type = P_INTEGER,
1887 .p_class = P_LOCAL,
1888 .ptr = &sDefault.iallocation_roundup_size,
1889 .special = NULL,
1890 .enum_list = NULL,
1891 .flags = FLAG_ADVANCED,
1894 .label = "aio read size",
1895 .type = P_INTEGER,
1896 .p_class = P_LOCAL,
1897 .ptr = &sDefault.iAioReadSize,
1898 .special = NULL,
1899 .enum_list = NULL,
1900 .flags = FLAG_ADVANCED,
1903 .label = "aio write size",
1904 .type = P_INTEGER,
1905 .p_class = P_LOCAL,
1906 .ptr = &sDefault.iAioWriteSize,
1907 .special = NULL,
1908 .enum_list = NULL,
1909 .flags = FLAG_ADVANCED,
1912 .label = "aio write behind",
1913 .type = P_STRING,
1914 .p_class = P_LOCAL,
1915 .ptr = &sDefault.szAioWriteBehind,
1916 .special = NULL,
1917 .enum_list = NULL,
1918 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1921 .label = "smb ports",
1922 .type = P_STRING,
1923 .p_class = P_GLOBAL,
1924 .ptr = &Globals.smb_ports,
1925 .special = NULL,
1926 .enum_list = NULL,
1927 .flags = FLAG_ADVANCED,
1930 .label = "large readwrite",
1931 .type = P_BOOL,
1932 .p_class = P_GLOBAL,
1933 .ptr = &Globals.bLargeReadwrite,
1934 .special = NULL,
1935 .enum_list = NULL,
1936 .flags = FLAG_ADVANCED,
1939 .label = "max protocol",
1940 .type = P_ENUM,
1941 .p_class = P_GLOBAL,
1942 .ptr = &Globals.maxprotocol,
1943 .special = NULL,
1944 .enum_list = enum_protocol,
1945 .flags = FLAG_ADVANCED,
1948 .label = "protocol",
1949 .type = P_ENUM,
1950 .p_class = P_GLOBAL,
1951 .ptr = &Globals.maxprotocol,
1952 .special = NULL,
1953 .enum_list = enum_protocol,
1954 .flags = FLAG_ADVANCED,
1957 .label = "min protocol",
1958 .type = P_ENUM,
1959 .p_class = P_GLOBAL,
1960 .ptr = &Globals.minprotocol,
1961 .special = NULL,
1962 .enum_list = enum_protocol,
1963 .flags = FLAG_ADVANCED,
1966 .label = "min receivefile size",
1967 .type = P_INTEGER,
1968 .p_class = P_GLOBAL,
1969 .ptr = &Globals.iminreceivefile,
1970 .special = NULL,
1971 .enum_list = NULL,
1972 .flags = FLAG_ADVANCED,
1975 .label = "read raw",
1976 .type = P_BOOL,
1977 .p_class = P_GLOBAL,
1978 .ptr = &Globals.bReadRaw,
1979 .special = NULL,
1980 .enum_list = NULL,
1981 .flags = FLAG_ADVANCED,
1984 .label = "write raw",
1985 .type = P_BOOL,
1986 .p_class = P_GLOBAL,
1987 .ptr = &Globals.bWriteRaw,
1988 .special = NULL,
1989 .enum_list = NULL,
1990 .flags = FLAG_ADVANCED,
1993 .label = "disable netbios",
1994 .type = P_BOOL,
1995 .p_class = P_GLOBAL,
1996 .ptr = &Globals.bDisableNetbios,
1997 .special = NULL,
1998 .enum_list = NULL,
1999 .flags = FLAG_ADVANCED,
2002 .label = "reset on zero vc",
2003 .type = P_BOOL,
2004 .p_class = P_GLOBAL,
2005 .ptr = &Globals.bResetOnZeroVC,
2006 .special = NULL,
2007 .enum_list = NULL,
2008 .flags = FLAG_ADVANCED,
2011 .label = "acl compatibility",
2012 .type = P_ENUM,
2013 .p_class = P_GLOBAL,
2014 .ptr = &Globals.iAclCompat,
2015 .special = NULL,
2016 .enum_list = enum_acl_compat_vals,
2017 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2020 .label = "defer sharing violations",
2021 .type = P_BOOL,
2022 .p_class = P_GLOBAL,
2023 .ptr = &Globals.bDeferSharingViolations,
2024 .special = NULL,
2025 .enum_list = NULL,
2026 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2029 .label = "ea support",
2030 .type = P_BOOL,
2031 .p_class = P_LOCAL,
2032 .ptr = &sDefault.bEASupport,
2033 .special = NULL,
2034 .enum_list = NULL,
2035 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2038 .label = "nt acl support",
2039 .type = P_BOOL,
2040 .p_class = P_LOCAL,
2041 .ptr = &sDefault.bNTAclSupport,
2042 .special = NULL,
2043 .enum_list = NULL,
2044 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2047 .label = "nt pipe support",
2048 .type = P_BOOL,
2049 .p_class = P_GLOBAL,
2050 .ptr = &Globals.bNTPipeSupport,
2051 .special = NULL,
2052 .enum_list = NULL,
2053 .flags = FLAG_ADVANCED,
2056 .label = "nt status support",
2057 .type = P_BOOL,
2058 .p_class = P_GLOBAL,
2059 .ptr = &Globals.bNTStatusSupport,
2060 .special = NULL,
2061 .enum_list = NULL,
2062 .flags = FLAG_ADVANCED,
2065 .label = "profile acls",
2066 .type = P_BOOL,
2067 .p_class = P_LOCAL,
2068 .ptr = &sDefault.bProfileAcls,
2069 .special = NULL,
2070 .enum_list = NULL,
2071 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2074 .label = "announce version",
2075 .type = P_STRING,
2076 .p_class = P_GLOBAL,
2077 .ptr = &Globals.szAnnounceVersion,
2078 .special = NULL,
2079 .enum_list = NULL,
2080 .flags = FLAG_ADVANCED,
2083 .label = "announce as",
2084 .type = P_ENUM,
2085 .p_class = P_GLOBAL,
2086 .ptr = &Globals.announce_as,
2087 .special = NULL,
2088 .enum_list = enum_announce_as,
2089 .flags = FLAG_ADVANCED,
2092 .label = "map acl inherit",
2093 .type = P_BOOL,
2094 .p_class = P_LOCAL,
2095 .ptr = &sDefault.bMap_acl_inherit,
2096 .special = NULL,
2097 .enum_list = NULL,
2098 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2101 .label = "afs share",
2102 .type = P_BOOL,
2103 .p_class = P_LOCAL,
2104 .ptr = &sDefault.bAfs_Share,
2105 .special = NULL,
2106 .enum_list = NULL,
2107 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2110 .label = "max mux",
2111 .type = P_INTEGER,
2112 .p_class = P_GLOBAL,
2113 .ptr = &Globals.max_mux,
2114 .special = NULL,
2115 .enum_list = NULL,
2116 .flags = FLAG_ADVANCED,
2119 .label = "max xmit",
2120 .type = P_INTEGER,
2121 .p_class = P_GLOBAL,
2122 .ptr = &Globals.max_xmit,
2123 .special = NULL,
2124 .enum_list = NULL,
2125 .flags = FLAG_ADVANCED,
2128 .label = "name resolve order",
2129 .type = P_STRING,
2130 .p_class = P_GLOBAL,
2131 .ptr = &Globals.szNameResolveOrder,
2132 .special = NULL,
2133 .enum_list = NULL,
2134 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2137 .label = "max ttl",
2138 .type = P_INTEGER,
2139 .p_class = P_GLOBAL,
2140 .ptr = &Globals.max_ttl,
2141 .special = NULL,
2142 .enum_list = NULL,
2143 .flags = FLAG_ADVANCED,
2146 .label = "max wins ttl",
2147 .type = P_INTEGER,
2148 .p_class = P_GLOBAL,
2149 .ptr = &Globals.max_wins_ttl,
2150 .special = NULL,
2151 .enum_list = NULL,
2152 .flags = FLAG_ADVANCED,
2155 .label = "min wins ttl",
2156 .type = P_INTEGER,
2157 .p_class = P_GLOBAL,
2158 .ptr = &Globals.min_wins_ttl,
2159 .special = NULL,
2160 .enum_list = NULL,
2161 .flags = FLAG_ADVANCED,
2164 .label = "time server",
2165 .type = P_BOOL,
2166 .p_class = P_GLOBAL,
2167 .ptr = &Globals.bTimeServer,
2168 .special = NULL,
2169 .enum_list = NULL,
2170 .flags = FLAG_ADVANCED,
2173 .label = "unix extensions",
2174 .type = P_BOOL,
2175 .p_class = P_GLOBAL,
2176 .ptr = &Globals.bUnixExtensions,
2177 .special = NULL,
2178 .enum_list = NULL,
2179 .flags = FLAG_ADVANCED,
2182 .label = "use spnego",
2183 .type = P_BOOL,
2184 .p_class = P_GLOBAL,
2185 .ptr = &Globals.bUseSpnego,
2186 .special = NULL,
2187 .enum_list = NULL,
2188 .flags = FLAG_ADVANCED,
2191 .label = "client signing",
2192 .type = P_ENUM,
2193 .p_class = P_GLOBAL,
2194 .ptr = &Globals.client_signing,
2195 .special = NULL,
2196 .enum_list = enum_smb_signing_vals,
2197 .flags = FLAG_ADVANCED,
2200 .label = "server signing",
2201 .type = P_ENUM,
2202 .p_class = P_GLOBAL,
2203 .ptr = &Globals.server_signing,
2204 .special = NULL,
2205 .enum_list = enum_smb_signing_vals,
2206 .flags = FLAG_ADVANCED,
2209 .label = "smb encrypt",
2210 .type = P_ENUM,
2211 .p_class = P_LOCAL,
2212 .ptr = &sDefault.ismb_encrypt,
2213 .special = NULL,
2214 .enum_list = enum_smb_signing_vals,
2215 .flags = FLAG_ADVANCED,
2218 .label = "client use spnego",
2219 .type = P_BOOL,
2220 .p_class = P_GLOBAL,
2221 .ptr = &Globals.bClientUseSpnego,
2222 .special = NULL,
2223 .enum_list = NULL,
2224 .flags = FLAG_ADVANCED,
2227 .label = "client ldap sasl wrapping",
2228 .type = P_ENUM,
2229 .p_class = P_GLOBAL,
2230 .ptr = &Globals.client_ldap_sasl_wrapping,
2231 .special = NULL,
2232 .enum_list = enum_ldap_sasl_wrapping,
2233 .flags = FLAG_ADVANCED,
2236 .label = "enable asu support",
2237 .type = P_BOOL,
2238 .p_class = P_GLOBAL,
2239 .ptr = &Globals.bASUSupport,
2240 .special = NULL,
2241 .enum_list = NULL,
2242 .flags = FLAG_ADVANCED,
2245 .label = "svcctl list",
2246 .type = P_LIST,
2247 .p_class = P_GLOBAL,
2248 .ptr = &Globals.szServicesList,
2249 .special = NULL,
2250 .enum_list = NULL,
2251 .flags = FLAG_ADVANCED,
2254 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2257 .label = "block size",
2258 .type = P_INTEGER,
2259 .p_class = P_LOCAL,
2260 .ptr = &sDefault.iBlock_size,
2261 .special = NULL,
2262 .enum_list = NULL,
2263 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2266 .label = "deadtime",
2267 .type = P_INTEGER,
2268 .p_class = P_GLOBAL,
2269 .ptr = &Globals.deadtime,
2270 .special = NULL,
2271 .enum_list = NULL,
2272 .flags = FLAG_ADVANCED,
2275 .label = "getwd cache",
2276 .type = P_BOOL,
2277 .p_class = P_GLOBAL,
2278 .ptr = &Globals.getwd_cache,
2279 .special = NULL,
2280 .enum_list = NULL,
2281 .flags = FLAG_ADVANCED,
2284 .label = "keepalive",
2285 .type = P_INTEGER,
2286 .p_class = P_GLOBAL,
2287 .ptr = &Globals.iKeepalive,
2288 .special = NULL,
2289 .enum_list = NULL,
2290 .flags = FLAG_ADVANCED,
2293 .label = "change notify",
2294 .type = P_BOOL,
2295 .p_class = P_LOCAL,
2296 .ptr = &sDefault.bChangeNotify,
2297 .special = NULL,
2298 .enum_list = NULL,
2299 .flags = FLAG_ADVANCED | FLAG_SHARE,
2302 .label = "directory name cache size",
2303 .type = P_INTEGER,
2304 .p_class = P_LOCAL,
2305 .ptr = &sDefault.iDirectoryNameCacheSize,
2306 .special = NULL,
2307 .enum_list = NULL,
2308 .flags = FLAG_ADVANCED | FLAG_SHARE,
2311 .label = "kernel change notify",
2312 .type = P_BOOL,
2313 .p_class = P_LOCAL,
2314 .ptr = &sDefault.bKernelChangeNotify,
2315 .special = NULL,
2316 .enum_list = NULL,
2317 .flags = FLAG_ADVANCED | FLAG_SHARE,
2320 .label = "lpq cache time",
2321 .type = P_INTEGER,
2322 .p_class = P_GLOBAL,
2323 .ptr = &Globals.lpqcachetime,
2324 .special = NULL,
2325 .enum_list = NULL,
2326 .flags = FLAG_ADVANCED,
2329 .label = "max smbd processes",
2330 .type = P_INTEGER,
2331 .p_class = P_GLOBAL,
2332 .ptr = &Globals.iMaxSmbdProcesses,
2333 .special = NULL,
2334 .enum_list = NULL,
2335 .flags = FLAG_ADVANCED,
2338 .label = "max connections",
2339 .type = P_INTEGER,
2340 .p_class = P_LOCAL,
2341 .ptr = &sDefault.iMaxConnections,
2342 .special = NULL,
2343 .enum_list = NULL,
2344 .flags = FLAG_ADVANCED | FLAG_SHARE,
2347 .label = "paranoid server security",
2348 .type = P_BOOL,
2349 .p_class = P_GLOBAL,
2350 .ptr = &Globals.paranoid_server_security,
2351 .special = NULL,
2352 .enum_list = NULL,
2353 .flags = FLAG_ADVANCED,
2356 .label = "max disk size",
2357 .type = P_INTEGER,
2358 .p_class = P_GLOBAL,
2359 .ptr = &Globals.maxdisksize,
2360 .special = NULL,
2361 .enum_list = NULL,
2362 .flags = FLAG_ADVANCED,
2365 .label = "max open files",
2366 .type = P_INTEGER,
2367 .p_class = P_GLOBAL,
2368 .ptr = &Globals.max_open_files,
2369 .special = NULL,
2370 .enum_list = NULL,
2371 .flags = FLAG_ADVANCED,
2374 .label = "min print space",
2375 .type = P_INTEGER,
2376 .p_class = P_LOCAL,
2377 .ptr = &sDefault.iMinPrintSpace,
2378 .special = NULL,
2379 .enum_list = NULL,
2380 .flags = FLAG_ADVANCED | FLAG_PRINT,
2383 .label = "socket options",
2384 .type = P_STRING,
2385 .p_class = P_GLOBAL,
2386 .ptr = &Globals.szSocketOptions,
2387 .special = NULL,
2388 .enum_list = NULL,
2389 .flags = FLAG_ADVANCED,
2392 .label = "strict allocate",
2393 .type = P_BOOL,
2394 .p_class = P_LOCAL,
2395 .ptr = &sDefault.bStrictAllocate,
2396 .special = NULL,
2397 .enum_list = NULL,
2398 .flags = FLAG_ADVANCED | FLAG_SHARE,
2401 .label = "strict sync",
2402 .type = P_BOOL,
2403 .p_class = P_LOCAL,
2404 .ptr = &sDefault.bStrictSync,
2405 .special = NULL,
2406 .enum_list = NULL,
2407 .flags = FLAG_ADVANCED | FLAG_SHARE,
2410 .label = "sync always",
2411 .type = P_BOOL,
2412 .p_class = P_LOCAL,
2413 .ptr = &sDefault.bSyncAlways,
2414 .special = NULL,
2415 .enum_list = NULL,
2416 .flags = FLAG_ADVANCED | FLAG_SHARE,
2419 .label = "use mmap",
2420 .type = P_BOOL,
2421 .p_class = P_GLOBAL,
2422 .ptr = &Globals.bUseMmap,
2423 .special = NULL,
2424 .enum_list = NULL,
2425 .flags = FLAG_ADVANCED,
2428 .label = "use sendfile",
2429 .type = P_BOOL,
2430 .p_class = P_LOCAL,
2431 .ptr = &sDefault.bUseSendfile,
2432 .special = NULL,
2433 .enum_list = NULL,
2434 .flags = FLAG_ADVANCED | FLAG_SHARE,
2437 .label = "hostname lookups",
2438 .type = P_BOOL,
2439 .p_class = P_GLOBAL,
2440 .ptr = &Globals.bHostnameLookups,
2441 .special = NULL,
2442 .enum_list = NULL,
2443 .flags = FLAG_ADVANCED,
2446 .label = "write cache size",
2447 .type = P_INTEGER,
2448 .p_class = P_LOCAL,
2449 .ptr = &sDefault.iWriteCacheSize,
2450 .special = NULL,
2451 .enum_list = NULL,
2452 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2455 .label = "name cache timeout",
2456 .type = P_INTEGER,
2457 .p_class = P_GLOBAL,
2458 .ptr = &Globals.name_cache_timeout,
2459 .special = NULL,
2460 .enum_list = NULL,
2461 .flags = FLAG_ADVANCED,
2464 .label = "ctdbd socket",
2465 .type = P_STRING,
2466 .p_class = P_GLOBAL,
2467 .ptr = &Globals.ctdbdSocket,
2468 .special = NULL,
2469 .enum_list = NULL,
2470 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2473 .label = "cluster addresses",
2474 .type = P_LIST,
2475 .p_class = P_GLOBAL,
2476 .ptr = &Globals.szClusterAddresses,
2477 .special = NULL,
2478 .enum_list = NULL,
2479 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2482 .label = "clustering",
2483 .type = P_BOOL,
2484 .p_class = P_GLOBAL,
2485 .ptr = &Globals.clustering,
2486 .special = NULL,
2487 .enum_list = NULL,
2488 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2491 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2494 .label = "max reported print jobs",
2495 .type = P_INTEGER,
2496 .p_class = P_LOCAL,
2497 .ptr = &sDefault.iMaxReportedPrintJobs,
2498 .special = NULL,
2499 .enum_list = NULL,
2500 .flags = FLAG_ADVANCED | FLAG_PRINT,
2503 .label = "max print jobs",
2504 .type = P_INTEGER,
2505 .p_class = P_LOCAL,
2506 .ptr = &sDefault.iMaxPrintJobs,
2507 .special = NULL,
2508 .enum_list = NULL,
2509 .flags = FLAG_ADVANCED | FLAG_PRINT,
2512 .label = "load printers",
2513 .type = P_BOOL,
2514 .p_class = P_GLOBAL,
2515 .ptr = &Globals.bLoadPrinters,
2516 .special = NULL,
2517 .enum_list = NULL,
2518 .flags = FLAG_ADVANCED | FLAG_PRINT,
2521 .label = "printcap cache time",
2522 .type = P_INTEGER,
2523 .p_class = P_GLOBAL,
2524 .ptr = &Globals.PrintcapCacheTime,
2525 .special = NULL,
2526 .enum_list = NULL,
2527 .flags = FLAG_ADVANCED | FLAG_PRINT,
2530 .label = "printcap name",
2531 .type = P_STRING,
2532 .p_class = P_GLOBAL,
2533 .ptr = &Globals.szPrintcapname,
2534 .special = NULL,
2535 .enum_list = NULL,
2536 .flags = FLAG_ADVANCED | FLAG_PRINT,
2539 .label = "printcap",
2540 .type = P_STRING,
2541 .p_class = P_GLOBAL,
2542 .ptr = &Globals.szPrintcapname,
2543 .special = NULL,
2544 .enum_list = NULL,
2545 .flags = FLAG_HIDE,
2548 .label = "printable",
2549 .type = P_BOOL,
2550 .p_class = P_LOCAL,
2551 .ptr = &sDefault.bPrint_ok,
2552 .special = NULL,
2553 .enum_list = NULL,
2554 .flags = FLAG_ADVANCED | FLAG_PRINT,
2557 .label = "print ok",
2558 .type = P_BOOL,
2559 .p_class = P_LOCAL,
2560 .ptr = &sDefault.bPrint_ok,
2561 .special = NULL,
2562 .enum_list = NULL,
2563 .flags = FLAG_HIDE,
2566 .label = "printing",
2567 .type = P_ENUM,
2568 .p_class = P_LOCAL,
2569 .ptr = &sDefault.iPrinting,
2570 .special = handle_printing,
2571 .enum_list = enum_printing,
2572 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2575 .label = "cups options",
2576 .type = P_STRING,
2577 .p_class = P_LOCAL,
2578 .ptr = &sDefault.szCupsOptions,
2579 .special = NULL,
2580 .enum_list = NULL,
2581 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2584 .label = "cups server",
2585 .type = P_STRING,
2586 .p_class = P_GLOBAL,
2587 .ptr = &Globals.szCupsServer,
2588 .special = NULL,
2589 .enum_list = NULL,
2590 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2593 .label = "cups connection timeout",
2594 .type = P_INTEGER,
2595 .p_class = P_GLOBAL,
2596 .ptr = &Globals.cups_connection_timeout,
2597 .special = NULL,
2598 .enum_list = NULL,
2599 .flags = FLAG_ADVANCED,
2602 .label = "iprint server",
2603 .type = P_STRING,
2604 .p_class = P_GLOBAL,
2605 .ptr = &Globals.szIPrintServer,
2606 .special = NULL,
2607 .enum_list = NULL,
2608 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2611 .label = "print command",
2612 .type = P_STRING,
2613 .p_class = P_LOCAL,
2614 .ptr = &sDefault.szPrintcommand,
2615 .special = NULL,
2616 .enum_list = NULL,
2617 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2620 .label = "disable spoolss",
2621 .type = P_BOOL,
2622 .p_class = P_GLOBAL,
2623 .ptr = &Globals.bDisableSpoolss,
2624 .special = NULL,
2625 .enum_list = NULL,
2626 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2629 .label = "enable spoolss",
2630 .type = P_BOOLREV,
2631 .p_class = P_GLOBAL,
2632 .ptr = &Globals.bDisableSpoolss,
2633 .special = NULL,
2634 .enum_list = NULL,
2635 .flags = FLAG_HIDE,
2638 .label = "lpq command",
2639 .type = P_STRING,
2640 .p_class = P_LOCAL,
2641 .ptr = &sDefault.szLpqcommand,
2642 .special = NULL,
2643 .enum_list = NULL,
2644 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2647 .label = "lprm command",
2648 .type = P_STRING,
2649 .p_class = P_LOCAL,
2650 .ptr = &sDefault.szLprmcommand,
2651 .special = NULL,
2652 .enum_list = NULL,
2653 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2656 .label = "lppause command",
2657 .type = P_STRING,
2658 .p_class = P_LOCAL,
2659 .ptr = &sDefault.szLppausecommand,
2660 .special = NULL,
2661 .enum_list = NULL,
2662 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2665 .label = "lpresume command",
2666 .type = P_STRING,
2667 .p_class = P_LOCAL,
2668 .ptr = &sDefault.szLpresumecommand,
2669 .special = NULL,
2670 .enum_list = NULL,
2671 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2674 .label = "queuepause command",
2675 .type = P_STRING,
2676 .p_class = P_LOCAL,
2677 .ptr = &sDefault.szQueuepausecommand,
2678 .special = NULL,
2679 .enum_list = NULL,
2680 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2683 .label = "queueresume command",
2684 .type = P_STRING,
2685 .p_class = P_LOCAL,
2686 .ptr = &sDefault.szQueueresumecommand,
2687 .special = NULL,
2688 .enum_list = NULL,
2689 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2692 .label = "addport command",
2693 .type = P_STRING,
2694 .p_class = P_GLOBAL,
2695 .ptr = &Globals.szAddPortCommand,
2696 .special = NULL,
2697 .enum_list = NULL,
2698 .flags = FLAG_ADVANCED,
2701 .label = "enumports command",
2702 .type = P_STRING,
2703 .p_class = P_GLOBAL,
2704 .ptr = &Globals.szEnumPortsCommand,
2705 .special = NULL,
2706 .enum_list = NULL,
2707 .flags = FLAG_ADVANCED,
2710 .label = "addprinter command",
2711 .type = P_STRING,
2712 .p_class = P_GLOBAL,
2713 .ptr = &Globals.szAddPrinterCommand,
2714 .special = NULL,
2715 .enum_list = NULL,
2716 .flags = FLAG_ADVANCED,
2719 .label = "deleteprinter command",
2720 .type = P_STRING,
2721 .p_class = P_GLOBAL,
2722 .ptr = &Globals.szDeletePrinterCommand,
2723 .special = NULL,
2724 .enum_list = NULL,
2725 .flags = FLAG_ADVANCED,
2728 .label = "show add printer wizard",
2729 .type = P_BOOL,
2730 .p_class = P_GLOBAL,
2731 .ptr = &Globals.bMsAddPrinterWizard,
2732 .special = NULL,
2733 .enum_list = NULL,
2734 .flags = FLAG_ADVANCED,
2737 .label = "os2 driver map",
2738 .type = P_STRING,
2739 .p_class = P_GLOBAL,
2740 .ptr = &Globals.szOs2DriverMap,
2741 .special = NULL,
2742 .enum_list = NULL,
2743 .flags = FLAG_ADVANCED,
2747 .label = "printer name",
2748 .type = P_STRING,
2749 .p_class = P_LOCAL,
2750 .ptr = &sDefault.szPrintername,
2751 .special = NULL,
2752 .enum_list = NULL,
2753 .flags = FLAG_ADVANCED | FLAG_PRINT,
2756 .label = "printer",
2757 .type = P_STRING,
2758 .p_class = P_LOCAL,
2759 .ptr = &sDefault.szPrintername,
2760 .special = NULL,
2761 .enum_list = NULL,
2762 .flags = FLAG_HIDE,
2765 .label = "use client driver",
2766 .type = P_BOOL,
2767 .p_class = P_LOCAL,
2768 .ptr = &sDefault.bUseClientDriver,
2769 .special = NULL,
2770 .enum_list = NULL,
2771 .flags = FLAG_ADVANCED | FLAG_PRINT,
2774 .label = "default devmode",
2775 .type = P_BOOL,
2776 .p_class = P_LOCAL,
2777 .ptr = &sDefault.bDefaultDevmode,
2778 .special = NULL,
2779 .enum_list = NULL,
2780 .flags = FLAG_ADVANCED | FLAG_PRINT,
2783 .label = "force printername",
2784 .type = P_BOOL,
2785 .p_class = P_LOCAL,
2786 .ptr = &sDefault.bForcePrintername,
2787 .special = NULL,
2788 .enum_list = NULL,
2789 .flags = FLAG_ADVANCED | FLAG_PRINT,
2792 .label = "printjob username",
2793 .type = P_STRING,
2794 .p_class = P_LOCAL,
2795 .ptr = &sDefault.szPrintjobUsername,
2796 .special = NULL,
2797 .enum_list = NULL,
2798 .flags = FLAG_ADVANCED | FLAG_PRINT,
2801 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2804 .label = "mangling method",
2805 .type = P_STRING,
2806 .p_class = P_GLOBAL,
2807 .ptr = &Globals.szManglingMethod,
2808 .special = NULL,
2809 .enum_list = NULL,
2810 .flags = FLAG_ADVANCED,
2813 .label = "mangle prefix",
2814 .type = P_INTEGER,
2815 .p_class = P_GLOBAL,
2816 .ptr = &Globals.mangle_prefix,
2817 .special = NULL,
2818 .enum_list = NULL,
2819 .flags = FLAG_ADVANCED,
2823 .label = "default case",
2824 .type = P_ENUM,
2825 .p_class = P_LOCAL,
2826 .ptr = &sDefault.iDefaultCase,
2827 .special = NULL,
2828 .enum_list = enum_case,
2829 .flags = FLAG_ADVANCED | FLAG_SHARE,
2832 .label = "case sensitive",
2833 .type = P_ENUM,
2834 .p_class = P_LOCAL,
2835 .ptr = &sDefault.iCaseSensitive,
2836 .special = NULL,
2837 .enum_list = enum_bool_auto,
2838 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2841 .label = "casesignames",
2842 .type = P_ENUM,
2843 .p_class = P_LOCAL,
2844 .ptr = &sDefault.iCaseSensitive,
2845 .special = NULL,
2846 .enum_list = enum_bool_auto,
2847 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2850 .label = "preserve case",
2851 .type = P_BOOL,
2852 .p_class = P_LOCAL,
2853 .ptr = &sDefault.bCasePreserve,
2854 .special = NULL,
2855 .enum_list = NULL,
2856 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2859 .label = "short preserve case",
2860 .type = P_BOOL,
2861 .p_class = P_LOCAL,
2862 .ptr = &sDefault.bShortCasePreserve,
2863 .special = NULL,
2864 .enum_list = NULL,
2865 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2868 .label = "mangling char",
2869 .type = P_CHAR,
2870 .p_class = P_LOCAL,
2871 .ptr = &sDefault.magic_char,
2872 .special = NULL,
2873 .enum_list = NULL,
2874 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2877 .label = "hide dot files",
2878 .type = P_BOOL,
2879 .p_class = P_LOCAL,
2880 .ptr = &sDefault.bHideDotFiles,
2881 .special = NULL,
2882 .enum_list = NULL,
2883 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2886 .label = "hide special files",
2887 .type = P_BOOL,
2888 .p_class = P_LOCAL,
2889 .ptr = &sDefault.bHideSpecialFiles,
2890 .special = NULL,
2891 .enum_list = NULL,
2892 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2895 .label = "hide unreadable",
2896 .type = P_BOOL,
2897 .p_class = P_LOCAL,
2898 .ptr = &sDefault.bHideUnReadable,
2899 .special = NULL,
2900 .enum_list = NULL,
2901 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2904 .label = "hide unwriteable files",
2905 .type = P_BOOL,
2906 .p_class = P_LOCAL,
2907 .ptr = &sDefault.bHideUnWriteableFiles,
2908 .special = NULL,
2909 .enum_list = NULL,
2910 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2913 .label = "delete veto files",
2914 .type = P_BOOL,
2915 .p_class = P_LOCAL,
2916 .ptr = &sDefault.bDeleteVetoFiles,
2917 .special = NULL,
2918 .enum_list = NULL,
2919 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2922 .label = "veto files",
2923 .type = P_STRING,
2924 .p_class = P_LOCAL,
2925 .ptr = &sDefault.szVetoFiles,
2926 .special = NULL,
2927 .enum_list = NULL,
2928 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2931 .label = "hide files",
2932 .type = P_STRING,
2933 .p_class = P_LOCAL,
2934 .ptr = &sDefault.szHideFiles,
2935 .special = NULL,
2936 .enum_list = NULL,
2937 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2940 .label = "veto oplock files",
2941 .type = P_STRING,
2942 .p_class = P_LOCAL,
2943 .ptr = &sDefault.szVetoOplockFiles,
2944 .special = NULL,
2945 .enum_list = NULL,
2946 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2949 .label = "map archive",
2950 .type = P_BOOL,
2951 .p_class = P_LOCAL,
2952 .ptr = &sDefault.bMap_archive,
2953 .special = NULL,
2954 .enum_list = NULL,
2955 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2958 .label = "map hidden",
2959 .type = P_BOOL,
2960 .p_class = P_LOCAL,
2961 .ptr = &sDefault.bMap_hidden,
2962 .special = NULL,
2963 .enum_list = NULL,
2964 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2967 .label = "map system",
2968 .type = P_BOOL,
2969 .p_class = P_LOCAL,
2970 .ptr = &sDefault.bMap_system,
2971 .special = NULL,
2972 .enum_list = NULL,
2973 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2976 .label = "map readonly",
2977 .type = P_ENUM,
2978 .p_class = P_LOCAL,
2979 .ptr = &sDefault.iMap_readonly,
2980 .special = NULL,
2981 .enum_list = enum_map_readonly,
2982 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2985 .label = "mangled names",
2986 .type = P_BOOL,
2987 .p_class = P_LOCAL,
2988 .ptr = &sDefault.bMangledNames,
2989 .special = NULL,
2990 .enum_list = NULL,
2991 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2994 .label = "max stat cache size",
2995 .type = P_INTEGER,
2996 .p_class = P_GLOBAL,
2997 .ptr = &Globals.iMaxStatCacheSize,
2998 .special = NULL,
2999 .enum_list = NULL,
3000 .flags = FLAG_ADVANCED,
3003 .label = "stat cache",
3004 .type = P_BOOL,
3005 .p_class = P_GLOBAL,
3006 .ptr = &Globals.bStatCache,
3007 .special = NULL,
3008 .enum_list = NULL,
3009 .flags = FLAG_ADVANCED,
3012 .label = "store dos attributes",
3013 .type = P_BOOL,
3014 .p_class = P_LOCAL,
3015 .ptr = &sDefault.bStoreDosAttributes,
3016 .special = NULL,
3017 .enum_list = NULL,
3018 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3021 .label = "dmapi support",
3022 .type = P_BOOL,
3023 .p_class = P_LOCAL,
3024 .ptr = &sDefault.bDmapiSupport,
3025 .special = NULL,
3026 .enum_list = NULL,
3027 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3031 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3034 .label = "machine password timeout",
3035 .type = P_INTEGER,
3036 .p_class = P_GLOBAL,
3037 .ptr = &Globals.machine_password_timeout,
3038 .special = NULL,
3039 .enum_list = NULL,
3040 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3043 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3046 .label = "add user script",
3047 .type = P_STRING,
3048 .p_class = P_GLOBAL,
3049 .ptr = &Globals.szAddUserScript,
3050 .special = NULL,
3051 .enum_list = NULL,
3052 .flags = FLAG_ADVANCED,
3055 .label = "rename user script",
3056 .type = P_STRING,
3057 .p_class = P_GLOBAL,
3058 .ptr = &Globals.szRenameUserScript,
3059 .special = NULL,
3060 .enum_list = NULL,
3061 .flags = FLAG_ADVANCED,
3064 .label = "delete user script",
3065 .type = P_STRING,
3066 .p_class = P_GLOBAL,
3067 .ptr = &Globals.szDelUserScript,
3068 .special = NULL,
3069 .enum_list = NULL,
3070 .flags = FLAG_ADVANCED,
3073 .label = "add group script",
3074 .type = P_STRING,
3075 .p_class = P_GLOBAL,
3076 .ptr = &Globals.szAddGroupScript,
3077 .special = NULL,
3078 .enum_list = NULL,
3079 .flags = FLAG_ADVANCED,
3082 .label = "delete group script",
3083 .type = P_STRING,
3084 .p_class = P_GLOBAL,
3085 .ptr = &Globals.szDelGroupScript,
3086 .special = NULL,
3087 .enum_list = NULL,
3088 .flags = FLAG_ADVANCED,
3091 .label = "add user to group script",
3092 .type = P_STRING,
3093 .p_class = P_GLOBAL,
3094 .ptr = &Globals.szAddUserToGroupScript,
3095 .special = NULL,
3096 .enum_list = NULL,
3097 .flags = FLAG_ADVANCED,
3100 .label = "delete user from group script",
3101 .type = P_STRING,
3102 .p_class = P_GLOBAL,
3103 .ptr = &Globals.szDelUserFromGroupScript,
3104 .special = NULL,
3105 .enum_list = NULL,
3106 .flags = FLAG_ADVANCED,
3109 .label = "set primary group script",
3110 .type = P_STRING,
3111 .p_class = P_GLOBAL,
3112 .ptr = &Globals.szSetPrimaryGroupScript,
3113 .special = NULL,
3114 .enum_list = NULL,
3115 .flags = FLAG_ADVANCED,
3118 .label = "add machine script",
3119 .type = P_STRING,
3120 .p_class = P_GLOBAL,
3121 .ptr = &Globals.szAddMachineScript,
3122 .special = NULL,
3123 .enum_list = NULL,
3124 .flags = FLAG_ADVANCED,
3127 .label = "shutdown script",
3128 .type = P_STRING,
3129 .p_class = P_GLOBAL,
3130 .ptr = &Globals.szShutdownScript,
3131 .special = NULL,
3132 .enum_list = NULL,
3133 .flags = FLAG_ADVANCED,
3136 .label = "abort shutdown script",
3137 .type = P_STRING,
3138 .p_class = P_GLOBAL,
3139 .ptr = &Globals.szAbortShutdownScript,
3140 .special = NULL,
3141 .enum_list = NULL,
3142 .flags = FLAG_ADVANCED,
3145 .label = "username map script",
3146 .type = P_STRING,
3147 .p_class = P_GLOBAL,
3148 .ptr = &Globals.szUsernameMapScript,
3149 .special = NULL,
3150 .enum_list = NULL,
3151 .flags = FLAG_ADVANCED,
3154 .label = "logon script",
3155 .type = P_STRING,
3156 .p_class = P_GLOBAL,
3157 .ptr = &Globals.szLogonScript,
3158 .special = NULL,
3159 .enum_list = NULL,
3160 .flags = FLAG_ADVANCED,
3163 .label = "logon path",
3164 .type = P_STRING,
3165 .p_class = P_GLOBAL,
3166 .ptr = &Globals.szLogonPath,
3167 .special = NULL,
3168 .enum_list = NULL,
3169 .flags = FLAG_ADVANCED,
3172 .label = "logon drive",
3173 .type = P_STRING,
3174 .p_class = P_GLOBAL,
3175 .ptr = &Globals.szLogonDrive,
3176 .special = NULL,
3177 .enum_list = NULL,
3178 .flags = FLAG_ADVANCED,
3181 .label = "logon home",
3182 .type = P_STRING,
3183 .p_class = P_GLOBAL,
3184 .ptr = &Globals.szLogonHome,
3185 .special = NULL,
3186 .enum_list = NULL,
3187 .flags = FLAG_ADVANCED,
3190 .label = "domain logons",
3191 .type = P_BOOL,
3192 .p_class = P_GLOBAL,
3193 .ptr = &Globals.bDomainLogons,
3194 .special = NULL,
3195 .enum_list = NULL,
3196 .flags = FLAG_ADVANCED,
3200 .label = "init logon delayed hosts",
3201 .type = P_LIST,
3202 .p_class = P_GLOBAL,
3203 .ptr = &Globals.szInitLogonDelayedHosts,
3204 .flags = FLAG_ADVANCED,
3208 .label = "init logon delay",
3209 .type = P_INTEGER,
3210 .p_class = P_GLOBAL,
3211 .ptr = &Globals.InitLogonDelay,
3212 .flags = FLAG_ADVANCED,
3216 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3219 .label = "os level",
3220 .type = P_INTEGER,
3221 .p_class = P_GLOBAL,
3222 .ptr = &Globals.os_level,
3223 .special = NULL,
3224 .enum_list = NULL,
3225 .flags = FLAG_BASIC | FLAG_ADVANCED,
3228 .label = "lm announce",
3229 .type = P_ENUM,
3230 .p_class = P_GLOBAL,
3231 .ptr = &Globals.lm_announce,
3232 .special = NULL,
3233 .enum_list = enum_bool_auto,
3234 .flags = FLAG_ADVANCED,
3237 .label = "lm interval",
3238 .type = P_INTEGER,
3239 .p_class = P_GLOBAL,
3240 .ptr = &Globals.lm_interval,
3241 .special = NULL,
3242 .enum_list = NULL,
3243 .flags = FLAG_ADVANCED,
3246 .label = "preferred master",
3247 .type = P_ENUM,
3248 .p_class = P_GLOBAL,
3249 .ptr = &Globals.iPreferredMaster,
3250 .special = NULL,
3251 .enum_list = enum_bool_auto,
3252 .flags = FLAG_BASIC | FLAG_ADVANCED,
3255 .label = "prefered master",
3256 .type = P_ENUM,
3257 .p_class = P_GLOBAL,
3258 .ptr = &Globals.iPreferredMaster,
3259 .special = NULL,
3260 .enum_list = enum_bool_auto,
3261 .flags = FLAG_HIDE,
3264 .label = "local master",
3265 .type = P_BOOL,
3266 .p_class = P_GLOBAL,
3267 .ptr = &Globals.bLocalMaster,
3268 .special = NULL,
3269 .enum_list = NULL,
3270 .flags = FLAG_BASIC | FLAG_ADVANCED,
3273 .label = "domain master",
3274 .type = P_ENUM,
3275 .p_class = P_GLOBAL,
3276 .ptr = &Globals.iDomainMaster,
3277 .special = NULL,
3278 .enum_list = enum_bool_auto,
3279 .flags = FLAG_BASIC | FLAG_ADVANCED,
3282 .label = "browse list",
3283 .type = P_BOOL,
3284 .p_class = P_GLOBAL,
3285 .ptr = &Globals.bBrowseList,
3286 .special = NULL,
3287 .enum_list = NULL,
3288 .flags = FLAG_ADVANCED,
3291 .label = "browseable",
3292 .type = P_BOOL,
3293 .p_class = P_LOCAL,
3294 .ptr = &sDefault.bBrowseable,
3295 .special = NULL,
3296 .enum_list = NULL,
3297 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3300 .label = "browsable",
3301 .type = P_BOOL,
3302 .p_class = P_LOCAL,
3303 .ptr = &sDefault.bBrowseable,
3304 .special = NULL,
3305 .enum_list = NULL,
3306 .flags = FLAG_HIDE,
3309 .label = "enhanced browsing",
3310 .type = P_BOOL,
3311 .p_class = P_GLOBAL,
3312 .ptr = &Globals.enhanced_browsing,
3313 .special = NULL,
3314 .enum_list = NULL,
3315 .flags = FLAG_ADVANCED,
3318 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3321 .label = "dns proxy",
3322 .type = P_BOOL,
3323 .p_class = P_GLOBAL,
3324 .ptr = &Globals.bDNSproxy,
3325 .special = NULL,
3326 .enum_list = NULL,
3327 .flags = FLAG_ADVANCED,
3330 .label = "wins proxy",
3331 .type = P_BOOL,
3332 .p_class = P_GLOBAL,
3333 .ptr = &Globals.bWINSproxy,
3334 .special = NULL,
3335 .enum_list = NULL,
3336 .flags = FLAG_ADVANCED,
3339 .label = "wins server",
3340 .type = P_LIST,
3341 .p_class = P_GLOBAL,
3342 .ptr = &Globals.szWINSservers,
3343 .special = NULL,
3344 .enum_list = NULL,
3345 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3348 .label = "wins support",
3349 .type = P_BOOL,
3350 .p_class = P_GLOBAL,
3351 .ptr = &Globals.bWINSsupport,
3352 .special = NULL,
3353 .enum_list = NULL,
3354 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3357 .label = "wins hook",
3358 .type = P_STRING,
3359 .p_class = P_GLOBAL,
3360 .ptr = &Globals.szWINSHook,
3361 .special = NULL,
3362 .enum_list = NULL,
3363 .flags = FLAG_ADVANCED,
3366 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3369 .label = "blocking locks",
3370 .type = P_BOOL,
3371 .p_class = P_LOCAL,
3372 .ptr = &sDefault.bBlockingLocks,
3373 .special = NULL,
3374 .enum_list = NULL,
3375 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3378 .label = "csc policy",
3379 .type = P_ENUM,
3380 .p_class = P_LOCAL,
3381 .ptr = &sDefault.iCSCPolicy,
3382 .special = NULL,
3383 .enum_list = enum_csc_policy,
3384 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3387 .label = "fake oplocks",
3388 .type = P_BOOL,
3389 .p_class = P_LOCAL,
3390 .ptr = &sDefault.bFakeOplocks,
3391 .special = NULL,
3392 .enum_list = NULL,
3393 .flags = FLAG_ADVANCED | FLAG_SHARE,
3396 .label = "kernel oplocks",
3397 .type = P_BOOL,
3398 .p_class = P_GLOBAL,
3399 .ptr = &Globals.bKernelOplocks,
3400 .special = NULL,
3401 .enum_list = NULL,
3402 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3405 .label = "locking",
3406 .type = P_BOOL,
3407 .p_class = P_LOCAL,
3408 .ptr = &sDefault.bLocking,
3409 .special = NULL,
3410 .enum_list = NULL,
3411 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3414 .label = "lock spin time",
3415 .type = P_INTEGER,
3416 .p_class = P_GLOBAL,
3417 .ptr = &Globals.iLockSpinTime,
3418 .special = NULL,
3419 .enum_list = NULL,
3420 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3423 .label = "oplocks",
3424 .type = P_BOOL,
3425 .p_class = P_LOCAL,
3426 .ptr = &sDefault.bOpLocks,
3427 .special = NULL,
3428 .enum_list = NULL,
3429 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3432 .label = "level2 oplocks",
3433 .type = P_BOOL,
3434 .p_class = P_LOCAL,
3435 .ptr = &sDefault.bLevel2OpLocks,
3436 .special = NULL,
3437 .enum_list = NULL,
3438 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3441 .label = "oplock break wait time",
3442 .type = P_INTEGER,
3443 .p_class = P_GLOBAL,
3444 .ptr = &Globals.oplock_break_wait_time,
3445 .special = NULL,
3446 .enum_list = NULL,
3447 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3450 .label = "oplock contention limit",
3451 .type = P_INTEGER,
3452 .p_class = P_LOCAL,
3453 .ptr = &sDefault.iOplockContentionLimit,
3454 .special = NULL,
3455 .enum_list = NULL,
3456 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3459 .label = "posix locking",
3460 .type = P_BOOL,
3461 .p_class = P_LOCAL,
3462 .ptr = &sDefault.bPosixLocking,
3463 .special = NULL,
3464 .enum_list = NULL,
3465 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3468 .label = "strict locking",
3469 .type = P_ENUM,
3470 .p_class = P_LOCAL,
3471 .ptr = &sDefault.iStrictLocking,
3472 .special = NULL,
3473 .enum_list = enum_bool_auto,
3474 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3477 .label = "share modes",
3478 .type = P_BOOL,
3479 .p_class = P_LOCAL,
3480 .ptr = &sDefault.bShareModes,
3481 .special = NULL,
3482 .enum_list = NULL,
3483 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3486 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3489 .label = "ldap admin dn",
3490 .type = P_STRING,
3491 .p_class = P_GLOBAL,
3492 .ptr = &Globals.szLdapAdminDn,
3493 .special = NULL,
3494 .enum_list = NULL,
3495 .flags = FLAG_ADVANCED,
3498 .label = "ldap delete dn",
3499 .type = P_BOOL,
3500 .p_class = P_GLOBAL,
3501 .ptr = &Globals.ldap_delete_dn,
3502 .special = NULL,
3503 .enum_list = NULL,
3504 .flags = FLAG_ADVANCED,
3507 .label = "ldap group suffix",
3508 .type = P_STRING,
3509 .p_class = P_GLOBAL,
3510 .ptr = &Globals.szLdapGroupSuffix,
3511 .special = NULL,
3512 .enum_list = NULL,
3513 .flags = FLAG_ADVANCED,
3516 .label = "ldap idmap suffix",
3517 .type = P_STRING,
3518 .p_class = P_GLOBAL,
3519 .ptr = &Globals.szLdapIdmapSuffix,
3520 .special = NULL,
3521 .enum_list = NULL,
3522 .flags = FLAG_ADVANCED,
3525 .label = "ldap machine suffix",
3526 .type = P_STRING,
3527 .p_class = P_GLOBAL,
3528 .ptr = &Globals.szLdapMachineSuffix,
3529 .special = NULL,
3530 .enum_list = NULL,
3531 .flags = FLAG_ADVANCED,
3534 .label = "ldap passwd sync",
3535 .type = P_ENUM,
3536 .p_class = P_GLOBAL,
3537 .ptr = &Globals.ldap_passwd_sync,
3538 .special = NULL,
3539 .enum_list = enum_ldap_passwd_sync,
3540 .flags = FLAG_ADVANCED,
3543 .label = "ldap password sync",
3544 .type = P_ENUM,
3545 .p_class = P_GLOBAL,
3546 .ptr = &Globals.ldap_passwd_sync,
3547 .special = NULL,
3548 .enum_list = enum_ldap_passwd_sync,
3549 .flags = FLAG_HIDE,
3552 .label = "ldap replication sleep",
3553 .type = P_INTEGER,
3554 .p_class = P_GLOBAL,
3555 .ptr = &Globals.ldap_replication_sleep,
3556 .special = NULL,
3557 .enum_list = NULL,
3558 .flags = FLAG_ADVANCED,
3561 .label = "ldap suffix",
3562 .type = P_STRING,
3563 .p_class = P_GLOBAL,
3564 .ptr = &Globals.szLdapSuffix,
3565 .special = NULL,
3566 .enum_list = NULL,
3567 .flags = FLAG_ADVANCED,
3570 .label = "ldap ssl",
3571 .type = P_ENUM,
3572 .p_class = P_GLOBAL,
3573 .ptr = &Globals.ldap_ssl,
3574 .special = NULL,
3575 .enum_list = enum_ldap_ssl,
3576 .flags = FLAG_ADVANCED,
3579 .label = "ldap timeout",
3580 .type = P_INTEGER,
3581 .p_class = P_GLOBAL,
3582 .ptr = &Globals.ldap_timeout,
3583 .special = NULL,
3584 .enum_list = NULL,
3585 .flags = FLAG_ADVANCED,
3588 .label = "ldap connection timeout",
3589 .type = P_INTEGER,
3590 .p_class = P_GLOBAL,
3591 .ptr = &Globals.ldap_connection_timeout,
3592 .special = NULL,
3593 .enum_list = NULL,
3594 .flags = FLAG_ADVANCED,
3597 .label = "ldap page size",
3598 .type = P_INTEGER,
3599 .p_class = P_GLOBAL,
3600 .ptr = &Globals.ldap_page_size,
3601 .special = NULL,
3602 .enum_list = NULL,
3603 .flags = FLAG_ADVANCED,
3606 .label = "ldap user suffix",
3607 .type = P_STRING,
3608 .p_class = P_GLOBAL,
3609 .ptr = &Globals.szLdapUserSuffix,
3610 .special = NULL,
3611 .enum_list = NULL,
3612 .flags = FLAG_ADVANCED,
3615 .label = "ldap debug level",
3616 .type = P_INTEGER,
3617 .p_class = P_GLOBAL,
3618 .ptr = &Globals.ldap_debug_level,
3619 .special = handle_ldap_debug_level,
3620 .enum_list = NULL,
3621 .flags = FLAG_ADVANCED,
3624 .label = "ldap debug threshold",
3625 .type = P_INTEGER,
3626 .p_class = P_GLOBAL,
3627 .ptr = &Globals.ldap_debug_threshold,
3628 .special = NULL,
3629 .enum_list = NULL,
3630 .flags = FLAG_ADVANCED,
3633 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3636 .label = "eventlog list",
3637 .type = P_LIST,
3638 .p_class = P_GLOBAL,
3639 .ptr = &Globals.szEventLogs,
3640 .special = NULL,
3641 .enum_list = NULL,
3642 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3645 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3648 .label = "add share command",
3649 .type = P_STRING,
3650 .p_class = P_GLOBAL,
3651 .ptr = &Globals.szAddShareCommand,
3652 .special = NULL,
3653 .enum_list = NULL,
3654 .flags = FLAG_ADVANCED,
3657 .label = "change share command",
3658 .type = P_STRING,
3659 .p_class = P_GLOBAL,
3660 .ptr = &Globals.szChangeShareCommand,
3661 .special = NULL,
3662 .enum_list = NULL,
3663 .flags = FLAG_ADVANCED,
3666 .label = "delete share command",
3667 .type = P_STRING,
3668 .p_class = P_GLOBAL,
3669 .ptr = &Globals.szDeleteShareCommand,
3670 .special = NULL,
3671 .enum_list = NULL,
3672 .flags = FLAG_ADVANCED,
3675 .label = "config file",
3676 .type = P_STRING,
3677 .p_class = P_GLOBAL,
3678 .ptr = &Globals.szConfigFile,
3679 .special = NULL,
3680 .enum_list = NULL,
3681 .flags = FLAG_HIDE,
3684 .label = "preload",
3685 .type = P_STRING,
3686 .p_class = P_GLOBAL,
3687 .ptr = &Globals.szAutoServices,
3688 .special = NULL,
3689 .enum_list = NULL,
3690 .flags = FLAG_ADVANCED,
3693 .label = "auto services",
3694 .type = P_STRING,
3695 .p_class = P_GLOBAL,
3696 .ptr = &Globals.szAutoServices,
3697 .special = NULL,
3698 .enum_list = NULL,
3699 .flags = FLAG_ADVANCED,
3702 .label = "lock directory",
3703 .type = P_STRING,
3704 .p_class = P_GLOBAL,
3705 .ptr = &Globals.szLockDir,
3706 .special = NULL,
3707 .enum_list = NULL,
3708 .flags = FLAG_ADVANCED,
3711 .label = "lock dir",
3712 .type = P_STRING,
3713 .p_class = P_GLOBAL,
3714 .ptr = &Globals.szLockDir,
3715 .special = NULL,
3716 .enum_list = NULL,
3717 .flags = FLAG_HIDE,
3720 .label = "pid directory",
3721 .type = P_STRING,
3722 .p_class = P_GLOBAL,
3723 .ptr = &Globals.szPidDir,
3724 .special = NULL,
3725 .enum_list = NULL,
3726 .flags = FLAG_ADVANCED,
3728 #ifdef WITH_UTMP
3730 .label = "utmp directory",
3731 .type = P_STRING,
3732 .p_class = P_GLOBAL,
3733 .ptr = &Globals.szUtmpDir,
3734 .special = NULL,
3735 .enum_list = NULL,
3736 .flags = FLAG_ADVANCED,
3739 .label = "wtmp directory",
3740 .type = P_STRING,
3741 .p_class = P_GLOBAL,
3742 .ptr = &Globals.szWtmpDir,
3743 .special = NULL,
3744 .enum_list = NULL,
3745 .flags = FLAG_ADVANCED,
3748 .label = "utmp",
3749 .type = P_BOOL,
3750 .p_class = P_GLOBAL,
3751 .ptr = &Globals.bUtmp,
3752 .special = NULL,
3753 .enum_list = NULL,
3754 .flags = FLAG_ADVANCED,
3756 #endif
3758 .label = "default service",
3759 .type = P_STRING,
3760 .p_class = P_GLOBAL,
3761 .ptr = &Globals.szDefaultService,
3762 .special = NULL,
3763 .enum_list = NULL,
3764 .flags = FLAG_ADVANCED,
3767 .label = "default",
3768 .type = P_STRING,
3769 .p_class = P_GLOBAL,
3770 .ptr = &Globals.szDefaultService,
3771 .special = NULL,
3772 .enum_list = NULL,
3773 .flags = FLAG_ADVANCED,
3776 .label = "message command",
3777 .type = P_STRING,
3778 .p_class = P_GLOBAL,
3779 .ptr = &Globals.szMsgCommand,
3780 .special = NULL,
3781 .enum_list = NULL,
3782 .flags = FLAG_ADVANCED,
3785 .label = "dfree cache time",
3786 .type = P_INTEGER,
3787 .p_class = P_LOCAL,
3788 .ptr = &sDefault.iDfreeCacheTime,
3789 .special = NULL,
3790 .enum_list = NULL,
3791 .flags = FLAG_ADVANCED,
3794 .label = "dfree command",
3795 .type = P_STRING,
3796 .p_class = P_LOCAL,
3797 .ptr = &sDefault.szDfree,
3798 .special = NULL,
3799 .enum_list = NULL,
3800 .flags = FLAG_ADVANCED,
3803 .label = "get quota command",
3804 .type = P_STRING,
3805 .p_class = P_GLOBAL,
3806 .ptr = &Globals.szGetQuota,
3807 .special = NULL,
3808 .enum_list = NULL,
3809 .flags = FLAG_ADVANCED,
3812 .label = "set quota command",
3813 .type = P_STRING,
3814 .p_class = P_GLOBAL,
3815 .ptr = &Globals.szSetQuota,
3816 .special = NULL,
3817 .enum_list = NULL,
3818 .flags = FLAG_ADVANCED,
3821 .label = "remote announce",
3822 .type = P_STRING,
3823 .p_class = P_GLOBAL,
3824 .ptr = &Globals.szRemoteAnnounce,
3825 .special = NULL,
3826 .enum_list = NULL,
3827 .flags = FLAG_ADVANCED,
3830 .label = "remote browse sync",
3831 .type = P_STRING,
3832 .p_class = P_GLOBAL,
3833 .ptr = &Globals.szRemoteBrowseSync,
3834 .special = NULL,
3835 .enum_list = NULL,
3836 .flags = FLAG_ADVANCED,
3839 .label = "socket address",
3840 .type = P_STRING,
3841 .p_class = P_GLOBAL,
3842 .ptr = &Globals.szSocketAddress,
3843 .special = NULL,
3844 .enum_list = NULL,
3845 .flags = FLAG_ADVANCED,
3848 .label = "homedir map",
3849 .type = P_STRING,
3850 .p_class = P_GLOBAL,
3851 .ptr = &Globals.szNISHomeMapName,
3852 .special = NULL,
3853 .enum_list = NULL,
3854 .flags = FLAG_ADVANCED,
3857 .label = "afs username map",
3858 .type = P_STRING,
3859 .p_class = P_GLOBAL,
3860 .ptr = &Globals.szAfsUsernameMap,
3861 .special = NULL,
3862 .enum_list = NULL,
3863 .flags = FLAG_ADVANCED,
3866 .label = "afs token lifetime",
3867 .type = P_INTEGER,
3868 .p_class = P_GLOBAL,
3869 .ptr = &Globals.iAfsTokenLifetime,
3870 .special = NULL,
3871 .enum_list = NULL,
3872 .flags = FLAG_ADVANCED,
3875 .label = "log nt token command",
3876 .type = P_STRING,
3877 .p_class = P_GLOBAL,
3878 .ptr = &Globals.szLogNtTokenCommand,
3879 .special = NULL,
3880 .enum_list = NULL,
3881 .flags = FLAG_ADVANCED,
3884 .label = "time offset",
3885 .type = P_INTEGER,
3886 .p_class = P_GLOBAL,
3887 .ptr = &extra_time_offset,
3888 .special = NULL,
3889 .enum_list = NULL,
3890 .flags = FLAG_ADVANCED,
3893 .label = "NIS homedir",
3894 .type = P_BOOL,
3895 .p_class = P_GLOBAL,
3896 .ptr = &Globals.bNISHomeMap,
3897 .special = NULL,
3898 .enum_list = NULL,
3899 .flags = FLAG_ADVANCED,
3902 .label = "-valid",
3903 .type = P_BOOL,
3904 .p_class = P_LOCAL,
3905 .ptr = &sDefault.valid,
3906 .special = NULL,
3907 .enum_list = NULL,
3908 .flags = FLAG_HIDE,
3911 .label = "copy",
3912 .type = P_STRING,
3913 .p_class = P_LOCAL,
3914 .ptr = &sDefault.szCopy,
3915 .special = handle_copy,
3916 .enum_list = NULL,
3917 .flags = FLAG_HIDE,
3920 .label = "include",
3921 .type = P_STRING,
3922 .p_class = P_LOCAL,
3923 .ptr = &sDefault.szInclude,
3924 .special = handle_include,
3925 .enum_list = NULL,
3926 .flags = FLAG_HIDE,
3929 .label = "preexec",
3930 .type = P_STRING,
3931 .p_class = P_LOCAL,
3932 .ptr = &sDefault.szPreExec,
3933 .special = NULL,
3934 .enum_list = NULL,
3935 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3938 .label = "exec",
3939 .type = P_STRING,
3940 .p_class = P_LOCAL,
3941 .ptr = &sDefault.szPreExec,
3942 .special = NULL,
3943 .enum_list = NULL,
3944 .flags = FLAG_ADVANCED,
3947 .label = "preexec close",
3948 .type = P_BOOL,
3949 .p_class = P_LOCAL,
3950 .ptr = &sDefault.bPreexecClose,
3951 .special = NULL,
3952 .enum_list = NULL,
3953 .flags = FLAG_ADVANCED | FLAG_SHARE,
3956 .label = "postexec",
3957 .type = P_STRING,
3958 .p_class = P_LOCAL,
3959 .ptr = &sDefault.szPostExec,
3960 .special = NULL,
3961 .enum_list = NULL,
3962 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3965 .label = "root preexec",
3966 .type = P_STRING,
3967 .p_class = P_LOCAL,
3968 .ptr = &sDefault.szRootPreExec,
3969 .special = NULL,
3970 .enum_list = NULL,
3971 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3974 .label = "root preexec close",
3975 .type = P_BOOL,
3976 .p_class = P_LOCAL,
3977 .ptr = &sDefault.bRootpreexecClose,
3978 .special = NULL,
3979 .enum_list = NULL,
3980 .flags = FLAG_ADVANCED | FLAG_SHARE,
3983 .label = "root postexec",
3984 .type = P_STRING,
3985 .p_class = P_LOCAL,
3986 .ptr = &sDefault.szRootPostExec,
3987 .special = NULL,
3988 .enum_list = NULL,
3989 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3992 .label = "available",
3993 .type = P_BOOL,
3994 .p_class = P_LOCAL,
3995 .ptr = &sDefault.bAvailable,
3996 .special = NULL,
3997 .enum_list = NULL,
3998 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4001 .label = "registry shares",
4002 .type = P_BOOL,
4003 .p_class = P_GLOBAL,
4004 .ptr = &Globals.bRegistryShares,
4005 .special = NULL,
4006 .enum_list = NULL,
4007 .flags = FLAG_ADVANCED,
4010 .label = "usershare allow guests",
4011 .type = P_BOOL,
4012 .p_class = P_GLOBAL,
4013 .ptr = &Globals.bUsershareAllowGuests,
4014 .special = NULL,
4015 .enum_list = NULL,
4016 .flags = FLAG_ADVANCED,
4019 .label = "usershare max shares",
4020 .type = P_INTEGER,
4021 .p_class = P_GLOBAL,
4022 .ptr = &Globals.iUsershareMaxShares,
4023 .special = NULL,
4024 .enum_list = NULL,
4025 .flags = FLAG_ADVANCED,
4028 .label = "usershare owner only",
4029 .type = P_BOOL,
4030 .p_class = P_GLOBAL,
4031 .ptr = &Globals.bUsershareOwnerOnly,
4032 .special = NULL,
4033 .enum_list = NULL,
4034 .flags = FLAG_ADVANCED,
4037 .label = "usershare path",
4038 .type = P_STRING,
4039 .p_class = P_GLOBAL,
4040 .ptr = &Globals.szUsersharePath,
4041 .special = NULL,
4042 .enum_list = NULL,
4043 .flags = FLAG_ADVANCED,
4046 .label = "usershare prefix allow list",
4047 .type = P_LIST,
4048 .p_class = P_GLOBAL,
4049 .ptr = &Globals.szUsersharePrefixAllowList,
4050 .special = NULL,
4051 .enum_list = NULL,
4052 .flags = FLAG_ADVANCED,
4055 .label = "usershare prefix deny list",
4056 .type = P_LIST,
4057 .p_class = P_GLOBAL,
4058 .ptr = &Globals.szUsersharePrefixDenyList,
4059 .special = NULL,
4060 .enum_list = NULL,
4061 .flags = FLAG_ADVANCED,
4064 .label = "usershare template share",
4065 .type = P_STRING,
4066 .p_class = P_GLOBAL,
4067 .ptr = &Globals.szUsershareTemplateShare,
4068 .special = NULL,
4069 .enum_list = NULL,
4070 .flags = FLAG_ADVANCED,
4073 .label = "volume",
4074 .type = P_STRING,
4075 .p_class = P_LOCAL,
4076 .ptr = &sDefault.volume,
4077 .special = NULL,
4078 .enum_list = NULL,
4079 .flags = FLAG_ADVANCED | FLAG_SHARE,
4082 .label = "fstype",
4083 .type = P_STRING,
4084 .p_class = P_LOCAL,
4085 .ptr = &sDefault.fstype,
4086 .special = NULL,
4087 .enum_list = NULL,
4088 .flags = FLAG_ADVANCED | FLAG_SHARE,
4091 .label = "set directory",
4092 .type = P_BOOLREV,
4093 .p_class = P_LOCAL,
4094 .ptr = &sDefault.bNo_set_dir,
4095 .special = NULL,
4096 .enum_list = NULL,
4097 .flags = FLAG_ADVANCED | FLAG_SHARE,
4100 .label = "wide links",
4101 .type = P_BOOL,
4102 .p_class = P_LOCAL,
4103 .ptr = &sDefault.bWidelinks,
4104 .special = NULL,
4105 .enum_list = NULL,
4106 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4109 .label = "follow symlinks",
4110 .type = P_BOOL,
4111 .p_class = P_LOCAL,
4112 .ptr = &sDefault.bSymlinks,
4113 .special = NULL,
4114 .enum_list = NULL,
4115 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4118 .label = "dont descend",
4119 .type = P_STRING,
4120 .p_class = P_LOCAL,
4121 .ptr = &sDefault.szDontdescend,
4122 .special = NULL,
4123 .enum_list = NULL,
4124 .flags = FLAG_ADVANCED | FLAG_SHARE,
4127 .label = "magic script",
4128 .type = P_STRING,
4129 .p_class = P_LOCAL,
4130 .ptr = &sDefault.szMagicScript,
4131 .special = NULL,
4132 .enum_list = NULL,
4133 .flags = FLAG_ADVANCED | FLAG_SHARE,
4136 .label = "magic output",
4137 .type = P_STRING,
4138 .p_class = P_LOCAL,
4139 .ptr = &sDefault.szMagicOutput,
4140 .special = NULL,
4141 .enum_list = NULL,
4142 .flags = FLAG_ADVANCED | FLAG_SHARE,
4145 .label = "delete readonly",
4146 .type = P_BOOL,
4147 .p_class = P_LOCAL,
4148 .ptr = &sDefault.bDeleteReadonly,
4149 .special = NULL,
4150 .enum_list = NULL,
4151 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4154 .label = "dos filemode",
4155 .type = P_BOOL,
4156 .p_class = P_LOCAL,
4157 .ptr = &sDefault.bDosFilemode,
4158 .special = NULL,
4159 .enum_list = NULL,
4160 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4163 .label = "dos filetimes",
4164 .type = P_BOOL,
4165 .p_class = P_LOCAL,
4166 .ptr = &sDefault.bDosFiletimes,
4167 .special = NULL,
4168 .enum_list = NULL,
4169 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4172 .label = "dos filetime resolution",
4173 .type = P_BOOL,
4174 .p_class = P_LOCAL,
4175 .ptr = &sDefault.bDosFiletimeResolution,
4176 .special = NULL,
4177 .enum_list = NULL,
4178 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4181 .label = "fake directory create times",
4182 .type = P_BOOL,
4183 .p_class = P_LOCAL,
4184 .ptr = &sDefault.bFakeDirCreateTimes,
4185 .special = NULL,
4186 .enum_list = NULL,
4187 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4190 .label = "panic action",
4191 .type = P_STRING,
4192 .p_class = P_GLOBAL,
4193 .ptr = &Globals.szPanicAction,
4194 .special = NULL,
4195 .enum_list = NULL,
4196 .flags = FLAG_ADVANCED,
4199 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4202 .label = "vfs objects",
4203 .type = P_LIST,
4204 .p_class = P_LOCAL,
4205 .ptr = &sDefault.szVfsObjects,
4206 .special = NULL,
4207 .enum_list = NULL,
4208 .flags = FLAG_ADVANCED | FLAG_SHARE,
4211 .label = "vfs object",
4212 .type = P_LIST,
4213 .p_class = P_LOCAL,
4214 .ptr = &sDefault.szVfsObjects,
4215 .special = NULL,
4216 .enum_list = NULL,
4217 .flags = FLAG_HIDE,
4221 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4224 .label = "msdfs root",
4225 .type = P_BOOL,
4226 .p_class = P_LOCAL,
4227 .ptr = &sDefault.bMSDfsRoot,
4228 .special = NULL,
4229 .enum_list = NULL,
4230 .flags = FLAG_ADVANCED | FLAG_SHARE,
4233 .label = "msdfs proxy",
4234 .type = P_STRING,
4235 .p_class = P_LOCAL,
4236 .ptr = &sDefault.szMSDfsProxy,
4237 .special = NULL,
4238 .enum_list = NULL,
4239 .flags = FLAG_ADVANCED | FLAG_SHARE,
4242 .label = "host msdfs",
4243 .type = P_BOOL,
4244 .p_class = P_GLOBAL,
4245 .ptr = &Globals.bHostMSDfs,
4246 .special = NULL,
4247 .enum_list = NULL,
4248 .flags = FLAG_ADVANCED,
4251 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4254 .label = "passdb expand explicit",
4255 .type = P_BOOL,
4256 .p_class = P_GLOBAL,
4257 .ptr = &Globals.bPassdbExpandExplicit,
4258 .special = NULL,
4259 .enum_list = NULL,
4260 .flags = FLAG_ADVANCED,
4263 .label = "idmap backend",
4264 .type = P_STRING,
4265 .p_class = P_GLOBAL,
4266 .ptr = &Globals.szIdmapBackend,
4267 .special = NULL,
4268 .enum_list = NULL,
4269 .flags = FLAG_ADVANCED,
4272 .label = "idmap alloc backend",
4273 .type = P_STRING,
4274 .p_class = P_GLOBAL,
4275 .ptr = &Globals.szIdmapAllocBackend,
4276 .special = NULL,
4277 .enum_list = NULL,
4278 .flags = FLAG_ADVANCED,
4281 .label = "idmap cache time",
4282 .type = P_INTEGER,
4283 .p_class = P_GLOBAL,
4284 .ptr = &Globals.iIdmapCacheTime,
4285 .special = NULL,
4286 .enum_list = NULL,
4287 .flags = FLAG_ADVANCED,
4290 .label = "idmap negative cache time",
4291 .type = P_INTEGER,
4292 .p_class = P_GLOBAL,
4293 .ptr = &Globals.iIdmapNegativeCacheTime,
4294 .special = NULL,
4295 .enum_list = NULL,
4296 .flags = FLAG_ADVANCED,
4299 .label = "idmap uid",
4300 .type = P_STRING,
4301 .p_class = P_GLOBAL,
4302 .ptr = &Globals.szIdmapUID,
4303 .special = handle_idmap_uid,
4304 .enum_list = NULL,
4305 .flags = FLAG_ADVANCED,
4308 .label = "winbind uid",
4309 .type = P_STRING,
4310 .p_class = P_GLOBAL,
4311 .ptr = &Globals.szIdmapUID,
4312 .special = handle_idmap_uid,
4313 .enum_list = NULL,
4314 .flags = FLAG_HIDE,
4317 .label = "idmap gid",
4318 .type = P_STRING,
4319 .p_class = P_GLOBAL,
4320 .ptr = &Globals.szIdmapGID,
4321 .special = handle_idmap_gid,
4322 .enum_list = NULL,
4323 .flags = FLAG_ADVANCED,
4326 .label = "winbind gid",
4327 .type = P_STRING,
4328 .p_class = P_GLOBAL,
4329 .ptr = &Globals.szIdmapGID,
4330 .special = handle_idmap_gid,
4331 .enum_list = NULL,
4332 .flags = FLAG_HIDE,
4335 .label = "template homedir",
4336 .type = P_STRING,
4337 .p_class = P_GLOBAL,
4338 .ptr = &Globals.szTemplateHomedir,
4339 .special = NULL,
4340 .enum_list = NULL,
4341 .flags = FLAG_ADVANCED,
4344 .label = "template shell",
4345 .type = P_STRING,
4346 .p_class = P_GLOBAL,
4347 .ptr = &Globals.szTemplateShell,
4348 .special = NULL,
4349 .enum_list = NULL,
4350 .flags = FLAG_ADVANCED,
4353 .label = "winbind separator",
4354 .type = P_STRING,
4355 .p_class = P_GLOBAL,
4356 .ptr = &Globals.szWinbindSeparator,
4357 .special = NULL,
4358 .enum_list = NULL,
4359 .flags = FLAG_ADVANCED,
4362 .label = "winbind cache time",
4363 .type = P_INTEGER,
4364 .p_class = P_GLOBAL,
4365 .ptr = &Globals.winbind_cache_time,
4366 .special = NULL,
4367 .enum_list = NULL,
4368 .flags = FLAG_ADVANCED,
4371 .label = "winbind reconnect delay",
4372 .type = P_INTEGER,
4373 .p_class = P_GLOBAL,
4374 .ptr = &Globals.winbind_reconnect_delay,
4375 .special = NULL,
4376 .enum_list = NULL,
4377 .flags = FLAG_ADVANCED,
4380 .label = "winbind enum users",
4381 .type = P_BOOL,
4382 .p_class = P_GLOBAL,
4383 .ptr = &Globals.bWinbindEnumUsers,
4384 .special = NULL,
4385 .enum_list = NULL,
4386 .flags = FLAG_ADVANCED,
4389 .label = "winbind enum groups",
4390 .type = P_BOOL,
4391 .p_class = P_GLOBAL,
4392 .ptr = &Globals.bWinbindEnumGroups,
4393 .special = NULL,
4394 .enum_list = NULL,
4395 .flags = FLAG_ADVANCED,
4398 .label = "winbind use default domain",
4399 .type = P_BOOL,
4400 .p_class = P_GLOBAL,
4401 .ptr = &Globals.bWinbindUseDefaultDomain,
4402 .special = NULL,
4403 .enum_list = NULL,
4404 .flags = FLAG_ADVANCED,
4407 .label = "winbind trusted domains only",
4408 .type = P_BOOL,
4409 .p_class = P_GLOBAL,
4410 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4411 .special = NULL,
4412 .enum_list = NULL,
4413 .flags = FLAG_ADVANCED,
4416 .label = "winbind nested groups",
4417 .type = P_BOOL,
4418 .p_class = P_GLOBAL,
4419 .ptr = &Globals.bWinbindNestedGroups,
4420 .special = NULL,
4421 .enum_list = NULL,
4422 .flags = FLAG_ADVANCED,
4425 .label = "winbind expand groups",
4426 .type = P_INTEGER,
4427 .p_class = P_GLOBAL,
4428 .ptr = &Globals.winbind_expand_groups,
4429 .special = NULL,
4430 .enum_list = NULL,
4431 .flags = FLAG_ADVANCED,
4434 .label = "winbind nss info",
4435 .type = P_LIST,
4436 .p_class = P_GLOBAL,
4437 .ptr = &Globals.szWinbindNssInfo,
4438 .special = NULL,
4439 .enum_list = NULL,
4440 .flags = FLAG_ADVANCED,
4443 .label = "winbind refresh tickets",
4444 .type = P_BOOL,
4445 .p_class = P_GLOBAL,
4446 .ptr = &Globals.bWinbindRefreshTickets,
4447 .special = NULL,
4448 .enum_list = NULL,
4449 .flags = FLAG_ADVANCED,
4452 .label = "winbind offline logon",
4453 .type = P_BOOL,
4454 .p_class = P_GLOBAL,
4455 .ptr = &Globals.bWinbindOfflineLogon,
4456 .special = NULL,
4457 .enum_list = NULL,
4458 .flags = FLAG_ADVANCED,
4461 .label = "winbind normalize names",
4462 .type = P_BOOL,
4463 .p_class = P_GLOBAL,
4464 .ptr = &Globals.bWinbindNormalizeNames,
4465 .special = NULL,
4466 .enum_list = NULL,
4467 .flags = FLAG_ADVANCED,
4470 .label = "winbind rpc only",
4471 .type = P_BOOL,
4472 .p_class = P_GLOBAL,
4473 .ptr = &Globals.bWinbindRpcOnly,
4474 .special = NULL,
4475 .enum_list = NULL,
4476 .flags = FLAG_ADVANCED,
4479 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4482 /***************************************************************************
4483 Initialise the sDefault parameter structure for the printer values.
4484 ***************************************************************************/
4486 static void init_printer_values(struct service *pService)
4488 /* choose defaults depending on the type of printing */
4489 switch (pService->iPrinting) {
4490 case PRINT_BSD:
4491 case PRINT_AIX:
4492 case PRINT_LPRNT:
4493 case PRINT_LPROS2:
4494 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4495 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4496 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4497 break;
4499 case PRINT_LPRNG:
4500 case PRINT_PLP:
4501 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4502 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4503 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4504 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4505 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4506 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4507 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4508 break;
4510 case PRINT_CUPS:
4511 case PRINT_IPRINT:
4512 #ifdef HAVE_CUPS
4513 /* set the lpq command to contain the destination printer
4514 name only. This is used by cups_queue_get() */
4515 string_set(&pService->szLpqcommand, "%p");
4516 string_set(&pService->szLprmcommand, "");
4517 string_set(&pService->szPrintcommand, "");
4518 string_set(&pService->szLppausecommand, "");
4519 string_set(&pService->szLpresumecommand, "");
4520 string_set(&pService->szQueuepausecommand, "");
4521 string_set(&pService->szQueueresumecommand, "");
4522 #else
4523 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4524 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4525 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4526 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4527 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4528 string_set(&pService->szQueuepausecommand, "disable '%p'");
4529 string_set(&pService->szQueueresumecommand, "enable '%p'");
4530 #endif /* HAVE_CUPS */
4531 break;
4533 case PRINT_SYSV:
4534 case PRINT_HPUX:
4535 string_set(&pService->szLpqcommand, "lpstat -o%p");
4536 string_set(&pService->szLprmcommand, "cancel %p-%j");
4537 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4538 string_set(&pService->szQueuepausecommand, "disable %p");
4539 string_set(&pService->szQueueresumecommand, "enable %p");
4540 #ifndef HPUX
4541 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4542 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4543 #endif /* HPUX */
4544 break;
4546 case PRINT_QNX:
4547 string_set(&pService->szLpqcommand, "lpq -P%p");
4548 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4549 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4550 break;
4552 #ifdef DEVELOPER
4553 case PRINT_TEST:
4554 case PRINT_VLP:
4555 string_set(&pService->szPrintcommand, "vlp print %p %s");
4556 string_set(&pService->szLpqcommand, "vlp lpq %p");
4557 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4558 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4559 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4560 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4561 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4562 break;
4563 #endif /* DEVELOPER */
4568 /***************************************************************************
4569 Initialise the global parameter structure.
4570 ***************************************************************************/
4572 static void init_globals(bool first_time_only)
4574 static bool done_init = False;
4575 char *s = NULL;
4576 int i;
4578 /* If requested to initialize only once and we've already done it... */
4579 if (first_time_only && done_init) {
4580 /* ... then we have nothing more to do */
4581 return;
4584 if (!done_init) {
4585 /* The logfile can be set before this is invoked. Free it if so. */
4586 if (Globals.szLogFile != NULL) {
4587 string_free(&Globals.szLogFile);
4588 Globals.szLogFile = NULL;
4590 done_init = True;
4591 } else {
4592 for (i = 0; parm_table[i].label; i++) {
4593 if ((parm_table[i].type == P_STRING ||
4594 parm_table[i].type == P_USTRING) &&
4595 parm_table[i].ptr)
4597 string_free((char **)parm_table[i].ptr);
4602 memset((void *)&Globals, '\0', sizeof(Globals));
4604 for (i = 0; parm_table[i].label; i++) {
4605 if ((parm_table[i].type == P_STRING ||
4606 parm_table[i].type == P_USTRING) &&
4607 parm_table[i].ptr)
4609 string_set((char **)parm_table[i].ptr, "");
4613 string_set(&sDefault.fstype, FSTYPE_STRING);
4614 string_set(&sDefault.szPrintjobUsername, "%U");
4616 init_printer_values(&sDefault);
4619 DEBUG(3, ("Initialising global parameters\n"));
4621 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4622 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4624 /* use the new 'hash2' method by default, with a prefix of 1 */
4625 string_set(&Globals.szManglingMethod, "hash2");
4626 Globals.mangle_prefix = 1;
4628 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4630 /* using UTF8 by default allows us to support all chars */
4631 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4633 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4634 /* If the system supports nl_langinfo(), try to grab the value
4635 from the user's locale */
4636 string_set(&Globals.display_charset, "LOCALE");
4637 #else
4638 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4639 #endif
4641 /* Use codepage 850 as a default for the dos character set */
4642 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4645 * Allow the default PASSWD_CHAT to be overridden in local.h.
4647 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4649 set_global_myname(myhostname());
4650 string_set(&Globals.szNetbiosName,global_myname());
4652 set_global_myworkgroup(WORKGROUP);
4653 string_set(&Globals.szWorkgroup, lp_workgroup());
4655 string_set(&Globals.szPasswdProgram, "");
4656 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4657 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4658 string_set(&Globals.szSocketAddress, "0.0.0.0");
4660 if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
4661 smb_panic("init_globals: ENOMEM");
4663 string_set(&Globals.szServerString, s);
4664 SAFE_FREE(s);
4665 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4666 DEFAULT_MINOR_VERSION) < 0) {
4667 smb_panic("init_globals: ENOMEM");
4669 string_set(&Globals.szAnnounceVersion, s);
4670 SAFE_FREE(s);
4671 #ifdef DEVELOPER
4672 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4673 #endif
4675 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4677 string_set(&Globals.szLogonDrive, "");
4678 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4679 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4680 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4682 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4683 string_set(&Globals.szPasswordServer, "*");
4685 Globals.AlgorithmicRidBase = BASE_RID;
4687 Globals.bLoadPrinters = True;
4688 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4690 Globals.ConfigBackend = config_backend;
4692 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4693 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4694 Globals.max_xmit = 0x4104;
4695 Globals.max_mux = 50; /* This is *needed* for profile support. */
4696 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4697 Globals.bDisableSpoolss = False;
4698 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4699 Globals.pwordlevel = 0;
4700 Globals.unamelevel = 0;
4701 Globals.deadtime = 0;
4702 Globals.getwd_cache = true;
4703 Globals.bLargeReadwrite = True;
4704 Globals.max_log_size = 5000;
4705 Globals.max_open_files = MAX_OPEN_FILES;
4706 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4707 Globals.maxprotocol = PROTOCOL_NT1;
4708 Globals.minprotocol = PROTOCOL_CORE;
4709 Globals.security = SEC_USER;
4710 Globals.paranoid_server_security = True;
4711 Globals.bEncryptPasswords = True;
4712 Globals.bUpdateEncrypt = False;
4713 Globals.clientSchannel = Auto;
4714 Globals.serverSchannel = Auto;
4715 Globals.bReadRaw = True;
4716 Globals.bWriteRaw = True;
4717 Globals.bNullPasswords = False;
4718 Globals.bObeyPamRestrictions = False;
4719 Globals.syslog = 1;
4720 Globals.bSyslogOnly = False;
4721 Globals.bTimestampLogs = True;
4722 string_set(&Globals.szLogLevel, "0");
4723 Globals.bDebugPrefixTimestamp = False;
4724 Globals.bDebugHiresTimestamp = False;
4725 Globals.bDebugPid = False;
4726 Globals.bDebugUid = False;
4727 Globals.bDebugClass = False;
4728 Globals.bEnableCoreFiles = True;
4729 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4730 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4731 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4732 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4733 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4734 Globals.lm_interval = 60;
4735 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4736 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4737 Globals.bNISHomeMap = False;
4738 #ifdef WITH_NISPLUS_HOME
4739 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4740 #else
4741 string_set(&Globals.szNISHomeMapName, "auto.home");
4742 #endif
4743 #endif
4744 Globals.bTimeServer = False;
4745 Globals.bBindInterfacesOnly = False;
4746 Globals.bUnixPasswdSync = False;
4747 Globals.bPamPasswordChange = False;
4748 Globals.bPasswdChatDebug = False;
4749 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4750 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4751 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4752 Globals.bStatCache = True; /* use stat cache by default */
4753 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4754 Globals.restrict_anonymous = 0;
4755 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4756 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4757 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4758 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4759 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4760 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4762 Globals.map_to_guest = 0; /* By Default, "Never" */
4763 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4764 Globals.enhanced_browsing = true;
4765 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4766 #ifdef MMAP_BLACKLIST
4767 Globals.bUseMmap = False;
4768 #else
4769 Globals.bUseMmap = True;
4770 #endif
4771 Globals.bUnixExtensions = True;
4772 Globals.bResetOnZeroVC = False;
4774 /* hostname lookups can be very expensive and are broken on
4775 a large number of sites (tridge) */
4776 Globals.bHostnameLookups = False;
4778 string_set(&Globals.szPassdbBackend, "smbpasswd");
4779 string_set(&Globals.szLdapSuffix, "");
4780 string_set(&Globals.szLdapMachineSuffix, "");
4781 string_set(&Globals.szLdapUserSuffix, "");
4782 string_set(&Globals.szLdapGroupSuffix, "");
4783 string_set(&Globals.szLdapIdmapSuffix, "");
4785 string_set(&Globals.szLdapAdminDn, "");
4786 Globals.ldap_ssl = LDAP_SSL_OFF;
4787 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4788 Globals.ldap_delete_dn = False;
4789 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4790 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4791 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4792 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4794 Globals.ldap_debug_level = 0;
4795 Globals.ldap_debug_threshold = 10;
4797 /* This is what we tell the afs client. in reality we set the token
4798 * to never expire, though, when this runs out the afs client will
4799 * forget the token. Set to 0 to get NEVERDATE.*/
4800 Globals.iAfsTokenLifetime = 604800;
4801 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
4803 /* these parameters are set to defaults that are more appropriate
4804 for the increasing samba install base:
4806 as a member of the workgroup, that will possibly become a
4807 _local_ master browser (lm = True). this is opposed to a forced
4808 local master browser startup (pm = True).
4810 doesn't provide WINS server service by default (wsupp = False),
4811 and doesn't provide domain master browser services by default, either.
4815 Globals.bMsAddPrinterWizard = True;
4816 Globals.os_level = 20;
4817 Globals.bLocalMaster = True;
4818 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4819 Globals.bDomainLogons = False;
4820 Globals.bBrowseList = True;
4821 Globals.bWINSsupport = False;
4822 Globals.bWINSproxy = False;
4824 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
4825 Globals.InitLogonDelay = 100; /* 100 ms default delay */
4827 Globals.bDNSproxy = True;
4829 /* this just means to use them if they exist */
4830 Globals.bKernelOplocks = True;
4832 Globals.bAllowTrustedDomains = True;
4833 string_set(&Globals.szIdmapBackend, "tdb");
4835 string_set(&Globals.szTemplateShell, "/bin/false");
4836 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4837 string_set(&Globals.szWinbindSeparator, "\\");
4839 string_set(&Globals.szCupsServer, "");
4840 string_set(&Globals.szIPrintServer, "");
4842 string_set(&Globals.ctdbdSocket, "");
4843 Globals.szClusterAddresses = NULL;
4844 Globals.clustering = False;
4846 Globals.winbind_cache_time = 300; /* 5 minutes */
4847 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
4848 Globals.bWinbindEnumUsers = False;
4849 Globals.bWinbindEnumGroups = False;
4850 Globals.bWinbindUseDefaultDomain = False;
4851 Globals.bWinbindTrustedDomainsOnly = False;
4852 Globals.bWinbindNestedGroups = True;
4853 Globals.winbind_expand_groups = 1;
4854 Globals.szWinbindNssInfo = str_list_make(talloc_autofree_context(), "template", NULL);
4855 Globals.bWinbindRefreshTickets = False;
4856 Globals.bWinbindOfflineLogon = False;
4858 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
4859 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4861 Globals.bPassdbExpandExplicit = False;
4863 Globals.name_cache_timeout = 660; /* In seconds */
4865 Globals.bUseSpnego = True;
4866 Globals.bClientUseSpnego = True;
4868 Globals.client_signing = Auto;
4869 Globals.server_signing = False;
4871 Globals.bDeferSharingViolations = True;
4872 string_set(&Globals.smb_ports, SMB_PORTS);
4874 Globals.bEnablePrivileges = True;
4875 Globals.bHostMSDfs = True;
4876 Globals.bASUSupport = False;
4878 /* User defined shares. */
4879 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4880 smb_panic("init_globals: ENOMEM");
4882 string_set(&Globals.szUsersharePath, s);
4883 SAFE_FREE(s);
4884 string_set(&Globals.szUsershareTemplateShare, "");
4885 Globals.iUsershareMaxShares = 0;
4886 /* By default disallow sharing of directories not owned by the sharer. */
4887 Globals.bUsershareOwnerOnly = True;
4888 /* By default disallow guest access to usershares. */
4889 Globals.bUsershareAllowGuests = False;
4891 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4893 /* By default no shares out of the registry */
4894 Globals.bRegistryShares = False;
4896 Globals.iminreceivefile = 0;
4899 /*******************************************************************
4900 Convenience routine to grab string parameters into temporary memory
4901 and run standard_sub_basic on them. The buffers can be written to by
4902 callers without affecting the source string.
4903 ********************************************************************/
4905 static char *lp_string(const char *s)
4907 char *ret;
4908 TALLOC_CTX *ctx = talloc_tos();
4910 /* The follow debug is useful for tracking down memory problems
4911 especially if you have an inner loop that is calling a lp_*()
4912 function that returns a string. Perhaps this debug should be
4913 present all the time? */
4915 #if 0
4916 DEBUG(10, ("lp_string(%s)\n", s));
4917 #endif
4919 ret = talloc_sub_basic(ctx,
4920 get_current_username(),
4921 current_user_info.domain,
4923 if (trim_char(ret, '\"', '\"')) {
4924 if (strchr(ret,'\"') != NULL) {
4925 TALLOC_FREE(ret);
4926 ret = talloc_sub_basic(ctx,
4927 get_current_username(),
4928 current_user_info.domain,
4932 return ret;
4936 In this section all the functions that are used to access the
4937 parameters from the rest of the program are defined
4940 #define FN_GLOBAL_STRING(fn_name,ptr) \
4941 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4942 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4943 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4944 #define FN_GLOBAL_LIST(fn_name,ptr) \
4945 const char **fn_name(void) {return(*(const char ***)(ptr));}
4946 #define FN_GLOBAL_BOOL(fn_name,ptr) \
4947 bool fn_name(void) {return(*(bool *)(ptr));}
4948 #define FN_GLOBAL_CHAR(fn_name,ptr) \
4949 char fn_name(void) {return(*(char *)(ptr));}
4950 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
4951 int fn_name(void) {return(*(int *)(ptr));}
4953 #define FN_LOCAL_STRING(fn_name,val) \
4954 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
4955 #define FN_LOCAL_CONST_STRING(fn_name,val) \
4956 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
4957 #define FN_LOCAL_LIST(fn_name,val) \
4958 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4959 #define FN_LOCAL_BOOL(fn_name,val) \
4960 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4961 #define FN_LOCAL_INTEGER(fn_name,val) \
4962 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4964 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
4965 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4966 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
4967 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4968 #define FN_LOCAL_PARM_STRING(fn_name,val) \
4969 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));}
4970 #define FN_LOCAL_CHAR(fn_name,val) \
4971 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4973 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
4974 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
4975 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
4976 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
4977 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
4978 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
4979 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
4980 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
4981 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
4982 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
4983 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
4984 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
4985 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
4986 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
4987 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
4988 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
4989 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
4990 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
4991 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
4992 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
4993 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
4994 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
4995 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
4996 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
4997 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
4998 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
4999 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5000 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5001 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5002 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5003 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5004 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5005 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5006 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5007 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5008 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5009 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5010 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5011 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5012 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5013 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5014 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5015 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5016 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5017 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5018 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5019 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5020 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5021 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5022 * lp_passdb_backend() should be replace by the this macro again after
5023 * some releases.
5024 * */
5025 const char *lp_passdb_backend(void)
5027 char *delim, *quote;
5029 delim = strchr( Globals.szPassdbBackend, ' ');
5030 /* no space at all */
5031 if (delim == NULL) {
5032 goto out;
5035 quote = strchr(Globals.szPassdbBackend, '"');
5036 /* no quote char or non in the first part */
5037 if (quote == NULL || quote > delim) {
5038 *delim = '\0';
5039 goto warn;
5042 quote = strchr(quote+1, '"');
5043 if (quote == NULL) {
5044 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5045 goto out;
5046 } else if (*(quote+1) == '\0') {
5047 /* space, fitting quote char, and one backend only */
5048 goto out;
5049 } else {
5050 /* terminate string after the fitting quote char */
5051 *(quote+1) = '\0';
5054 warn:
5055 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5056 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5057 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5058 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5060 out:
5061 return Globals.szPassdbBackend;
5063 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5064 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5065 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5066 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5067 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5069 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5070 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5071 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5072 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5073 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5074 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5076 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5078 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5079 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5080 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5082 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5084 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5085 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5086 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5087 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5088 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5089 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5090 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5091 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5092 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5093 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5094 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5095 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5096 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5097 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5098 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5100 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5101 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5102 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5103 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5104 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5105 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5107 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5108 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5109 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5110 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5111 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5112 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5113 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5114 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5115 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5116 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5117 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5118 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5119 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5120 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5121 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5122 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5123 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5125 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5127 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5128 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5129 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5130 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5131 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5132 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5133 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5134 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5135 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5136 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5137 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5138 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5139 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5140 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5141 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5142 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5143 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5144 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5145 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5146 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5147 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5148 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5149 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5150 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5151 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5152 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5153 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5154 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5155 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5156 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5157 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5158 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5159 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5160 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5161 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5162 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5163 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5164 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5165 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5166 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5167 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5168 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5169 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5170 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5171 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5172 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5173 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5174 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5175 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5176 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5177 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5178 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5179 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5180 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5181 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5182 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5183 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5184 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5185 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5186 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5187 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5188 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5189 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5190 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5191 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5192 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5193 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5194 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5195 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5196 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5197 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5198 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5199 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5200 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5201 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5202 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5203 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5204 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5205 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5206 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5207 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5208 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5209 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5210 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5211 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5212 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5213 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5214 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5215 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5216 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5217 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5218 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5219 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5220 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5221 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5222 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5223 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5224 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5226 FN_LOCAL_STRING(lp_preexec, szPreExec)
5227 FN_LOCAL_STRING(lp_postexec, szPostExec)
5228 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5229 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5230 FN_LOCAL_STRING(lp_servicename, szService)
5231 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5232 FN_LOCAL_STRING(lp_pathname, szPath)
5233 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5234 FN_LOCAL_STRING(lp_username, szUsername)
5235 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5236 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5237 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5238 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5239 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5240 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5241 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5242 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5243 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5244 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5245 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5246 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5247 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5248 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5249 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5250 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5251 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5252 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5253 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5254 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5255 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5256 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5257 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5258 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5259 FN_LOCAL_STRING(lp_comment, comment)
5260 FN_LOCAL_STRING(lp_force_user, force_user)
5261 FN_LOCAL_STRING(lp_force_group, force_group)
5262 FN_LOCAL_LIST(lp_readlist, readlist)
5263 FN_LOCAL_LIST(lp_writelist, writelist)
5264 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5265 FN_LOCAL_STRING(lp_fstype, fstype)
5266 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5267 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5268 static FN_LOCAL_STRING(lp_volume, volume)
5269 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5270 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5271 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5272 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5273 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5274 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5275 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5276 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5277 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5278 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5279 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5280 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5281 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5282 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5283 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5284 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5285 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5286 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5287 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5288 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5289 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5290 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5291 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5292 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5293 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5294 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5295 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5296 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5297 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5298 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5299 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5300 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5301 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5302 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5303 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5304 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5305 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5306 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5307 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5308 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5309 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5310 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5311 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5312 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5313 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5314 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5315 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5316 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5317 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5318 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5319 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5320 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5321 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5322 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5323 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5324 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5325 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5326 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5327 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5328 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5329 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5330 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5331 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5332 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5333 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5334 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5335 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5336 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5337 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5338 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5339 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5340 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5341 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5342 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5343 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5344 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5345 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5346 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5347 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5348 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5349 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5350 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5351 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5352 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5353 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5354 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5355 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5356 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5357 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5358 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5359 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5360 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5361 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5362 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5363 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5364 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5365 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5366 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5368 /* local prototypes */
5370 static int map_parameter(const char *pszParmName);
5371 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5372 static bool set_boolean(bool *pb, const char *pszParmValue);
5373 static const char *get_boolean(bool bool_value);
5374 static int getservicebyname(const char *pszServiceName,
5375 struct service *pserviceDest);
5376 static void copy_service(struct service *pserviceDest,
5377 struct service *pserviceSource,
5378 struct bitmap *pcopymapDest);
5379 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5380 void *userdata);
5381 static bool do_section(const char *pszSectionName, void *userdata);
5382 static void init_copymap(struct service *pservice);
5383 static bool hash_a_service(const char *name, int number);
5384 static void free_service_byindex(int iService);
5385 static char * canonicalize_servicename(const char *name);
5386 static void show_parameter(int parmIndex);
5387 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5390 * This is a helper function for parametrical options support. It returns a
5391 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5392 * parametrical functions are quite simple
5394 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5395 const char *option)
5397 bool global_section = False;
5398 char* param_key;
5399 struct param_opt_struct *data;
5401 if (snum >= iNumServices) return NULL;
5403 if (snum < 0) {
5404 data = Globals.param_opt;
5405 global_section = True;
5406 } else {
5407 data = ServicePtrs[snum]->param_opt;
5410 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5411 DEBUG(0,("asprintf failed!\n"));
5412 return NULL;
5415 while (data) {
5416 if (strwicmp(data->key, param_key) == 0) {
5417 string_free(&param_key);
5418 return data;
5420 data = data->next;
5423 if (!global_section) {
5424 /* Try to fetch the same option but from globals */
5425 /* but only if we are not already working with Globals */
5426 data = Globals.param_opt;
5427 while (data) {
5428 if (strwicmp(data->key, param_key) == 0) {
5429 string_free(&param_key);
5430 return data;
5432 data = data->next;
5436 string_free(&param_key);
5438 return NULL;
5442 #define MISSING_PARAMETER(name) \
5443 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5445 /*******************************************************************
5446 convenience routine to return int parameters.
5447 ********************************************************************/
5448 static int lp_int(const char *s)
5451 if (!s || !*s) {
5452 MISSING_PARAMETER(lp_int);
5453 return (-1);
5456 return (int)strtol(s, NULL, 0);
5459 /*******************************************************************
5460 convenience routine to return unsigned long parameters.
5461 ********************************************************************/
5462 static unsigned long lp_ulong(const char *s)
5465 if (!s || !*s) {
5466 MISSING_PARAMETER(lp_ulong);
5467 return (0);
5470 return strtoul(s, NULL, 0);
5473 /*******************************************************************
5474 convenience routine to return boolean parameters.
5475 ********************************************************************/
5476 static bool lp_bool(const char *s)
5478 bool ret = False;
5480 if (!s || !*s) {
5481 MISSING_PARAMETER(lp_bool);
5482 return False;
5485 if (!set_boolean(&ret,s)) {
5486 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5487 return False;
5490 return ret;
5493 /*******************************************************************
5494 convenience routine to return enum parameters.
5495 ********************************************************************/
5496 static int lp_enum(const char *s,const struct enum_list *_enum)
5498 int i;
5500 if (!s || !*s || !_enum) {
5501 MISSING_PARAMETER(lp_enum);
5502 return (-1);
5505 for (i=0; _enum[i].name; i++) {
5506 if (strequal(_enum[i].name,s))
5507 return _enum[i].value;
5510 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5511 return (-1);
5514 #undef MISSING_PARAMETER
5516 /* DO NOT USE lp_parm_string ANYMORE!!!!
5517 * use lp_parm_const_string or lp_parm_talloc_string
5519 * lp_parm_string is only used to let old modules find this symbol
5521 #undef lp_parm_string
5522 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5523 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5525 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5528 /* Return parametric option from a given service. Type is a part of option before ':' */
5529 /* Parametric option has following syntax: 'Type: option = value' */
5530 /* the returned value is talloced on the talloc_tos() */
5531 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5533 struct param_opt_struct *data = get_parametrics(snum, type, option);
5535 if (data == NULL||data->value==NULL) {
5536 if (def) {
5537 return lp_string(def);
5538 } else {
5539 return NULL;
5543 return lp_string(data->value);
5546 /* Return parametric option from a given service. Type is a part of option before ':' */
5547 /* Parametric option has following syntax: 'Type: option = value' */
5548 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5550 struct param_opt_struct *data = get_parametrics(snum, type, option);
5552 if (data == NULL||data->value==NULL)
5553 return def;
5555 return data->value;
5558 /* Return parametric option from a given service. Type is a part of option before ':' */
5559 /* Parametric option has following syntax: 'Type: option = value' */
5561 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5563 struct param_opt_struct *data = get_parametrics(snum, type, option);
5565 if (data == NULL||data->value==NULL)
5566 return (const char **)def;
5568 if (data->list==NULL) {
5569 data->list = str_list_make(talloc_autofree_context(), data->value, NULL);
5572 return (const char **)data->list;
5575 /* Return parametric option from a given service. Type is a part of option before ':' */
5576 /* Parametric option has following syntax: 'Type: option = value' */
5578 int lp_parm_int(int snum, const char *type, const char *option, int def)
5580 struct param_opt_struct *data = get_parametrics(snum, type, option);
5582 if (data && data->value && *data->value)
5583 return lp_int(data->value);
5585 return def;
5588 /* Return parametric option from a given service. Type is a part of option before ':' */
5589 /* Parametric option has following syntax: 'Type: option = value' */
5591 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5593 struct param_opt_struct *data = get_parametrics(snum, type, option);
5595 if (data && data->value && *data->value)
5596 return lp_ulong(data->value);
5598 return def;
5601 /* Return parametric option from a given service. Type is a part of option before ':' */
5602 /* Parametric option has following syntax: 'Type: option = value' */
5604 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5606 struct param_opt_struct *data = get_parametrics(snum, type, option);
5608 if (data && data->value && *data->value)
5609 return lp_bool(data->value);
5611 return def;
5614 /* Return parametric option from a given service. Type is a part of option before ':' */
5615 /* Parametric option has following syntax: 'Type: option = value' */
5617 int lp_parm_enum(int snum, const char *type, const char *option,
5618 const struct enum_list *_enum, int def)
5620 struct param_opt_struct *data = get_parametrics(snum, type, option);
5622 if (data && data->value && *data->value && _enum)
5623 return lp_enum(data->value, _enum);
5625 return def;
5629 /***************************************************************************
5630 Initialise a service to the defaults.
5631 ***************************************************************************/
5633 static void init_service(struct service *pservice)
5635 memset((char *)pservice, '\0', sizeof(struct service));
5636 copy_service(pservice, &sDefault, NULL);
5639 /***************************************************************************
5640 Free the dynamically allocated parts of a service struct.
5641 ***************************************************************************/
5643 static void free_service(struct service *pservice)
5645 int i;
5646 struct param_opt_struct *data, *pdata;
5647 if (!pservice)
5648 return;
5650 if (pservice->szService)
5651 DEBUG(5, ("free_service: Freeing service %s\n",
5652 pservice->szService));
5654 string_free(&pservice->szService);
5655 bitmap_free(pservice->copymap);
5657 for (i = 0; parm_table[i].label; i++) {
5658 if ((parm_table[i].type == P_STRING ||
5659 parm_table[i].type == P_USTRING) &&
5660 parm_table[i].p_class == P_LOCAL)
5661 string_free((char **)
5662 (((char *)pservice) +
5663 PTR_DIFF(parm_table[i].ptr, &sDefault)));
5664 else if (parm_table[i].type == P_LIST &&
5665 parm_table[i].p_class == P_LOCAL)
5666 TALLOC_FREE(*((char ***)
5667 (((char *)pservice) +
5668 PTR_DIFF(parm_table[i].ptr,
5669 &sDefault))));
5672 data = pservice->param_opt;
5673 if (data)
5674 DEBUG(5,("Freeing parametrics:\n"));
5675 while (data) {
5676 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5677 string_free(&data->key);
5678 string_free(&data->value);
5679 TALLOC_FREE(data->list);
5680 pdata = data->next;
5681 SAFE_FREE(data);
5682 data = pdata;
5685 ZERO_STRUCTP(pservice);
5689 /***************************************************************************
5690 remove a service indexed in the ServicePtrs array from the ServiceHash
5691 and free the dynamically allocated parts
5692 ***************************************************************************/
5694 static void free_service_byindex(int idx)
5696 if ( !LP_SNUM_OK(idx) )
5697 return;
5699 ServicePtrs[idx]->valid = False;
5700 invalid_services[num_invalid_services++] = idx;
5702 /* we have to cleanup the hash record */
5704 if (ServicePtrs[idx]->szService) {
5705 char *canon_name = canonicalize_servicename(
5706 ServicePtrs[idx]->szService );
5708 dbwrap_delete_bystring(ServiceHash, canon_name );
5709 TALLOC_FREE(canon_name);
5712 free_service(ServicePtrs[idx]);
5715 /***************************************************************************
5716 Add a new service to the services array initialising it with the given
5717 service.
5718 ***************************************************************************/
5720 static int add_a_service(const struct service *pservice, const char *name)
5722 int i;
5723 struct service tservice;
5724 int num_to_alloc = iNumServices + 1;
5725 struct param_opt_struct *data, *pdata;
5727 tservice = *pservice;
5729 /* it might already exist */
5730 if (name) {
5731 i = getservicebyname(name, NULL);
5732 if (i >= 0) {
5733 /* Clean all parametric options for service */
5734 /* They will be added during parsing again */
5735 data = ServicePtrs[i]->param_opt;
5736 while (data) {
5737 string_free(&data->key);
5738 string_free(&data->value);
5739 TALLOC_FREE(data->list);
5740 pdata = data->next;
5741 SAFE_FREE(data);
5742 data = pdata;
5744 ServicePtrs[i]->param_opt = NULL;
5745 return (i);
5749 /* find an invalid one */
5750 i = iNumServices;
5751 if (num_invalid_services > 0) {
5752 i = invalid_services[--num_invalid_services];
5755 /* if not, then create one */
5756 if (i == iNumServices) {
5757 struct service **tsp;
5758 int *tinvalid;
5760 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5761 if (tsp == NULL) {
5762 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5763 return (-1);
5765 ServicePtrs = tsp;
5766 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5767 if (!ServicePtrs[iNumServices]) {
5768 DEBUG(0,("add_a_service: out of memory!\n"));
5769 return (-1);
5771 iNumServices++;
5773 /* enlarge invalid_services here for now... */
5774 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5775 num_to_alloc);
5776 if (tinvalid == NULL) {
5777 DEBUG(0,("add_a_service: failed to enlarge "
5778 "invalid_services!\n"));
5779 return (-1);
5781 invalid_services = tinvalid;
5782 } else {
5783 free_service_byindex(i);
5786 ServicePtrs[i]->valid = True;
5788 init_service(ServicePtrs[i]);
5789 copy_service(ServicePtrs[i], &tservice, NULL);
5790 if (name)
5791 string_set(&ServicePtrs[i]->szService, name);
5793 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5794 i, ServicePtrs[i]->szService));
5796 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5797 return (-1);
5800 return (i);
5803 /***************************************************************************
5804 Convert a string to uppercase and remove whitespaces.
5805 ***************************************************************************/
5807 static char *canonicalize_servicename(const char *src)
5809 char *result;
5811 if ( !src ) {
5812 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5813 return NULL;
5816 result = talloc_strdup(talloc_tos(), src);
5817 SMB_ASSERT(result != NULL);
5819 strlower_m(result);
5820 return result;
5823 /***************************************************************************
5824 Add a name/index pair for the services array to the hash table.
5825 ***************************************************************************/
5827 static bool hash_a_service(const char *name, int idx)
5829 char *canon_name;
5831 if ( !ServiceHash ) {
5832 DEBUG(10,("hash_a_service: creating servicehash\n"));
5833 ServiceHash = db_open_rbt(NULL);
5834 if ( !ServiceHash ) {
5835 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5836 return False;
5840 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5841 idx, name));
5843 canon_name = canonicalize_servicename( name );
5845 dbwrap_store_bystring(ServiceHash, canon_name,
5846 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5847 TDB_REPLACE);
5849 TALLOC_FREE(canon_name);
5851 return True;
5854 /***************************************************************************
5855 Add a new home service, with the specified home directory, defaults coming
5856 from service ifrom.
5857 ***************************************************************************/
5859 bool lp_add_home(const char *pszHomename, int iDefaultService,
5860 const char *user, const char *pszHomedir)
5862 int i;
5864 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5866 if (i < 0)
5867 return (False);
5869 if (!(*(ServicePtrs[iDefaultService]->szPath))
5870 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5871 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5874 if (!(*(ServicePtrs[i]->comment))) {
5875 char *comment = NULL;
5876 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5877 return false;
5879 string_set(&ServicePtrs[i]->comment, comment);
5880 SAFE_FREE(comment);
5883 /* set the browseable flag from the global default */
5885 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5887 ServicePtrs[i]->autoloaded = True;
5889 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5890 user, ServicePtrs[i]->szPath ));
5892 return (True);
5895 /***************************************************************************
5896 Add a new service, based on an old one.
5897 ***************************************************************************/
5899 int lp_add_service(const char *pszService, int iDefaultService)
5901 if (iDefaultService < 0) {
5902 return add_a_service(&sDefault, pszService);
5905 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5908 /***************************************************************************
5909 Add the IPC service.
5910 ***************************************************************************/
5912 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5914 char *comment = NULL;
5915 int i = add_a_service(&sDefault, ipc_name);
5917 if (i < 0)
5918 return (False);
5920 if (asprintf(&comment, "IPC Service (%s)",
5921 Globals.szServerString) < 0) {
5922 return (False);
5925 string_set(&ServicePtrs[i]->szPath, tmpdir());
5926 string_set(&ServicePtrs[i]->szUsername, "");
5927 string_set(&ServicePtrs[i]->comment, comment);
5928 string_set(&ServicePtrs[i]->fstype, "IPC");
5929 ServicePtrs[i]->iMaxConnections = 0;
5930 ServicePtrs[i]->bAvailable = True;
5931 ServicePtrs[i]->bRead_only = True;
5932 ServicePtrs[i]->bGuest_only = False;
5933 ServicePtrs[i]->bAdministrative_share = True;
5934 ServicePtrs[i]->bGuest_ok = guest_ok;
5935 ServicePtrs[i]->bPrint_ok = False;
5936 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5938 DEBUG(3, ("adding IPC service\n"));
5940 SAFE_FREE(comment);
5941 return (True);
5944 /***************************************************************************
5945 Add a new printer service, with defaults coming from service iFrom.
5946 ***************************************************************************/
5948 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5950 const char *comment = "From Printcap";
5951 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5953 if (i < 0)
5954 return (False);
5956 /* note that we do NOT default the availability flag to True - */
5957 /* we take it from the default service passed. This allows all */
5958 /* dynamic printers to be disabled by disabling the [printers] */
5959 /* entry (if/when the 'available' keyword is implemented!). */
5961 /* the printer name is set to the service name. */
5962 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5963 string_set(&ServicePtrs[i]->comment, comment);
5965 /* set the browseable flag from the gloabl default */
5966 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5968 /* Printers cannot be read_only. */
5969 ServicePtrs[i]->bRead_only = False;
5970 /* No share modes on printer services. */
5971 ServicePtrs[i]->bShareModes = False;
5972 /* No oplocks on printer services. */
5973 ServicePtrs[i]->bOpLocks = False;
5974 /* Printer services must be printable. */
5975 ServicePtrs[i]->bPrint_ok = True;
5977 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5979 return (True);
5983 /***************************************************************************
5984 Check whether the given parameter name is valid.
5985 Parametric options (names containing a colon) are considered valid.
5986 ***************************************************************************/
5988 bool lp_parameter_is_valid(const char *pszParmName)
5990 return ((map_parameter(pszParmName) != -1) ||
5991 (strchr(pszParmName, ':') != NULL));
5994 /***************************************************************************
5995 Check whether the given name is the name of a global parameter.
5996 Returns True for strings belonging to parameters of class
5997 P_GLOBAL, False for all other strings, also for parametric options
5998 and strings not belonging to any option.
5999 ***************************************************************************/
6001 bool lp_parameter_is_global(const char *pszParmName)
6003 int num = map_parameter(pszParmName);
6005 if (num >= 0) {
6006 return (parm_table[num].p_class == P_GLOBAL);
6009 return False;
6012 /**************************************************************************
6013 Check whether the given name is the canonical name of a parameter.
6014 Returns False if it is not a valid parameter Name.
6015 For parametric options, True is returned.
6016 **************************************************************************/
6018 bool lp_parameter_is_canonical(const char *parm_name)
6020 if (!lp_parameter_is_valid(parm_name)) {
6021 return False;
6024 return (map_parameter(parm_name) ==
6025 map_parameter_canonical(parm_name, NULL));
6028 /**************************************************************************
6029 Determine the canonical name for a parameter.
6030 Indicate when it is an inverse (boolean) synonym instead of a
6031 "usual" synonym.
6032 **************************************************************************/
6034 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6035 bool *inverse)
6037 int num;
6039 if (!lp_parameter_is_valid(parm_name)) {
6040 *canon_parm = NULL;
6041 return False;
6044 num = map_parameter_canonical(parm_name, inverse);
6045 if (num < 0) {
6046 /* parametric option */
6047 *canon_parm = parm_name;
6048 } else {
6049 *canon_parm = parm_table[num].label;
6052 return True;
6056 /**************************************************************************
6057 Determine the canonical name for a parameter.
6058 Turn the value given into the inverse boolean expression when
6059 the synonym is an invers boolean synonym.
6061 Return True if parm_name is a valid parameter name and
6062 in case it is an invers boolean synonym, if the val string could
6063 successfully be converted to the reverse bool.
6064 Return false in all other cases.
6065 **************************************************************************/
6067 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6068 const char *val,
6069 const char **canon_parm,
6070 const char **canon_val)
6072 int num;
6073 bool inverse;
6075 if (!lp_parameter_is_valid(parm_name)) {
6076 *canon_parm = NULL;
6077 *canon_val = NULL;
6078 return False;
6081 num = map_parameter_canonical(parm_name, &inverse);
6082 if (num < 0) {
6083 /* parametric option */
6084 *canon_parm = parm_name;
6085 *canon_val = val;
6086 } else {
6087 *canon_parm = parm_table[num].label;
6088 if (inverse) {
6089 if (!lp_invert_boolean(val, canon_val)) {
6090 *canon_val = NULL;
6091 return False;
6093 } else {
6094 *canon_val = val;
6098 return True;
6101 /***************************************************************************
6102 Map a parameter's string representation to something we can use.
6103 Returns False if the parameter string is not recognised, else TRUE.
6104 ***************************************************************************/
6106 static int map_parameter(const char *pszParmName)
6108 int iIndex;
6110 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6111 return (-1);
6113 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6114 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6115 return (iIndex);
6117 /* Warn only if it isn't parametric option */
6118 if (strchr(pszParmName, ':') == NULL)
6119 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6120 /* We do return 'fail' for parametric options as well because they are
6121 stored in different storage
6123 return (-1);
6126 /***************************************************************************
6127 Map a parameter's string representation to the index of the canonical
6128 form of the parameter (it might be a synonym).
6129 Returns -1 if the parameter string is not recognised.
6130 ***************************************************************************/
6132 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6134 int parm_num, canon_num;
6135 bool loc_inverse = False;
6137 parm_num = map_parameter(pszParmName);
6138 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6139 /* invalid, parametric or no canidate for synonyms ... */
6140 goto done;
6143 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6144 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6145 parm_num = canon_num;
6146 goto done;
6150 done:
6151 if (inverse != NULL) {
6152 *inverse = loc_inverse;
6154 return parm_num;
6157 /***************************************************************************
6158 return true if parameter number parm1 is a synonym of parameter
6159 number parm2 (parm2 being the principal name).
6160 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6161 False otherwise.
6162 ***************************************************************************/
6164 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6166 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6167 (parm_table[parm1].flags & FLAG_HIDE) &&
6168 !(parm_table[parm2].flags & FLAG_HIDE))
6170 if (inverse != NULL) {
6171 if ((parm_table[parm1].type == P_BOOLREV) &&
6172 (parm_table[parm2].type == P_BOOL))
6174 *inverse = True;
6175 } else {
6176 *inverse = False;
6179 return True;
6181 return False;
6184 /***************************************************************************
6185 Show one parameter's name, type, [values,] and flags.
6186 (helper functions for show_parameter_list)
6187 ***************************************************************************/
6189 static void show_parameter(int parmIndex)
6191 int enumIndex, flagIndex;
6192 int parmIndex2;
6193 bool hadFlag;
6194 bool hadSyn;
6195 bool inverse;
6196 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6197 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6198 "P_ENUM", "P_SEP"};
6199 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6200 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6201 FLAG_HIDE, FLAG_DOS_STRING};
6202 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6203 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6204 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6206 printf("%s=%s", parm_table[parmIndex].label,
6207 type[parm_table[parmIndex].type]);
6208 if (parm_table[parmIndex].type == P_ENUM) {
6209 printf(",");
6210 for (enumIndex=0;
6211 parm_table[parmIndex].enum_list[enumIndex].name;
6212 enumIndex++)
6214 printf("%s%s",
6215 enumIndex ? "|" : "",
6216 parm_table[parmIndex].enum_list[enumIndex].name);
6219 printf(",");
6220 hadFlag = False;
6221 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6222 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6223 printf("%s%s",
6224 hadFlag ? "|" : "",
6225 flag_names[flagIndex]);
6226 hadFlag = True;
6230 /* output synonyms */
6231 hadSyn = False;
6232 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6233 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6234 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6235 parm_table[parmIndex2].label);
6236 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6237 if (!hadSyn) {
6238 printf(" (synonyms: ");
6239 hadSyn = True;
6240 } else {
6241 printf(", ");
6243 printf("%s%s", parm_table[parmIndex2].label,
6244 inverse ? "[i]" : "");
6247 if (hadSyn) {
6248 printf(")");
6251 printf("\n");
6254 /***************************************************************************
6255 Show all parameter's name, type, [values,] and flags.
6256 ***************************************************************************/
6258 void show_parameter_list(void)
6260 int classIndex, parmIndex;
6261 const char *section_names[] = { "local", "global", NULL};
6263 for (classIndex=0; section_names[classIndex]; classIndex++) {
6264 printf("[%s]\n", section_names[classIndex]);
6265 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6266 if (parm_table[parmIndex].p_class == classIndex) {
6267 show_parameter(parmIndex);
6273 /***************************************************************************
6274 Set a boolean variable from the text value stored in the passed string.
6275 Returns True in success, False if the passed string does not correctly
6276 represent a boolean.
6277 ***************************************************************************/
6279 static bool set_boolean(bool *pb, const char *pszParmValue)
6281 bool bRetval;
6282 bool value;
6284 bRetval = True;
6285 value = False;
6286 if (strwicmp(pszParmValue, "yes") == 0 ||
6287 strwicmp(pszParmValue, "true") == 0 ||
6288 strwicmp(pszParmValue, "1") == 0)
6289 value = True;
6290 else if (strwicmp(pszParmValue, "no") == 0 ||
6291 strwicmp(pszParmValue, "False") == 0 ||
6292 strwicmp(pszParmValue, "0") == 0)
6293 value = False;
6294 else {
6295 DEBUG(2,
6296 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6297 pszParmValue));
6298 bRetval = False;
6301 if ((pb != NULL) && (bRetval != False)) {
6302 *pb = value;
6305 return (bRetval);
6309 /***************************************************************************
6310 Check if a given string correctly represents a boolean value.
6311 ***************************************************************************/
6313 bool lp_string_is_valid_boolean(const char *parm_value)
6315 return set_boolean(NULL, parm_value);
6318 /***************************************************************************
6319 Get the standard string representation of a boolean value ("yes" or "no")
6320 ***************************************************************************/
6322 static const char *get_boolean(bool bool_value)
6324 static const char *yes_str = "yes";
6325 static const char *no_str = "no";
6327 return (bool_value ? yes_str : no_str);
6330 /***************************************************************************
6331 Provide the string of the negated boolean value associated to the boolean
6332 given as a string. Returns False if the passed string does not correctly
6333 represent a boolean.
6334 ***************************************************************************/
6336 bool lp_invert_boolean(const char *str, const char **inverse_str)
6338 bool val;
6340 if (!set_boolean(&val, str)) {
6341 return False;
6344 *inverse_str = get_boolean(!val);
6345 return True;
6348 /***************************************************************************
6349 Provide the canonical string representation of a boolean value given
6350 as a string. Return True on success, False if the string given does
6351 not correctly represent a boolean.
6352 ***************************************************************************/
6354 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6356 bool val;
6358 if (!set_boolean(&val, str)) {
6359 return False;
6362 *canon_str = get_boolean(val);
6363 return True;
6366 /***************************************************************************
6367 Find a service by name. Otherwise works like get_service.
6368 ***************************************************************************/
6370 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6372 int iService = -1;
6373 char *canon_name;
6374 TDB_DATA data;
6376 if (ServiceHash == NULL) {
6377 return -1;
6380 canon_name = canonicalize_servicename(pszServiceName);
6382 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6384 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6385 iService = *(int *)data.dptr;
6388 TALLOC_FREE(canon_name);
6390 if ((iService != -1) && (LP_SNUM_OK(iService))
6391 && (pserviceDest != NULL)) {
6392 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6395 return (iService);
6398 /***************************************************************************
6399 Copy a service structure to another.
6400 If pcopymapDest is NULL then copy all fields
6401 ***************************************************************************/
6403 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6404 struct bitmap *pcopymapDest)
6406 int i;
6407 bool bcopyall = (pcopymapDest == NULL);
6408 struct param_opt_struct *data, *pdata, *paramo;
6409 bool not_added;
6411 for (i = 0; parm_table[i].label; i++)
6412 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6413 (bcopyall || bitmap_query(pcopymapDest,i))) {
6414 void *def_ptr = parm_table[i].ptr;
6415 void *src_ptr =
6416 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6417 &sDefault);
6418 void *dest_ptr =
6419 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6420 &sDefault);
6422 switch (parm_table[i].type) {
6423 case P_BOOL:
6424 case P_BOOLREV:
6425 *(bool *)dest_ptr = *(bool *)src_ptr;
6426 break;
6428 case P_INTEGER:
6429 case P_ENUM:
6430 case P_OCTAL:
6431 *(int *)dest_ptr = *(int *)src_ptr;
6432 break;
6434 case P_CHAR:
6435 *(char *)dest_ptr = *(char *)src_ptr;
6436 break;
6438 case P_STRING:
6439 string_set((char **)dest_ptr,
6440 *(char **)src_ptr);
6441 break;
6443 case P_USTRING:
6444 string_set((char **)dest_ptr,
6445 *(char **)src_ptr);
6446 strupper_m(*(char **)dest_ptr);
6447 break;
6448 case P_LIST:
6449 TALLOC_FREE(*((char ***)dest_ptr));
6450 str_list_copy(NULL, (char ***)dest_ptr,
6451 *(const char ***)src_ptr);
6452 break;
6453 default:
6454 break;
6458 if (bcopyall) {
6459 init_copymap(pserviceDest);
6460 if (pserviceSource->copymap)
6461 bitmap_copy(pserviceDest->copymap,
6462 pserviceSource->copymap);
6465 data = pserviceSource->param_opt;
6466 while (data) {
6467 not_added = True;
6468 pdata = pserviceDest->param_opt;
6469 /* Traverse destination */
6470 while (pdata) {
6471 /* If we already have same option, override it */
6472 if (strwicmp(pdata->key, data->key) == 0) {
6473 string_free(&pdata->value);
6474 TALLOC_FREE(data->list);
6475 pdata->value = SMB_STRDUP(data->value);
6476 not_added = False;
6477 break;
6479 pdata = pdata->next;
6481 if (not_added) {
6482 paramo = SMB_XMALLOC_P(struct param_opt_struct);
6483 paramo->key = SMB_STRDUP(data->key);
6484 paramo->value = SMB_STRDUP(data->value);
6485 paramo->list = NULL;
6486 DLIST_ADD(pserviceDest->param_opt, paramo);
6488 data = data->next;
6492 /***************************************************************************
6493 Check a service for consistency. Return False if the service is in any way
6494 incomplete or faulty, else True.
6495 ***************************************************************************/
6497 bool service_ok(int iService)
6499 bool bRetval;
6501 bRetval = True;
6502 if (ServicePtrs[iService]->szService[0] == '\0') {
6503 DEBUG(0, ("The following message indicates an internal error:\n"));
6504 DEBUG(0, ("No service name in service entry.\n"));
6505 bRetval = False;
6508 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6509 /* I can't see why you'd want a non-printable printer service... */
6510 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6511 if (!ServicePtrs[iService]->bPrint_ok) {
6512 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6513 ServicePtrs[iService]->szService));
6514 ServicePtrs[iService]->bPrint_ok = True;
6516 /* [printers] service must also be non-browsable. */
6517 if (ServicePtrs[iService]->bBrowseable)
6518 ServicePtrs[iService]->bBrowseable = False;
6521 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6522 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6523 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6525 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6526 ServicePtrs[iService]->szService));
6527 ServicePtrs[iService]->bAvailable = False;
6530 /* If a service is flagged unavailable, log the fact at level 1. */
6531 if (!ServicePtrs[iService]->bAvailable)
6532 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6533 ServicePtrs[iService]->szService));
6535 return (bRetval);
6538 static struct smbconf_ctx *lp_smbconf_ctx(void)
6540 WERROR werr;
6541 static struct smbconf_ctx *conf_ctx = NULL;
6543 if (conf_ctx == NULL) {
6544 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6545 if (!W_ERROR_IS_OK(werr)) {
6546 DEBUG(1, ("error initializing registry configuration: "
6547 "%s\n", dos_errstr(werr)));
6548 conf_ctx = NULL;
6552 return conf_ctx;
6555 static bool process_registry_service(struct smbconf_service *service)
6557 uint32_t count;
6558 bool ret;
6560 if (service == NULL) {
6561 return false;
6564 ret = do_section(service->name, NULL);
6565 if (ret != true) {
6566 return false;
6568 for (count = 0; count < service->num_params; count++) {
6569 ret = do_parameter(service->param_names[count],
6570 service->param_values[count],
6571 NULL);
6572 if (ret != true) {
6573 return false;
6576 return true;
6580 * process_registry_globals
6582 static bool process_registry_globals(void)
6584 WERROR werr;
6585 struct smbconf_service *service = NULL;
6586 TALLOC_CTX *mem_ctx = talloc_stackframe();
6587 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6588 bool ret = false;
6590 if (conf_ctx == NULL) {
6591 goto done;
6594 ret = do_parameter("registry shares", "yes", NULL);
6595 if (!ret) {
6596 goto done;
6599 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6600 /* nothing to read from the registry yet but make sure lp_load
6601 * doesn't return false */
6602 ret = true;
6603 goto done;
6606 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6607 if (!W_ERROR_IS_OK(werr)) {
6608 goto done;
6611 ret = process_registry_service(service);
6612 if (!ret) {
6613 goto done;
6616 /* store the csn */
6617 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6619 done:
6620 TALLOC_FREE(mem_ctx);
6621 return ret;
6624 static bool process_registry_shares(void)
6626 WERROR werr;
6627 uint32_t count;
6628 struct smbconf_service **service = NULL;
6629 uint32_t num_shares = 0;
6630 TALLOC_CTX *mem_ctx = talloc_stackframe();
6631 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6632 bool ret = false;
6634 if (conf_ctx == NULL) {
6635 goto done;
6638 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6639 if (!W_ERROR_IS_OK(werr)) {
6640 goto done;
6643 ret = true;
6645 for (count = 0; count < num_shares; count++) {
6646 if (strequal(service[count]->name, GLOBAL_NAME)) {
6647 continue;
6649 ret = process_registry_service(service[count]);
6650 if (!ret) {
6651 goto done;
6655 /* store the csn */
6656 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6658 done:
6659 TALLOC_FREE(mem_ctx);
6660 return ret;
6663 static struct file_lists {
6664 struct file_lists *next;
6665 char *name;
6666 char *subfname;
6667 time_t modtime;
6668 } *file_lists = NULL;
6670 /*******************************************************************
6671 Keep a linked list of all config files so we know when one has changed
6672 it's date and needs to be reloaded.
6673 ********************************************************************/
6675 static void add_to_file_list(const char *fname, const char *subfname)
6677 struct file_lists *f = file_lists;
6679 while (f) {
6680 if (f->name && !strcmp(f->name, fname))
6681 break;
6682 f = f->next;
6685 if (!f) {
6686 f = SMB_MALLOC_P(struct file_lists);
6687 if (!f)
6688 return;
6689 f->next = file_lists;
6690 f->name = SMB_STRDUP(fname);
6691 if (!f->name) {
6692 SAFE_FREE(f);
6693 return;
6695 f->subfname = SMB_STRDUP(subfname);
6696 if (!f->subfname) {
6697 SAFE_FREE(f);
6698 return;
6700 file_lists = f;
6701 f->modtime = file_modtime(subfname);
6702 } else {
6703 time_t t = file_modtime(subfname);
6704 if (t)
6705 f->modtime = t;
6710 * Utility function for outsiders to check if we're running on registry.
6712 bool lp_config_backend_is_registry(void)
6714 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6718 * Utility function to check if the config backend is FILE.
6720 bool lp_config_backend_is_file(void)
6722 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6725 /*******************************************************************
6726 Check if a config file has changed date.
6727 ********************************************************************/
6729 bool lp_file_list_changed(void)
6731 struct file_lists *f = file_lists;
6733 DEBUG(6, ("lp_file_list_changed()\n"));
6735 if (lp_config_backend_is_registry()) {
6736 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6738 if (conf_ctx == NULL) {
6739 return false;
6741 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6742 DEBUGADD(6, ("registry config changed\n"));
6743 return true;
6747 while (f) {
6748 char *n2 = NULL;
6749 time_t mod_time;
6751 n2 = alloc_sub_basic(get_current_username(),
6752 current_user_info.domain,
6753 f->name);
6754 if (!n2) {
6755 return false;
6757 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6758 f->name, n2, ctime(&f->modtime)));
6760 mod_time = file_modtime(n2);
6762 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6763 DEBUGADD(6,
6764 ("file %s modified: %s\n", n2,
6765 ctime(&mod_time)));
6766 f->modtime = mod_time;
6767 SAFE_FREE(f->subfname);
6768 f->subfname = n2; /* Passing ownership of
6769 return from alloc_sub_basic
6770 above. */
6771 return true;
6773 SAFE_FREE(n2);
6774 f = f->next;
6776 return (False);
6780 /***************************************************************************
6781 Run standard_sub_basic on netbios name... needed because global_myname
6782 is not accessed through any lp_ macro.
6783 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6784 ***************************************************************************/
6786 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6788 bool ret;
6789 char *netbios_name = alloc_sub_basic(get_current_username(),
6790 current_user_info.domain,
6791 pszParmValue);
6793 ret = set_global_myname(netbios_name);
6794 SAFE_FREE(netbios_name);
6795 string_set(&Globals.szNetbiosName,global_myname());
6797 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6798 global_myname()));
6800 return ret;
6803 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6805 if (strcmp(*ptr, pszParmValue) != 0) {
6806 string_set(ptr, pszParmValue);
6807 init_iconv();
6809 return True;
6814 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6816 bool ret;
6818 ret = set_global_myworkgroup(pszParmValue);
6819 string_set(&Globals.szWorkgroup,lp_workgroup());
6821 return ret;
6824 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6826 bool ret;
6828 ret = set_global_scope(pszParmValue);
6829 string_set(&Globals.szNetbiosScope,global_scope());
6831 return ret;
6834 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6836 TALLOC_FREE(Globals.szNetbiosAliases);
6837 Globals.szNetbiosAliases = str_list_make(talloc_autofree_context(), pszParmValue, NULL);
6838 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6841 /***************************************************************************
6842 Handle the include operation.
6843 ***************************************************************************/
6844 static bool bAllowIncludeRegistry = true;
6846 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6848 char *fname;
6850 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6851 if (!bAllowIncludeRegistry) {
6852 return true;
6854 if (bInGlobalSection) {
6855 return process_registry_globals();
6856 } else {
6857 DEBUG(1, ("\"include = registry\" only effective "
6858 "in %s section\n", GLOBAL_NAME));
6859 return false;
6863 fname = alloc_sub_basic(get_current_username(),
6864 current_user_info.domain,
6865 pszParmValue);
6867 add_to_file_list(pszParmValue, fname);
6869 string_set(ptr, fname);
6871 if (file_exist(fname, NULL)) {
6872 bool ret = pm_process(fname, do_section, do_parameter, NULL);
6873 SAFE_FREE(fname);
6874 return ret;
6877 DEBUG(2, ("Can't find include file %s\n", fname));
6878 SAFE_FREE(fname);
6879 return true;
6882 /***************************************************************************
6883 Handle the interpretation of the copy parameter.
6884 ***************************************************************************/
6886 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6888 bool bRetval;
6889 int iTemp;
6890 struct service serviceTemp;
6892 string_set(ptr, pszParmValue);
6894 init_service(&serviceTemp);
6896 bRetval = False;
6898 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6900 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6901 if (iTemp == iServiceIndex) {
6902 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6903 } else {
6904 copy_service(ServicePtrs[iServiceIndex],
6905 &serviceTemp,
6906 ServicePtrs[iServiceIndex]->copymap);
6907 bRetval = True;
6909 } else {
6910 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6911 bRetval = False;
6914 free_service(&serviceTemp);
6915 return (bRetval);
6918 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6920 Globals.ldap_debug_level = lp_int(pszParmValue);
6921 init_ldap_debugging();
6922 return true;
6925 /***************************************************************************
6926 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6927 parameters is:
6929 [global]
6931 idmap uid = 1000-1999
6932 idmap gid = 700-899
6934 We only do simple parsing checks here. The strings are parsed into useful
6935 structures in the idmap daemon code.
6937 ***************************************************************************/
6939 /* Some lp_ routines to return idmap [ug]id information */
6941 static uid_t idmap_uid_low, idmap_uid_high;
6942 static gid_t idmap_gid_low, idmap_gid_high;
6944 bool lp_idmap_uid(uid_t *low, uid_t *high)
6946 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6947 return False;
6949 if (low)
6950 *low = idmap_uid_low;
6952 if (high)
6953 *high = idmap_uid_high;
6955 return True;
6958 bool lp_idmap_gid(gid_t *low, gid_t *high)
6960 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6961 return False;
6963 if (low)
6964 *low = idmap_gid_low;
6966 if (high)
6967 *high = idmap_gid_high;
6969 return True;
6972 /* Do some simple checks on "idmap [ug]id" parameter values */
6974 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6976 uint32 low, high;
6978 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6979 return False;
6981 /* Parse OK */
6983 string_set(ptr, pszParmValue);
6985 idmap_uid_low = low;
6986 idmap_uid_high = high;
6988 return True;
6991 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6993 uint32 low, high;
6995 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6996 return False;
6998 /* Parse OK */
7000 string_set(ptr, pszParmValue);
7002 idmap_gid_low = low;
7003 idmap_gid_high = high;
7005 return True;
7008 /***************************************************************************
7009 Handle the DEBUG level list.
7010 ***************************************************************************/
7012 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7014 string_set(ptr, pszParmValueIn);
7015 return debug_parse_levels(pszParmValueIn);
7018 /***************************************************************************
7019 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7020 ***************************************************************************/
7022 static const char *append_ldap_suffix( const char *str )
7024 const char *suffix_string;
7027 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7028 Globals.szLdapSuffix );
7029 if ( !suffix_string ) {
7030 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7031 return "";
7034 return suffix_string;
7037 const char *lp_ldap_machine_suffix(void)
7039 if (Globals.szLdapMachineSuffix[0])
7040 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7042 return lp_string(Globals.szLdapSuffix);
7045 const char *lp_ldap_user_suffix(void)
7047 if (Globals.szLdapUserSuffix[0])
7048 return append_ldap_suffix(Globals.szLdapUserSuffix);
7050 return lp_string(Globals.szLdapSuffix);
7053 const char *lp_ldap_group_suffix(void)
7055 if (Globals.szLdapGroupSuffix[0])
7056 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7058 return lp_string(Globals.szLdapSuffix);
7061 const char *lp_ldap_idmap_suffix(void)
7063 if (Globals.szLdapIdmapSuffix[0])
7064 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7066 return lp_string(Globals.szLdapSuffix);
7069 /****************************************************************************
7070 set the value for a P_ENUM
7071 ***************************************************************************/
7073 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7074 int *ptr )
7076 int i;
7078 for (i = 0; parm->enum_list[i].name; i++) {
7079 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7080 *ptr = parm->enum_list[i].value;
7081 return;
7084 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7085 pszParmValue, parm->label));
7088 /***************************************************************************
7089 ***************************************************************************/
7091 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7093 static int parm_num = -1;
7094 struct service *s;
7096 if ( parm_num == -1 )
7097 parm_num = map_parameter( "printing" );
7099 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7101 if ( snum < 0 )
7102 s = &sDefault;
7103 else
7104 s = ServicePtrs[snum];
7106 init_printer_values( s );
7108 return True;
7112 /***************************************************************************
7113 Initialise a copymap.
7114 ***************************************************************************/
7116 static void init_copymap(struct service *pservice)
7118 int i;
7119 if (pservice->copymap) {
7120 bitmap_free(pservice->copymap);
7122 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7123 if (!pservice->copymap)
7124 DEBUG(0,
7125 ("Couldn't allocate copymap!! (size %d)\n",
7126 (int)NUMPARAMETERS));
7127 else
7128 for (i = 0; i < NUMPARAMETERS; i++)
7129 bitmap_set(pservice->copymap, i);
7132 /***************************************************************************
7133 Return the local pointer to a parameter given the service number and the
7134 pointer into the default structure.
7135 ***************************************************************************/
7137 void *lp_local_ptr(int snum, void *ptr)
7139 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7142 /***************************************************************************
7143 Process a parameter for a particular service number. If snum < 0
7144 then assume we are in the globals.
7145 ***************************************************************************/
7147 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7149 int parmnum, i;
7150 void *parm_ptr = NULL; /* where we are going to store the result */
7151 void *def_ptr = NULL;
7152 struct param_opt_struct *paramo, *data;
7153 bool not_added;
7155 parmnum = map_parameter(pszParmName);
7157 if (parmnum < 0) {
7158 TALLOC_CTX *frame;
7160 if (strchr(pszParmName, ':') == NULL) {
7161 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7162 pszParmName));
7163 return (True);
7167 * We've got a parametric option
7170 frame = talloc_stackframe();
7172 not_added = True;
7173 data = (snum < 0)
7174 ? Globals.param_opt : ServicePtrs[snum]->param_opt;
7175 /* Traverse destination */
7176 while (data) {
7177 /* If we already have same option, override it */
7178 if (strwicmp(data->key, pszParmName) == 0) {
7179 string_free(&data->value);
7180 TALLOC_FREE(data->list);
7181 data->value = SMB_STRDUP(pszParmValue);
7182 not_added = False;
7183 break;
7185 data = data->next;
7187 if (not_added) {
7188 paramo = SMB_XMALLOC_P(struct param_opt_struct);
7189 paramo->key = SMB_STRDUP(pszParmName);
7190 paramo->value = SMB_STRDUP(pszParmValue);
7191 paramo->list = NULL;
7192 if (snum < 0) {
7193 DLIST_ADD(Globals.param_opt, paramo);
7194 } else {
7195 DLIST_ADD(ServicePtrs[snum]->param_opt,
7196 paramo);
7200 TALLOC_FREE(frame);
7201 return (True);
7204 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7205 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7206 pszParmName));
7209 def_ptr = parm_table[parmnum].ptr;
7211 /* we might point at a service, the default service or a global */
7212 if (snum < 0) {
7213 parm_ptr = def_ptr;
7214 } else {
7215 if (parm_table[parmnum].p_class == P_GLOBAL) {
7216 DEBUG(0,
7217 ("Global parameter %s found in service section!\n",
7218 pszParmName));
7219 return (True);
7221 parm_ptr =
7222 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7223 &sDefault);
7226 if (snum >= 0) {
7227 if (!ServicePtrs[snum]->copymap)
7228 init_copymap(ServicePtrs[snum]);
7230 /* this handles the aliases - set the copymap for other entries with
7231 the same data pointer */
7232 for (i = 0; parm_table[i].label; i++)
7233 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7234 bitmap_clear(ServicePtrs[snum]->copymap, i);
7237 /* if it is a special case then go ahead */
7238 if (parm_table[parmnum].special) {
7239 return parm_table[parmnum].special(snum, pszParmValue,
7240 (char **)parm_ptr);
7243 /* now switch on the type of variable it is */
7244 switch (parm_table[parmnum].type)
7246 case P_BOOL:
7247 *(bool *)parm_ptr = lp_bool(pszParmValue);
7248 break;
7250 case P_BOOLREV:
7251 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7252 break;
7254 case P_INTEGER:
7255 *(int *)parm_ptr = lp_int(pszParmValue);
7256 break;
7258 case P_CHAR:
7259 *(char *)parm_ptr = *pszParmValue;
7260 break;
7262 case P_OCTAL:
7263 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7264 if ( i != 1 ) {
7265 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7267 break;
7269 case P_LIST:
7270 TALLOC_FREE(*((char ***)parm_ptr));
7271 *(char ***)parm_ptr = str_list_make(
7272 talloc_autofree_context(), pszParmValue, NULL);
7273 break;
7275 case P_STRING:
7276 string_set((char **)parm_ptr, pszParmValue);
7277 break;
7279 case P_USTRING:
7280 string_set((char **)parm_ptr, pszParmValue);
7281 strupper_m(*(char **)parm_ptr);
7282 break;
7284 case P_ENUM:
7285 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7286 break;
7287 case P_SEP:
7288 break;
7291 return (True);
7294 /***************************************************************************
7295 Process a parameter.
7296 ***************************************************************************/
7298 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7299 void *userdata)
7301 if (!bInGlobalSection && bGlobalOnly)
7302 return (True);
7304 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7306 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7307 pszParmName, pszParmValue));
7310 /***************************************************************************
7311 Print a parameter of the specified type.
7312 ***************************************************************************/
7314 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7316 int i;
7317 switch (p->type)
7319 case P_ENUM:
7320 for (i = 0; p->enum_list[i].name; i++) {
7321 if (*(int *)ptr == p->enum_list[i].value) {
7322 fprintf(f, "%s",
7323 p->enum_list[i].name);
7324 break;
7327 break;
7329 case P_BOOL:
7330 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7331 break;
7333 case P_BOOLREV:
7334 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7335 break;
7337 case P_INTEGER:
7338 fprintf(f, "%d", *(int *)ptr);
7339 break;
7341 case P_CHAR:
7342 fprintf(f, "%c", *(char *)ptr);
7343 break;
7345 case P_OCTAL: {
7346 char *o = octal_string(*(int *)ptr);
7347 fprintf(f, "%s", o);
7348 TALLOC_FREE(o);
7349 break;
7352 case P_LIST:
7353 if ((char ***)ptr && *(char ***)ptr) {
7354 char **list = *(char ***)ptr;
7355 for (; *list; list++) {
7356 /* surround strings with whitespace in double quotes */
7357 if ( strchr_m( *list, ' ' ) )
7358 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7359 else
7360 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7363 break;
7365 case P_STRING:
7366 case P_USTRING:
7367 if (*(char **)ptr) {
7368 fprintf(f, "%s", *(char **)ptr);
7370 break;
7371 case P_SEP:
7372 break;
7376 /***************************************************************************
7377 Check if two parameters are equal.
7378 ***************************************************************************/
7380 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7382 switch (type) {
7383 case P_BOOL:
7384 case P_BOOLREV:
7385 return (*((bool *)ptr1) == *((bool *)ptr2));
7387 case P_INTEGER:
7388 case P_ENUM:
7389 case P_OCTAL:
7390 return (*((int *)ptr1) == *((int *)ptr2));
7392 case P_CHAR:
7393 return (*((char *)ptr1) == *((char *)ptr2));
7395 case P_LIST:
7396 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7398 case P_STRING:
7399 case P_USTRING:
7401 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7402 if (p1 && !*p1)
7403 p1 = NULL;
7404 if (p2 && !*p2)
7405 p2 = NULL;
7406 return (p1 == p2 || strequal(p1, p2));
7408 case P_SEP:
7409 break;
7411 return (False);
7414 /***************************************************************************
7415 Initialize any local varients in the sDefault table.
7416 ***************************************************************************/
7418 void init_locals(void)
7420 /* None as yet. */
7423 /***************************************************************************
7424 Process a new section (service). At this stage all sections are services.
7425 Later we'll have special sections that permit server parameters to be set.
7426 Returns True on success, False on failure.
7427 ***************************************************************************/
7429 static bool do_section(const char *pszSectionName, void *userdata)
7431 bool bRetval;
7432 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7433 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7434 bRetval = False;
7436 /* if we were in a global section then do the local inits */
7437 if (bInGlobalSection && !isglobal)
7438 init_locals();
7440 /* if we've just struck a global section, note the fact. */
7441 bInGlobalSection = isglobal;
7443 /* check for multiple global sections */
7444 if (bInGlobalSection) {
7445 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7446 return (True);
7449 if (!bInGlobalSection && bGlobalOnly)
7450 return (True);
7452 /* if we have a current service, tidy it up before moving on */
7453 bRetval = True;
7455 if (iServiceIndex >= 0)
7456 bRetval = service_ok(iServiceIndex);
7458 /* if all is still well, move to the next record in the services array */
7459 if (bRetval) {
7460 /* We put this here to avoid an odd message order if messages are */
7461 /* issued by the post-processing of a previous section. */
7462 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7464 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7465 < 0) {
7466 DEBUG(0, ("Failed to add a new service\n"));
7467 return (False);
7471 return (bRetval);
7475 /***************************************************************************
7476 Determine if a partcular base parameter is currentl set to the default value.
7477 ***************************************************************************/
7479 static bool is_default(int i)
7481 if (!defaults_saved)
7482 return False;
7483 switch (parm_table[i].type) {
7484 case P_LIST:
7485 return str_list_compare (parm_table[i].def.lvalue,
7486 *(char ***)parm_table[i].ptr);
7487 case P_STRING:
7488 case P_USTRING:
7489 return strequal(parm_table[i].def.svalue,
7490 *(char **)parm_table[i].ptr);
7491 case P_BOOL:
7492 case P_BOOLREV:
7493 return parm_table[i].def.bvalue ==
7494 *(bool *)parm_table[i].ptr;
7495 case P_CHAR:
7496 return parm_table[i].def.cvalue ==
7497 *(char *)parm_table[i].ptr;
7498 case P_INTEGER:
7499 case P_OCTAL:
7500 case P_ENUM:
7501 return parm_table[i].def.ivalue ==
7502 *(int *)parm_table[i].ptr;
7503 case P_SEP:
7504 break;
7506 return False;
7509 /***************************************************************************
7510 Display the contents of the global structure.
7511 ***************************************************************************/
7513 static void dump_globals(FILE *f)
7515 int i;
7516 struct param_opt_struct *data;
7518 fprintf(f, "[global]\n");
7520 for (i = 0; parm_table[i].label; i++)
7521 if (parm_table[i].p_class == P_GLOBAL &&
7522 parm_table[i].ptr &&
7523 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7524 if (defaults_saved && is_default(i))
7525 continue;
7526 fprintf(f, "\t%s = ", parm_table[i].label);
7527 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7528 fprintf(f, "\n");
7530 if (Globals.param_opt != NULL) {
7531 data = Globals.param_opt;
7532 while(data) {
7533 fprintf(f, "\t%s = %s\n", data->key, data->value);
7534 data = data->next;
7540 /***************************************************************************
7541 Return True if a local parameter is currently set to the global default.
7542 ***************************************************************************/
7544 bool lp_is_default(int snum, struct parm_struct *parm)
7546 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7548 return equal_parameter(parm->type,
7549 ((char *)ServicePtrs[snum]) + pdiff,
7550 ((char *)&sDefault) + pdiff);
7553 /***************************************************************************
7554 Display the contents of a single services record.
7555 ***************************************************************************/
7557 static void dump_a_service(struct service *pService, FILE * f)
7559 int i;
7560 struct param_opt_struct *data;
7562 if (pService != &sDefault)
7563 fprintf(f, "[%s]\n", pService->szService);
7565 for (i = 0; parm_table[i].label; i++) {
7567 if (parm_table[i].p_class == P_LOCAL &&
7568 parm_table[i].ptr &&
7569 (*parm_table[i].label != '-') &&
7570 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7573 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7575 if (pService == &sDefault) {
7576 if (defaults_saved && is_default(i))
7577 continue;
7578 } else {
7579 if (equal_parameter(parm_table[i].type,
7580 ((char *)pService) +
7581 pdiff,
7582 ((char *)&sDefault) +
7583 pdiff))
7584 continue;
7587 fprintf(f, "\t%s = ", parm_table[i].label);
7588 print_parameter(&parm_table[i],
7589 ((char *)pService) + pdiff, f);
7590 fprintf(f, "\n");
7594 if (pService->param_opt != NULL) {
7595 data = pService->param_opt;
7596 while(data) {
7597 fprintf(f, "\t%s = %s\n", data->key, data->value);
7598 data = data->next;
7603 /***************************************************************************
7604 Display the contents of a parameter of a single services record.
7605 ***************************************************************************/
7607 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7609 int i;
7610 bool result = False;
7611 parm_class p_class;
7612 unsigned flag = 0;
7613 fstring local_parm_name;
7614 char *parm_opt;
7615 const char *parm_opt_value;
7617 /* check for parametrical option */
7618 fstrcpy( local_parm_name, parm_name);
7619 parm_opt = strchr( local_parm_name, ':');
7621 if (parm_opt) {
7622 *parm_opt = '\0';
7623 parm_opt++;
7624 if (strlen(parm_opt)) {
7625 parm_opt_value = lp_parm_const_string( snum,
7626 local_parm_name, parm_opt, NULL);
7627 if (parm_opt_value) {
7628 printf( "%s\n", parm_opt_value);
7629 result = True;
7632 return result;
7635 /* check for a key and print the value */
7636 if (isGlobal) {
7637 p_class = P_GLOBAL;
7638 flag = FLAG_GLOBAL;
7639 } else
7640 p_class = P_LOCAL;
7642 for (i = 0; parm_table[i].label; i++) {
7643 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7644 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7645 parm_table[i].ptr &&
7646 (*parm_table[i].label != '-') &&
7647 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7649 void *ptr;
7651 if (isGlobal) {
7652 ptr = parm_table[i].ptr;
7653 } else {
7654 struct service *pService = ServicePtrs[snum];
7655 ptr = ((char *)pService) +
7656 PTR_DIFF(parm_table[i].ptr, &sDefault);
7659 print_parameter(&parm_table[i],
7660 ptr, f);
7661 fprintf(f, "\n");
7662 result = True;
7663 break;
7667 return result;
7670 /***************************************************************************
7671 Return info about the requested parameter (given as a string).
7672 Return NULL when the string is not a valid parameter name.
7673 ***************************************************************************/
7675 struct parm_struct *lp_get_parameter(const char *param_name)
7677 int num = map_parameter(param_name);
7679 if (num < 0) {
7680 return NULL;
7683 return &parm_table[num];
7686 /***************************************************************************
7687 Return info about the next parameter in a service.
7688 snum==GLOBAL_SECTION_SNUM gives the globals.
7689 Return NULL when out of parameters.
7690 ***************************************************************************/
7692 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7694 if (snum < 0) {
7695 /* do the globals */
7696 for (; parm_table[*i].label; (*i)++) {
7697 if (parm_table[*i].p_class == P_SEPARATOR)
7698 return &parm_table[(*i)++];
7700 if (!parm_table[*i].ptr
7701 || (*parm_table[*i].label == '-'))
7702 continue;
7704 if ((*i) > 0
7705 && (parm_table[*i].ptr ==
7706 parm_table[(*i) - 1].ptr))
7707 continue;
7709 if (is_default(*i) && !allparameters)
7710 continue;
7712 return &parm_table[(*i)++];
7714 } else {
7715 struct service *pService = ServicePtrs[snum];
7717 for (; parm_table[*i].label; (*i)++) {
7718 if (parm_table[*i].p_class == P_SEPARATOR)
7719 return &parm_table[(*i)++];
7721 if (parm_table[*i].p_class == P_LOCAL &&
7722 parm_table[*i].ptr &&
7723 (*parm_table[*i].label != '-') &&
7724 ((*i) == 0 ||
7725 (parm_table[*i].ptr !=
7726 parm_table[(*i) - 1].ptr)))
7728 int pdiff =
7729 PTR_DIFF(parm_table[*i].ptr,
7730 &sDefault);
7732 if (allparameters ||
7733 !equal_parameter(parm_table[*i].type,
7734 ((char *)pService) +
7735 pdiff,
7736 ((char *)&sDefault) +
7737 pdiff))
7739 return &parm_table[(*i)++];
7745 return NULL;
7749 #if 0
7750 /***************************************************************************
7751 Display the contents of a single copy structure.
7752 ***************************************************************************/
7753 static void dump_copy_map(bool *pcopymap)
7755 int i;
7756 if (!pcopymap)
7757 return;
7759 printf("\n\tNon-Copied parameters:\n");
7761 for (i = 0; parm_table[i].label; i++)
7762 if (parm_table[i].p_class == P_LOCAL &&
7763 parm_table[i].ptr && !pcopymap[i] &&
7764 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7766 printf("\t\t%s\n", parm_table[i].label);
7769 #endif
7771 /***************************************************************************
7772 Return TRUE if the passed service number is within range.
7773 ***************************************************************************/
7775 bool lp_snum_ok(int iService)
7777 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7780 /***************************************************************************
7781 Auto-load some home services.
7782 ***************************************************************************/
7784 static void lp_add_auto_services(char *str)
7786 char *s;
7787 char *p;
7788 int homes;
7789 char *saveptr;
7791 if (!str)
7792 return;
7794 s = SMB_STRDUP(str);
7795 if (!s)
7796 return;
7798 homes = lp_servicenumber(HOMES_NAME);
7800 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7801 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7802 char *home;
7804 if (lp_servicenumber(p) >= 0)
7805 continue;
7807 home = get_user_home_dir(talloc_tos(), p);
7809 if (home && homes >= 0)
7810 lp_add_home(p, homes, p, home);
7812 TALLOC_FREE(home);
7814 SAFE_FREE(s);
7817 /***************************************************************************
7818 Auto-load one printer.
7819 ***************************************************************************/
7821 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
7823 int printers = lp_servicenumber(PRINTERS_NAME);
7824 int i;
7826 if (lp_servicenumber(name) < 0) {
7827 lp_add_printer(name, printers);
7828 if ((i = lp_servicenumber(name)) >= 0) {
7829 string_set(&ServicePtrs[i]->comment, comment);
7830 ServicePtrs[i]->autoloaded = True;
7835 /***************************************************************************
7836 Have we loaded a services file yet?
7837 ***************************************************************************/
7839 bool lp_loaded(void)
7841 return (bLoaded);
7844 /***************************************************************************
7845 Unload unused services.
7846 ***************************************************************************/
7848 void lp_killunused(bool (*snumused) (int))
7850 int i;
7851 for (i = 0; i < iNumServices; i++) {
7852 if (!VALID(i))
7853 continue;
7855 /* don't kill autoloaded or usershare services */
7856 if ( ServicePtrs[i]->autoloaded ||
7857 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7858 continue;
7861 if (!snumused || !snumused(i)) {
7862 free_service_byindex(i);
7868 * Kill all except autoloaded and usershare services - convenience wrapper
7870 void lp_kill_all_services(void)
7872 lp_killunused(NULL);
7875 /***************************************************************************
7876 Unload a service.
7877 ***************************************************************************/
7879 void lp_killservice(int iServiceIn)
7881 if (VALID(iServiceIn)) {
7882 free_service_byindex(iServiceIn);
7886 /***************************************************************************
7887 Save the curent values of all global and sDefault parameters into the
7888 defaults union. This allows swat and testparm to show only the
7889 changed (ie. non-default) parameters.
7890 ***************************************************************************/
7892 static void lp_save_defaults(void)
7894 int i;
7895 for (i = 0; parm_table[i].label; i++) {
7896 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7897 continue;
7898 switch (parm_table[i].type) {
7899 case P_LIST:
7900 str_list_copy(
7901 NULL, &(parm_table[i].def.lvalue),
7902 *(const char ***)parm_table[i].ptr);
7903 break;
7904 case P_STRING:
7905 case P_USTRING:
7906 if (parm_table[i].ptr) {
7907 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7908 } else {
7909 parm_table[i].def.svalue = NULL;
7911 break;
7912 case P_BOOL:
7913 case P_BOOLREV:
7914 parm_table[i].def.bvalue =
7915 *(bool *)parm_table[i].ptr;
7916 break;
7917 case P_CHAR:
7918 parm_table[i].def.cvalue =
7919 *(char *)parm_table[i].ptr;
7920 break;
7921 case P_INTEGER:
7922 case P_OCTAL:
7923 case P_ENUM:
7924 parm_table[i].def.ivalue =
7925 *(int *)parm_table[i].ptr;
7926 break;
7927 case P_SEP:
7928 break;
7931 defaults_saved = True;
7934 /*******************************************************************
7935 Set the server type we will announce as via nmbd.
7936 ********************************************************************/
7938 static const struct srv_role_tab {
7939 uint32 role;
7940 const char *role_str;
7941 } srv_role_tab [] = {
7942 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7943 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7944 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7945 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7946 { 0, NULL }
7949 const char* server_role_str(uint32 role)
7951 int i = 0;
7952 for (i=0; srv_role_tab[i].role_str; i++) {
7953 if (role == srv_role_tab[i].role) {
7954 return srv_role_tab[i].role_str;
7957 return NULL;
7960 static void set_server_role(void)
7962 server_role = ROLE_STANDALONE;
7964 switch (lp_security()) {
7965 case SEC_SHARE:
7966 if (lp_domain_logons())
7967 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7968 break;
7969 case SEC_SERVER:
7970 if (lp_domain_logons())
7971 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7972 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7973 server_role = ROLE_STANDALONE;
7974 break;
7975 case SEC_DOMAIN:
7976 if (lp_domain_logons()) {
7977 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7978 server_role = ROLE_DOMAIN_BDC;
7979 break;
7981 server_role = ROLE_DOMAIN_MEMBER;
7982 break;
7983 case SEC_ADS:
7984 if (lp_domain_logons()) {
7985 server_role = ROLE_DOMAIN_PDC;
7986 break;
7988 server_role = ROLE_DOMAIN_MEMBER;
7989 break;
7990 case SEC_USER:
7991 if (lp_domain_logons()) {
7993 if (Globals.iDomainMaster) /* auto or yes */
7994 server_role = ROLE_DOMAIN_PDC;
7995 else
7996 server_role = ROLE_DOMAIN_BDC;
7998 break;
7999 default:
8000 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8001 break;
8004 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8007 /***********************************************************
8008 If we should send plaintext/LANMAN passwords in the clinet
8009 ************************************************************/
8011 static void set_allowed_client_auth(void)
8013 if (Globals.bClientNTLMv2Auth) {
8014 Globals.bClientLanManAuth = False;
8016 if (!Globals.bClientLanManAuth) {
8017 Globals.bClientPlaintextAuth = False;
8021 /***************************************************************************
8022 JRA.
8023 The following code allows smbd to read a user defined share file.
8024 Yes, this is my intent. Yes, I'm comfortable with that...
8026 THE FOLLOWING IS SECURITY CRITICAL CODE.
8028 It washes your clothes, it cleans your house, it guards you while you sleep...
8029 Do not f%^k with it....
8030 ***************************************************************************/
8032 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8034 /***************************************************************************
8035 Check allowed stat state of a usershare file.
8036 Ensure we print out who is dicking with us so the admin can
8037 get their sorry ass fired.
8038 ***************************************************************************/
8040 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8042 if (!S_ISREG(psbuf->st_mode)) {
8043 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8044 "not a regular file\n",
8045 fname, (unsigned int)psbuf->st_uid ));
8046 return False;
8049 /* Ensure this doesn't have the other write bit set. */
8050 if (psbuf->st_mode & S_IWOTH) {
8051 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8052 "public write. Refusing to allow as a usershare file.\n",
8053 fname, (unsigned int)psbuf->st_uid ));
8054 return False;
8057 /* Should be 10k or less. */
8058 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8059 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8060 "too large (%u) to be a user share file.\n",
8061 fname, (unsigned int)psbuf->st_uid,
8062 (unsigned int)psbuf->st_size ));
8063 return False;
8066 return True;
8069 /***************************************************************************
8070 Parse the contents of a usershare file.
8071 ***************************************************************************/
8073 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8074 SMB_STRUCT_STAT *psbuf,
8075 const char *servicename,
8076 int snum,
8077 char **lines,
8078 int numlines,
8079 char **pp_sharepath,
8080 char **pp_comment,
8081 SEC_DESC **ppsd,
8082 bool *pallow_guest)
8084 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8085 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8086 int us_vers;
8087 SMB_STRUCT_DIR *dp;
8088 SMB_STRUCT_STAT sbuf;
8089 char *sharepath = NULL;
8090 char *comment = NULL;
8092 *pp_sharepath = NULL;
8093 *pp_comment = NULL;
8095 *pallow_guest = False;
8097 if (numlines < 4) {
8098 return USERSHARE_MALFORMED_FILE;
8101 if (strcmp(lines[0], "#VERSION 1") == 0) {
8102 us_vers = 1;
8103 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8104 us_vers = 2;
8105 if (numlines < 5) {
8106 return USERSHARE_MALFORMED_FILE;
8108 } else {
8109 return USERSHARE_BAD_VERSION;
8112 if (strncmp(lines[1], "path=", 5) != 0) {
8113 return USERSHARE_MALFORMED_PATH;
8116 sharepath = talloc_strdup(ctx, &lines[1][5]);
8117 if (!sharepath) {
8118 return USERSHARE_POSIX_ERR;
8120 trim_string(sharepath, " ", " ");
8122 if (strncmp(lines[2], "comment=", 8) != 0) {
8123 return USERSHARE_MALFORMED_COMMENT_DEF;
8126 comment = talloc_strdup(ctx, &lines[2][8]);
8127 if (!comment) {
8128 return USERSHARE_POSIX_ERR;
8130 trim_string(comment, " ", " ");
8131 trim_char(comment, '"', '"');
8133 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8134 return USERSHARE_MALFORMED_ACL_DEF;
8137 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8138 return USERSHARE_ACL_ERR;
8141 if (us_vers == 2) {
8142 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8143 return USERSHARE_MALFORMED_ACL_DEF;
8145 if (lines[4][9] == 'y') {
8146 *pallow_guest = True;
8150 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8151 /* Path didn't change, no checks needed. */
8152 *pp_sharepath = sharepath;
8153 *pp_comment = comment;
8154 return USERSHARE_OK;
8157 /* The path *must* be absolute. */
8158 if (sharepath[0] != '/') {
8159 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8160 servicename, sharepath));
8161 return USERSHARE_PATH_NOT_ABSOLUTE;
8164 /* If there is a usershare prefix deny list ensure one of these paths
8165 doesn't match the start of the user given path. */
8166 if (prefixdenylist) {
8167 int i;
8168 for ( i=0; prefixdenylist[i]; i++ ) {
8169 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8170 servicename, i, prefixdenylist[i], sharepath ));
8171 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8172 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8173 "usershare prefix deny list entries.\n",
8174 servicename, sharepath));
8175 return USERSHARE_PATH_IS_DENIED;
8180 /* If there is a usershare prefix allow list ensure one of these paths
8181 does match the start of the user given path. */
8183 if (prefixallowlist) {
8184 int i;
8185 for ( i=0; prefixallowlist[i]; i++ ) {
8186 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8187 servicename, i, prefixallowlist[i], sharepath ));
8188 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8189 break;
8192 if (prefixallowlist[i] == NULL) {
8193 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8194 "usershare prefix allow list entries.\n",
8195 servicename, sharepath));
8196 return USERSHARE_PATH_NOT_ALLOWED;
8200 /* Ensure this is pointing to a directory. */
8201 dp = sys_opendir(sharepath);
8203 if (!dp) {
8204 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8205 servicename, sharepath));
8206 return USERSHARE_PATH_NOT_DIRECTORY;
8209 /* Ensure the owner of the usershare file has permission to share
8210 this directory. */
8212 if (sys_stat(sharepath, &sbuf) == -1) {
8213 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8214 servicename, sharepath, strerror(errno) ));
8215 sys_closedir(dp);
8216 return USERSHARE_POSIX_ERR;
8219 sys_closedir(dp);
8221 if (!S_ISDIR(sbuf.st_mode)) {
8222 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8223 servicename, sharepath ));
8224 return USERSHARE_PATH_NOT_DIRECTORY;
8227 /* Check if sharing is restricted to owner-only. */
8228 /* psbuf is the stat of the usershare definition file,
8229 sbuf is the stat of the target directory to be shared. */
8231 if (lp_usershare_owner_only()) {
8232 /* root can share anything. */
8233 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8234 return USERSHARE_PATH_NOT_ALLOWED;
8238 *pp_sharepath = sharepath;
8239 *pp_comment = comment;
8240 return USERSHARE_OK;
8243 /***************************************************************************
8244 Deal with a usershare file.
8245 Returns:
8246 >= 0 - snum
8247 -1 - Bad name, invalid contents.
8248 - service name already existed and not a usershare, problem
8249 with permissions to share directory etc.
8250 ***************************************************************************/
8252 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8254 SMB_STRUCT_STAT sbuf;
8255 SMB_STRUCT_STAT lsbuf;
8256 char *fname = NULL;
8257 char *sharepath = NULL;
8258 char *comment = NULL;
8259 fstring service_name;
8260 char **lines = NULL;
8261 int numlines = 0;
8262 int fd = -1;
8263 int iService = -1;
8264 TALLOC_CTX *ctx = NULL;
8265 SEC_DESC *psd = NULL;
8266 bool guest_ok = False;
8268 /* Ensure share name doesn't contain invalid characters. */
8269 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8270 DEBUG(0,("process_usershare_file: share name %s contains "
8271 "invalid characters (any of %s)\n",
8272 file_name, INVALID_SHARENAME_CHARS ));
8273 return -1;
8276 fstrcpy(service_name, file_name);
8278 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8281 /* Minimize the race condition by doing an lstat before we
8282 open and fstat. Ensure this isn't a symlink link. */
8284 if (sys_lstat(fname, &lsbuf) != 0) {
8285 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8286 fname, strerror(errno) ));
8287 SAFE_FREE(fname);
8288 return -1;
8291 /* This must be a regular file, not a symlink, directory or
8292 other strange filetype. */
8293 if (!check_usershare_stat(fname, &lsbuf)) {
8294 SAFE_FREE(fname);
8295 return -1;
8299 char *canon_name = canonicalize_servicename(service_name);
8300 TDB_DATA data = dbwrap_fetch_bystring(
8301 ServiceHash, canon_name, canon_name);
8303 iService = -1;
8305 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8306 iService = *(int *)data.dptr;
8308 TALLOC_FREE(canon_name);
8311 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8312 /* Nothing changed - Mark valid and return. */
8313 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8314 service_name ));
8315 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8316 SAFE_FREE(fname);
8317 return iService;
8320 /* Try and open the file read only - no symlinks allowed. */
8321 #ifdef O_NOFOLLOW
8322 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8323 #else
8324 fd = sys_open(fname, O_RDONLY, 0);
8325 #endif
8327 if (fd == -1) {
8328 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8329 fname, strerror(errno) ));
8330 SAFE_FREE(fname);
8331 return -1;
8334 /* Now fstat to be *SURE* it's a regular file. */
8335 if (sys_fstat(fd, &sbuf) != 0) {
8336 close(fd);
8337 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8338 fname, strerror(errno) ));
8339 SAFE_FREE(fname);
8340 return -1;
8343 /* Is it the same dev/inode as was lstated ? */
8344 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8345 close(fd);
8346 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8347 "Symlink spoofing going on ?\n", fname ));
8348 SAFE_FREE(fname);
8349 return -1;
8352 /* This must be a regular file, not a symlink, directory or
8353 other strange filetype. */
8354 if (!check_usershare_stat(fname, &sbuf)) {
8355 SAFE_FREE(fname);
8356 return -1;
8359 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8361 close(fd);
8362 if (lines == NULL) {
8363 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8364 fname, (unsigned int)sbuf.st_uid ));
8365 SAFE_FREE(fname);
8366 return -1;
8369 SAFE_FREE(fname);
8371 /* Should we allow printers to be shared... ? */
8372 ctx = talloc_init("usershare_sd_xctx");
8373 if (!ctx) {
8374 file_lines_free(lines);
8375 return 1;
8378 if (parse_usershare_file(ctx, &sbuf, service_name,
8379 iService, lines, numlines, &sharepath,
8380 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8381 talloc_destroy(ctx);
8382 file_lines_free(lines);
8383 return -1;
8386 file_lines_free(lines);
8388 /* Everything ok - add the service possibly using a template. */
8389 if (iService < 0) {
8390 const struct service *sp = &sDefault;
8391 if (snum_template != -1) {
8392 sp = ServicePtrs[snum_template];
8395 if ((iService = add_a_service(sp, service_name)) < 0) {
8396 DEBUG(0, ("process_usershare_file: Failed to add "
8397 "new service %s\n", service_name));
8398 talloc_destroy(ctx);
8399 return -1;
8402 /* Read only is controlled by usershare ACL below. */
8403 ServicePtrs[iService]->bRead_only = False;
8406 /* Write the ACL of the new/modified share. */
8407 if (!set_share_security(service_name, psd)) {
8408 DEBUG(0, ("process_usershare_file: Failed to set share "
8409 "security for user share %s\n",
8410 service_name ));
8411 lp_remove_service(iService);
8412 talloc_destroy(ctx);
8413 return -1;
8416 /* If from a template it may be marked invalid. */
8417 ServicePtrs[iService]->valid = True;
8419 /* Set the service as a valid usershare. */
8420 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8422 /* Set guest access. */
8423 if (lp_usershare_allow_guests()) {
8424 ServicePtrs[iService]->bGuest_ok = guest_ok;
8427 /* And note when it was loaded. */
8428 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8429 string_set(&ServicePtrs[iService]->szPath, sharepath);
8430 string_set(&ServicePtrs[iService]->comment, comment);
8432 talloc_destroy(ctx);
8434 return iService;
8437 /***************************************************************************
8438 Checks if a usershare entry has been modified since last load.
8439 ***************************************************************************/
8441 static bool usershare_exists(int iService, time_t *last_mod)
8443 SMB_STRUCT_STAT lsbuf;
8444 const char *usersharepath = Globals.szUsersharePath;
8445 char *fname;
8447 if (asprintf(&fname, "%s/%s",
8448 usersharepath,
8449 ServicePtrs[iService]->szService) < 0) {
8450 return false;
8453 if (sys_lstat(fname, &lsbuf) != 0) {
8454 SAFE_FREE(fname);
8455 return false;
8458 if (!S_ISREG(lsbuf.st_mode)) {
8459 SAFE_FREE(fname);
8460 return false;
8463 SAFE_FREE(fname);
8464 *last_mod = lsbuf.st_mtime;
8465 return true;
8468 /***************************************************************************
8469 Load a usershare service by name. Returns a valid servicenumber or -1.
8470 ***************************************************************************/
8472 int load_usershare_service(const char *servicename)
8474 SMB_STRUCT_STAT sbuf;
8475 const char *usersharepath = Globals.szUsersharePath;
8476 int max_user_shares = Globals.iUsershareMaxShares;
8477 int snum_template = -1;
8479 if (*usersharepath == 0 || max_user_shares == 0) {
8480 return -1;
8483 if (sys_stat(usersharepath, &sbuf) != 0) {
8484 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8485 usersharepath, strerror(errno) ));
8486 return -1;
8489 if (!S_ISDIR(sbuf.st_mode)) {
8490 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8491 usersharepath ));
8492 return -1;
8496 * This directory must be owned by root, and have the 't' bit set.
8497 * It also must not be writable by "other".
8500 #ifdef S_ISVTX
8501 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8502 #else
8503 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8504 #endif
8505 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8506 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8507 usersharepath ));
8508 return -1;
8511 /* Ensure the template share exists if it's set. */
8512 if (Globals.szUsershareTemplateShare[0]) {
8513 /* We can't use lp_servicenumber here as we are recommending that
8514 template shares have -valid=False set. */
8515 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8516 if (ServicePtrs[snum_template]->szService &&
8517 strequal(ServicePtrs[snum_template]->szService,
8518 Globals.szUsershareTemplateShare)) {
8519 break;
8523 if (snum_template == -1) {
8524 DEBUG(0,("load_usershare_service: usershare template share %s "
8525 "does not exist.\n",
8526 Globals.szUsershareTemplateShare ));
8527 return -1;
8531 return process_usershare_file(usersharepath, servicename, snum_template);
8534 /***************************************************************************
8535 Load all user defined shares from the user share directory.
8536 We only do this if we're enumerating the share list.
8537 This is the function that can delete usershares that have
8538 been removed.
8539 ***************************************************************************/
8541 int load_usershare_shares(void)
8543 SMB_STRUCT_DIR *dp;
8544 SMB_STRUCT_STAT sbuf;
8545 SMB_STRUCT_DIRENT *de;
8546 int num_usershares = 0;
8547 int max_user_shares = Globals.iUsershareMaxShares;
8548 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8549 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8550 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8551 int iService;
8552 int snum_template = -1;
8553 const char *usersharepath = Globals.szUsersharePath;
8554 int ret = lp_numservices();
8556 if (max_user_shares == 0 || *usersharepath == '\0') {
8557 return lp_numservices();
8560 if (sys_stat(usersharepath, &sbuf) != 0) {
8561 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8562 usersharepath, strerror(errno) ));
8563 return ret;
8567 * This directory must be owned by root, and have the 't' bit set.
8568 * It also must not be writable by "other".
8571 #ifdef S_ISVTX
8572 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8573 #else
8574 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8575 #endif
8576 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8577 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8578 usersharepath ));
8579 return ret;
8582 /* Ensure the template share exists if it's set. */
8583 if (Globals.szUsershareTemplateShare[0]) {
8584 /* We can't use lp_servicenumber here as we are recommending that
8585 template shares have -valid=False set. */
8586 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8587 if (ServicePtrs[snum_template]->szService &&
8588 strequal(ServicePtrs[snum_template]->szService,
8589 Globals.szUsershareTemplateShare)) {
8590 break;
8594 if (snum_template == -1) {
8595 DEBUG(0,("load_usershare_shares: usershare template share %s "
8596 "does not exist.\n",
8597 Globals.szUsershareTemplateShare ));
8598 return ret;
8602 /* Mark all existing usershares as pending delete. */
8603 for (iService = iNumServices - 1; iService >= 0; iService--) {
8604 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8605 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8609 dp = sys_opendir(usersharepath);
8610 if (!dp) {
8611 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8612 usersharepath, strerror(errno) ));
8613 return ret;
8616 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8617 (de = sys_readdir(dp));
8618 num_dir_entries++ ) {
8619 int r;
8620 const char *n = de->d_name;
8622 /* Ignore . and .. */
8623 if (*n == '.') {
8624 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8625 continue;
8629 if (n[0] == ':') {
8630 /* Temporary file used when creating a share. */
8631 num_tmp_dir_entries++;
8634 /* Allow 20% tmp entries. */
8635 if (num_tmp_dir_entries > allowed_tmp_entries) {
8636 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8637 "in directory %s\n",
8638 num_tmp_dir_entries, usersharepath));
8639 break;
8642 r = process_usershare_file(usersharepath, n, snum_template);
8643 if (r == 0) {
8644 /* Update the services count. */
8645 num_usershares++;
8646 if (num_usershares >= max_user_shares) {
8647 DEBUG(0,("load_usershare_shares: max user shares reached "
8648 "on file %s in directory %s\n",
8649 n, usersharepath ));
8650 break;
8652 } else if (r == -1) {
8653 num_bad_dir_entries++;
8656 /* Allow 20% bad entries. */
8657 if (num_bad_dir_entries > allowed_bad_entries) {
8658 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8659 "in directory %s\n",
8660 num_bad_dir_entries, usersharepath));
8661 break;
8664 /* Allow 20% bad entries. */
8665 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8666 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8667 "in directory %s\n",
8668 num_dir_entries, usersharepath));
8669 break;
8673 sys_closedir(dp);
8675 /* Sweep through and delete any non-refreshed usershares that are
8676 not currently in use. */
8677 for (iService = iNumServices - 1; iService >= 0; iService--) {
8678 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8679 if (conn_snum_used(iService)) {
8680 continue;
8682 /* Remove from the share ACL db. */
8683 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8684 lp_servicename(iService) ));
8685 delete_share_security(lp_servicename(iService));
8686 free_service_byindex(iService);
8690 return lp_numservices();
8693 /********************************************************
8694 Destroy global resources allocated in this file
8695 ********************************************************/
8697 void gfree_loadparm(void)
8699 struct file_lists *f;
8700 struct file_lists *next;
8701 int i;
8703 /* Free the file lists */
8705 f = file_lists;
8706 while( f ) {
8707 next = f->next;
8708 SAFE_FREE( f->name );
8709 SAFE_FREE( f->subfname );
8710 SAFE_FREE( f );
8711 f = next;
8713 file_lists = NULL;
8715 /* Free resources allocated to services */
8717 for ( i = 0; i < iNumServices; i++ ) {
8718 if ( VALID(i) ) {
8719 free_service_byindex(i);
8723 SAFE_FREE( ServicePtrs );
8724 iNumServices = 0;
8726 /* Now release all resources allocated to global
8727 parameters and the default service */
8729 for (i = 0; parm_table[i].label; i++)
8731 if ( parm_table[i].type == P_STRING
8732 || parm_table[i].type == P_USTRING )
8734 string_free( (char**)parm_table[i].ptr );
8736 else if (parm_table[i].type == P_LIST) {
8737 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8743 /***************************************************************************
8744 Allow client apps to specify that they are a client
8745 ***************************************************************************/
8746 void lp_set_in_client(bool b)
8748 in_client = b;
8752 /***************************************************************************
8753 Determine if we're running in a client app
8754 ***************************************************************************/
8755 bool lp_is_in_client(void)
8757 return in_client;
8763 /***************************************************************************
8764 Load the services array from the services file. Return True on success,
8765 False on failure.
8766 ***************************************************************************/
8768 bool lp_load_ex(const char *pszFname,
8769 bool global_only,
8770 bool save_defaults,
8771 bool add_ipc,
8772 bool initialize_globals,
8773 bool allow_include_registry,
8774 bool allow_registry_shares)
8776 char *n2 = NULL;
8777 bool bRetval;
8778 struct param_opt_struct *data, *pdata;
8780 bRetval = False;
8782 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8784 bInGlobalSection = True;
8785 bGlobalOnly = global_only;
8786 bAllowIncludeRegistry = allow_include_registry;
8788 init_globals(! initialize_globals);
8789 debug_init();
8791 if (save_defaults) {
8792 init_locals();
8793 lp_save_defaults();
8796 /* We get sections first, so have to start 'behind' to make up */
8797 iServiceIndex = -1;
8799 if (Globals.param_opt != NULL) {
8800 data = Globals.param_opt;
8801 while (data) {
8802 string_free(&data->key);
8803 string_free(&data->value);
8804 TALLOC_FREE(data->list);
8805 pdata = data->next;
8806 SAFE_FREE(data);
8807 data = pdata;
8809 Globals.param_opt = NULL;
8812 if (lp_config_backend_is_file()) {
8813 n2 = alloc_sub_basic(get_current_username(),
8814 current_user_info.domain,
8815 pszFname);
8816 if (!n2) {
8817 smb_panic("lp_load_ex: out of memory");
8820 add_to_file_list(pszFname, n2);
8822 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8823 SAFE_FREE(n2);
8825 /* finish up the last section */
8826 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8827 if (bRetval) {
8828 if (iServiceIndex >= 0) {
8829 bRetval = service_ok(iServiceIndex);
8833 if (lp_config_backend_is_registry()) {
8834 /* config backend changed to registry in config file */
8836 * We need to use this extra global variable here to
8837 * survive restart: init_globals uses this as a default
8838 * for ConfigBackend. Otherwise, init_globals would
8839 * send us into an endless loop here.
8841 config_backend = CONFIG_BACKEND_REGISTRY;
8842 /* start over */
8843 DEBUG(1, ("lp_load_ex: changing to config backend "
8844 "registry\n"));
8845 init_globals(false);
8846 lp_kill_all_services();
8847 return lp_load_ex(pszFname, global_only, save_defaults,
8848 add_ipc, initialize_globals,
8849 allow_include_registry,
8850 allow_registry_shares);
8852 } else if (lp_config_backend_is_registry()) {
8853 bRetval = process_registry_globals();
8854 } else {
8855 DEBUG(0, ("Illegal config backend given: %d\n",
8856 lp_config_backend()));
8857 bRetval = false;
8860 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8861 bRetval = process_registry_shares();
8864 lp_add_auto_services(lp_auto_services());
8866 if (add_ipc) {
8867 /* When 'restrict anonymous = 2' guest connections to ipc$
8868 are denied */
8869 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8870 if ( lp_enable_asu_support() ) {
8871 lp_add_ipc("ADMIN$", false);
8875 set_server_role();
8876 set_default_server_announce_type();
8877 set_allowed_client_auth();
8879 bLoaded = True;
8881 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8882 /* if bWINSsupport is true and we are in the client */
8883 if (lp_is_in_client() && Globals.bWINSsupport) {
8884 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8887 init_iconv();
8889 bAllowIncludeRegistry = true;
8891 return (bRetval);
8894 bool lp_load(const char *pszFname,
8895 bool global_only,
8896 bool save_defaults,
8897 bool add_ipc,
8898 bool initialize_globals)
8900 return lp_load_ex(pszFname,
8901 global_only,
8902 save_defaults,
8903 add_ipc,
8904 initialize_globals,
8905 true, false);
8908 bool lp_load_initial_only(const char *pszFname)
8910 return lp_load_ex(pszFname,
8911 true,
8912 false,
8913 false,
8914 true,
8915 false,
8916 false);
8919 bool lp_load_with_registry_shares(const char *pszFname,
8920 bool global_only,
8921 bool save_defaults,
8922 bool add_ipc,
8923 bool initialize_globals)
8925 return lp_load_ex(pszFname,
8926 global_only,
8927 save_defaults,
8928 add_ipc,
8929 initialize_globals,
8930 true,
8931 true);
8934 /***************************************************************************
8935 Return the max number of services.
8936 ***************************************************************************/
8938 int lp_numservices(void)
8940 return (iNumServices);
8943 /***************************************************************************
8944 Display the contents of the services array in human-readable form.
8945 ***************************************************************************/
8947 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8949 int iService;
8951 if (show_defaults)
8952 defaults_saved = False;
8954 dump_globals(f);
8956 dump_a_service(&sDefault, f);
8958 for (iService = 0; iService < maxtoprint; iService++) {
8959 fprintf(f,"\n");
8960 lp_dump_one(f, show_defaults, iService);
8964 /***************************************************************************
8965 Display the contents of one service in human-readable form.
8966 ***************************************************************************/
8968 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8970 if (VALID(snum)) {
8971 if (ServicePtrs[snum]->szService[0] == '\0')
8972 return;
8973 dump_a_service(ServicePtrs[snum], f);
8977 /***************************************************************************
8978 Return the number of the service with the given name, or -1 if it doesn't
8979 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8980 getservicebyname()! This works ONLY if all services have been loaded, and
8981 does not copy the found service.
8982 ***************************************************************************/
8984 int lp_servicenumber(const char *pszServiceName)
8986 int iService;
8987 fstring serviceName;
8989 if (!pszServiceName) {
8990 return GLOBAL_SECTION_SNUM;
8993 for (iService = iNumServices - 1; iService >= 0; iService--) {
8994 if (VALID(iService) && ServicePtrs[iService]->szService) {
8996 * The substitution here is used to support %U is
8997 * service names
8999 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9000 standard_sub_basic(get_current_username(),
9001 current_user_info.domain,
9002 serviceName,sizeof(serviceName));
9003 if (strequal(serviceName, pszServiceName)) {
9004 break;
9009 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9010 time_t last_mod;
9012 if (!usershare_exists(iService, &last_mod)) {
9013 /* Remove the share security tdb entry for it. */
9014 delete_share_security(lp_servicename(iService));
9015 /* Remove it from the array. */
9016 free_service_byindex(iService);
9017 /* Doesn't exist anymore. */
9018 return GLOBAL_SECTION_SNUM;
9021 /* Has it been modified ? If so delete and reload. */
9022 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9023 /* Remove it from the array. */
9024 free_service_byindex(iService);
9025 /* and now reload it. */
9026 iService = load_usershare_service(pszServiceName);
9030 if (iService < 0) {
9031 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9032 return GLOBAL_SECTION_SNUM;
9035 return (iService);
9038 bool share_defined(const char *service_name)
9040 return (lp_servicenumber(service_name) != -1);
9043 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9044 const char *sharename)
9046 struct share_params *result;
9047 char *sname;
9048 int snum;
9050 if (!(sname = SMB_STRDUP(sharename))) {
9051 return NULL;
9054 snum = find_service(sname);
9055 SAFE_FREE(sname);
9057 if (snum < 0) {
9058 return NULL;
9061 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9062 DEBUG(0, ("talloc failed\n"));
9063 return NULL;
9066 result->service = snum;
9067 return result;
9070 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9072 struct share_iterator *result;
9074 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9075 DEBUG(0, ("talloc failed\n"));
9076 return NULL;
9079 result->next_id = 0;
9080 return result;
9083 struct share_params *next_share(struct share_iterator *list)
9085 struct share_params *result;
9087 while (!lp_snum_ok(list->next_id) &&
9088 (list->next_id < lp_numservices())) {
9089 list->next_id += 1;
9092 if (list->next_id >= lp_numservices()) {
9093 return NULL;
9096 if (!(result = TALLOC_P(list, struct share_params))) {
9097 DEBUG(0, ("talloc failed\n"));
9098 return NULL;
9101 result->service = list->next_id;
9102 list->next_id += 1;
9103 return result;
9106 struct share_params *next_printer(struct share_iterator *list)
9108 struct share_params *result;
9110 while ((result = next_share(list)) != NULL) {
9111 if (lp_print_ok(result->service)) {
9112 break;
9115 return result;
9119 * This is a hack for a transition period until we transformed all code from
9120 * service numbers to struct share_params.
9123 struct share_params *snum2params_static(int snum)
9125 static struct share_params result;
9126 result.service = snum;
9127 return &result;
9130 /*******************************************************************
9131 A useful volume label function.
9132 ********************************************************************/
9134 const char *volume_label(int snum)
9136 char *ret;
9137 const char *label = lp_volume(snum);
9138 if (!*label) {
9139 label = lp_servicename(snum);
9142 /* This returns a 33 byte guarenteed null terminated string. */
9143 ret = talloc_strndup(talloc_tos(), label, 32);
9144 if (!ret) {
9145 return "";
9147 return ret;
9150 /*******************************************************************
9151 Set the server type we will announce as via nmbd.
9152 ********************************************************************/
9154 static void set_default_server_announce_type(void)
9156 default_server_announce = 0;
9157 default_server_announce |= SV_TYPE_WORKSTATION;
9158 default_server_announce |= SV_TYPE_SERVER;
9159 default_server_announce |= SV_TYPE_SERVER_UNIX;
9161 /* note that the flag should be set only if we have a
9162 printer service but nmbd doesn't actually load the
9163 services so we can't tell --jerry */
9165 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9167 switch (lp_announce_as()) {
9168 case ANNOUNCE_AS_NT_SERVER:
9169 default_server_announce |= SV_TYPE_SERVER_NT;
9170 /* fall through... */
9171 case ANNOUNCE_AS_NT_WORKSTATION:
9172 default_server_announce |= SV_TYPE_NT;
9173 break;
9174 case ANNOUNCE_AS_WIN95:
9175 default_server_announce |= SV_TYPE_WIN95_PLUS;
9176 break;
9177 case ANNOUNCE_AS_WFW:
9178 default_server_announce |= SV_TYPE_WFW;
9179 break;
9180 default:
9181 break;
9184 switch (lp_server_role()) {
9185 case ROLE_DOMAIN_MEMBER:
9186 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9187 break;
9188 case ROLE_DOMAIN_PDC:
9189 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9190 break;
9191 case ROLE_DOMAIN_BDC:
9192 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9193 break;
9194 case ROLE_STANDALONE:
9195 default:
9196 break;
9198 if (lp_time_server())
9199 default_server_announce |= SV_TYPE_TIME_SOURCE;
9201 if (lp_host_msdfs())
9202 default_server_announce |= SV_TYPE_DFS_SERVER;
9205 /***********************************************************
9206 returns role of Samba server
9207 ************************************************************/
9209 int lp_server_role(void)
9211 return server_role;
9214 /***********************************************************
9215 If we are PDC then prefer us as DMB
9216 ************************************************************/
9218 bool lp_domain_master(void)
9220 if (Globals.iDomainMaster == Auto)
9221 return (lp_server_role() == ROLE_DOMAIN_PDC);
9223 return (bool)Globals.iDomainMaster;
9226 /***********************************************************
9227 If we are DMB then prefer us as LMB
9228 ************************************************************/
9230 bool lp_preferred_master(void)
9232 if (Globals.iPreferredMaster == Auto)
9233 return (lp_local_master() && lp_domain_master());
9235 return (bool)Globals.iPreferredMaster;
9238 /*******************************************************************
9239 Remove a service.
9240 ********************************************************************/
9242 void lp_remove_service(int snum)
9244 ServicePtrs[snum]->valid = False;
9245 invalid_services[num_invalid_services++] = snum;
9248 /*******************************************************************
9249 Copy a service.
9250 ********************************************************************/
9252 void lp_copy_service(int snum, const char *new_name)
9254 do_section(new_name, NULL);
9255 if (snum >= 0) {
9256 snum = lp_servicenumber(new_name);
9257 if (snum >= 0)
9258 lp_do_parameter(snum, "copy", lp_servicename(snum));
9263 /*******************************************************************
9264 Get the default server type we will announce as via nmbd.
9265 ********************************************************************/
9267 int lp_default_server_announce(void)
9269 return default_server_announce;
9272 /*******************************************************************
9273 Split the announce version into major and minor numbers.
9274 ********************************************************************/
9276 int lp_major_announce_version(void)
9278 static bool got_major = False;
9279 static int major_version = DEFAULT_MAJOR_VERSION;
9280 char *vers;
9281 char *p;
9283 if (got_major)
9284 return major_version;
9286 got_major = True;
9287 if ((vers = lp_announce_version()) == NULL)
9288 return major_version;
9290 if ((p = strchr_m(vers, '.')) == 0)
9291 return major_version;
9293 *p = '\0';
9294 major_version = atoi(vers);
9295 return major_version;
9298 int lp_minor_announce_version(void)
9300 static bool got_minor = False;
9301 static int minor_version = DEFAULT_MINOR_VERSION;
9302 char *vers;
9303 char *p;
9305 if (got_minor)
9306 return minor_version;
9308 got_minor = True;
9309 if ((vers = lp_announce_version()) == NULL)
9310 return minor_version;
9312 if ((p = strchr_m(vers, '.')) == 0)
9313 return minor_version;
9315 p++;
9316 minor_version = atoi(p);
9317 return minor_version;
9320 /***********************************************************
9321 Set the global name resolution order (used in smbclient).
9322 ************************************************************/
9324 void lp_set_name_resolve_order(const char *new_order)
9326 string_set(&Globals.szNameResolveOrder, new_order);
9329 const char *lp_printername(int snum)
9331 const char *ret = _lp_printername(snum);
9332 if (ret == NULL || (ret != NULL && *ret == '\0'))
9333 ret = lp_const_servicename(snum);
9335 return ret;
9339 /***********************************************************
9340 Allow daemons such as winbindd to fix their logfile name.
9341 ************************************************************/
9343 void lp_set_logfile(const char *name)
9345 string_set(&Globals.szLogFile, name);
9346 debug_set_logfile(name);
9349 /*******************************************************************
9350 Return the max print jobs per queue.
9351 ********************************************************************/
9353 int lp_maxprintjobs(int snum)
9355 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9356 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9357 maxjobs = PRINT_MAX_JOBID - 1;
9359 return maxjobs;
9362 const char *lp_printcapname(void)
9364 if ((Globals.szPrintcapname != NULL) &&
9365 (Globals.szPrintcapname[0] != '\0'))
9366 return Globals.szPrintcapname;
9368 if (sDefault.iPrinting == PRINT_CUPS) {
9369 #ifdef HAVE_CUPS
9370 return "cups";
9371 #else
9372 return "lpstat";
9373 #endif
9376 if (sDefault.iPrinting == PRINT_BSD)
9377 return "/etc/printcap";
9379 return PRINTCAP_NAME;
9382 /*******************************************************************
9383 Ensure we don't use sendfile if server smb signing is active.
9384 ********************************************************************/
9386 static uint32 spoolss_state;
9388 bool lp_disable_spoolss( void )
9390 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9391 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9393 return spoolss_state == SVCCTL_STOPPED ? True : False;
9396 void lp_set_spoolss_state( uint32 state )
9398 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9400 spoolss_state = state;
9403 uint32 lp_get_spoolss_state( void )
9405 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9408 /*******************************************************************
9409 Ensure we don't use sendfile if server smb signing is active.
9410 ********************************************************************/
9412 bool lp_use_sendfile(int snum)
9414 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9415 if (Protocol < PROTOCOL_NT1) {
9416 return False;
9418 return (_lp_use_sendfile(snum) &&
9419 (get_remote_arch() != RA_WIN95) &&
9420 !srv_is_signing_active());
9423 /*******************************************************************
9424 Turn off sendfile if we find the underlying OS doesn't support it.
9425 ********************************************************************/
9427 void set_use_sendfile(int snum, bool val)
9429 if (LP_SNUM_OK(snum))
9430 ServicePtrs[snum]->bUseSendfile = val;
9431 else
9432 sDefault.bUseSendfile = val;
9435 /*******************************************************************
9436 Turn off storing DOS attributes if this share doesn't support it.
9437 ********************************************************************/
9439 void set_store_dos_attributes(int snum, bool val)
9441 if (!LP_SNUM_OK(snum))
9442 return;
9443 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9446 void lp_set_mangling_method(const char *new_method)
9448 string_set(&Globals.szManglingMethod, new_method);
9451 /*******************************************************************
9452 Global state for POSIX pathname processing.
9453 ********************************************************************/
9455 static bool posix_pathnames;
9457 bool lp_posix_pathnames(void)
9459 return posix_pathnames;
9462 /*******************************************************************
9463 Change everything needed to ensure POSIX pathname processing (currently
9464 not much).
9465 ********************************************************************/
9467 void lp_set_posix_pathnames(void)
9469 posix_pathnames = True;
9472 /*******************************************************************
9473 Global state for POSIX lock processing - CIFS unix extensions.
9474 ********************************************************************/
9476 bool posix_default_lock_was_set;
9477 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9479 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9481 if (posix_default_lock_was_set) {
9482 return posix_cifsx_locktype;
9483 } else {
9484 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9488 /*******************************************************************
9489 ********************************************************************/
9491 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9493 posix_default_lock_was_set = True;
9494 posix_cifsx_locktype = val;
9497 int lp_min_receive_file_size(void)
9499 if (Globals.iminreceivefile < 0) {
9500 return 0;
9502 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9505 /*******************************************************************
9506 If socket address is an empty character string, it is necessary to
9507 define it as "0.0.0.0".
9508 ********************************************************************/
9510 const char *lp_socket_address(void)
9512 char *sock_addr = Globals.szSocketAddress;
9514 if (sock_addr[0] == '\0'){
9515 string_set(&Globals.szSocketAddress, "0.0.0.0");
9517 return Globals.szSocketAddress;