Remove "strict allocate = partial" code that got accidentally committed.
[Samba.git] / source / param / loadparm.c
blobaa41bf961568908ff31d85dc75cd264a0973ac05
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"
56 bool bLoaded = False;
58 extern enum protocol_types Protocol;
59 extern userdom_struct current_user_info;
61 #ifndef GLOBAL_NAME
62 #define GLOBAL_NAME "global"
63 #endif
65 #ifndef PRINTERS_NAME
66 #define PRINTERS_NAME "printers"
67 #endif
69 #ifndef HOMES_NAME
70 #define HOMES_NAME "homes"
71 #endif
73 /* the special value for the include parameter
74 * to be interpreted not as a file name but to
75 * trigger loading of the global smb.conf options
76 * from registry. */
77 #ifndef INCLUDE_REGISTRY_NAME
78 #define INCLUDE_REGISTRY_NAME "registry"
79 #endif
81 static bool in_client = False; /* Not in the client by default */
82 static struct smbconf_csn conf_last_csn;
84 #define CONFIG_BACKEND_FILE 0
85 #define CONFIG_BACKEND_REGISTRY 1
87 static int config_backend = CONFIG_BACKEND_FILE;
89 /* some helpful bits */
90 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
91 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
93 #define USERSHARE_VALID 1
94 #define USERSHARE_PENDING_DELETE 2
96 extern int extra_time_offset;
98 static bool defaults_saved = False;
100 typedef struct _param_opt_struct param_opt_struct;
101 struct _param_opt_struct {
102 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 **szIdmapDomains;
199 char **szIdmapBackend; /* deprecated */
200 char *szIdmapAllocBackend;
201 char *szAddShareCommand;
202 char *szChangeShareCommand;
203 char *szDeleteShareCommand;
204 char **szEventLogs;
205 char *szGuestaccount;
206 char *szManglingMethod;
207 char **szServicesList;
208 char *szUsersharePath;
209 char *szUsershareTemplateShare;
210 char **szUsersharePrefixAllowList;
211 char **szUsersharePrefixDenyList;
212 int mangle_prefix;
213 int max_log_size;
214 char *szLogLevel;
215 int max_xmit;
216 int max_mux;
217 int max_open_files;
218 int open_files_db_hash_size;
219 int pwordlevel;
220 int unamelevel;
221 int deadtime;
222 bool getwd_cache;
223 int maxprotocol;
224 int minprotocol;
225 int security;
226 char **AuthMethods;
227 bool paranoid_server_security;
228 int maxdisksize;
229 int lpqcachetime;
230 int iMaxSmbdProcesses;
231 bool bDisableSpoolss;
232 int syslog;
233 int os_level;
234 bool enhanced_browsing;
235 int max_ttl;
236 int max_wins_ttl;
237 int min_wins_ttl;
238 int lm_announce;
239 int lm_interval;
240 int announce_as; /* This is initialised in init_globals */
241 int machine_password_timeout;
242 int map_to_guest;
243 int oplock_break_wait_time;
244 int winbind_cache_time;
245 int winbind_max_idle_children;
246 char **szWinbindNssInfo;
247 int iLockSpinTime;
248 char *szLdapMachineSuffix;
249 char *szLdapUserSuffix;
250 char *szLdapIdmapSuffix;
251 char *szLdapGroupSuffix;
252 int ldap_ssl;
253 char *szLdapSuffix;
254 char *szLdapAdminDn;
255 int ldap_debug_level;
256 int ldap_debug_threshold;
257 int iAclCompat;
258 char *szCupsServer;
259 char *szIPrintServer;
260 char *ctdbdSocket;
261 char **szClusterAddresses;
262 bool clustering;
263 int ldap_passwd_sync;
264 int ldap_replication_sleep;
265 int ldap_timeout; /* This is initialised in init_globals */
266 int ldap_connection_timeout;
267 int ldap_page_size;
268 bool ldap_delete_dn;
269 bool bMsAddPrinterWizard;
270 bool bDNSproxy;
271 bool bWINSsupport;
272 bool bWINSproxy;
273 bool bLocalMaster;
274 int iPreferredMaster;
275 int iDomainMaster;
276 bool bDomainLogons;
277 bool bEncryptPasswords;
278 bool bUpdateEncrypt;
279 int clientSchannel;
280 int serverSchannel;
281 bool bNullPasswords;
282 bool bObeyPamRestrictions;
283 bool bLoadPrinters;
284 int PrintcapCacheTime;
285 bool bLargeReadwrite;
286 bool bReadRaw;
287 bool bWriteRaw;
288 bool bSyslogOnly;
289 bool bBrowseList;
290 bool bNISHomeMap;
291 bool bTimeServer;
292 bool bBindInterfacesOnly;
293 bool bPamPasswordChange;
294 bool bUnixPasswdSync;
295 bool bPasswdChatDebug;
296 int iPasswdChatTimeout;
297 bool bTimestampLogs;
298 bool bNTSmbSupport;
299 bool bNTPipeSupport;
300 bool bNTStatusSupport;
301 bool bStatCache;
302 int iMaxStatCacheSize;
303 bool bKernelOplocks;
304 bool bAllowTrustedDomains;
305 bool bLanmanAuth;
306 bool bNTLMAuth;
307 bool bUseSpnego;
308 bool bClientLanManAuth;
309 bool bClientNTLMv2Auth;
310 bool bClientPlaintextAuth;
311 bool bClientUseSpnego;
312 bool bDebugPrefixTimestamp;
313 bool bDebugHiresTimestamp;
314 bool bDebugPid;
315 bool bDebugUid;
316 bool bDebugClass;
317 bool bEnableCoreFiles;
318 bool bHostMSDfs;
319 bool bUseMmap;
320 bool bHostnameLookups;
321 bool bUnixExtensions;
322 bool bDisableNetbios;
323 bool bUseKerberosKeytab;
324 bool bDeferSharingViolations;
325 bool bEnablePrivileges;
326 bool bASUSupport;
327 bool bUsershareOwnerOnly;
328 bool bUsershareAllowGuests;
329 bool bRegistryShares;
330 int restrict_anonymous;
331 int name_cache_timeout;
332 int client_signing;
333 int server_signing;
334 int client_ldap_sasl_wrapping;
335 int iUsershareMaxShares;
336 int iIdmapCacheTime;
337 int iIdmapNegativeCacheTime;
338 bool bResetOnZeroVC;
339 int iKeepalive;
340 int iminreceivefile;
341 param_opt_struct *param_opt;
344 static struct global Globals;
347 * This structure describes a single service.
349 struct service {
350 bool valid;
351 bool autoloaded;
352 int usershare;
353 time_t usershare_last_mod;
354 char *szService;
355 char *szPath;
356 char *szUsername;
357 char **szInvalidUsers;
358 char **szValidUsers;
359 char **szAdminUsers;
360 char *szCopy;
361 char *szInclude;
362 char *szPreExec;
363 char *szPostExec;
364 char *szRootPreExec;
365 char *szRootPostExec;
366 char *szCupsOptions;
367 char *szPrintcommand;
368 char *szLpqcommand;
369 char *szLprmcommand;
370 char *szLppausecommand;
371 char *szLpresumecommand;
372 char *szQueuepausecommand;
373 char *szQueueresumecommand;
374 char *szPrintername;
375 char *szPrintjobUsername;
376 char *szDontdescend;
377 char **szHostsallow;
378 char **szHostsdeny;
379 char *szMagicScript;
380 char *szMagicOutput;
381 char *szVetoFiles;
382 char *szHideFiles;
383 char *szVetoOplockFiles;
384 char *comment;
385 char *force_user;
386 char *force_group;
387 char **readlist;
388 char **writelist;
389 char **printer_admin;
390 char *volume;
391 char *fstype;
392 char **szVfsObjects;
393 char *szMSDfsProxy;
394 char *szAioWriteBehind;
395 char *szDfree;
396 int iMinPrintSpace;
397 int iMaxPrintJobs;
398 int iMaxReportedPrintJobs;
399 int iWriteCacheSize;
400 int iCreate_mask;
401 int iCreate_force_mode;
402 int iSecurity_mask;
403 int iSecurity_force_mode;
404 int iDir_mask;
405 int iDir_force_mode;
406 int iDir_Security_mask;
407 int iDir_Security_force_mode;
408 int iMaxConnections;
409 int iDefaultCase;
410 int iPrinting;
411 int iOplockContentionLimit;
412 int iCSCPolicy;
413 int iBlock_size;
414 int iDfreeCacheTime;
415 bool bPreexecClose;
416 bool bRootpreexecClose;
417 int iCaseSensitive;
418 bool bCasePreserve;
419 bool bShortCasePreserve;
420 bool bHideDotFiles;
421 bool bHideSpecialFiles;
422 bool bHideUnReadable;
423 bool bHideUnWriteableFiles;
424 bool bBrowseable;
425 bool bAvailable;
426 bool bRead_only;
427 bool bNo_set_dir;
428 bool bGuest_only;
429 bool bAdministrative_share;
430 bool bGuest_ok;
431 bool bPrint_ok;
432 bool bMap_system;
433 bool bMap_hidden;
434 bool bMap_archive;
435 bool bStoreDosAttributes;
436 bool bDmapiSupport;
437 bool bLocking;
438 int iStrictLocking;
439 bool bPosixLocking;
440 bool bShareModes;
441 bool bOpLocks;
442 bool bLevel2OpLocks;
443 bool bOnlyUser;
444 bool bMangledNames;
445 bool bWidelinks;
446 bool bSymlinks;
447 bool bSyncAlways;
448 bool bStrictAllocate;
449 bool bStrictSync;
450 char magic_char;
451 struct bitmap *copymap;
452 bool bDeleteReadonly;
453 bool bFakeOplocks;
454 bool bDeleteVetoFiles;
455 bool bDosFilemode;
456 bool bDosFiletimes;
457 bool bDosFiletimeResolution;
458 bool bFakeDirCreateTimes;
459 bool bBlockingLocks;
460 bool bInheritPerms;
461 bool bInheritACLS;
462 bool bInheritOwner;
463 bool bMSDfsRoot;
464 bool bUseClientDriver;
465 bool bDefaultDevmode;
466 bool bForcePrintername;
467 bool bNTAclSupport;
468 bool bForceUnknownAclUser;
469 bool bUseSendfile;
470 bool bProfileAcls;
471 bool bMap_acl_inherit;
472 bool bAfs_Share;
473 bool bEASupport;
474 bool bAclCheckPermissions;
475 bool bAclMapFullControl;
476 bool bAclGroupControl;
477 bool bChangeNotify;
478 bool bKernelChangeNotify;
479 int iallocation_roundup_size;
480 int iAioReadSize;
481 int iAioWriteSize;
482 int iMap_readonly;
483 int iDirectoryNameCacheSize;
484 int ismb_encrypt;
485 param_opt_struct *param_opt;
487 char dummy[3]; /* for alignment */
491 /* This is a default service used to prime a services structure */
492 static struct service sDefault = {
493 True, /* valid */
494 False, /* not autoloaded */
495 0, /* not a usershare */
496 (time_t)0, /* No last mod time */
497 NULL, /* szService */
498 NULL, /* szPath */
499 NULL, /* szUsername */
500 NULL, /* szInvalidUsers */
501 NULL, /* szValidUsers */
502 NULL, /* szAdminUsers */
503 NULL, /* szCopy */
504 NULL, /* szInclude */
505 NULL, /* szPreExec */
506 NULL, /* szPostExec */
507 NULL, /* szRootPreExec */
508 NULL, /* szRootPostExec */
509 NULL, /* szCupsOptions */
510 NULL, /* szPrintcommand */
511 NULL, /* szLpqcommand */
512 NULL, /* szLprmcommand */
513 NULL, /* szLppausecommand */
514 NULL, /* szLpresumecommand */
515 NULL, /* szQueuepausecommand */
516 NULL, /* szQueueresumecommand */
517 NULL, /* szPrintername */
518 NULL, /* szPrintjobUsername */
519 NULL, /* szDontdescend */
520 NULL, /* szHostsallow */
521 NULL, /* szHostsdeny */
522 NULL, /* szMagicScript */
523 NULL, /* szMagicOutput */
524 NULL, /* szVetoFiles */
525 NULL, /* szHideFiles */
526 NULL, /* szVetoOplockFiles */
527 NULL, /* comment */
528 NULL, /* force user */
529 NULL, /* force group */
530 NULL, /* readlist */
531 NULL, /* writelist */
532 NULL, /* printer admin */
533 NULL, /* volume */
534 NULL, /* fstype */
535 NULL, /* vfs objects */
536 NULL, /* szMSDfsProxy */
537 NULL, /* szAioWriteBehind */
538 NULL, /* szDfree */
539 0, /* iMinPrintSpace */
540 1000, /* iMaxPrintJobs */
541 0, /* iMaxReportedPrintJobs */
542 0, /* iWriteCacheSize */
543 0744, /* iCreate_mask */
544 0000, /* iCreate_force_mode */
545 0777, /* iSecurity_mask */
546 0, /* iSecurity_force_mode */
547 0755, /* iDir_mask */
548 0000, /* iDir_force_mode */
549 0777, /* iDir_Security_mask */
550 0, /* iDir_Security_force_mode */
551 0, /* iMaxConnections */
552 CASE_LOWER, /* iDefaultCase */
553 DEFAULT_PRINTING, /* iPrinting */
554 2, /* iOplockContentionLimit */
555 0, /* iCSCPolicy */
556 1024, /* iBlock_size */
557 0, /* iDfreeCacheTime */
558 False, /* bPreexecClose */
559 False, /* bRootpreexecClose */
560 Auto, /* case sensitive */
561 True, /* case preserve */
562 True, /* short case preserve */
563 True, /* bHideDotFiles */
564 False, /* bHideSpecialFiles */
565 False, /* bHideUnReadable */
566 False, /* bHideUnWriteableFiles */
567 True, /* bBrowseable */
568 True, /* bAvailable */
569 True, /* bRead_only */
570 True, /* bNo_set_dir */
571 False, /* bGuest_only */
572 False, /* bAdministrative_share */
573 False, /* bGuest_ok */
574 False, /* bPrint_ok */
575 False, /* bMap_system */
576 False, /* bMap_hidden */
577 True, /* bMap_archive */
578 False, /* bStoreDosAttributes */
579 False, /* bDmapiSupport */
580 True, /* bLocking */
581 Auto, /* iStrictLocking */
582 True, /* bPosixLocking */
583 True, /* bShareModes */
584 True, /* bOpLocks */
585 True, /* bLevel2OpLocks */
586 False, /* bOnlyUser */
587 True, /* bMangledNames */
588 True, /* bWidelinks */
589 True, /* bSymlinks */
590 False, /* bSyncAlways */
591 False, /* bStrictAllocate */
592 False, /* bStrictSync */
593 '~', /* magic char */
594 NULL, /* copymap */
595 False, /* bDeleteReadonly */
596 False, /* bFakeOplocks */
597 False, /* bDeleteVetoFiles */
598 False, /* bDosFilemode */
599 True, /* bDosFiletimes */
600 False, /* bDosFiletimeResolution */
601 False, /* bFakeDirCreateTimes */
602 True, /* bBlockingLocks */
603 False, /* bInheritPerms */
604 False, /* bInheritACLS */
605 False, /* bInheritOwner */
606 False, /* bMSDfsRoot */
607 False, /* bUseClientDriver */
608 True, /* bDefaultDevmode */
609 False, /* bForcePrintername */
610 True, /* bNTAclSupport */
611 False, /* bForceUnknownAclUser */
612 False, /* bUseSendfile */
613 False, /* bProfileAcls */
614 False, /* bMap_acl_inherit */
615 False, /* bAfs_Share */
616 False, /* bEASupport */
617 True, /* bAclCheckPermissions */
618 True, /* bAclMapFullControl */
619 False, /* bAclGroupControl */
620 True, /* bChangeNotify */
621 True, /* bKernelChangeNotify */
622 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
623 0, /* iAioReadSize */
624 0, /* iAioWriteSize */
625 MAP_READONLY_YES, /* iMap_readonly */
626 #ifdef BROKEN_DIRECTORY_HANDLING
627 0, /* iDirectoryNameCacheSize */
628 #else
629 100, /* iDirectoryNameCacheSize */
630 #endif
631 Auto, /* ismb_encrypt */
632 NULL, /* Parametric options */
634 "" /* dummy */
637 /* local variables */
638 static struct service **ServicePtrs = NULL;
639 static int iNumServices = 0;
640 static int iServiceIndex = 0;
641 static struct db_context *ServiceHash;
642 static int *invalid_services = NULL;
643 static int num_invalid_services = 0;
644 static bool bInGlobalSection = True;
645 static bool bGlobalOnly = False;
646 static int server_role;
647 static int default_server_announce;
649 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
651 /* prototypes for the special type handlers */
652 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
653 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
654 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
655 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
656 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
657 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
658 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
659 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
660 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
661 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
662 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
663 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
665 static void set_server_role(void);
666 static void set_default_server_announce_type(void);
667 static void set_allowed_client_auth(void);
669 static const struct enum_list enum_protocol[] = {
670 {PROTOCOL_NT1, "NT1"},
671 {PROTOCOL_LANMAN2, "LANMAN2"},
672 {PROTOCOL_LANMAN1, "LANMAN1"},
673 {PROTOCOL_CORE, "CORE"},
674 {PROTOCOL_COREPLUS, "COREPLUS"},
675 {PROTOCOL_COREPLUS, "CORE+"},
676 {-1, NULL}
679 static const struct enum_list enum_security[] = {
680 {SEC_SHARE, "SHARE"},
681 {SEC_USER, "USER"},
682 {SEC_SERVER, "SERVER"},
683 {SEC_DOMAIN, "DOMAIN"},
684 #ifdef HAVE_ADS
685 {SEC_ADS, "ADS"},
686 #endif
687 {-1, NULL}
690 static const struct enum_list enum_printing[] = {
691 {PRINT_SYSV, "sysv"},
692 {PRINT_AIX, "aix"},
693 {PRINT_HPUX, "hpux"},
694 {PRINT_BSD, "bsd"},
695 {PRINT_QNX, "qnx"},
696 {PRINT_PLP, "plp"},
697 {PRINT_LPRNG, "lprng"},
698 {PRINT_CUPS, "cups"},
699 {PRINT_IPRINT, "iprint"},
700 {PRINT_LPRNT, "nt"},
701 {PRINT_LPROS2, "os2"},
702 #ifdef DEVELOPER
703 {PRINT_TEST, "test"},
704 {PRINT_VLP, "vlp"},
705 #endif /* DEVELOPER */
706 {-1, NULL}
709 static const struct enum_list enum_ldap_sasl_wrapping[] = {
710 {0, "plain"},
711 {ADS_AUTH_SASL_SIGN, "sign"},
712 {ADS_AUTH_SASL_SEAL, "seal"},
713 {-1, NULL}
716 static const struct enum_list enum_ldap_ssl[] = {
717 {LDAP_SSL_OFF, "no"},
718 {LDAP_SSL_OFF, "No"},
719 {LDAP_SSL_OFF, "off"},
720 {LDAP_SSL_OFF, "Off"},
721 {LDAP_SSL_START_TLS, "start tls"},
722 {LDAP_SSL_START_TLS, "Start_tls"},
723 {-1, NULL}
726 static const struct enum_list enum_ldap_passwd_sync[] = {
727 {LDAP_PASSWD_SYNC_OFF, "no"},
728 {LDAP_PASSWD_SYNC_OFF, "No"},
729 {LDAP_PASSWD_SYNC_OFF, "off"},
730 {LDAP_PASSWD_SYNC_OFF, "Off"},
731 {LDAP_PASSWD_SYNC_ON, "Yes"},
732 {LDAP_PASSWD_SYNC_ON, "yes"},
733 {LDAP_PASSWD_SYNC_ON, "on"},
734 {LDAP_PASSWD_SYNC_ON, "On"},
735 {LDAP_PASSWD_SYNC_ONLY, "Only"},
736 {LDAP_PASSWD_SYNC_ONLY, "only"},
737 {-1, NULL}
740 /* Types of machine we can announce as. */
741 #define ANNOUNCE_AS_NT_SERVER 1
742 #define ANNOUNCE_AS_WIN95 2
743 #define ANNOUNCE_AS_WFW 3
744 #define ANNOUNCE_AS_NT_WORKSTATION 4
746 static const struct enum_list enum_announce_as[] = {
747 {ANNOUNCE_AS_NT_SERVER, "NT"},
748 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
749 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
750 {ANNOUNCE_AS_WIN95, "win95"},
751 {ANNOUNCE_AS_WFW, "WfW"},
752 {-1, NULL}
755 static const struct enum_list enum_map_readonly[] = {
756 {MAP_READONLY_NO, "no"},
757 {MAP_READONLY_NO, "false"},
758 {MAP_READONLY_NO, "0"},
759 {MAP_READONLY_YES, "yes"},
760 {MAP_READONLY_YES, "true"},
761 {MAP_READONLY_YES, "1"},
762 {MAP_READONLY_PERMISSIONS, "permissions"},
763 {MAP_READONLY_PERMISSIONS, "perms"},
764 {-1, NULL}
767 static const struct enum_list enum_case[] = {
768 {CASE_LOWER, "lower"},
769 {CASE_UPPER, "upper"},
770 {-1, NULL}
773 static const struct enum_list enum_bool_auto[] = {
774 {False, "No"},
775 {False, "False"},
776 {False, "0"},
777 {True, "Yes"},
778 {True, "True"},
779 {True, "1"},
780 {Auto, "Auto"},
781 {-1, NULL}
784 /* Client-side offline caching policy types */
785 #define CSC_POLICY_MANUAL 0
786 #define CSC_POLICY_DOCUMENTS 1
787 #define CSC_POLICY_PROGRAMS 2
788 #define CSC_POLICY_DISABLE 3
790 static const struct enum_list enum_csc_policy[] = {
791 {CSC_POLICY_MANUAL, "manual"},
792 {CSC_POLICY_DOCUMENTS, "documents"},
793 {CSC_POLICY_PROGRAMS, "programs"},
794 {CSC_POLICY_DISABLE, "disable"},
795 {-1, NULL}
798 /* SMB signing types. */
799 static const struct enum_list enum_smb_signing_vals[] = {
800 {False, "No"},
801 {False, "False"},
802 {False, "0"},
803 {False, "Off"},
804 {False, "disabled"},
805 {True, "Yes"},
806 {True, "True"},
807 {True, "1"},
808 {True, "On"},
809 {True, "enabled"},
810 {Auto, "auto"},
811 {Required, "required"},
812 {Required, "mandatory"},
813 {Required, "force"},
814 {Required, "forced"},
815 {Required, "enforced"},
816 {-1, NULL}
819 /* ACL compatibility options. */
820 static const struct enum_list enum_acl_compat_vals[] = {
821 { ACL_COMPAT_AUTO, "auto" },
822 { ACL_COMPAT_WINNT, "winnt" },
823 { ACL_COMPAT_WIN2K, "win2k" },
824 { -1, NULL}
828 Do you want session setups at user level security with a invalid
829 password to be rejected or allowed in as guest? WinNT rejects them
830 but it can be a pain as it means "net view" needs to use a password
832 You have 3 choices in the setting of map_to_guest:
834 "Never" means session setups with an invalid password
835 are rejected. This is the default.
837 "Bad User" means session setups with an invalid password
838 are rejected, unless the username does not exist, in which case it
839 is treated as a guest login
841 "Bad Password" means session setups with an invalid password
842 are treated as a guest login
844 Note that map_to_guest only has an effect in user or server
845 level security.
848 static const struct enum_list enum_map_to_guest[] = {
849 {NEVER_MAP_TO_GUEST, "Never"},
850 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
851 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
852 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
853 {-1, NULL}
856 /* Config backend options */
858 static const struct enum_list enum_config_backend[] = {
859 {CONFIG_BACKEND_FILE, "file"},
860 {CONFIG_BACKEND_REGISTRY, "registry"},
861 {-1, NULL}
864 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
866 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
867 * screen in SWAT. This is used to exclude parameters as well as to squash all
868 * parameters that have been duplicated by pseudonyms.
870 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
871 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
872 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
873 * respective views.
875 * NOTE2: Handling of duplicated (synonym) paramters:
876 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
877 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
878 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
879 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
882 static struct parm_struct parm_table[] = {
883 {N_("Base Options"), P_SEP, P_SEPARATOR},
886 .label = "dos charset",
887 .type = P_STRING,
888 .p_class = P_GLOBAL,
889 .ptr = &Globals.dos_charset,
890 .special = handle_charset,
891 .enum_list = NULL,
892 .flags = FLAG_ADVANCED
895 .label = "unix charset",
896 .type = P_STRING,
897 .p_class = P_GLOBAL,
898 .ptr = &Globals.unix_charset,
899 .special = handle_charset,
900 .enum_list = NULL,
901 .flags = FLAG_ADVANCED
904 .label = "display charset",
905 .type = P_STRING,
906 .p_class = P_GLOBAL,
907 .ptr = &Globals.display_charset,
908 .special = handle_charset,
909 .enum_list = NULL,
910 .flags = FLAG_ADVANCED
913 .label = "comment",
914 .type = P_STRING,
915 .p_class = P_LOCAL,
916 .ptr = &sDefault.comment,
917 .special = NULL,
918 .enum_list = NULL,
919 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
922 .label = "path",
923 .type = P_STRING,
924 .p_class = P_LOCAL,
925 .ptr = &sDefault.szPath,
926 .special = NULL,
927 .enum_list = NULL,
928 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
931 .label = "directory",
932 .type = P_STRING,
933 .p_class = P_LOCAL,
934 .ptr = &sDefault.szPath,
935 .special = NULL,
936 .enum_list = NULL,
937 .flags = FLAG_HIDE,
940 .label = "workgroup",
941 .type = P_USTRING,
942 .p_class = P_GLOBAL,
943 .ptr = &Globals.szWorkgroup,
944 .special = handle_workgroup,
945 .enum_list = NULL,
946 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
948 #ifdef WITH_ADS
950 .label = "realm",
951 .type = P_USTRING,
952 .p_class = P_GLOBAL,
953 .ptr = &Globals.szRealm,
954 .special = NULL,
955 .enum_list = NULL,
956 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
958 #endif
960 .label = "netbios name",
961 .type = P_USTRING,
962 .p_class = P_GLOBAL,
963 .ptr = &Globals.szNetbiosName,
964 .special = handle_netbios_name,
965 .enum_list = NULL,
966 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
969 .label = "netbios aliases",
970 .type = P_LIST,
971 .p_class = P_GLOBAL,
972 .ptr = &Globals.szNetbiosAliases,
973 .special = handle_netbios_aliases,
974 .enum_list = NULL,
975 .flags = FLAG_ADVANCED,
978 .label = "netbios scope",
979 .type = P_USTRING,
980 .p_class = P_GLOBAL,
981 .ptr = &Globals.szNetbiosScope,
982 .special = handle_netbios_scope,
983 .enum_list = NULL,
984 .flags = FLAG_ADVANCED,
987 .label = "server string",
988 .type = P_STRING,
989 .p_class = P_GLOBAL,
990 .ptr = &Globals.szServerString,
991 .special = NULL,
992 .enum_list = NULL,
993 .flags = FLAG_BASIC | FLAG_ADVANCED,
996 .label = "interfaces",
997 .type = P_LIST,
998 .p_class = P_GLOBAL,
999 .ptr = &Globals.szInterfaces,
1000 .special = NULL,
1001 .enum_list = NULL,
1002 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1005 .label = "bind interfaces only",
1006 .type = P_BOOL,
1007 .p_class = P_GLOBAL,
1008 .ptr = &Globals.bBindInterfacesOnly,
1009 .special = NULL,
1010 .enum_list = NULL,
1011 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1014 .label = "config backend",
1015 .type = P_ENUM,
1016 .p_class = P_GLOBAL,
1017 .ptr = &Globals.ConfigBackend,
1018 .special = NULL,
1019 .enum_list = enum_config_backend,
1020 .flags = FLAG_ADVANCED,
1023 {N_("Security Options"), P_SEP, P_SEPARATOR},
1026 .label = "security",
1027 .type = P_ENUM,
1028 .p_class = P_GLOBAL,
1029 .ptr = &Globals.security,
1030 .special = NULL,
1031 .enum_list = enum_security,
1032 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1035 .label = "auth methods",
1036 .type = P_LIST,
1037 .p_class = P_GLOBAL,
1038 .ptr = &Globals.AuthMethods,
1039 .special = NULL,
1040 .enum_list = NULL,
1041 .flags = FLAG_ADVANCED,
1044 .label = "encrypt passwords",
1045 .type = P_BOOL,
1046 .p_class = P_GLOBAL,
1047 .ptr = &Globals.bEncryptPasswords,
1048 .special = NULL,
1049 .enum_list = NULL,
1050 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1053 .label = "update encrypted",
1054 .type = P_BOOL,
1055 .p_class = P_GLOBAL,
1056 .ptr = &Globals.bUpdateEncrypt,
1057 .special = NULL,
1058 .enum_list = NULL,
1059 .flags = FLAG_ADVANCED,
1062 .label = "client schannel",
1063 .type = P_ENUM,
1064 .p_class = P_GLOBAL,
1065 .ptr = &Globals.clientSchannel,
1066 .special = NULL,
1067 .enum_list = enum_bool_auto,
1068 .flags = FLAG_BASIC | FLAG_ADVANCED,
1071 .label = "server schannel",
1072 .type = P_ENUM,
1073 .p_class = P_GLOBAL,
1074 .ptr = &Globals.serverSchannel,
1075 .special = NULL,
1076 .enum_list = enum_bool_auto,
1077 .flags = FLAG_BASIC | FLAG_ADVANCED,
1080 .label = "allow trusted domains",
1081 .type = P_BOOL,
1082 .p_class = P_GLOBAL,
1083 .ptr = &Globals.bAllowTrustedDomains,
1084 .special = NULL,
1085 .enum_list = NULL,
1086 .flags = FLAG_ADVANCED,
1089 .label = "map to guest",
1090 .type = P_ENUM,
1091 .p_class = P_GLOBAL,
1092 .ptr = &Globals.map_to_guest,
1093 .special = NULL,
1094 .enum_list = enum_map_to_guest,
1095 .flags = FLAG_ADVANCED,
1098 .label = "null passwords",
1099 .type = P_BOOL,
1100 .p_class = P_GLOBAL,
1101 .ptr = &Globals.bNullPasswords,
1102 .special = NULL,
1103 .enum_list = NULL,
1104 .flags = FLAG_ADVANCED,
1107 .label = "obey pam restrictions",
1108 .type = P_BOOL,
1109 .p_class = P_GLOBAL,
1110 .ptr = &Globals.bObeyPamRestrictions,
1111 .special = NULL,
1112 .enum_list = NULL,
1113 .flags = FLAG_ADVANCED,
1116 .label = "password server",
1117 .type = P_STRING,
1118 .p_class = P_GLOBAL,
1119 .ptr = &Globals.szPasswordServer,
1120 .special = NULL,
1121 .enum_list = NULL,
1122 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1125 .label = "smb passwd file",
1126 .type = P_STRING,
1127 .p_class = P_GLOBAL,
1128 .ptr = &Globals.szSMBPasswdFile,
1129 .special = NULL,
1130 .enum_list = NULL,
1131 .flags = FLAG_ADVANCED,
1134 .label = "private dir",
1135 .type = P_STRING,
1136 .p_class = P_GLOBAL,
1137 .ptr = &Globals.szPrivateDir,
1138 .special = NULL,
1139 .enum_list = NULL,
1140 .flags = FLAG_ADVANCED,
1143 .label = "passdb backend",
1144 .type = P_STRING,
1145 .p_class = P_GLOBAL,
1146 .ptr = &Globals.szPassdbBackend,
1147 .special = NULL,
1148 .enum_list = NULL,
1149 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1152 .label = "algorithmic rid base",
1153 .type = P_INTEGER,
1154 .p_class = P_GLOBAL,
1155 .ptr = &Globals.AlgorithmicRidBase,
1156 .special = NULL,
1157 .enum_list = NULL,
1158 .flags = FLAG_ADVANCED,
1161 .label = "root directory",
1162 .type = P_STRING,
1163 .p_class = P_GLOBAL,
1164 .ptr = &Globals.szRootdir,
1165 .special = NULL,
1166 .enum_list = NULL,
1167 .flags = FLAG_ADVANCED,
1170 .label = "root dir",
1171 .type = P_STRING,
1172 .p_class = P_GLOBAL,
1173 .ptr = &Globals.szRootdir,
1174 .special = NULL,
1175 .enum_list = NULL,
1176 .flags = FLAG_HIDE,
1179 .label = "root",
1180 .type = P_STRING,
1181 .p_class = P_GLOBAL,
1182 .ptr = &Globals.szRootdir,
1183 .special = NULL,
1184 .enum_list = NULL,
1185 .flags = FLAG_HIDE,
1188 .label = "guest account",
1189 .type = P_STRING,
1190 .p_class = P_GLOBAL,
1191 .ptr = &Globals.szGuestaccount,
1192 .special = NULL,
1193 .enum_list = NULL,
1194 .flags = FLAG_BASIC | FLAG_ADVANCED,
1197 .label = "enable privileges",
1198 .type = P_BOOL,
1199 .p_class = P_GLOBAL,
1200 .ptr = &Globals.bEnablePrivileges,
1201 .special = NULL,
1202 .enum_list = NULL,
1203 .flags = FLAG_ADVANCED,
1207 .label = "pam password change",
1208 .type = P_BOOL,
1209 .p_class = P_GLOBAL,
1210 .ptr = &Globals.bPamPasswordChange,
1211 .special = NULL,
1212 .enum_list = NULL,
1213 .flags = FLAG_ADVANCED,
1216 .label = "passwd program",
1217 .type = P_STRING,
1218 .p_class = P_GLOBAL,
1219 .ptr = &Globals.szPasswdProgram,
1220 .special = NULL,
1221 .enum_list = NULL,
1222 .flags = FLAG_ADVANCED,
1225 .label = "passwd chat",
1226 .type = P_STRING,
1227 .p_class = P_GLOBAL,
1228 .ptr = &Globals.szPasswdChat,
1229 .special = NULL,
1230 .enum_list = NULL,
1231 .flags = FLAG_ADVANCED,
1234 .label = "passwd chat debug",
1235 .type = P_BOOL,
1236 .p_class = P_GLOBAL,
1237 .ptr = &Globals.bPasswdChatDebug,
1238 .special = NULL,
1239 .enum_list = NULL,
1240 .flags = FLAG_ADVANCED,
1243 .label = "passwd chat timeout",
1244 .type = P_INTEGER,
1245 .p_class = P_GLOBAL,
1246 .ptr = &Globals.iPasswdChatTimeout,
1247 .special = NULL,
1248 .enum_list = NULL,
1249 .flags = FLAG_ADVANCED,
1252 .label = "check password script",
1253 .type = P_STRING,
1254 .p_class = P_GLOBAL,
1255 .ptr = &Globals.szCheckPasswordScript,
1256 .special = NULL,
1257 .enum_list = NULL,
1258 .flags = FLAG_ADVANCED,
1261 .label = "username map",
1262 .type = P_STRING,
1263 .p_class = P_GLOBAL,
1264 .ptr = &Globals.szUsernameMap,
1265 .special = NULL,
1266 .enum_list = NULL,
1267 .flags = FLAG_ADVANCED,
1270 .label = "password level",
1271 .type = P_INTEGER,
1272 .p_class = P_GLOBAL,
1273 .ptr = &Globals.pwordlevel,
1274 .special = NULL,
1275 .enum_list = NULL,
1276 .flags = FLAG_ADVANCED,
1279 .label = "username level",
1280 .type = P_INTEGER,
1281 .p_class = P_GLOBAL,
1282 .ptr = &Globals.unamelevel,
1283 .special = NULL,
1284 .enum_list = NULL,
1285 .flags = FLAG_ADVANCED,
1288 .label = "unix password sync",
1289 .type = P_BOOL,
1290 .p_class = P_GLOBAL,
1291 .ptr = &Globals.bUnixPasswdSync,
1292 .special = NULL,
1293 .enum_list = NULL,
1294 .flags = FLAG_ADVANCED,
1297 .label = "restrict anonymous",
1298 .type = P_INTEGER,
1299 .p_class = P_GLOBAL,
1300 .ptr = &Globals.restrict_anonymous,
1301 .special = NULL,
1302 .enum_list = NULL,
1303 .flags = FLAG_ADVANCED,
1306 .label = "lanman auth",
1307 .type = P_BOOL,
1308 .p_class = P_GLOBAL,
1309 .ptr = &Globals.bLanmanAuth,
1310 .special = NULL,
1311 .enum_list = NULL,
1312 .flags = FLAG_ADVANCED,
1315 .label = "ntlm auth",
1316 .type = P_BOOL,
1317 .p_class = P_GLOBAL,
1318 .ptr = &Globals.bNTLMAuth,
1319 .special = NULL,
1320 .enum_list = NULL,
1321 .flags = FLAG_ADVANCED,
1324 .label = "client NTLMv2 auth",
1325 .type = P_BOOL,
1326 .p_class = P_GLOBAL,
1327 .ptr = &Globals.bClientNTLMv2Auth,
1328 .special = NULL,
1329 .enum_list = NULL,
1330 .flags = FLAG_ADVANCED,
1333 .label = "client lanman auth",
1334 .type = P_BOOL,
1335 .p_class = P_GLOBAL,
1336 .ptr = &Globals.bClientLanManAuth,
1337 .special = NULL,
1338 .enum_list = NULL,
1339 .flags = FLAG_ADVANCED,
1342 .label = "client plaintext auth",
1343 .type = P_BOOL,
1344 .p_class = P_GLOBAL,
1345 .ptr = &Globals.bClientPlaintextAuth,
1346 .special = NULL,
1347 .enum_list = NULL,
1348 .flags = FLAG_ADVANCED,
1351 .label = "username",
1352 .type = P_STRING,
1353 .p_class = P_LOCAL,
1354 .ptr = &sDefault.szUsername,
1355 .special = NULL,
1356 .enum_list = NULL,
1357 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1360 .label = "user",
1361 .type = P_STRING,
1362 .p_class = P_LOCAL,
1363 .ptr = &sDefault.szUsername,
1364 .special = NULL,
1365 .enum_list = NULL,
1366 .flags = FLAG_HIDE,
1369 .label = "users",
1370 .type = P_STRING,
1371 .p_class = P_LOCAL,
1372 .ptr = &sDefault.szUsername,
1373 .special = NULL,
1374 .enum_list = NULL,
1375 .flags = FLAG_HIDE,
1378 .label = "invalid users",
1379 .type = P_LIST,
1380 .p_class = P_LOCAL,
1381 .ptr = &sDefault.szInvalidUsers,
1382 .special = NULL,
1383 .enum_list = NULL,
1384 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1387 .label = "valid users",
1388 .type = P_LIST,
1389 .p_class = P_LOCAL,
1390 .ptr = &sDefault.szValidUsers,
1391 .special = NULL,
1392 .enum_list = NULL,
1393 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1396 .label = "admin users",
1397 .type = P_LIST,
1398 .p_class = P_LOCAL,
1399 .ptr = &sDefault.szAdminUsers,
1400 .special = NULL,
1401 .enum_list = NULL,
1402 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1405 .label = "read list",
1406 .type = P_LIST,
1407 .p_class = P_LOCAL,
1408 .ptr = &sDefault.readlist,
1409 .special = NULL,
1410 .enum_list = NULL,
1411 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1414 .label = "write list",
1415 .type = P_LIST,
1416 .p_class = P_LOCAL,
1417 .ptr = &sDefault.writelist,
1418 .special = NULL,
1419 .enum_list = NULL,
1420 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1423 .label = "printer admin",
1424 .type = P_LIST,
1425 .p_class = P_LOCAL,
1426 .ptr = &sDefault.printer_admin,
1427 .special = NULL,
1428 .enum_list = NULL,
1429 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1432 .label = "force user",
1433 .type = P_STRING,
1434 .p_class = P_LOCAL,
1435 .ptr = &sDefault.force_user,
1436 .special = NULL,
1437 .enum_list = NULL,
1438 .flags = FLAG_ADVANCED | FLAG_SHARE,
1441 .label = "force group",
1442 .type = P_STRING,
1443 .p_class = P_LOCAL,
1444 .ptr = &sDefault.force_group,
1445 .special = NULL,
1446 .enum_list = NULL,
1447 .flags = FLAG_ADVANCED | FLAG_SHARE,
1450 .label = "group",
1451 .type = P_STRING,
1452 .p_class = P_LOCAL,
1453 .ptr = &sDefault.force_group,
1454 .special = NULL,
1455 .enum_list = NULL,
1456 .flags = FLAG_ADVANCED,
1459 .label = "read only",
1460 .type = P_BOOL,
1461 .p_class = P_LOCAL,
1462 .ptr = &sDefault.bRead_only,
1463 .special = NULL,
1464 .enum_list = NULL,
1465 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1468 .label = "write ok",
1469 .type = P_BOOLREV,
1470 .p_class = P_LOCAL,
1471 .ptr = &sDefault.bRead_only,
1472 .special = NULL,
1473 .enum_list = NULL,
1474 .flags = FLAG_HIDE,
1477 .label = "writeable",
1478 .type = P_BOOLREV,
1479 .p_class = P_LOCAL,
1480 .ptr = &sDefault.bRead_only,
1481 .special = NULL,
1482 .enum_list = NULL,
1483 .flags = FLAG_HIDE,
1486 .label = "writable",
1487 .type = P_BOOLREV,
1488 .p_class = P_LOCAL,
1489 .ptr = &sDefault.bRead_only,
1490 .special = NULL,
1491 .enum_list = NULL,
1492 .flags = FLAG_HIDE,
1495 .label = "acl check permissions",
1496 .type = P_BOOL,
1497 .p_class = P_LOCAL,
1498 .ptr = &sDefault.bAclCheckPermissions,
1499 .special = NULL,
1500 .enum_list = NULL,
1501 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1504 .label = "acl group control",
1505 .type = P_BOOL,
1506 .p_class = P_LOCAL,
1507 .ptr = &sDefault.bAclGroupControl,
1508 .special = NULL,
1509 .enum_list = NULL,
1510 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1513 .label = "acl map full control",
1514 .type = P_BOOL,
1515 .p_class = P_LOCAL,
1516 .ptr = &sDefault.bAclMapFullControl,
1517 .special = NULL,
1518 .enum_list = NULL,
1519 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1522 .label = "create mask",
1523 .type = P_OCTAL,
1524 .p_class = P_LOCAL,
1525 .ptr = &sDefault.iCreate_mask,
1526 .special = NULL,
1527 .enum_list = NULL,
1528 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1531 .label = "create mode",
1532 .type = P_OCTAL,
1533 .p_class = P_LOCAL,
1534 .ptr = &sDefault.iCreate_mask,
1535 .special = NULL,
1536 .enum_list = NULL,
1537 .flags = FLAG_HIDE,
1540 .label = "force create mode",
1541 .type = P_OCTAL,
1542 .p_class = P_LOCAL,
1543 .ptr = &sDefault.iCreate_force_mode,
1544 .special = NULL,
1545 .enum_list = NULL,
1546 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1549 .label = "security mask",
1550 .type = P_OCTAL,
1551 .p_class = P_LOCAL,
1552 .ptr = &sDefault.iSecurity_mask,
1553 .special = NULL,
1554 .enum_list = NULL,
1555 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1558 .label = "force security mode",
1559 .type = P_OCTAL,
1560 .p_class = P_LOCAL,
1561 .ptr = &sDefault.iSecurity_force_mode,
1562 .special = NULL,
1563 .enum_list = NULL,
1564 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1567 .label = "directory mask",
1568 .type = P_OCTAL,
1569 .p_class = P_LOCAL,
1570 .ptr = &sDefault.iDir_mask,
1571 .special = NULL,
1572 .enum_list = NULL,
1573 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1576 .label = "directory mode",
1577 .type = P_OCTAL,
1578 .p_class = P_LOCAL,
1579 .ptr = &sDefault.iDir_mask,
1580 .special = NULL,
1581 .enum_list = NULL,
1582 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1585 .label = "force directory mode",
1586 .type = P_OCTAL,
1587 .p_class = P_LOCAL,
1588 .ptr = &sDefault.iDir_force_mode,
1589 .special = NULL,
1590 .enum_list = NULL,
1591 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1594 .label = "directory security mask",
1595 .type = P_OCTAL,
1596 .p_class = P_LOCAL,
1597 .ptr = &sDefault.iDir_Security_mask,
1598 .special = NULL,
1599 .enum_list = NULL,
1600 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1603 .label = "force directory security mode",
1604 .type = P_OCTAL,
1605 .p_class = P_LOCAL,
1606 .ptr = &sDefault.iDir_Security_force_mode,
1607 .special = NULL,
1608 .enum_list = NULL,
1609 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1612 .label = "force unknown acl user",
1613 .type = P_BOOL,
1614 .p_class = P_LOCAL,
1615 .ptr = &sDefault.bForceUnknownAclUser,
1616 .special = NULL,
1617 .enum_list = NULL,
1618 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1621 .label = "inherit permissions",
1622 .type = P_BOOL,
1623 .p_class = P_LOCAL,
1624 .ptr = &sDefault.bInheritPerms,
1625 .special = NULL,
1626 .enum_list = NULL,
1627 .flags = FLAG_ADVANCED | FLAG_SHARE,
1630 .label = "inherit acls",
1631 .type = P_BOOL,
1632 .p_class = P_LOCAL,
1633 .ptr = &sDefault.bInheritACLS,
1634 .special = NULL,
1635 .enum_list = NULL,
1636 .flags = FLAG_ADVANCED | FLAG_SHARE,
1639 .label = "inherit owner",
1640 .type = P_BOOL,
1641 .p_class = P_LOCAL,
1642 .ptr = &sDefault.bInheritOwner,
1643 .special = NULL,
1644 .enum_list = NULL,
1645 .flags = FLAG_ADVANCED | FLAG_SHARE,
1648 .label = "guest only",
1649 .type = P_BOOL,
1650 .p_class = P_LOCAL,
1651 .ptr = &sDefault.bGuest_only,
1652 .special = NULL,
1653 .enum_list = NULL,
1654 .flags = FLAG_ADVANCED | FLAG_SHARE,
1657 .label = "only guest",
1658 .type = P_BOOL,
1659 .p_class = P_LOCAL,
1660 .ptr = &sDefault.bGuest_only,
1661 .special = NULL,
1662 .enum_list = NULL,
1663 .flags = FLAG_HIDE,
1666 .label = "administrative share",
1667 .type = P_BOOL,
1668 .p_class = P_LOCAL,
1669 .ptr = &sDefault.bAdministrative_share,
1670 .special = NULL,
1671 .enum_list = NULL,
1672 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1676 .label = "guest ok",
1677 .type = P_BOOL,
1678 .p_class = P_LOCAL,
1679 .ptr = &sDefault.bGuest_ok,
1680 .special = NULL,
1681 .enum_list = NULL,
1682 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1685 .label = "public",
1686 .type = P_BOOL,
1687 .p_class = P_LOCAL,
1688 .ptr = &sDefault.bGuest_ok,
1689 .special = NULL,
1690 .enum_list = NULL,
1691 .flags = FLAG_HIDE,
1694 .label = "only user",
1695 .type = P_BOOL,
1696 .p_class = P_LOCAL,
1697 .ptr = &sDefault.bOnlyUser,
1698 .special = NULL,
1699 .enum_list = NULL,
1700 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1703 .label = "hosts allow",
1704 .type = P_LIST,
1705 .p_class = P_LOCAL,
1706 .ptr = &sDefault.szHostsallow,
1707 .special = NULL,
1708 .enum_list = NULL,
1709 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1712 .label = "allow hosts",
1713 .type = P_LIST,
1714 .p_class = P_LOCAL,
1715 .ptr = &sDefault.szHostsallow,
1716 .special = NULL,
1717 .enum_list = NULL,
1718 .flags = FLAG_HIDE,
1721 .label = "hosts deny",
1722 .type = P_LIST,
1723 .p_class = P_LOCAL,
1724 .ptr = &sDefault.szHostsdeny,
1725 .special = NULL,
1726 .enum_list = NULL,
1727 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1730 .label = "deny hosts",
1731 .type = P_LIST,
1732 .p_class = P_LOCAL,
1733 .ptr = &sDefault.szHostsdeny,
1734 .special = NULL,
1735 .enum_list = NULL,
1736 .flags = FLAG_HIDE,
1739 .label = "preload modules",
1740 .type = P_LIST,
1741 .p_class = P_GLOBAL,
1742 .ptr = &Globals.szPreloadModules,
1743 .special = NULL,
1744 .enum_list = NULL,
1745 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1748 .label = "use kerberos keytab",
1749 .type = P_BOOL,
1750 .p_class = P_GLOBAL,
1751 .ptr = &Globals.bUseKerberosKeytab,
1752 .special = NULL,
1753 .enum_list = NULL,
1754 .flags = FLAG_ADVANCED,
1757 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1760 .label = "log level",
1761 .type = P_STRING,
1762 .p_class = P_GLOBAL,
1763 .ptr = &Globals.szLogLevel,
1764 .special = handle_debug_list,
1765 .enum_list = NULL,
1766 .flags = FLAG_ADVANCED,
1769 .label = "debuglevel",
1770 .type = P_STRING,
1771 .p_class = P_GLOBAL,
1772 .ptr = &Globals.szLogLevel,
1773 .special = handle_debug_list,
1774 .enum_list = NULL,
1775 .flags = FLAG_HIDE,
1778 .label = "syslog",
1779 .type = P_INTEGER,
1780 .p_class = P_GLOBAL,
1781 .ptr = &Globals.syslog,
1782 .special = NULL,
1783 .enum_list = NULL,
1784 .flags = FLAG_ADVANCED,
1787 .label = "syslog only",
1788 .type = P_BOOL,
1789 .p_class = P_GLOBAL,
1790 .ptr = &Globals.bSyslogOnly,
1791 .special = NULL,
1792 .enum_list = NULL,
1793 .flags = FLAG_ADVANCED,
1796 .label = "log file",
1797 .type = P_STRING,
1798 .p_class = P_GLOBAL,
1799 .ptr = &Globals.szLogFile,
1800 .special = NULL,
1801 .enum_list = NULL,
1802 .flags = FLAG_ADVANCED,
1805 .label = "max log size",
1806 .type = P_INTEGER,
1807 .p_class = P_GLOBAL,
1808 .ptr = &Globals.max_log_size,
1809 .special = NULL,
1810 .enum_list = NULL,
1811 .flags = FLAG_ADVANCED,
1814 .label = "debug timestamp",
1815 .type = P_BOOL,
1816 .p_class = P_GLOBAL,
1817 .ptr = &Globals.bTimestampLogs,
1818 .special = NULL,
1819 .enum_list = NULL,
1820 .flags = FLAG_ADVANCED,
1823 .label = "timestamp logs",
1824 .type = P_BOOL,
1825 .p_class = P_GLOBAL,
1826 .ptr = &Globals.bTimestampLogs,
1827 .special = NULL,
1828 .enum_list = NULL,
1829 .flags = FLAG_ADVANCED,
1832 .label = "debug prefix timestamp",
1833 .type = P_BOOL,
1834 .p_class = P_GLOBAL,
1835 .ptr = &Globals.bDebugPrefixTimestamp,
1836 .special = NULL,
1837 .enum_list = NULL,
1838 .flags = FLAG_ADVANCED,
1841 .label = "debug hires timestamp",
1842 .type = P_BOOL,
1843 .p_class = P_GLOBAL,
1844 .ptr = &Globals.bDebugHiresTimestamp,
1845 .special = NULL,
1846 .enum_list = NULL,
1847 .flags = FLAG_ADVANCED,
1850 .label = "debug pid",
1851 .type = P_BOOL,
1852 .p_class = P_GLOBAL,
1853 .ptr = &Globals.bDebugPid,
1854 .special = NULL,
1855 .enum_list = NULL,
1856 .flags = FLAG_ADVANCED,
1859 .label = "debug uid",
1860 .type = P_BOOL,
1861 .p_class = P_GLOBAL,
1862 .ptr = &Globals.bDebugUid,
1863 .special = NULL,
1864 .enum_list = NULL,
1865 .flags = FLAG_ADVANCED,
1868 .label = "debug class",
1869 .type = P_BOOL,
1870 .p_class = P_GLOBAL,
1871 .ptr = &Globals.bDebugClass,
1872 .special = NULL,
1873 .enum_list = NULL,
1874 .flags = FLAG_ADVANCED,
1877 .label = "enable core files",
1878 .type = P_BOOL,
1879 .p_class = P_GLOBAL,
1880 .ptr = &Globals.bEnableCoreFiles,
1881 .special = NULL,
1882 .enum_list = NULL,
1883 .flags = FLAG_ADVANCED,
1886 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1889 .label = "allocation roundup size",
1890 .type = P_INTEGER,
1891 .p_class = P_LOCAL,
1892 .ptr = &sDefault.iallocation_roundup_size,
1893 .special = NULL,
1894 .enum_list = NULL,
1895 .flags = FLAG_ADVANCED,
1898 .label = "aio read size",
1899 .type = P_INTEGER,
1900 .p_class = P_LOCAL,
1901 .ptr = &sDefault.iAioReadSize,
1902 .special = NULL,
1903 .enum_list = NULL,
1904 .flags = FLAG_ADVANCED,
1907 .label = "aio write size",
1908 .type = P_INTEGER,
1909 .p_class = P_LOCAL,
1910 .ptr = &sDefault.iAioWriteSize,
1911 .special = NULL,
1912 .enum_list = NULL,
1913 .flags = FLAG_ADVANCED,
1916 .label = "aio write behind",
1917 .type = P_STRING,
1918 .p_class = P_LOCAL,
1919 .ptr = &sDefault.szAioWriteBehind,
1920 .special = NULL,
1921 .enum_list = NULL,
1922 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1925 .label = "smb ports",
1926 .type = P_STRING,
1927 .p_class = P_GLOBAL,
1928 .ptr = &Globals.smb_ports,
1929 .special = NULL,
1930 .enum_list = NULL,
1931 .flags = FLAG_ADVANCED,
1934 .label = "large readwrite",
1935 .type = P_BOOL,
1936 .p_class = P_GLOBAL,
1937 .ptr = &Globals.bLargeReadwrite,
1938 .special = NULL,
1939 .enum_list = NULL,
1940 .flags = FLAG_ADVANCED,
1943 .label = "max protocol",
1944 .type = P_ENUM,
1945 .p_class = P_GLOBAL,
1946 .ptr = &Globals.maxprotocol,
1947 .special = NULL,
1948 .enum_list = enum_protocol,
1949 .flags = FLAG_ADVANCED,
1952 .label = "protocol",
1953 .type = P_ENUM,
1954 .p_class = P_GLOBAL,
1955 .ptr = &Globals.maxprotocol,
1956 .special = NULL,
1957 .enum_list = enum_protocol,
1958 .flags = FLAG_ADVANCED,
1961 .label = "min protocol",
1962 .type = P_ENUM,
1963 .p_class = P_GLOBAL,
1964 .ptr = &Globals.minprotocol,
1965 .special = NULL,
1966 .enum_list = enum_protocol,
1967 .flags = FLAG_ADVANCED,
1970 .label = "min receivefile size",
1971 .type = P_INTEGER,
1972 .p_class = P_GLOBAL,
1973 .ptr = &Globals.iminreceivefile,
1974 .special = NULL,
1975 .enum_list = NULL,
1976 .flags = FLAG_ADVANCED,
1979 .label = "read raw",
1980 .type = P_BOOL,
1981 .p_class = P_GLOBAL,
1982 .ptr = &Globals.bReadRaw,
1983 .special = NULL,
1984 .enum_list = NULL,
1985 .flags = FLAG_ADVANCED,
1988 .label = "write raw",
1989 .type = P_BOOL,
1990 .p_class = P_GLOBAL,
1991 .ptr = &Globals.bWriteRaw,
1992 .special = NULL,
1993 .enum_list = NULL,
1994 .flags = FLAG_ADVANCED,
1997 .label = "disable netbios",
1998 .type = P_BOOL,
1999 .p_class = P_GLOBAL,
2000 .ptr = &Globals.bDisableNetbios,
2001 .special = NULL,
2002 .enum_list = NULL,
2003 .flags = FLAG_ADVANCED,
2006 .label = "reset on zero vc",
2007 .type = P_BOOL,
2008 .p_class = P_GLOBAL,
2009 .ptr = &Globals.bResetOnZeroVC,
2010 .special = NULL,
2011 .enum_list = NULL,
2012 .flags = FLAG_ADVANCED,
2015 .label = "acl compatibility",
2016 .type = P_ENUM,
2017 .p_class = P_GLOBAL,
2018 .ptr = &Globals.iAclCompat,
2019 .special = NULL,
2020 .enum_list = enum_acl_compat_vals,
2021 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2024 .label = "defer sharing violations",
2025 .type = P_BOOL,
2026 .p_class = P_GLOBAL,
2027 .ptr = &Globals.bDeferSharingViolations,
2028 .special = NULL,
2029 .enum_list = NULL,
2030 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2033 .label = "ea support",
2034 .type = P_BOOL,
2035 .p_class = P_LOCAL,
2036 .ptr = &sDefault.bEASupport,
2037 .special = NULL,
2038 .enum_list = NULL,
2039 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2042 .label = "nt acl support",
2043 .type = P_BOOL,
2044 .p_class = P_LOCAL,
2045 .ptr = &sDefault.bNTAclSupport,
2046 .special = NULL,
2047 .enum_list = NULL,
2048 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2051 .label = "nt pipe support",
2052 .type = P_BOOL,
2053 .p_class = P_GLOBAL,
2054 .ptr = &Globals.bNTPipeSupport,
2055 .special = NULL,
2056 .enum_list = NULL,
2057 .flags = FLAG_ADVANCED,
2060 .label = "nt status support",
2061 .type = P_BOOL,
2062 .p_class = P_GLOBAL,
2063 .ptr = &Globals.bNTStatusSupport,
2064 .special = NULL,
2065 .enum_list = NULL,
2066 .flags = FLAG_ADVANCED,
2069 .label = "profile acls",
2070 .type = P_BOOL,
2071 .p_class = P_LOCAL,
2072 .ptr = &sDefault.bProfileAcls,
2073 .special = NULL,
2074 .enum_list = NULL,
2075 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2078 .label = "announce version",
2079 .type = P_STRING,
2080 .p_class = P_GLOBAL,
2081 .ptr = &Globals.szAnnounceVersion,
2082 .special = NULL,
2083 .enum_list = NULL,
2084 .flags = FLAG_ADVANCED,
2087 .label = "announce as",
2088 .type = P_ENUM,
2089 .p_class = P_GLOBAL,
2090 .ptr = &Globals.announce_as,
2091 .special = NULL,
2092 .enum_list = enum_announce_as,
2093 .flags = FLAG_ADVANCED,
2096 .label = "map acl inherit",
2097 .type = P_BOOL,
2098 .p_class = P_LOCAL,
2099 .ptr = &sDefault.bMap_acl_inherit,
2100 .special = NULL,
2101 .enum_list = NULL,
2102 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2105 .label = "afs share",
2106 .type = P_BOOL,
2107 .p_class = P_LOCAL,
2108 .ptr = &sDefault.bAfs_Share,
2109 .special = NULL,
2110 .enum_list = NULL,
2111 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2114 .label = "max mux",
2115 .type = P_INTEGER,
2116 .p_class = P_GLOBAL,
2117 .ptr = &Globals.max_mux,
2118 .special = NULL,
2119 .enum_list = NULL,
2120 .flags = FLAG_ADVANCED,
2123 .label = "max xmit",
2124 .type = P_INTEGER,
2125 .p_class = P_GLOBAL,
2126 .ptr = &Globals.max_xmit,
2127 .special = NULL,
2128 .enum_list = NULL,
2129 .flags = FLAG_ADVANCED,
2132 .label = "name resolve order",
2133 .type = P_STRING,
2134 .p_class = P_GLOBAL,
2135 .ptr = &Globals.szNameResolveOrder,
2136 .special = NULL,
2137 .enum_list = NULL,
2138 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2141 .label = "max ttl",
2142 .type = P_INTEGER,
2143 .p_class = P_GLOBAL,
2144 .ptr = &Globals.max_ttl,
2145 .special = NULL,
2146 .enum_list = NULL,
2147 .flags = FLAG_ADVANCED,
2150 .label = "max wins ttl",
2151 .type = P_INTEGER,
2152 .p_class = P_GLOBAL,
2153 .ptr = &Globals.max_wins_ttl,
2154 .special = NULL,
2155 .enum_list = NULL,
2156 .flags = FLAG_ADVANCED,
2159 .label = "min wins ttl",
2160 .type = P_INTEGER,
2161 .p_class = P_GLOBAL,
2162 .ptr = &Globals.min_wins_ttl,
2163 .special = NULL,
2164 .enum_list = NULL,
2165 .flags = FLAG_ADVANCED,
2168 .label = "time server",
2169 .type = P_BOOL,
2170 .p_class = P_GLOBAL,
2171 .ptr = &Globals.bTimeServer,
2172 .special = NULL,
2173 .enum_list = NULL,
2174 .flags = FLAG_ADVANCED,
2177 .label = "unix extensions",
2178 .type = P_BOOL,
2179 .p_class = P_GLOBAL,
2180 .ptr = &Globals.bUnixExtensions,
2181 .special = NULL,
2182 .enum_list = NULL,
2183 .flags = FLAG_ADVANCED,
2186 .label = "use spnego",
2187 .type = P_BOOL,
2188 .p_class = P_GLOBAL,
2189 .ptr = &Globals.bUseSpnego,
2190 .special = NULL,
2191 .enum_list = NULL,
2192 .flags = FLAG_ADVANCED,
2195 .label = "client signing",
2196 .type = P_ENUM,
2197 .p_class = P_GLOBAL,
2198 .ptr = &Globals.client_signing,
2199 .special = NULL,
2200 .enum_list = enum_smb_signing_vals,
2201 .flags = FLAG_ADVANCED,
2204 .label = "server signing",
2205 .type = P_ENUM,
2206 .p_class = P_GLOBAL,
2207 .ptr = &Globals.server_signing,
2208 .special = NULL,
2209 .enum_list = enum_smb_signing_vals,
2210 .flags = FLAG_ADVANCED,
2213 .label = "smb encrypt",
2214 .type = P_ENUM,
2215 .p_class = P_LOCAL,
2216 .ptr = &sDefault.ismb_encrypt,
2217 .special = NULL,
2218 .enum_list = enum_smb_signing_vals,
2219 .flags = FLAG_ADVANCED,
2222 .label = "client use spnego",
2223 .type = P_BOOL,
2224 .p_class = P_GLOBAL,
2225 .ptr = &Globals.bClientUseSpnego,
2226 .special = NULL,
2227 .enum_list = NULL,
2228 .flags = FLAG_ADVANCED,
2231 .label = "client ldap sasl wrapping",
2232 .type = P_ENUM,
2233 .p_class = P_GLOBAL,
2234 .ptr = &Globals.client_ldap_sasl_wrapping,
2235 .special = NULL,
2236 .enum_list = enum_ldap_sasl_wrapping,
2237 .flags = FLAG_ADVANCED,
2240 .label = "enable asu support",
2241 .type = P_BOOL,
2242 .p_class = P_GLOBAL,
2243 .ptr = &Globals.bASUSupport,
2244 .special = NULL,
2245 .enum_list = NULL,
2246 .flags = FLAG_ADVANCED,
2249 .label = "svcctl list",
2250 .type = P_LIST,
2251 .p_class = P_GLOBAL,
2252 .ptr = &Globals.szServicesList,
2253 .special = NULL,
2254 .enum_list = NULL,
2255 .flags = FLAG_ADVANCED,
2258 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2261 .label = "block size",
2262 .type = P_INTEGER,
2263 .p_class = P_LOCAL,
2264 .ptr = &sDefault.iBlock_size,
2265 .special = NULL,
2266 .enum_list = NULL,
2267 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2270 .label = "deadtime",
2271 .type = P_INTEGER,
2272 .p_class = P_GLOBAL,
2273 .ptr = &Globals.deadtime,
2274 .special = NULL,
2275 .enum_list = NULL,
2276 .flags = FLAG_ADVANCED,
2279 .label = "getwd cache",
2280 .type = P_BOOL,
2281 .p_class = P_GLOBAL,
2282 .ptr = &Globals.getwd_cache,
2283 .special = NULL,
2284 .enum_list = NULL,
2285 .flags = FLAG_ADVANCED,
2288 .label = "keepalive",
2289 .type = P_INTEGER,
2290 .p_class = P_GLOBAL,
2291 .ptr = &Globals.iKeepalive,
2292 .special = NULL,
2293 .enum_list = NULL,
2294 .flags = FLAG_ADVANCED,
2297 .label = "change notify",
2298 .type = P_BOOL,
2299 .p_class = P_LOCAL,
2300 .ptr = &sDefault.bChangeNotify,
2301 .special = NULL,
2302 .enum_list = NULL,
2303 .flags = FLAG_ADVANCED | FLAG_SHARE,
2306 .label = "directory name cache size",
2307 .type = P_INTEGER,
2308 .p_class = P_LOCAL,
2309 .ptr = &sDefault.iDirectoryNameCacheSize,
2310 .special = NULL,
2311 .enum_list = NULL,
2312 .flags = FLAG_ADVANCED | FLAG_SHARE,
2315 .label = "kernel change notify",
2316 .type = P_BOOL,
2317 .p_class = P_LOCAL,
2318 .ptr = &sDefault.bKernelChangeNotify,
2319 .special = NULL,
2320 .enum_list = NULL,
2321 .flags = FLAG_ADVANCED | FLAG_SHARE,
2324 .label = "lpq cache time",
2325 .type = P_INTEGER,
2326 .p_class = P_GLOBAL,
2327 .ptr = &Globals.lpqcachetime,
2328 .special = NULL,
2329 .enum_list = NULL,
2330 .flags = FLAG_ADVANCED,
2333 .label = "max smbd processes",
2334 .type = P_INTEGER,
2335 .p_class = P_GLOBAL,
2336 .ptr = &Globals.iMaxSmbdProcesses,
2337 .special = NULL,
2338 .enum_list = NULL,
2339 .flags = FLAG_ADVANCED,
2342 .label = "max connections",
2343 .type = P_INTEGER,
2344 .p_class = P_LOCAL,
2345 .ptr = &sDefault.iMaxConnections,
2346 .special = NULL,
2347 .enum_list = NULL,
2348 .flags = FLAG_ADVANCED | FLAG_SHARE,
2351 .label = "paranoid server security",
2352 .type = P_BOOL,
2353 .p_class = P_GLOBAL,
2354 .ptr = &Globals.paranoid_server_security,
2355 .special = NULL,
2356 .enum_list = NULL,
2357 .flags = FLAG_ADVANCED,
2360 .label = "max disk size",
2361 .type = P_INTEGER,
2362 .p_class = P_GLOBAL,
2363 .ptr = &Globals.maxdisksize,
2364 .special = NULL,
2365 .enum_list = NULL,
2366 .flags = FLAG_ADVANCED,
2369 .label = "max open files",
2370 .type = P_INTEGER,
2371 .p_class = P_GLOBAL,
2372 .ptr = &Globals.max_open_files,
2373 .special = NULL,
2374 .enum_list = NULL,
2375 .flags = FLAG_ADVANCED,
2378 .label = "min print space",
2379 .type = P_INTEGER,
2380 .p_class = P_LOCAL,
2381 .ptr = &sDefault.iMinPrintSpace,
2382 .special = NULL,
2383 .enum_list = NULL,
2384 .flags = FLAG_ADVANCED | FLAG_PRINT,
2387 .label = "socket options",
2388 .type = P_STRING,
2389 .p_class = P_GLOBAL,
2390 .ptr = &Globals.szSocketOptions,
2391 .special = NULL,
2392 .enum_list = NULL,
2393 .flags = FLAG_ADVANCED,
2396 .label = "strict allocate",
2397 .type = P_BOOL,
2398 .p_class = P_LOCAL,
2399 .ptr = &sDefault.bStrictAllocate,
2400 .special = NULL,
2401 .enum_list = NULL,
2402 .flags = FLAG_ADVANCED | FLAG_SHARE,
2405 .label = "strict sync",
2406 .type = P_BOOL,
2407 .p_class = P_LOCAL,
2408 .ptr = &sDefault.bStrictSync,
2409 .special = NULL,
2410 .enum_list = NULL,
2411 .flags = FLAG_ADVANCED | FLAG_SHARE,
2414 .label = "sync always",
2415 .type = P_BOOL,
2416 .p_class = P_LOCAL,
2417 .ptr = &sDefault.bSyncAlways,
2418 .special = NULL,
2419 .enum_list = NULL,
2420 .flags = FLAG_ADVANCED | FLAG_SHARE,
2423 .label = "use mmap",
2424 .type = P_BOOL,
2425 .p_class = P_GLOBAL,
2426 .ptr = &Globals.bUseMmap,
2427 .special = NULL,
2428 .enum_list = NULL,
2429 .flags = FLAG_ADVANCED,
2432 .label = "use sendfile",
2433 .type = P_BOOL,
2434 .p_class = P_LOCAL,
2435 .ptr = &sDefault.bUseSendfile,
2436 .special = NULL,
2437 .enum_list = NULL,
2438 .flags = FLAG_ADVANCED | FLAG_SHARE,
2441 .label = "hostname lookups",
2442 .type = P_BOOL,
2443 .p_class = P_GLOBAL,
2444 .ptr = &Globals.bHostnameLookups,
2445 .special = NULL,
2446 .enum_list = NULL,
2447 .flags = FLAG_ADVANCED,
2450 .label = "write cache size",
2451 .type = P_INTEGER,
2452 .p_class = P_LOCAL,
2453 .ptr = &sDefault.iWriteCacheSize,
2454 .special = NULL,
2455 .enum_list = NULL,
2456 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2459 .label = "name cache timeout",
2460 .type = P_INTEGER,
2461 .p_class = P_GLOBAL,
2462 .ptr = &Globals.name_cache_timeout,
2463 .special = NULL,
2464 .enum_list = NULL,
2465 .flags = FLAG_ADVANCED,
2468 .label = "ctdbd socket",
2469 .type = P_STRING,
2470 .p_class = P_GLOBAL,
2471 .ptr = &Globals.ctdbdSocket,
2472 .special = NULL,
2473 .enum_list = NULL,
2474 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2477 .label = "cluster addresses",
2478 .type = P_LIST,
2479 .p_class = P_GLOBAL,
2480 .ptr = &Globals.szClusterAddresses,
2481 .special = NULL,
2482 .enum_list = NULL,
2483 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2486 .label = "clustering",
2487 .type = P_BOOL,
2488 .p_class = P_GLOBAL,
2489 .ptr = &Globals.clustering,
2490 .special = NULL,
2491 .enum_list = NULL,
2492 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2495 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2498 .label = "max reported print jobs",
2499 .type = P_INTEGER,
2500 .p_class = P_LOCAL,
2501 .ptr = &sDefault.iMaxReportedPrintJobs,
2502 .special = NULL,
2503 .enum_list = NULL,
2504 .flags = FLAG_ADVANCED | FLAG_PRINT,
2507 .label = "max print jobs",
2508 .type = P_INTEGER,
2509 .p_class = P_LOCAL,
2510 .ptr = &sDefault.iMaxPrintJobs,
2511 .special = NULL,
2512 .enum_list = NULL,
2513 .flags = FLAG_ADVANCED | FLAG_PRINT,
2516 .label = "load printers",
2517 .type = P_BOOL,
2518 .p_class = P_GLOBAL,
2519 .ptr = &Globals.bLoadPrinters,
2520 .special = NULL,
2521 .enum_list = NULL,
2522 .flags = FLAG_ADVANCED | FLAG_PRINT,
2525 .label = "printcap cache time",
2526 .type = P_INTEGER,
2527 .p_class = P_GLOBAL,
2528 .ptr = &Globals.PrintcapCacheTime,
2529 .special = NULL,
2530 .enum_list = NULL,
2531 .flags = FLAG_ADVANCED | FLAG_PRINT,
2534 .label = "printcap name",
2535 .type = P_STRING,
2536 .p_class = P_GLOBAL,
2537 .ptr = &Globals.szPrintcapname,
2538 .special = NULL,
2539 .enum_list = NULL,
2540 .flags = FLAG_ADVANCED | FLAG_PRINT,
2543 .label = "printcap",
2544 .type = P_STRING,
2545 .p_class = P_GLOBAL,
2546 .ptr = &Globals.szPrintcapname,
2547 .special = NULL,
2548 .enum_list = NULL,
2549 .flags = FLAG_HIDE,
2552 .label = "printable",
2553 .type = P_BOOL,
2554 .p_class = P_LOCAL,
2555 .ptr = &sDefault.bPrint_ok,
2556 .special = NULL,
2557 .enum_list = NULL,
2558 .flags = FLAG_ADVANCED | FLAG_PRINT,
2561 .label = "print ok",
2562 .type = P_BOOL,
2563 .p_class = P_LOCAL,
2564 .ptr = &sDefault.bPrint_ok,
2565 .special = NULL,
2566 .enum_list = NULL,
2567 .flags = FLAG_HIDE,
2570 .label = "printing",
2571 .type = P_ENUM,
2572 .p_class = P_LOCAL,
2573 .ptr = &sDefault.iPrinting,
2574 .special = handle_printing,
2575 .enum_list = enum_printing,
2576 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2579 .label = "cups options",
2580 .type = P_STRING,
2581 .p_class = P_LOCAL,
2582 .ptr = &sDefault.szCupsOptions,
2583 .special = NULL,
2584 .enum_list = NULL,
2585 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2588 .label = "cups server",
2589 .type = P_STRING,
2590 .p_class = P_GLOBAL,
2591 .ptr = &Globals.szCupsServer,
2592 .special = NULL,
2593 .enum_list = NULL,
2594 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2597 .label = "iprint server",
2598 .type = P_STRING,
2599 .p_class = P_GLOBAL,
2600 .ptr = &Globals.szIPrintServer,
2601 .special = NULL,
2602 .enum_list = NULL,
2603 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2606 .label = "print command",
2607 .type = P_STRING,
2608 .p_class = P_LOCAL,
2609 .ptr = &sDefault.szPrintcommand,
2610 .special = NULL,
2611 .enum_list = NULL,
2612 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2615 .label = "disable spoolss",
2616 .type = P_BOOL,
2617 .p_class = P_GLOBAL,
2618 .ptr = &Globals.bDisableSpoolss,
2619 .special = NULL,
2620 .enum_list = NULL,
2621 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2624 .label = "enable spoolss",
2625 .type = P_BOOLREV,
2626 .p_class = P_GLOBAL,
2627 .ptr = &Globals.bDisableSpoolss,
2628 .special = NULL,
2629 .enum_list = NULL,
2630 .flags = FLAG_HIDE,
2633 .label = "lpq command",
2634 .type = P_STRING,
2635 .p_class = P_LOCAL,
2636 .ptr = &sDefault.szLpqcommand,
2637 .special = NULL,
2638 .enum_list = NULL,
2639 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2642 .label = "lprm command",
2643 .type = P_STRING,
2644 .p_class = P_LOCAL,
2645 .ptr = &sDefault.szLprmcommand,
2646 .special = NULL,
2647 .enum_list = NULL,
2648 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2651 .label = "lppause command",
2652 .type = P_STRING,
2653 .p_class = P_LOCAL,
2654 .ptr = &sDefault.szLppausecommand,
2655 .special = NULL,
2656 .enum_list = NULL,
2657 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2660 .label = "lpresume command",
2661 .type = P_STRING,
2662 .p_class = P_LOCAL,
2663 .ptr = &sDefault.szLpresumecommand,
2664 .special = NULL,
2665 .enum_list = NULL,
2666 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2669 .label = "queuepause command",
2670 .type = P_STRING,
2671 .p_class = P_LOCAL,
2672 .ptr = &sDefault.szQueuepausecommand,
2673 .special = NULL,
2674 .enum_list = NULL,
2675 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2678 .label = "queueresume command",
2679 .type = P_STRING,
2680 .p_class = P_LOCAL,
2681 .ptr = &sDefault.szQueueresumecommand,
2682 .special = NULL,
2683 .enum_list = NULL,
2684 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2687 .label = "addport command",
2688 .type = P_STRING,
2689 .p_class = P_GLOBAL,
2690 .ptr = &Globals.szAddPortCommand,
2691 .special = NULL,
2692 .enum_list = NULL,
2693 .flags = FLAG_ADVANCED,
2696 .label = "enumports command",
2697 .type = P_STRING,
2698 .p_class = P_GLOBAL,
2699 .ptr = &Globals.szEnumPortsCommand,
2700 .special = NULL,
2701 .enum_list = NULL,
2702 .flags = FLAG_ADVANCED,
2705 .label = "addprinter command",
2706 .type = P_STRING,
2707 .p_class = P_GLOBAL,
2708 .ptr = &Globals.szAddPrinterCommand,
2709 .special = NULL,
2710 .enum_list = NULL,
2711 .flags = FLAG_ADVANCED,
2714 .label = "deleteprinter command",
2715 .type = P_STRING,
2716 .p_class = P_GLOBAL,
2717 .ptr = &Globals.szDeletePrinterCommand,
2718 .special = NULL,
2719 .enum_list = NULL,
2720 .flags = FLAG_ADVANCED,
2723 .label = "show add printer wizard",
2724 .type = P_BOOL,
2725 .p_class = P_GLOBAL,
2726 .ptr = &Globals.bMsAddPrinterWizard,
2727 .special = NULL,
2728 .enum_list = NULL,
2729 .flags = FLAG_ADVANCED,
2732 .label = "os2 driver map",
2733 .type = P_STRING,
2734 .p_class = P_GLOBAL,
2735 .ptr = &Globals.szOs2DriverMap,
2736 .special = NULL,
2737 .enum_list = NULL,
2738 .flags = FLAG_ADVANCED,
2742 .label = "printer name",
2743 .type = P_STRING,
2744 .p_class = P_LOCAL,
2745 .ptr = &sDefault.szPrintername,
2746 .special = NULL,
2747 .enum_list = NULL,
2748 .flags = FLAG_ADVANCED | FLAG_PRINT,
2751 .label = "printer",
2752 .type = P_STRING,
2753 .p_class = P_LOCAL,
2754 .ptr = &sDefault.szPrintername,
2755 .special = NULL,
2756 .enum_list = NULL,
2757 .flags = FLAG_HIDE,
2760 .label = "use client driver",
2761 .type = P_BOOL,
2762 .p_class = P_LOCAL,
2763 .ptr = &sDefault.bUseClientDriver,
2764 .special = NULL,
2765 .enum_list = NULL,
2766 .flags = FLAG_ADVANCED | FLAG_PRINT,
2769 .label = "default devmode",
2770 .type = P_BOOL,
2771 .p_class = P_LOCAL,
2772 .ptr = &sDefault.bDefaultDevmode,
2773 .special = NULL,
2774 .enum_list = NULL,
2775 .flags = FLAG_ADVANCED | FLAG_PRINT,
2778 .label = "force printername",
2779 .type = P_BOOL,
2780 .p_class = P_LOCAL,
2781 .ptr = &sDefault.bForcePrintername,
2782 .special = NULL,
2783 .enum_list = NULL,
2784 .flags = FLAG_ADVANCED | FLAG_PRINT,
2787 .label = "printjob username",
2788 .type = P_STRING,
2789 .p_class = P_LOCAL,
2790 .ptr = &sDefault.szPrintjobUsername,
2791 .special = NULL,
2792 .enum_list = NULL,
2793 .flags = FLAG_ADVANCED | FLAG_PRINT,
2796 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2799 .label = "mangling method",
2800 .type = P_STRING,
2801 .p_class = P_GLOBAL,
2802 .ptr = &Globals.szManglingMethod,
2803 .special = NULL,
2804 .enum_list = NULL,
2805 .flags = FLAG_ADVANCED,
2808 .label = "mangle prefix",
2809 .type = P_INTEGER,
2810 .p_class = P_GLOBAL,
2811 .ptr = &Globals.mangle_prefix,
2812 .special = NULL,
2813 .enum_list = NULL,
2814 .flags = FLAG_ADVANCED,
2818 .label = "default case",
2819 .type = P_ENUM,
2820 .p_class = P_LOCAL,
2821 .ptr = &sDefault.iDefaultCase,
2822 .special = NULL,
2823 .enum_list = enum_case,
2824 .flags = FLAG_ADVANCED | FLAG_SHARE,
2827 .label = "case sensitive",
2828 .type = P_ENUM,
2829 .p_class = P_LOCAL,
2830 .ptr = &sDefault.iCaseSensitive,
2831 .special = NULL,
2832 .enum_list = enum_bool_auto,
2833 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2836 .label = "casesignames",
2837 .type = P_ENUM,
2838 .p_class = P_LOCAL,
2839 .ptr = &sDefault.iCaseSensitive,
2840 .special = NULL,
2841 .enum_list = enum_bool_auto,
2842 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2845 .label = "preserve case",
2846 .type = P_BOOL,
2847 .p_class = P_LOCAL,
2848 .ptr = &sDefault.bCasePreserve,
2849 .special = NULL,
2850 .enum_list = NULL,
2851 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2854 .label = "short preserve case",
2855 .type = P_BOOL,
2856 .p_class = P_LOCAL,
2857 .ptr = &sDefault.bShortCasePreserve,
2858 .special = NULL,
2859 .enum_list = NULL,
2860 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2863 .label = "mangling char",
2864 .type = P_CHAR,
2865 .p_class = P_LOCAL,
2866 .ptr = &sDefault.magic_char,
2867 .special = NULL,
2868 .enum_list = NULL,
2869 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2872 .label = "hide dot files",
2873 .type = P_BOOL,
2874 .p_class = P_LOCAL,
2875 .ptr = &sDefault.bHideDotFiles,
2876 .special = NULL,
2877 .enum_list = NULL,
2878 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2881 .label = "hide special files",
2882 .type = P_BOOL,
2883 .p_class = P_LOCAL,
2884 .ptr = &sDefault.bHideSpecialFiles,
2885 .special = NULL,
2886 .enum_list = NULL,
2887 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2890 .label = "hide unreadable",
2891 .type = P_BOOL,
2892 .p_class = P_LOCAL,
2893 .ptr = &sDefault.bHideUnReadable,
2894 .special = NULL,
2895 .enum_list = NULL,
2896 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2899 .label = "hide unwriteable files",
2900 .type = P_BOOL,
2901 .p_class = P_LOCAL,
2902 .ptr = &sDefault.bHideUnWriteableFiles,
2903 .special = NULL,
2904 .enum_list = NULL,
2905 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2908 .label = "delete veto files",
2909 .type = P_BOOL,
2910 .p_class = P_LOCAL,
2911 .ptr = &sDefault.bDeleteVetoFiles,
2912 .special = NULL,
2913 .enum_list = NULL,
2914 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2917 .label = "veto files",
2918 .type = P_STRING,
2919 .p_class = P_LOCAL,
2920 .ptr = &sDefault.szVetoFiles,
2921 .special = NULL,
2922 .enum_list = NULL,
2923 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2926 .label = "hide files",
2927 .type = P_STRING,
2928 .p_class = P_LOCAL,
2929 .ptr = &sDefault.szHideFiles,
2930 .special = NULL,
2931 .enum_list = NULL,
2932 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2935 .label = "veto oplock files",
2936 .type = P_STRING,
2937 .p_class = P_LOCAL,
2938 .ptr = &sDefault.szVetoOplockFiles,
2939 .special = NULL,
2940 .enum_list = NULL,
2941 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2944 .label = "map archive",
2945 .type = P_BOOL,
2946 .p_class = P_LOCAL,
2947 .ptr = &sDefault.bMap_archive,
2948 .special = NULL,
2949 .enum_list = NULL,
2950 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2953 .label = "map hidden",
2954 .type = P_BOOL,
2955 .p_class = P_LOCAL,
2956 .ptr = &sDefault.bMap_hidden,
2957 .special = NULL,
2958 .enum_list = NULL,
2959 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2962 .label = "map system",
2963 .type = P_BOOL,
2964 .p_class = P_LOCAL,
2965 .ptr = &sDefault.bMap_system,
2966 .special = NULL,
2967 .enum_list = NULL,
2968 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2971 .label = "map readonly",
2972 .type = P_ENUM,
2973 .p_class = P_LOCAL,
2974 .ptr = &sDefault.iMap_readonly,
2975 .special = NULL,
2976 .enum_list = enum_map_readonly,
2977 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2980 .label = "mangled names",
2981 .type = P_BOOL,
2982 .p_class = P_LOCAL,
2983 .ptr = &sDefault.bMangledNames,
2984 .special = NULL,
2985 .enum_list = NULL,
2986 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2989 .label = "max stat cache size",
2990 .type = P_INTEGER,
2991 .p_class = P_GLOBAL,
2992 .ptr = &Globals.iMaxStatCacheSize,
2993 .special = NULL,
2994 .enum_list = NULL,
2995 .flags = FLAG_ADVANCED,
2998 .label = "stat cache",
2999 .type = P_BOOL,
3000 .p_class = P_GLOBAL,
3001 .ptr = &Globals.bStatCache,
3002 .special = NULL,
3003 .enum_list = NULL,
3004 .flags = FLAG_ADVANCED,
3007 .label = "store dos attributes",
3008 .type = P_BOOL,
3009 .p_class = P_LOCAL,
3010 .ptr = &sDefault.bStoreDosAttributes,
3011 .special = NULL,
3012 .enum_list = NULL,
3013 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3016 .label = "dmapi support",
3017 .type = P_BOOL,
3018 .p_class = P_LOCAL,
3019 .ptr = &sDefault.bDmapiSupport,
3020 .special = NULL,
3021 .enum_list = NULL,
3022 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3026 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3029 .label = "machine password timeout",
3030 .type = P_INTEGER,
3031 .p_class = P_GLOBAL,
3032 .ptr = &Globals.machine_password_timeout,
3033 .special = NULL,
3034 .enum_list = NULL,
3035 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3038 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3041 .label = "add user script",
3042 .type = P_STRING,
3043 .p_class = P_GLOBAL,
3044 .ptr = &Globals.szAddUserScript,
3045 .special = NULL,
3046 .enum_list = NULL,
3047 .flags = FLAG_ADVANCED,
3050 .label = "rename user script",
3051 .type = P_STRING,
3052 .p_class = P_GLOBAL,
3053 .ptr = &Globals.szRenameUserScript,
3054 .special = NULL,
3055 .enum_list = NULL,
3056 .flags = FLAG_ADVANCED,
3059 .label = "delete user script",
3060 .type = P_STRING,
3061 .p_class = P_GLOBAL,
3062 .ptr = &Globals.szDelUserScript,
3063 .special = NULL,
3064 .enum_list = NULL,
3065 .flags = FLAG_ADVANCED,
3068 .label = "add group script",
3069 .type = P_STRING,
3070 .p_class = P_GLOBAL,
3071 .ptr = &Globals.szAddGroupScript,
3072 .special = NULL,
3073 .enum_list = NULL,
3074 .flags = FLAG_ADVANCED,
3077 .label = "delete group script",
3078 .type = P_STRING,
3079 .p_class = P_GLOBAL,
3080 .ptr = &Globals.szDelGroupScript,
3081 .special = NULL,
3082 .enum_list = NULL,
3083 .flags = FLAG_ADVANCED,
3086 .label = "add user to group script",
3087 .type = P_STRING,
3088 .p_class = P_GLOBAL,
3089 .ptr = &Globals.szAddUserToGroupScript,
3090 .special = NULL,
3091 .enum_list = NULL,
3092 .flags = FLAG_ADVANCED,
3095 .label = "delete user from group script",
3096 .type = P_STRING,
3097 .p_class = P_GLOBAL,
3098 .ptr = &Globals.szDelUserFromGroupScript,
3099 .special = NULL,
3100 .enum_list = NULL,
3101 .flags = FLAG_ADVANCED,
3104 .label = "set primary group script",
3105 .type = P_STRING,
3106 .p_class = P_GLOBAL,
3107 .ptr = &Globals.szSetPrimaryGroupScript,
3108 .special = NULL,
3109 .enum_list = NULL,
3110 .flags = FLAG_ADVANCED,
3113 .label = "add machine script",
3114 .type = P_STRING,
3115 .p_class = P_GLOBAL,
3116 .ptr = &Globals.szAddMachineScript,
3117 .special = NULL,
3118 .enum_list = NULL,
3119 .flags = FLAG_ADVANCED,
3122 .label = "shutdown script",
3123 .type = P_STRING,
3124 .p_class = P_GLOBAL,
3125 .ptr = &Globals.szShutdownScript,
3126 .special = NULL,
3127 .enum_list = NULL,
3128 .flags = FLAG_ADVANCED,
3131 .label = "abort shutdown script",
3132 .type = P_STRING,
3133 .p_class = P_GLOBAL,
3134 .ptr = &Globals.szAbortShutdownScript,
3135 .special = NULL,
3136 .enum_list = NULL,
3137 .flags = FLAG_ADVANCED,
3140 .label = "username map script",
3141 .type = P_STRING,
3142 .p_class = P_GLOBAL,
3143 .ptr = &Globals.szUsernameMapScript,
3144 .special = NULL,
3145 .enum_list = NULL,
3146 .flags = FLAG_ADVANCED,
3149 .label = "logon script",
3150 .type = P_STRING,
3151 .p_class = P_GLOBAL,
3152 .ptr = &Globals.szLogonScript,
3153 .special = NULL,
3154 .enum_list = NULL,
3155 .flags = FLAG_ADVANCED,
3158 .label = "logon path",
3159 .type = P_STRING,
3160 .p_class = P_GLOBAL,
3161 .ptr = &Globals.szLogonPath,
3162 .special = NULL,
3163 .enum_list = NULL,
3164 .flags = FLAG_ADVANCED,
3167 .label = "logon drive",
3168 .type = P_STRING,
3169 .p_class = P_GLOBAL,
3170 .ptr = &Globals.szLogonDrive,
3171 .special = NULL,
3172 .enum_list = NULL,
3173 .flags = FLAG_ADVANCED,
3176 .label = "logon home",
3177 .type = P_STRING,
3178 .p_class = P_GLOBAL,
3179 .ptr = &Globals.szLogonHome,
3180 .special = NULL,
3181 .enum_list = NULL,
3182 .flags = FLAG_ADVANCED,
3185 .label = "domain logons",
3186 .type = P_BOOL,
3187 .p_class = P_GLOBAL,
3188 .ptr = &Globals.bDomainLogons,
3189 .special = NULL,
3190 .enum_list = NULL,
3191 .flags = FLAG_ADVANCED,
3194 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3197 .label = "os level",
3198 .type = P_INTEGER,
3199 .p_class = P_GLOBAL,
3200 .ptr = &Globals.os_level,
3201 .special = NULL,
3202 .enum_list = NULL,
3203 .flags = FLAG_BASIC | FLAG_ADVANCED,
3206 .label = "lm announce",
3207 .type = P_ENUM,
3208 .p_class = P_GLOBAL,
3209 .ptr = &Globals.lm_announce,
3210 .special = NULL,
3211 .enum_list = enum_bool_auto,
3212 .flags = FLAG_ADVANCED,
3215 .label = "lm interval",
3216 .type = P_INTEGER,
3217 .p_class = P_GLOBAL,
3218 .ptr = &Globals.lm_interval,
3219 .special = NULL,
3220 .enum_list = NULL,
3221 .flags = FLAG_ADVANCED,
3224 .label = "preferred master",
3225 .type = P_ENUM,
3226 .p_class = P_GLOBAL,
3227 .ptr = &Globals.iPreferredMaster,
3228 .special = NULL,
3229 .enum_list = enum_bool_auto,
3230 .flags = FLAG_BASIC | FLAG_ADVANCED,
3233 .label = "prefered master",
3234 .type = P_ENUM,
3235 .p_class = P_GLOBAL,
3236 .ptr = &Globals.iPreferredMaster,
3237 .special = NULL,
3238 .enum_list = enum_bool_auto,
3239 .flags = FLAG_HIDE,
3242 .label = "local master",
3243 .type = P_BOOL,
3244 .p_class = P_GLOBAL,
3245 .ptr = &Globals.bLocalMaster,
3246 .special = NULL,
3247 .enum_list = NULL,
3248 .flags = FLAG_BASIC | FLAG_ADVANCED,
3251 .label = "domain master",
3252 .type = P_ENUM,
3253 .p_class = P_GLOBAL,
3254 .ptr = &Globals.iDomainMaster,
3255 .special = NULL,
3256 .enum_list = enum_bool_auto,
3257 .flags = FLAG_BASIC | FLAG_ADVANCED,
3260 .label = "browse list",
3261 .type = P_BOOL,
3262 .p_class = P_GLOBAL,
3263 .ptr = &Globals.bBrowseList,
3264 .special = NULL,
3265 .enum_list = NULL,
3266 .flags = FLAG_ADVANCED,
3269 .label = "browseable",
3270 .type = P_BOOL,
3271 .p_class = P_LOCAL,
3272 .ptr = &sDefault.bBrowseable,
3273 .special = NULL,
3274 .enum_list = NULL,
3275 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3278 .label = "browsable",
3279 .type = P_BOOL,
3280 .p_class = P_LOCAL,
3281 .ptr = &sDefault.bBrowseable,
3282 .special = NULL,
3283 .enum_list = NULL,
3284 .flags = FLAG_HIDE,
3287 .label = "enhanced browsing",
3288 .type = P_BOOL,
3289 .p_class = P_GLOBAL,
3290 .ptr = &Globals.enhanced_browsing,
3291 .special = NULL,
3292 .enum_list = NULL,
3293 .flags = FLAG_ADVANCED,
3296 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3299 .label = "dns proxy",
3300 .type = P_BOOL,
3301 .p_class = P_GLOBAL,
3302 .ptr = &Globals.bDNSproxy,
3303 .special = NULL,
3304 .enum_list = NULL,
3305 .flags = FLAG_ADVANCED,
3308 .label = "wins proxy",
3309 .type = P_BOOL,
3310 .p_class = P_GLOBAL,
3311 .ptr = &Globals.bWINSproxy,
3312 .special = NULL,
3313 .enum_list = NULL,
3314 .flags = FLAG_ADVANCED,
3317 .label = "wins server",
3318 .type = P_LIST,
3319 .p_class = P_GLOBAL,
3320 .ptr = &Globals.szWINSservers,
3321 .special = NULL,
3322 .enum_list = NULL,
3323 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3326 .label = "wins support",
3327 .type = P_BOOL,
3328 .p_class = P_GLOBAL,
3329 .ptr = &Globals.bWINSsupport,
3330 .special = NULL,
3331 .enum_list = NULL,
3332 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3335 .label = "wins hook",
3336 .type = P_STRING,
3337 .p_class = P_GLOBAL,
3338 .ptr = &Globals.szWINSHook,
3339 .special = NULL,
3340 .enum_list = NULL,
3341 .flags = FLAG_ADVANCED,
3344 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3347 .label = "blocking locks",
3348 .type = P_BOOL,
3349 .p_class = P_LOCAL,
3350 .ptr = &sDefault.bBlockingLocks,
3351 .special = NULL,
3352 .enum_list = NULL,
3353 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3356 .label = "csc policy",
3357 .type = P_ENUM,
3358 .p_class = P_LOCAL,
3359 .ptr = &sDefault.iCSCPolicy,
3360 .special = NULL,
3361 .enum_list = enum_csc_policy,
3362 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3365 .label = "fake oplocks",
3366 .type = P_BOOL,
3367 .p_class = P_LOCAL,
3368 .ptr = &sDefault.bFakeOplocks,
3369 .special = NULL,
3370 .enum_list = NULL,
3371 .flags = FLAG_ADVANCED | FLAG_SHARE,
3374 .label = "kernel oplocks",
3375 .type = P_BOOL,
3376 .p_class = P_GLOBAL,
3377 .ptr = &Globals.bKernelOplocks,
3378 .special = NULL,
3379 .enum_list = NULL,
3380 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3383 .label = "locking",
3384 .type = P_BOOL,
3385 .p_class = P_LOCAL,
3386 .ptr = &sDefault.bLocking,
3387 .special = NULL,
3388 .enum_list = NULL,
3389 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3392 .label = "lock spin time",
3393 .type = P_INTEGER,
3394 .p_class = P_GLOBAL,
3395 .ptr = &Globals.iLockSpinTime,
3396 .special = NULL,
3397 .enum_list = NULL,
3398 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3401 .label = "oplocks",
3402 .type = P_BOOL,
3403 .p_class = P_LOCAL,
3404 .ptr = &sDefault.bOpLocks,
3405 .special = NULL,
3406 .enum_list = NULL,
3407 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3410 .label = "level2 oplocks",
3411 .type = P_BOOL,
3412 .p_class = P_LOCAL,
3413 .ptr = &sDefault.bLevel2OpLocks,
3414 .special = NULL,
3415 .enum_list = NULL,
3416 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3419 .label = "oplock break wait time",
3420 .type = P_INTEGER,
3421 .p_class = P_GLOBAL,
3422 .ptr = &Globals.oplock_break_wait_time,
3423 .special = NULL,
3424 .enum_list = NULL,
3425 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3428 .label = "oplock contention limit",
3429 .type = P_INTEGER,
3430 .p_class = P_LOCAL,
3431 .ptr = &sDefault.iOplockContentionLimit,
3432 .special = NULL,
3433 .enum_list = NULL,
3434 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3437 .label = "posix locking",
3438 .type = P_BOOL,
3439 .p_class = P_LOCAL,
3440 .ptr = &sDefault.bPosixLocking,
3441 .special = NULL,
3442 .enum_list = NULL,
3443 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3446 .label = "strict locking",
3447 .type = P_ENUM,
3448 .p_class = P_LOCAL,
3449 .ptr = &sDefault.iStrictLocking,
3450 .special = NULL,
3451 .enum_list = enum_bool_auto,
3452 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3455 .label = "share modes",
3456 .type = P_BOOL,
3457 .p_class = P_LOCAL,
3458 .ptr = &sDefault.bShareModes,
3459 .special = NULL,
3460 .enum_list = NULL,
3461 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3464 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3467 .label = "ldap admin dn",
3468 .type = P_STRING,
3469 .p_class = P_GLOBAL,
3470 .ptr = &Globals.szLdapAdminDn,
3471 .special = NULL,
3472 .enum_list = NULL,
3473 .flags = FLAG_ADVANCED,
3476 .label = "ldap delete dn",
3477 .type = P_BOOL,
3478 .p_class = P_GLOBAL,
3479 .ptr = &Globals.ldap_delete_dn,
3480 .special = NULL,
3481 .enum_list = NULL,
3482 .flags = FLAG_ADVANCED,
3485 .label = "ldap group suffix",
3486 .type = P_STRING,
3487 .p_class = P_GLOBAL,
3488 .ptr = &Globals.szLdapGroupSuffix,
3489 .special = NULL,
3490 .enum_list = NULL,
3491 .flags = FLAG_ADVANCED,
3494 .label = "ldap idmap suffix",
3495 .type = P_STRING,
3496 .p_class = P_GLOBAL,
3497 .ptr = &Globals.szLdapIdmapSuffix,
3498 .special = NULL,
3499 .enum_list = NULL,
3500 .flags = FLAG_ADVANCED,
3503 .label = "ldap machine suffix",
3504 .type = P_STRING,
3505 .p_class = P_GLOBAL,
3506 .ptr = &Globals.szLdapMachineSuffix,
3507 .special = NULL,
3508 .enum_list = NULL,
3509 .flags = FLAG_ADVANCED,
3512 .label = "ldap passwd sync",
3513 .type = P_ENUM,
3514 .p_class = P_GLOBAL,
3515 .ptr = &Globals.ldap_passwd_sync,
3516 .special = NULL,
3517 .enum_list = enum_ldap_passwd_sync,
3518 .flags = FLAG_ADVANCED,
3521 .label = "ldap password sync",
3522 .type = P_ENUM,
3523 .p_class = P_GLOBAL,
3524 .ptr = &Globals.ldap_passwd_sync,
3525 .special = NULL,
3526 .enum_list = enum_ldap_passwd_sync,
3527 .flags = FLAG_HIDE,
3530 .label = "ldap replication sleep",
3531 .type = P_INTEGER,
3532 .p_class = P_GLOBAL,
3533 .ptr = &Globals.ldap_replication_sleep,
3534 .special = NULL,
3535 .enum_list = NULL,
3536 .flags = FLAG_ADVANCED,
3539 .label = "ldap suffix",
3540 .type = P_STRING,
3541 .p_class = P_GLOBAL,
3542 .ptr = &Globals.szLdapSuffix,
3543 .special = NULL,
3544 .enum_list = NULL,
3545 .flags = FLAG_ADVANCED,
3548 .label = "ldap ssl",
3549 .type = P_ENUM,
3550 .p_class = P_GLOBAL,
3551 .ptr = &Globals.ldap_ssl,
3552 .special = NULL,
3553 .enum_list = enum_ldap_ssl,
3554 .flags = FLAG_ADVANCED,
3557 .label = "ldap timeout",
3558 .type = P_INTEGER,
3559 .p_class = P_GLOBAL,
3560 .ptr = &Globals.ldap_timeout,
3561 .special = NULL,
3562 .enum_list = NULL,
3563 .flags = FLAG_ADVANCED,
3566 .label = "ldap connection timeout",
3567 .type = P_INTEGER,
3568 .p_class = P_GLOBAL,
3569 .ptr = &Globals.ldap_connection_timeout,
3570 .special = NULL,
3571 .enum_list = NULL,
3572 .flags = FLAG_ADVANCED,
3575 .label = "ldap page size",
3576 .type = P_INTEGER,
3577 .p_class = P_GLOBAL,
3578 .ptr = &Globals.ldap_page_size,
3579 .special = NULL,
3580 .enum_list = NULL,
3581 .flags = FLAG_ADVANCED,
3584 .label = "ldap user suffix",
3585 .type = P_STRING,
3586 .p_class = P_GLOBAL,
3587 .ptr = &Globals.szLdapUserSuffix,
3588 .special = NULL,
3589 .enum_list = NULL,
3590 .flags = FLAG_ADVANCED,
3593 .label = "ldap debug level",
3594 .type = P_INTEGER,
3595 .p_class = P_GLOBAL,
3596 .ptr = &Globals.ldap_debug_level,
3597 .special = handle_ldap_debug_level,
3598 .enum_list = NULL,
3599 .flags = FLAG_ADVANCED,
3602 .label = "ldap debug threshold",
3603 .type = P_INTEGER,
3604 .p_class = P_GLOBAL,
3605 .ptr = &Globals.ldap_debug_threshold,
3606 .special = NULL,
3607 .enum_list = NULL,
3608 .flags = FLAG_ADVANCED,
3611 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3614 .label = "eventlog list",
3615 .type = P_LIST,
3616 .p_class = P_GLOBAL,
3617 .ptr = &Globals.szEventLogs,
3618 .special = NULL,
3619 .enum_list = NULL,
3620 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3623 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3626 .label = "add share command",
3627 .type = P_STRING,
3628 .p_class = P_GLOBAL,
3629 .ptr = &Globals.szAddShareCommand,
3630 .special = NULL,
3631 .enum_list = NULL,
3632 .flags = FLAG_ADVANCED,
3635 .label = "change share command",
3636 .type = P_STRING,
3637 .p_class = P_GLOBAL,
3638 .ptr = &Globals.szChangeShareCommand,
3639 .special = NULL,
3640 .enum_list = NULL,
3641 .flags = FLAG_ADVANCED,
3644 .label = "delete share command",
3645 .type = P_STRING,
3646 .p_class = P_GLOBAL,
3647 .ptr = &Globals.szDeleteShareCommand,
3648 .special = NULL,
3649 .enum_list = NULL,
3650 .flags = FLAG_ADVANCED,
3653 .label = "config file",
3654 .type = P_STRING,
3655 .p_class = P_GLOBAL,
3656 .ptr = &Globals.szConfigFile,
3657 .special = NULL,
3658 .enum_list = NULL,
3659 .flags = FLAG_HIDE,
3662 .label = "preload",
3663 .type = P_STRING,
3664 .p_class = P_GLOBAL,
3665 .ptr = &Globals.szAutoServices,
3666 .special = NULL,
3667 .enum_list = NULL,
3668 .flags = FLAG_ADVANCED,
3671 .label = "auto services",
3672 .type = P_STRING,
3673 .p_class = P_GLOBAL,
3674 .ptr = &Globals.szAutoServices,
3675 .special = NULL,
3676 .enum_list = NULL,
3677 .flags = FLAG_ADVANCED,
3680 .label = "lock directory",
3681 .type = P_STRING,
3682 .p_class = P_GLOBAL,
3683 .ptr = &Globals.szLockDir,
3684 .special = NULL,
3685 .enum_list = NULL,
3686 .flags = FLAG_ADVANCED,
3689 .label = "lock dir",
3690 .type = P_STRING,
3691 .p_class = P_GLOBAL,
3692 .ptr = &Globals.szLockDir,
3693 .special = NULL,
3694 .enum_list = NULL,
3695 .flags = FLAG_HIDE,
3698 .label = "pid directory",
3699 .type = P_STRING,
3700 .p_class = P_GLOBAL,
3701 .ptr = &Globals.szPidDir,
3702 .special = NULL,
3703 .enum_list = NULL,
3704 .flags = FLAG_ADVANCED,
3706 #ifdef WITH_UTMP
3708 .label = "utmp directory",
3709 .type = P_STRING,
3710 .p_class = P_GLOBAL,
3711 .ptr = &Globals.szUtmpDir,
3712 .special = NULL,
3713 .enum_list = NULL,
3714 .flags = FLAG_ADVANCED,
3717 .label = "wtmp directory",
3718 .type = P_STRING,
3719 .p_class = P_GLOBAL,
3720 .ptr = &Globals.szWtmpDir,
3721 .special = NULL,
3722 .enum_list = NULL,
3723 .flags = FLAG_ADVANCED,
3726 .label = "utmp",
3727 .type = P_BOOL,
3728 .p_class = P_GLOBAL,
3729 .ptr = &Globals.bUtmp,
3730 .special = NULL,
3731 .enum_list = NULL,
3732 .flags = FLAG_ADVANCED,
3734 #endif
3736 .label = "default service",
3737 .type = P_STRING,
3738 .p_class = P_GLOBAL,
3739 .ptr = &Globals.szDefaultService,
3740 .special = NULL,
3741 .enum_list = NULL,
3742 .flags = FLAG_ADVANCED,
3745 .label = "default",
3746 .type = P_STRING,
3747 .p_class = P_GLOBAL,
3748 .ptr = &Globals.szDefaultService,
3749 .special = NULL,
3750 .enum_list = NULL,
3751 .flags = FLAG_ADVANCED,
3754 .label = "message command",
3755 .type = P_STRING,
3756 .p_class = P_GLOBAL,
3757 .ptr = &Globals.szMsgCommand,
3758 .special = NULL,
3759 .enum_list = NULL,
3760 .flags = FLAG_ADVANCED,
3763 .label = "dfree cache time",
3764 .type = P_INTEGER,
3765 .p_class = P_LOCAL,
3766 .ptr = &sDefault.iDfreeCacheTime,
3767 .special = NULL,
3768 .enum_list = NULL,
3769 .flags = FLAG_ADVANCED,
3772 .label = "dfree command",
3773 .type = P_STRING,
3774 .p_class = P_LOCAL,
3775 .ptr = &sDefault.szDfree,
3776 .special = NULL,
3777 .enum_list = NULL,
3778 .flags = FLAG_ADVANCED,
3781 .label = "get quota command",
3782 .type = P_STRING,
3783 .p_class = P_GLOBAL,
3784 .ptr = &Globals.szGetQuota,
3785 .special = NULL,
3786 .enum_list = NULL,
3787 .flags = FLAG_ADVANCED,
3790 .label = "set quota command",
3791 .type = P_STRING,
3792 .p_class = P_GLOBAL,
3793 .ptr = &Globals.szSetQuota,
3794 .special = NULL,
3795 .enum_list = NULL,
3796 .flags = FLAG_ADVANCED,
3799 .label = "remote announce",
3800 .type = P_STRING,
3801 .p_class = P_GLOBAL,
3802 .ptr = &Globals.szRemoteAnnounce,
3803 .special = NULL,
3804 .enum_list = NULL,
3805 .flags = FLAG_ADVANCED,
3808 .label = "remote browse sync",
3809 .type = P_STRING,
3810 .p_class = P_GLOBAL,
3811 .ptr = &Globals.szRemoteBrowseSync,
3812 .special = NULL,
3813 .enum_list = NULL,
3814 .flags = FLAG_ADVANCED,
3817 .label = "socket address",
3818 .type = P_STRING,
3819 .p_class = P_GLOBAL,
3820 .ptr = &Globals.szSocketAddress,
3821 .special = NULL,
3822 .enum_list = NULL,
3823 .flags = FLAG_ADVANCED,
3826 .label = "homedir map",
3827 .type = P_STRING,
3828 .p_class = P_GLOBAL,
3829 .ptr = &Globals.szNISHomeMapName,
3830 .special = NULL,
3831 .enum_list = NULL,
3832 .flags = FLAG_ADVANCED,
3835 .label = "afs username map",
3836 .type = P_STRING,
3837 .p_class = P_GLOBAL,
3838 .ptr = &Globals.szAfsUsernameMap,
3839 .special = NULL,
3840 .enum_list = NULL,
3841 .flags = FLAG_ADVANCED,
3844 .label = "afs token lifetime",
3845 .type = P_INTEGER,
3846 .p_class = P_GLOBAL,
3847 .ptr = &Globals.iAfsTokenLifetime,
3848 .special = NULL,
3849 .enum_list = NULL,
3850 .flags = FLAG_ADVANCED,
3853 .label = "log nt token command",
3854 .type = P_STRING,
3855 .p_class = P_GLOBAL,
3856 .ptr = &Globals.szLogNtTokenCommand,
3857 .special = NULL,
3858 .enum_list = NULL,
3859 .flags = FLAG_ADVANCED,
3862 .label = "time offset",
3863 .type = P_INTEGER,
3864 .p_class = P_GLOBAL,
3865 .ptr = &extra_time_offset,
3866 .special = NULL,
3867 .enum_list = NULL,
3868 .flags = FLAG_ADVANCED,
3871 .label = "NIS homedir",
3872 .type = P_BOOL,
3873 .p_class = P_GLOBAL,
3874 .ptr = &Globals.bNISHomeMap,
3875 .special = NULL,
3876 .enum_list = NULL,
3877 .flags = FLAG_ADVANCED,
3880 .label = "-valid",
3881 .type = P_BOOL,
3882 .p_class = P_LOCAL,
3883 .ptr = &sDefault.valid,
3884 .special = NULL,
3885 .enum_list = NULL,
3886 .flags = FLAG_HIDE,
3889 .label = "copy",
3890 .type = P_STRING,
3891 .p_class = P_LOCAL,
3892 .ptr = &sDefault.szCopy,
3893 .special = handle_copy,
3894 .enum_list = NULL,
3895 .flags = FLAG_HIDE,
3898 .label = "include",
3899 .type = P_STRING,
3900 .p_class = P_LOCAL,
3901 .ptr = &sDefault.szInclude,
3902 .special = handle_include,
3903 .enum_list = NULL,
3904 .flags = FLAG_HIDE,
3907 .label = "preexec",
3908 .type = P_STRING,
3909 .p_class = P_LOCAL,
3910 .ptr = &sDefault.szPreExec,
3911 .special = NULL,
3912 .enum_list = NULL,
3913 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3916 .label = "exec",
3917 .type = P_STRING,
3918 .p_class = P_LOCAL,
3919 .ptr = &sDefault.szPreExec,
3920 .special = NULL,
3921 .enum_list = NULL,
3922 .flags = FLAG_ADVANCED,
3925 .label = "preexec close",
3926 .type = P_BOOL,
3927 .p_class = P_LOCAL,
3928 .ptr = &sDefault.bPreexecClose,
3929 .special = NULL,
3930 .enum_list = NULL,
3931 .flags = FLAG_ADVANCED | FLAG_SHARE,
3934 .label = "postexec",
3935 .type = P_STRING,
3936 .p_class = P_LOCAL,
3937 .ptr = &sDefault.szPostExec,
3938 .special = NULL,
3939 .enum_list = NULL,
3940 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3943 .label = "root preexec",
3944 .type = P_STRING,
3945 .p_class = P_LOCAL,
3946 .ptr = &sDefault.szRootPreExec,
3947 .special = NULL,
3948 .enum_list = NULL,
3949 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3952 .label = "root preexec close",
3953 .type = P_BOOL,
3954 .p_class = P_LOCAL,
3955 .ptr = &sDefault.bRootpreexecClose,
3956 .special = NULL,
3957 .enum_list = NULL,
3958 .flags = FLAG_ADVANCED | FLAG_SHARE,
3961 .label = "root postexec",
3962 .type = P_STRING,
3963 .p_class = P_LOCAL,
3964 .ptr = &sDefault.szRootPostExec,
3965 .special = NULL,
3966 .enum_list = NULL,
3967 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3970 .label = "available",
3971 .type = P_BOOL,
3972 .p_class = P_LOCAL,
3973 .ptr = &sDefault.bAvailable,
3974 .special = NULL,
3975 .enum_list = NULL,
3976 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3979 .label = "registry shares",
3980 .type = P_BOOL,
3981 .p_class = P_GLOBAL,
3982 .ptr = &Globals.bRegistryShares,
3983 .special = NULL,
3984 .enum_list = NULL,
3985 .flags = FLAG_ADVANCED,
3988 .label = "usershare allow guests",
3989 .type = P_BOOL,
3990 .p_class = P_GLOBAL,
3991 .ptr = &Globals.bUsershareAllowGuests,
3992 .special = NULL,
3993 .enum_list = NULL,
3994 .flags = FLAG_ADVANCED,
3997 .label = "usershare max shares",
3998 .type = P_INTEGER,
3999 .p_class = P_GLOBAL,
4000 .ptr = &Globals.iUsershareMaxShares,
4001 .special = NULL,
4002 .enum_list = NULL,
4003 .flags = FLAG_ADVANCED,
4006 .label = "usershare owner only",
4007 .type = P_BOOL,
4008 .p_class = P_GLOBAL,
4009 .ptr = &Globals.bUsershareOwnerOnly,
4010 .special = NULL,
4011 .enum_list = NULL,
4012 .flags = FLAG_ADVANCED,
4015 .label = "usershare path",
4016 .type = P_STRING,
4017 .p_class = P_GLOBAL,
4018 .ptr = &Globals.szUsersharePath,
4019 .special = NULL,
4020 .enum_list = NULL,
4021 .flags = FLAG_ADVANCED,
4024 .label = "usershare prefix allow list",
4025 .type = P_LIST,
4026 .p_class = P_GLOBAL,
4027 .ptr = &Globals.szUsersharePrefixAllowList,
4028 .special = NULL,
4029 .enum_list = NULL,
4030 .flags = FLAG_ADVANCED,
4033 .label = "usershare prefix deny list",
4034 .type = P_LIST,
4035 .p_class = P_GLOBAL,
4036 .ptr = &Globals.szUsersharePrefixDenyList,
4037 .special = NULL,
4038 .enum_list = NULL,
4039 .flags = FLAG_ADVANCED,
4042 .label = "usershare template share",
4043 .type = P_STRING,
4044 .p_class = P_GLOBAL,
4045 .ptr = &Globals.szUsershareTemplateShare,
4046 .special = NULL,
4047 .enum_list = NULL,
4048 .flags = FLAG_ADVANCED,
4051 .label = "volume",
4052 .type = P_STRING,
4053 .p_class = P_LOCAL,
4054 .ptr = &sDefault.volume,
4055 .special = NULL,
4056 .enum_list = NULL,
4057 .flags = FLAG_ADVANCED | FLAG_SHARE,
4060 .label = "fstype",
4061 .type = P_STRING,
4062 .p_class = P_LOCAL,
4063 .ptr = &sDefault.fstype,
4064 .special = NULL,
4065 .enum_list = NULL,
4066 .flags = FLAG_ADVANCED | FLAG_SHARE,
4069 .label = "set directory",
4070 .type = P_BOOLREV,
4071 .p_class = P_LOCAL,
4072 .ptr = &sDefault.bNo_set_dir,
4073 .special = NULL,
4074 .enum_list = NULL,
4075 .flags = FLAG_ADVANCED | FLAG_SHARE,
4078 .label = "wide links",
4079 .type = P_BOOL,
4080 .p_class = P_LOCAL,
4081 .ptr = &sDefault.bWidelinks,
4082 .special = NULL,
4083 .enum_list = NULL,
4084 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4087 .label = "follow symlinks",
4088 .type = P_BOOL,
4089 .p_class = P_LOCAL,
4090 .ptr = &sDefault.bSymlinks,
4091 .special = NULL,
4092 .enum_list = NULL,
4093 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4096 .label = "dont descend",
4097 .type = P_STRING,
4098 .p_class = P_LOCAL,
4099 .ptr = &sDefault.szDontdescend,
4100 .special = NULL,
4101 .enum_list = NULL,
4102 .flags = FLAG_ADVANCED | FLAG_SHARE,
4105 .label = "magic script",
4106 .type = P_STRING,
4107 .p_class = P_LOCAL,
4108 .ptr = &sDefault.szMagicScript,
4109 .special = NULL,
4110 .enum_list = NULL,
4111 .flags = FLAG_ADVANCED | FLAG_SHARE,
4114 .label = "magic output",
4115 .type = P_STRING,
4116 .p_class = P_LOCAL,
4117 .ptr = &sDefault.szMagicOutput,
4118 .special = NULL,
4119 .enum_list = NULL,
4120 .flags = FLAG_ADVANCED | FLAG_SHARE,
4123 .label = "delete readonly",
4124 .type = P_BOOL,
4125 .p_class = P_LOCAL,
4126 .ptr = &sDefault.bDeleteReadonly,
4127 .special = NULL,
4128 .enum_list = NULL,
4129 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4132 .label = "dos filemode",
4133 .type = P_BOOL,
4134 .p_class = P_LOCAL,
4135 .ptr = &sDefault.bDosFilemode,
4136 .special = NULL,
4137 .enum_list = NULL,
4138 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4141 .label = "dos filetimes",
4142 .type = P_BOOL,
4143 .p_class = P_LOCAL,
4144 .ptr = &sDefault.bDosFiletimes,
4145 .special = NULL,
4146 .enum_list = NULL,
4147 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4150 .label = "dos filetime resolution",
4151 .type = P_BOOL,
4152 .p_class = P_LOCAL,
4153 .ptr = &sDefault.bDosFiletimeResolution,
4154 .special = NULL,
4155 .enum_list = NULL,
4156 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4159 .label = "fake directory create times",
4160 .type = P_BOOL,
4161 .p_class = P_LOCAL,
4162 .ptr = &sDefault.bFakeDirCreateTimes,
4163 .special = NULL,
4164 .enum_list = NULL,
4165 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4168 .label = "panic action",
4169 .type = P_STRING,
4170 .p_class = P_GLOBAL,
4171 .ptr = &Globals.szPanicAction,
4172 .special = NULL,
4173 .enum_list = NULL,
4174 .flags = FLAG_ADVANCED,
4177 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4180 .label = "vfs objects",
4181 .type = P_LIST,
4182 .p_class = P_LOCAL,
4183 .ptr = &sDefault.szVfsObjects,
4184 .special = NULL,
4185 .enum_list = NULL,
4186 .flags = FLAG_ADVANCED | FLAG_SHARE,
4189 .label = "vfs object",
4190 .type = P_LIST,
4191 .p_class = P_LOCAL,
4192 .ptr = &sDefault.szVfsObjects,
4193 .special = NULL,
4194 .enum_list = NULL,
4195 .flags = FLAG_HIDE,
4199 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4202 .label = "msdfs root",
4203 .type = P_BOOL,
4204 .p_class = P_LOCAL,
4205 .ptr = &sDefault.bMSDfsRoot,
4206 .special = NULL,
4207 .enum_list = NULL,
4208 .flags = FLAG_ADVANCED | FLAG_SHARE,
4211 .label = "msdfs proxy",
4212 .type = P_STRING,
4213 .p_class = P_LOCAL,
4214 .ptr = &sDefault.szMSDfsProxy,
4215 .special = NULL,
4216 .enum_list = NULL,
4217 .flags = FLAG_ADVANCED | FLAG_SHARE,
4220 .label = "host msdfs",
4221 .type = P_BOOL,
4222 .p_class = P_GLOBAL,
4223 .ptr = &Globals.bHostMSDfs,
4224 .special = NULL,
4225 .enum_list = NULL,
4226 .flags = FLAG_ADVANCED,
4229 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4232 .label = "passdb expand explicit",
4233 .type = P_BOOL,
4234 .p_class = P_GLOBAL,
4235 .ptr = &Globals.bPassdbExpandExplicit,
4236 .special = NULL,
4237 .enum_list = NULL,
4238 .flags = FLAG_ADVANCED,
4241 .label = "idmap domains",
4242 .type = P_LIST,
4243 .p_class = P_GLOBAL,
4244 .ptr = &Globals.szIdmapDomains,
4245 .special = NULL,
4246 .enum_list = NULL,
4247 .flags = FLAG_ADVANCED,
4250 .label = "idmap backend",
4251 .type = P_LIST,
4252 .p_class = P_GLOBAL,
4253 .ptr = &Globals.szIdmapBackend,
4254 .special = NULL,
4255 .enum_list = NULL,
4256 .flags = FLAG_ADVANCED,
4259 .label = "idmap alloc backend",
4260 .type = P_STRING,
4261 .p_class = P_GLOBAL,
4262 .ptr = &Globals.szIdmapAllocBackend,
4263 .special = NULL,
4264 .enum_list = NULL,
4265 .flags = FLAG_ADVANCED,
4268 .label = "idmap cache time",
4269 .type = P_INTEGER,
4270 .p_class = P_GLOBAL,
4271 .ptr = &Globals.iIdmapCacheTime,
4272 .special = NULL,
4273 .enum_list = NULL,
4274 .flags = FLAG_ADVANCED,
4277 .label = "idmap negative cache time",
4278 .type = P_INTEGER,
4279 .p_class = P_GLOBAL,
4280 .ptr = &Globals.iIdmapNegativeCacheTime,
4281 .special = NULL,
4282 .enum_list = NULL,
4283 .flags = FLAG_ADVANCED,
4286 .label = "idmap uid",
4287 .type = P_STRING,
4288 .p_class = P_GLOBAL,
4289 .ptr = &Globals.szIdmapUID,
4290 .special = handle_idmap_uid,
4291 .enum_list = NULL,
4292 .flags = FLAG_ADVANCED,
4295 .label = "winbind uid",
4296 .type = P_STRING,
4297 .p_class = P_GLOBAL,
4298 .ptr = &Globals.szIdmapUID,
4299 .special = handle_idmap_uid,
4300 .enum_list = NULL,
4301 .flags = FLAG_HIDE,
4304 .label = "idmap gid",
4305 .type = P_STRING,
4306 .p_class = P_GLOBAL,
4307 .ptr = &Globals.szIdmapGID,
4308 .special = handle_idmap_gid,
4309 .enum_list = NULL,
4310 .flags = FLAG_ADVANCED,
4313 .label = "winbind gid",
4314 .type = P_STRING,
4315 .p_class = P_GLOBAL,
4316 .ptr = &Globals.szIdmapGID,
4317 .special = handle_idmap_gid,
4318 .enum_list = NULL,
4319 .flags = FLAG_HIDE,
4322 .label = "template homedir",
4323 .type = P_STRING,
4324 .p_class = P_GLOBAL,
4325 .ptr = &Globals.szTemplateHomedir,
4326 .special = NULL,
4327 .enum_list = NULL,
4328 .flags = FLAG_ADVANCED,
4331 .label = "template shell",
4332 .type = P_STRING,
4333 .p_class = P_GLOBAL,
4334 .ptr = &Globals.szTemplateShell,
4335 .special = NULL,
4336 .enum_list = NULL,
4337 .flags = FLAG_ADVANCED,
4340 .label = "winbind separator",
4341 .type = P_STRING,
4342 .p_class = P_GLOBAL,
4343 .ptr = &Globals.szWinbindSeparator,
4344 .special = NULL,
4345 .enum_list = NULL,
4346 .flags = FLAG_ADVANCED,
4349 .label = "winbind cache time",
4350 .type = P_INTEGER,
4351 .p_class = P_GLOBAL,
4352 .ptr = &Globals.winbind_cache_time,
4353 .special = NULL,
4354 .enum_list = NULL,
4355 .flags = FLAG_ADVANCED,
4358 .label = "winbind enum users",
4359 .type = P_BOOL,
4360 .p_class = P_GLOBAL,
4361 .ptr = &Globals.bWinbindEnumUsers,
4362 .special = NULL,
4363 .enum_list = NULL,
4364 .flags = FLAG_ADVANCED,
4367 .label = "winbind enum groups",
4368 .type = P_BOOL,
4369 .p_class = P_GLOBAL,
4370 .ptr = &Globals.bWinbindEnumGroups,
4371 .special = NULL,
4372 .enum_list = NULL,
4373 .flags = FLAG_ADVANCED,
4376 .label = "winbind use default domain",
4377 .type = P_BOOL,
4378 .p_class = P_GLOBAL,
4379 .ptr = &Globals.bWinbindUseDefaultDomain,
4380 .special = NULL,
4381 .enum_list = NULL,
4382 .flags = FLAG_ADVANCED,
4385 .label = "winbind trusted domains only",
4386 .type = P_BOOL,
4387 .p_class = P_GLOBAL,
4388 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4389 .special = NULL,
4390 .enum_list = NULL,
4391 .flags = FLAG_ADVANCED,
4394 .label = "winbind nested groups",
4395 .type = P_BOOL,
4396 .p_class = P_GLOBAL,
4397 .ptr = &Globals.bWinbindNestedGroups,
4398 .special = NULL,
4399 .enum_list = NULL,
4400 .flags = FLAG_ADVANCED,
4403 .label = "winbind expand groups",
4404 .type = P_INTEGER,
4405 .p_class = P_GLOBAL,
4406 .ptr = &Globals.winbind_expand_groups,
4407 .special = NULL,
4408 .enum_list = NULL,
4409 .flags = FLAG_ADVANCED,
4412 .label = "winbind nss info",
4413 .type = P_LIST,
4414 .p_class = P_GLOBAL,
4415 .ptr = &Globals.szWinbindNssInfo,
4416 .special = NULL,
4417 .enum_list = NULL,
4418 .flags = FLAG_ADVANCED,
4421 .label = "winbind refresh tickets",
4422 .type = P_BOOL,
4423 .p_class = P_GLOBAL,
4424 .ptr = &Globals.bWinbindRefreshTickets,
4425 .special = NULL,
4426 .enum_list = NULL,
4427 .flags = FLAG_ADVANCED,
4430 .label = "winbind offline logon",
4431 .type = P_BOOL,
4432 .p_class = P_GLOBAL,
4433 .ptr = &Globals.bWinbindOfflineLogon,
4434 .special = NULL,
4435 .enum_list = NULL,
4436 .flags = FLAG_ADVANCED,
4439 .label = "winbind normalize names",
4440 .type = P_BOOL,
4441 .p_class = P_GLOBAL,
4442 .ptr = &Globals.bWinbindNormalizeNames,
4443 .special = NULL,
4444 .enum_list = NULL,
4445 .flags = FLAG_ADVANCED,
4448 .label = "winbind rpc only",
4449 .type = P_BOOL,
4450 .p_class = P_GLOBAL,
4451 .ptr = &Globals.bWinbindRpcOnly,
4452 .special = NULL,
4453 .enum_list = NULL,
4454 .flags = FLAG_ADVANCED,
4457 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4460 /***************************************************************************
4461 Initialise the sDefault parameter structure for the printer values.
4462 ***************************************************************************/
4464 static void init_printer_values(struct service *pService)
4466 /* choose defaults depending on the type of printing */
4467 switch (pService->iPrinting) {
4468 case PRINT_BSD:
4469 case PRINT_AIX:
4470 case PRINT_LPRNT:
4471 case PRINT_LPROS2:
4472 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4473 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4474 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4475 break;
4477 case PRINT_LPRNG:
4478 case PRINT_PLP:
4479 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4480 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4481 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4482 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4483 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4484 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4485 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4486 break;
4488 case PRINT_CUPS:
4489 case PRINT_IPRINT:
4490 #ifdef HAVE_CUPS
4491 /* set the lpq command to contain the destination printer
4492 name only. This is used by cups_queue_get() */
4493 string_set(&pService->szLpqcommand, "%p");
4494 string_set(&pService->szLprmcommand, "");
4495 string_set(&pService->szPrintcommand, "");
4496 string_set(&pService->szLppausecommand, "");
4497 string_set(&pService->szLpresumecommand, "");
4498 string_set(&pService->szQueuepausecommand, "");
4499 string_set(&pService->szQueueresumecommand, "");
4500 #else
4501 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4502 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4503 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4504 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4505 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4506 string_set(&pService->szQueuepausecommand, "disable '%p'");
4507 string_set(&pService->szQueueresumecommand, "enable '%p'");
4508 #endif /* HAVE_CUPS */
4509 break;
4511 case PRINT_SYSV:
4512 case PRINT_HPUX:
4513 string_set(&pService->szLpqcommand, "lpstat -o%p");
4514 string_set(&pService->szLprmcommand, "cancel %p-%j");
4515 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4516 string_set(&pService->szQueuepausecommand, "disable %p");
4517 string_set(&pService->szQueueresumecommand, "enable %p");
4518 #ifndef HPUX
4519 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4520 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4521 #endif /* HPUX */
4522 break;
4524 case PRINT_QNX:
4525 string_set(&pService->szLpqcommand, "lpq -P%p");
4526 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4527 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4528 break;
4530 #ifdef DEVELOPER
4531 case PRINT_TEST:
4532 case PRINT_VLP:
4533 string_set(&pService->szPrintcommand, "vlp print %p %s");
4534 string_set(&pService->szLpqcommand, "vlp lpq %p");
4535 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4536 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4537 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4538 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4539 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4540 break;
4541 #endif /* DEVELOPER */
4546 /***************************************************************************
4547 Initialise the global parameter structure.
4548 ***************************************************************************/
4550 static void init_globals(bool first_time_only)
4552 static bool done_init = False;
4553 char *s = NULL;
4554 int i;
4556 /* If requested to initialize only once and we've already done it... */
4557 if (first_time_only && done_init) {
4558 /* ... then we have nothing more to do */
4559 return;
4562 if (!done_init) {
4563 /* The logfile can be set before this is invoked. Free it if so. */
4564 if (Globals.szLogFile != NULL) {
4565 string_free(&Globals.szLogFile);
4566 Globals.szLogFile = NULL;
4568 done_init = True;
4569 } else {
4570 for (i = 0; parm_table[i].label; i++) {
4571 if ((parm_table[i].type == P_STRING ||
4572 parm_table[i].type == P_USTRING) &&
4573 parm_table[i].ptr)
4575 string_free((char **)parm_table[i].ptr);
4580 memset((void *)&Globals, '\0', sizeof(Globals));
4582 for (i = 0; parm_table[i].label; i++) {
4583 if ((parm_table[i].type == P_STRING ||
4584 parm_table[i].type == P_USTRING) &&
4585 parm_table[i].ptr)
4587 string_set((char **)parm_table[i].ptr, "");
4591 string_set(&sDefault.fstype, FSTYPE_STRING);
4592 string_set(&sDefault.szPrintjobUsername, "%U");
4594 init_printer_values(&sDefault);
4597 DEBUG(3, ("Initialising global parameters\n"));
4599 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4600 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4602 /* use the new 'hash2' method by default, with a prefix of 1 */
4603 string_set(&Globals.szManglingMethod, "hash2");
4604 Globals.mangle_prefix = 1;
4606 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4608 /* using UTF8 by default allows us to support all chars */
4609 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4611 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4612 /* If the system supports nl_langinfo(), try to grab the value
4613 from the user's locale */
4614 string_set(&Globals.display_charset, "LOCALE");
4615 #else
4616 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4617 #endif
4619 /* Use codepage 850 as a default for the dos character set */
4620 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4623 * Allow the default PASSWD_CHAT to be overridden in local.h.
4625 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4627 set_global_myname(myhostname());
4628 string_set(&Globals.szNetbiosName,global_myname());
4630 set_global_myworkgroup(WORKGROUP);
4631 string_set(&Globals.szWorkgroup, lp_workgroup());
4633 string_set(&Globals.szPasswdProgram, "");
4634 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4635 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4636 string_set(&Globals.szSocketAddress, "0.0.0.0");
4638 if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
4639 smb_panic("init_globals: ENOMEM");
4641 string_set(&Globals.szServerString, s);
4642 SAFE_FREE(s);
4643 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4644 DEFAULT_MINOR_VERSION) < 0) {
4645 smb_panic("init_globals: ENOMEM");
4647 string_set(&Globals.szAnnounceVersion, s);
4648 SAFE_FREE(s);
4649 #ifdef DEVELOPER
4650 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4651 #endif
4653 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4655 string_set(&Globals.szLogonDrive, "");
4656 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4657 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4658 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4660 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4661 string_set(&Globals.szPasswordServer, "*");
4663 Globals.AlgorithmicRidBase = BASE_RID;
4665 Globals.bLoadPrinters = True;
4666 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4668 Globals.ConfigBackend = config_backend;
4670 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4671 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4672 Globals.max_xmit = 0x4104;
4673 Globals.max_mux = 50; /* This is *needed* for profile support. */
4674 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4675 Globals.bDisableSpoolss = False;
4676 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4677 Globals.pwordlevel = 0;
4678 Globals.unamelevel = 0;
4679 Globals.deadtime = 0;
4680 Globals.getwd_cache = true;
4681 Globals.bLargeReadwrite = True;
4682 Globals.max_log_size = 5000;
4683 Globals.max_open_files = MAX_OPEN_FILES;
4684 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4685 Globals.maxprotocol = PROTOCOL_NT1;
4686 Globals.minprotocol = PROTOCOL_CORE;
4687 Globals.security = SEC_USER;
4688 Globals.paranoid_server_security = True;
4689 Globals.bEncryptPasswords = True;
4690 Globals.bUpdateEncrypt = False;
4691 Globals.clientSchannel = Auto;
4692 Globals.serverSchannel = Auto;
4693 Globals.bReadRaw = True;
4694 Globals.bWriteRaw = True;
4695 Globals.bNullPasswords = False;
4696 Globals.bObeyPamRestrictions = False;
4697 Globals.syslog = 1;
4698 Globals.bSyslogOnly = False;
4699 Globals.bTimestampLogs = True;
4700 string_set(&Globals.szLogLevel, "0");
4701 Globals.bDebugPrefixTimestamp = False;
4702 Globals.bDebugHiresTimestamp = False;
4703 Globals.bDebugPid = False;
4704 Globals.bDebugUid = False;
4705 Globals.bDebugClass = False;
4706 Globals.bEnableCoreFiles = True;
4707 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4708 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4709 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4710 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4711 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4712 Globals.lm_interval = 60;
4713 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4714 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4715 Globals.bNISHomeMap = False;
4716 #ifdef WITH_NISPLUS_HOME
4717 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4718 #else
4719 string_set(&Globals.szNISHomeMapName, "auto.home");
4720 #endif
4721 #endif
4722 Globals.bTimeServer = False;
4723 Globals.bBindInterfacesOnly = False;
4724 Globals.bUnixPasswdSync = False;
4725 Globals.bPamPasswordChange = False;
4726 Globals.bPasswdChatDebug = False;
4727 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4728 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4729 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4730 Globals.bStatCache = True; /* use stat cache by default */
4731 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4732 Globals.restrict_anonymous = 0;
4733 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4734 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4735 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4736 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4737 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4738 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4740 Globals.map_to_guest = 0; /* By Default, "Never" */
4741 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4742 Globals.enhanced_browsing = true;
4743 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4744 #ifdef MMAP_BLACKLIST
4745 Globals.bUseMmap = False;
4746 #else
4747 Globals.bUseMmap = True;
4748 #endif
4749 Globals.bUnixExtensions = True;
4750 Globals.bResetOnZeroVC = False;
4752 /* hostname lookups can be very expensive and are broken on
4753 a large number of sites (tridge) */
4754 Globals.bHostnameLookups = False;
4756 string_set(&Globals.szPassdbBackend, "smbpasswd");
4757 string_set(&Globals.szLdapSuffix, "");
4758 string_set(&Globals.szLdapMachineSuffix, "");
4759 string_set(&Globals.szLdapUserSuffix, "");
4760 string_set(&Globals.szLdapGroupSuffix, "");
4761 string_set(&Globals.szLdapIdmapSuffix, "");
4763 string_set(&Globals.szLdapAdminDn, "");
4764 Globals.ldap_ssl = LDAP_SSL_OFF;
4765 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4766 Globals.ldap_delete_dn = False;
4767 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4768 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4769 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4770 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4772 Globals.ldap_debug_level = 0;
4773 Globals.ldap_debug_threshold = 10;
4775 /* This is what we tell the afs client. in reality we set the token
4776 * to never expire, though, when this runs out the afs client will
4777 * forget the token. Set to 0 to get NEVERDATE.*/
4778 Globals.iAfsTokenLifetime = 604800;
4780 /* these parameters are set to defaults that are more appropriate
4781 for the increasing samba install base:
4783 as a member of the workgroup, that will possibly become a
4784 _local_ master browser (lm = True). this is opposed to a forced
4785 local master browser startup (pm = True).
4787 doesn't provide WINS server service by default (wsupp = False),
4788 and doesn't provide domain master browser services by default, either.
4792 Globals.bMsAddPrinterWizard = True;
4793 Globals.os_level = 20;
4794 Globals.bLocalMaster = True;
4795 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4796 Globals.bDomainLogons = False;
4797 Globals.bBrowseList = True;
4798 Globals.bWINSsupport = False;
4799 Globals.bWINSproxy = False;
4801 Globals.bDNSproxy = True;
4803 /* this just means to use them if they exist */
4804 Globals.bKernelOplocks = True;
4806 Globals.bAllowTrustedDomains = True;
4808 string_set(&Globals.szTemplateShell, "/bin/false");
4809 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4810 string_set(&Globals.szWinbindSeparator, "\\");
4812 string_set(&Globals.szCupsServer, "");
4813 string_set(&Globals.szIPrintServer, "");
4815 string_set(&Globals.ctdbdSocket, "");
4816 Globals.szClusterAddresses = NULL;
4817 Globals.clustering = False;
4819 Globals.winbind_cache_time = 300; /* 5 minutes */
4820 Globals.bWinbindEnumUsers = False;
4821 Globals.bWinbindEnumGroups = False;
4822 Globals.bWinbindUseDefaultDomain = False;
4823 Globals.bWinbindTrustedDomainsOnly = False;
4824 Globals.bWinbindNestedGroups = True;
4825 Globals.winbind_expand_groups = 1;
4826 Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
4827 Globals.bWinbindRefreshTickets = False;
4828 Globals.bWinbindOfflineLogon = False;
4830 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
4831 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4833 Globals.bPassdbExpandExplicit = False;
4835 Globals.name_cache_timeout = 660; /* In seconds */
4837 Globals.bUseSpnego = True;
4838 Globals.bClientUseSpnego = True;
4840 Globals.client_signing = Auto;
4841 Globals.server_signing = False;
4843 Globals.bDeferSharingViolations = True;
4844 string_set(&Globals.smb_ports, SMB_PORTS);
4846 Globals.bEnablePrivileges = True;
4847 Globals.bHostMSDfs = True;
4848 Globals.bASUSupport = False;
4850 /* User defined shares. */
4851 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4852 smb_panic("init_globals: ENOMEM");
4854 string_set(&Globals.szUsersharePath, s);
4855 SAFE_FREE(s);
4856 string_set(&Globals.szUsershareTemplateShare, "");
4857 Globals.iUsershareMaxShares = 0;
4858 /* By default disallow sharing of directories not owned by the sharer. */
4859 Globals.bUsershareOwnerOnly = True;
4860 /* By default disallow guest access to usershares. */
4861 Globals.bUsershareAllowGuests = False;
4863 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4865 /* By default no shares out of the registry */
4866 Globals.bRegistryShares = False;
4868 Globals.iminreceivefile = 0;
4871 /*******************************************************************
4872 Convenience routine to grab string parameters into temporary memory
4873 and run standard_sub_basic on them. The buffers can be written to by
4874 callers without affecting the source string.
4875 ********************************************************************/
4877 static char *lp_string(const char *s)
4879 char *ret;
4880 TALLOC_CTX *ctx = talloc_tos();
4882 /* The follow debug is useful for tracking down memory problems
4883 especially if you have an inner loop that is calling a lp_*()
4884 function that returns a string. Perhaps this debug should be
4885 present all the time? */
4887 #if 0
4888 DEBUG(10, ("lp_string(%s)\n", s));
4889 #endif
4891 ret = talloc_sub_basic(ctx,
4892 get_current_username(),
4893 current_user_info.domain,
4895 if (trim_char(ret, '\"', '\"')) {
4896 if (strchr(ret,'\"') != NULL) {
4897 TALLOC_FREE(ret);
4898 ret = talloc_sub_basic(ctx,
4899 get_current_username(),
4900 current_user_info.domain,
4904 return ret;
4908 In this section all the functions that are used to access the
4909 parameters from the rest of the program are defined
4912 #define FN_GLOBAL_STRING(fn_name,ptr) \
4913 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4914 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4915 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4916 #define FN_GLOBAL_LIST(fn_name,ptr) \
4917 const char **fn_name(void) {return(*(const char ***)(ptr));}
4918 #define FN_GLOBAL_BOOL(fn_name,ptr) \
4919 bool fn_name(void) {return(*(bool *)(ptr));}
4920 #define FN_GLOBAL_CHAR(fn_name,ptr) \
4921 char fn_name(void) {return(*(char *)(ptr));}
4922 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
4923 int fn_name(void) {return(*(int *)(ptr));}
4925 #define FN_LOCAL_STRING(fn_name,val) \
4926 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
4927 #define FN_LOCAL_CONST_STRING(fn_name,val) \
4928 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
4929 #define FN_LOCAL_LIST(fn_name,val) \
4930 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4931 #define FN_LOCAL_BOOL(fn_name,val) \
4932 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4933 #define FN_LOCAL_INTEGER(fn_name,val) \
4934 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4936 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
4937 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4938 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
4939 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4940 #define FN_LOCAL_PARM_STRING(fn_name,val) \
4941 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));}
4942 #define FN_LOCAL_CHAR(fn_name,val) \
4943 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4945 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
4946 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
4947 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
4948 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
4949 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
4950 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
4951 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
4952 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
4953 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
4954 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
4955 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
4956 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
4957 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
4958 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
4959 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
4960 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
4961 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
4962 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
4963 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
4964 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
4965 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
4966 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
4967 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
4968 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
4969 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
4970 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
4971 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
4972 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
4973 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
4974 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
4975 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
4976 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
4977 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
4978 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
4979 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
4980 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
4981 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
4982 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
4983 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
4984 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
4985 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
4986 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
4987 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
4988 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
4989 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
4990 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
4991 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
4992 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
4993 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
4994 * lp_passdb_backend() should be replace by the this macro again after
4995 * some releases.
4996 * */
4997 const char *lp_passdb_backend(void)
4999 char *delim, *quote;
5001 delim = strchr( Globals.szPassdbBackend, ' ');
5002 /* no space at all */
5003 if (delim == NULL) {
5004 goto out;
5007 quote = strchr(Globals.szPassdbBackend, '"');
5008 /* no quote char or non in the first part */
5009 if (quote == NULL || quote > delim) {
5010 *delim = '\0';
5011 goto warn;
5014 quote = strchr(quote+1, '"');
5015 if (quote == NULL) {
5016 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5017 goto out;
5018 } else if (*(quote+1) == '\0') {
5019 /* space, fitting quote char, and one backend only */
5020 goto out;
5021 } else {
5022 /* terminate string after the fitting quote char */
5023 *(quote+1) = '\0';
5026 warn:
5027 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5028 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5029 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5030 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5032 out:
5033 return Globals.szPassdbBackend;
5035 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5036 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5037 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5038 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5039 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5041 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5042 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5043 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5044 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5045 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5046 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5048 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5050 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5051 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5052 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5054 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5056 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5057 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5058 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5059 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5060 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5061 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5062 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5063 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5064 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5065 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5066 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5067 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5068 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5069 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5070 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5072 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
5073 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
5074 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5075 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5076 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5077 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5078 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5080 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5081 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5082 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5083 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5084 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5085 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5086 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5087 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5088 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5089 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5090 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5091 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5092 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5093 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5094 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5095 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5096 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5098 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5100 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5101 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5102 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5103 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5104 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5105 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5106 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5107 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5108 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5109 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5110 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5111 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5112 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5113 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5114 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5115 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5116 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5117 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5118 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5119 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5120 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5121 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5122 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5123 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5124 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5125 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5126 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5127 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5128 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5129 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5130 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5131 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5132 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5133 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5134 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5135 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5136 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5137 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5138 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5139 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5140 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5141 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5142 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5143 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5144 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5145 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5146 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5147 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5148 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5149 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5150 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5151 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5152 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5153 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5154 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5155 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5156 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5157 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5158 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5159 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5160 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5161 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5162 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5163 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5164 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5165 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5166 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5167 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5168 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5169 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5170 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5171 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5172 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5173 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5174 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5175 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5176 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5177 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5178 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5179 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5180 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5181 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5182 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5183 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5184 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5185 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5186 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5187 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5188 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5189 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5190 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5191 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5192 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5193 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5194 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5195 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5197 FN_LOCAL_STRING(lp_preexec, szPreExec)
5198 FN_LOCAL_STRING(lp_postexec, szPostExec)
5199 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5200 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5201 FN_LOCAL_STRING(lp_servicename, szService)
5202 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5203 FN_LOCAL_STRING(lp_pathname, szPath)
5204 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5205 FN_LOCAL_STRING(lp_username, szUsername)
5206 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5207 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5208 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5209 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5210 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5211 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5212 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5213 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5214 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5215 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5216 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5217 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5218 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5219 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5220 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5221 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5222 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5223 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5224 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5225 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5226 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5227 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5228 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5229 FN_LOCAL_STRING(lp_comment, comment)
5230 FN_LOCAL_STRING(lp_force_user, force_user)
5231 FN_LOCAL_STRING(lp_force_group, force_group)
5232 FN_LOCAL_LIST(lp_readlist, readlist)
5233 FN_LOCAL_LIST(lp_writelist, writelist)
5234 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5235 FN_LOCAL_STRING(lp_fstype, fstype)
5236 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5237 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5238 static FN_LOCAL_STRING(lp_volume, volume)
5239 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5240 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5241 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5242 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5243 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5244 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5245 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5246 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5247 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5248 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5249 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5250 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5251 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5252 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5253 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5254 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5255 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5256 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5257 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5258 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5259 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5260 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5261 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5262 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5263 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5264 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5265 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5266 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5267 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5268 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5269 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5270 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5271 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5272 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5273 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5274 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5275 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5276 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5277 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5278 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5279 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5280 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5281 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5282 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5283 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5284 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5285 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5286 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5287 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5288 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5289 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5290 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5291 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5292 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5293 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5294 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5295 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5296 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5297 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5298 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5299 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5300 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5301 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5302 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5303 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5304 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5305 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5306 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5307 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5308 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5309 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5310 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5311 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5312 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5313 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5314 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5315 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5316 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5317 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5318 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5319 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5320 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5321 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5322 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5323 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5324 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5325 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5326 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5327 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5328 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5329 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5330 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5331 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5332 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5333 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5334 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5335 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5337 /* local prototypes */
5339 static int map_parameter(const char *pszParmName);
5340 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5341 static bool set_boolean(bool *pb, const char *pszParmValue);
5342 static const char *get_boolean(bool bool_value);
5343 static int getservicebyname(const char *pszServiceName,
5344 struct service *pserviceDest);
5345 static void copy_service(struct service *pserviceDest,
5346 struct service *pserviceSource,
5347 struct bitmap *pcopymapDest);
5348 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5349 void *userdata);
5350 static bool do_section(const char *pszSectionName, void *userdata);
5351 static void init_copymap(struct service *pservice);
5352 static bool hash_a_service(const char *name, int number);
5353 static void free_service_byindex(int iService);
5354 static char * canonicalize_servicename(const char *name);
5355 static void show_parameter(int parmIndex);
5356 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5358 /* This is a helper function for parametrical options support. */
5359 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
5360 /* Actual parametrical functions are quite simple */
5361 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
5363 bool global_section = False;
5364 char* param_key;
5365 param_opt_struct *data;
5367 if (snum >= iNumServices) return NULL;
5369 if (snum < 0) {
5370 data = Globals.param_opt;
5371 global_section = True;
5372 } else {
5373 data = ServicePtrs[snum]->param_opt;
5376 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5377 DEBUG(0,("asprintf failed!\n"));
5378 return NULL;
5381 while (data) {
5382 if (strcmp(data->key, param_key) == 0) {
5383 string_free(&param_key);
5384 return data;
5386 data = data->next;
5389 if (!global_section) {
5390 /* Try to fetch the same option but from globals */
5391 /* but only if we are not already working with Globals */
5392 data = Globals.param_opt;
5393 while (data) {
5394 if (strcmp(data->key, param_key) == 0) {
5395 string_free(&param_key);
5396 return data;
5398 data = data->next;
5402 string_free(&param_key);
5404 return NULL;
5408 #define MISSING_PARAMETER(name) \
5409 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5411 /*******************************************************************
5412 convenience routine to return int parameters.
5413 ********************************************************************/
5414 static int lp_int(const char *s)
5417 if (!s || !*s) {
5418 MISSING_PARAMETER(lp_int);
5419 return (-1);
5422 return (int)strtol(s, NULL, 0);
5425 /*******************************************************************
5426 convenience routine to return unsigned long parameters.
5427 ********************************************************************/
5428 static unsigned long lp_ulong(const char *s)
5431 if (!s || !*s) {
5432 MISSING_PARAMETER(lp_ulong);
5433 return (0);
5436 return strtoul(s, NULL, 0);
5439 /*******************************************************************
5440 convenience routine to return boolean parameters.
5441 ********************************************************************/
5442 static bool lp_bool(const char *s)
5444 bool ret = False;
5446 if (!s || !*s) {
5447 MISSING_PARAMETER(lp_bool);
5448 return False;
5451 if (!set_boolean(&ret,s)) {
5452 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5453 return False;
5456 return ret;
5459 /*******************************************************************
5460 convenience routine to return enum parameters.
5461 ********************************************************************/
5462 static int lp_enum(const char *s,const struct enum_list *_enum)
5464 int i;
5466 if (!s || !*s || !_enum) {
5467 MISSING_PARAMETER(lp_enum);
5468 return (-1);
5471 for (i=0; _enum[i].name; i++) {
5472 if (strequal(_enum[i].name,s))
5473 return _enum[i].value;
5476 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5477 return (-1);
5480 #undef MISSING_PARAMETER
5482 /* DO NOT USE lp_parm_string ANYMORE!!!!
5483 * use lp_parm_const_string or lp_parm_talloc_string
5485 * lp_parm_string is only used to let old modules find this symbol
5487 #undef lp_parm_string
5488 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5489 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5491 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5494 /* Return parametric option from a given service. Type is a part of option before ':' */
5495 /* Parametric option has following syntax: 'Type: option = value' */
5496 /* the returned value is talloced on the talloc_tos() */
5497 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5499 param_opt_struct *data = get_parametrics(snum, type, option);
5501 if (data == NULL||data->value==NULL) {
5502 if (def) {
5503 return lp_string(def);
5504 } else {
5505 return NULL;
5509 return lp_string(data->value);
5512 /* Return parametric option from a given service. Type is a part of option before ':' */
5513 /* Parametric option has following syntax: 'Type: option = value' */
5514 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5516 param_opt_struct *data = get_parametrics(snum, type, option);
5518 if (data == NULL||data->value==NULL)
5519 return def;
5521 return data->value;
5524 /* Return parametric option from a given service. Type is a part of option before ':' */
5525 /* Parametric option has following syntax: 'Type: option = value' */
5527 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5529 param_opt_struct *data = get_parametrics(snum, type, option);
5531 if (data == NULL||data->value==NULL)
5532 return (const char **)def;
5534 if (data->list==NULL) {
5535 data->list = str_list_make(NULL, data->value, NULL);
5538 return (const char **)data->list;
5541 /* Return parametric option from a given service. Type is a part of option before ':' */
5542 /* Parametric option has following syntax: 'Type: option = value' */
5544 int lp_parm_int(int snum, const char *type, const char *option, int def)
5546 param_opt_struct *data = get_parametrics(snum, type, option);
5548 if (data && data->value && *data->value)
5549 return lp_int(data->value);
5551 return def;
5554 /* Return parametric option from a given service. Type is a part of option before ':' */
5555 /* Parametric option has following syntax: 'Type: option = value' */
5557 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5559 param_opt_struct *data = get_parametrics(snum, type, option);
5561 if (data && data->value && *data->value)
5562 return lp_ulong(data->value);
5564 return def;
5567 /* Return parametric option from a given service. Type is a part of option before ':' */
5568 /* Parametric option has following syntax: 'Type: option = value' */
5570 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5572 param_opt_struct *data = get_parametrics(snum, type, option);
5574 if (data && data->value && *data->value)
5575 return lp_bool(data->value);
5577 return def;
5580 /* Return parametric option from a given service. Type is a part of option before ':' */
5581 /* Parametric option has following syntax: 'Type: option = value' */
5583 int lp_parm_enum(int snum, const char *type, const char *option,
5584 const struct enum_list *_enum, int def)
5586 param_opt_struct *data = get_parametrics(snum, type, option);
5588 if (data && data->value && *data->value && _enum)
5589 return lp_enum(data->value, _enum);
5591 return def;
5595 /***************************************************************************
5596 Initialise a service to the defaults.
5597 ***************************************************************************/
5599 static void init_service(struct service *pservice)
5601 memset((char *)pservice, '\0', sizeof(struct service));
5602 copy_service(pservice, &sDefault, NULL);
5605 /***************************************************************************
5606 Free the dynamically allocated parts of a service struct.
5607 ***************************************************************************/
5609 static void free_service(struct service *pservice)
5611 int i;
5612 param_opt_struct *data, *pdata;
5613 if (!pservice)
5614 return;
5616 if (pservice->szService)
5617 DEBUG(5, ("free_service: Freeing service %s\n",
5618 pservice->szService));
5620 string_free(&pservice->szService);
5621 bitmap_free(pservice->copymap);
5623 for (i = 0; parm_table[i].label; i++) {
5624 if ((parm_table[i].type == P_STRING ||
5625 parm_table[i].type == P_USTRING) &&
5626 parm_table[i].p_class == P_LOCAL)
5627 string_free((char **)
5628 (((char *)pservice) +
5629 PTR_DIFF(parm_table[i].ptr, &sDefault)));
5630 else if (parm_table[i].type == P_LIST &&
5631 parm_table[i].p_class == P_LOCAL)
5632 TALLOC_FREE(*((char ***)
5633 (((char *)pservice) +
5634 PTR_DIFF(parm_table[i].ptr,
5635 &sDefault))));
5638 data = pservice->param_opt;
5639 if (data)
5640 DEBUG(5,("Freeing parametrics:\n"));
5641 while (data) {
5642 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5643 string_free(&data->key);
5644 string_free(&data->value);
5645 TALLOC_FREE(data->list);
5646 pdata = data->next;
5647 SAFE_FREE(data);
5648 data = pdata;
5651 ZERO_STRUCTP(pservice);
5655 /***************************************************************************
5656 remove a service indexed in the ServicePtrs array from the ServiceHash
5657 and free the dynamically allocated parts
5658 ***************************************************************************/
5660 static void free_service_byindex(int idx)
5662 if ( !LP_SNUM_OK(idx) )
5663 return;
5665 ServicePtrs[idx]->valid = False;
5666 invalid_services[num_invalid_services++] = idx;
5668 /* we have to cleanup the hash record */
5670 if (ServicePtrs[idx]->szService) {
5671 char *canon_name = canonicalize_servicename(
5672 ServicePtrs[idx]->szService );
5674 dbwrap_delete_bystring(ServiceHash, canon_name );
5675 TALLOC_FREE(canon_name);
5678 free_service(ServicePtrs[idx]);
5681 /***************************************************************************
5682 Add a new service to the services array initialising it with the given
5683 service.
5684 ***************************************************************************/
5686 static int add_a_service(const struct service *pservice, const char *name)
5688 int i;
5689 struct service tservice;
5690 int num_to_alloc = iNumServices + 1;
5691 param_opt_struct *data, *pdata;
5693 tservice = *pservice;
5695 /* it might already exist */
5696 if (name) {
5697 i = getservicebyname(name, NULL);
5698 if (i >= 0) {
5699 /* Clean all parametric options for service */
5700 /* They will be added during parsing again */
5701 data = ServicePtrs[i]->param_opt;
5702 while (data) {
5703 string_free(&data->key);
5704 string_free(&data->value);
5705 TALLOC_FREE(data->list);
5706 pdata = data->next;
5707 SAFE_FREE(data);
5708 data = pdata;
5710 ServicePtrs[i]->param_opt = NULL;
5711 return (i);
5715 /* find an invalid one */
5716 i = iNumServices;
5717 if (num_invalid_services > 0) {
5718 i = invalid_services[--num_invalid_services];
5721 /* if not, then create one */
5722 if (i == iNumServices) {
5723 struct service **tsp;
5724 int *tinvalid;
5726 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5727 if (tsp == NULL) {
5728 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5729 return (-1);
5731 ServicePtrs = tsp;
5732 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5733 if (!ServicePtrs[iNumServices]) {
5734 DEBUG(0,("add_a_service: out of memory!\n"));
5735 return (-1);
5737 iNumServices++;
5739 /* enlarge invalid_services here for now... */
5740 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5741 num_to_alloc);
5742 if (tinvalid == NULL) {
5743 DEBUG(0,("add_a_service: failed to enlarge "
5744 "invalid_services!\n"));
5745 return (-1);
5747 invalid_services = tinvalid;
5748 } else {
5749 free_service_byindex(i);
5752 ServicePtrs[i]->valid = True;
5754 init_service(ServicePtrs[i]);
5755 copy_service(ServicePtrs[i], &tservice, NULL);
5756 if (name)
5757 string_set(&ServicePtrs[i]->szService, name);
5759 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5760 i, ServicePtrs[i]->szService));
5762 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5763 return (-1);
5766 return (i);
5769 /***************************************************************************
5770 Convert a string to uppercase and remove whitespaces.
5771 ***************************************************************************/
5773 static char *canonicalize_servicename(const char *src)
5775 char *result;
5777 if ( !src ) {
5778 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5779 return NULL;
5782 result = talloc_strdup(talloc_tos(), src);
5783 SMB_ASSERT(result != NULL);
5785 strlower_m(result);
5786 return result;
5789 /***************************************************************************
5790 Add a name/index pair for the services array to the hash table.
5791 ***************************************************************************/
5793 static bool hash_a_service(const char *name, int idx)
5795 char *canon_name;
5797 if ( !ServiceHash ) {
5798 DEBUG(10,("hash_a_service: creating servicehash\n"));
5799 ServiceHash = db_open_rbt(NULL);
5800 if ( !ServiceHash ) {
5801 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5802 return False;
5806 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5807 idx, name));
5809 canon_name = canonicalize_servicename( name );
5811 dbwrap_store_bystring(ServiceHash, canon_name,
5812 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5813 TDB_REPLACE);
5815 TALLOC_FREE(canon_name);
5817 return True;
5820 /***************************************************************************
5821 Add a new home service, with the specified home directory, defaults coming
5822 from service ifrom.
5823 ***************************************************************************/
5825 bool lp_add_home(const char *pszHomename, int iDefaultService,
5826 const char *user, const char *pszHomedir)
5828 int i;
5830 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5832 if (i < 0)
5833 return (False);
5835 if (!(*(ServicePtrs[iDefaultService]->szPath))
5836 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5837 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5840 if (!(*(ServicePtrs[i]->comment))) {
5841 char *comment = NULL;
5842 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5843 return false;
5845 string_set(&ServicePtrs[i]->comment, comment);
5846 SAFE_FREE(comment);
5849 /* set the browseable flag from the global default */
5851 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5853 ServicePtrs[i]->autoloaded = True;
5855 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5856 user, ServicePtrs[i]->szPath ));
5858 return (True);
5861 /***************************************************************************
5862 Add a new service, based on an old one.
5863 ***************************************************************************/
5865 int lp_add_service(const char *pszService, int iDefaultService)
5867 if (iDefaultService < 0) {
5868 return add_a_service(&sDefault, pszService);
5871 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5874 /***************************************************************************
5875 Add the IPC service.
5876 ***************************************************************************/
5878 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5880 char *comment = NULL;
5881 int i = add_a_service(&sDefault, ipc_name);
5883 if (i < 0)
5884 return (False);
5886 if (asprintf(&comment, "IPC Service (%s)",
5887 Globals.szServerString) < 0) {
5888 return (False);
5891 string_set(&ServicePtrs[i]->szPath, tmpdir());
5892 string_set(&ServicePtrs[i]->szUsername, "");
5893 string_set(&ServicePtrs[i]->comment, comment);
5894 string_set(&ServicePtrs[i]->fstype, "IPC");
5895 ServicePtrs[i]->iMaxConnections = 0;
5896 ServicePtrs[i]->bAvailable = True;
5897 ServicePtrs[i]->bRead_only = True;
5898 ServicePtrs[i]->bGuest_only = False;
5899 ServicePtrs[i]->bAdministrative_share = True;
5900 ServicePtrs[i]->bGuest_ok = guest_ok;
5901 ServicePtrs[i]->bPrint_ok = False;
5902 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5904 DEBUG(3, ("adding IPC service\n"));
5906 SAFE_FREE(comment);
5907 return (True);
5910 /***************************************************************************
5911 Add a new printer service, with defaults coming from service iFrom.
5912 ***************************************************************************/
5914 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5916 const char *comment = "From Printcap";
5917 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5919 if (i < 0)
5920 return (False);
5922 /* note that we do NOT default the availability flag to True - */
5923 /* we take it from the default service passed. This allows all */
5924 /* dynamic printers to be disabled by disabling the [printers] */
5925 /* entry (if/when the 'available' keyword is implemented!). */
5927 /* the printer name is set to the service name. */
5928 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5929 string_set(&ServicePtrs[i]->comment, comment);
5931 /* set the browseable flag from the gloabl default */
5932 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5934 /* Printers cannot be read_only. */
5935 ServicePtrs[i]->bRead_only = False;
5936 /* No share modes on printer services. */
5937 ServicePtrs[i]->bShareModes = False;
5938 /* No oplocks on printer services. */
5939 ServicePtrs[i]->bOpLocks = False;
5940 /* Printer services must be printable. */
5941 ServicePtrs[i]->bPrint_ok = True;
5943 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5945 return (True);
5949 /***************************************************************************
5950 Check whether the given parameter name is valid.
5951 Parametric options (names containing a colon) are considered valid.
5952 ***************************************************************************/
5954 bool lp_parameter_is_valid(const char *pszParmName)
5956 return ((map_parameter(pszParmName) != -1) ||
5957 (strchr(pszParmName, ':') != NULL));
5960 /***************************************************************************
5961 Check whether the given name is the name of a global parameter.
5962 Returns True for strings belonging to parameters of class
5963 P_GLOBAL, False for all other strings, also for parametric options
5964 and strings not belonging to any option.
5965 ***************************************************************************/
5967 bool lp_parameter_is_global(const char *pszParmName)
5969 int num = map_parameter(pszParmName);
5971 if (num >= 0) {
5972 return (parm_table[num].p_class == P_GLOBAL);
5975 return False;
5978 /**************************************************************************
5979 Check whether the given name is the canonical name of a parameter.
5980 Returns False if it is not a valid parameter Name.
5981 For parametric options, True is returned.
5982 **************************************************************************/
5984 bool lp_parameter_is_canonical(const char *parm_name)
5986 if (!lp_parameter_is_valid(parm_name)) {
5987 return False;
5990 return (map_parameter(parm_name) ==
5991 map_parameter_canonical(parm_name, NULL));
5994 /**************************************************************************
5995 Determine the canonical name for a parameter.
5996 Indicate when it is an inverse (boolean) synonym instead of a
5997 "usual" synonym.
5998 **************************************************************************/
6000 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6001 bool *inverse)
6003 int num;
6005 if (!lp_parameter_is_valid(parm_name)) {
6006 *canon_parm = NULL;
6007 return False;
6010 num = map_parameter_canonical(parm_name, inverse);
6011 if (num < 0) {
6012 /* parametric option */
6013 *canon_parm = parm_name;
6014 } else {
6015 *canon_parm = parm_table[num].label;
6018 return True;
6022 /**************************************************************************
6023 Determine the canonical name for a parameter.
6024 Turn the value given into the inverse boolean expression when
6025 the synonym is an invers boolean synonym.
6027 Return True if parm_name is a valid parameter name and
6028 in case it is an invers boolean synonym, if the val string could
6029 successfully be converted to the reverse bool.
6030 Return false in all other cases.
6031 **************************************************************************/
6033 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6034 const char *val,
6035 const char **canon_parm,
6036 const char **canon_val)
6038 int num;
6039 bool inverse;
6041 if (!lp_parameter_is_valid(parm_name)) {
6042 *canon_parm = NULL;
6043 *canon_val = NULL;
6044 return False;
6047 num = map_parameter_canonical(parm_name, &inverse);
6048 if (num < 0) {
6049 /* parametric option */
6050 *canon_parm = parm_name;
6051 *canon_val = val;
6052 } else {
6053 *canon_parm = parm_table[num].label;
6054 if (inverse) {
6055 if (!lp_invert_boolean(val, canon_val)) {
6056 *canon_val = NULL;
6057 return False;
6059 } else {
6060 *canon_val = val;
6064 return True;
6067 /***************************************************************************
6068 Map a parameter's string representation to something we can use.
6069 Returns False if the parameter string is not recognised, else TRUE.
6070 ***************************************************************************/
6072 static int map_parameter(const char *pszParmName)
6074 int iIndex;
6076 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6077 return (-1);
6079 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6080 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6081 return (iIndex);
6083 /* Warn only if it isn't parametric option */
6084 if (strchr(pszParmName, ':') == NULL)
6085 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6086 /* We do return 'fail' for parametric options as well because they are
6087 stored in different storage
6089 return (-1);
6092 /***************************************************************************
6093 Map a parameter's string representation to the index of the canonical
6094 form of the parameter (it might be a synonym).
6095 Returns -1 if the parameter string is not recognised.
6096 ***************************************************************************/
6098 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6100 int parm_num, canon_num;
6101 bool loc_inverse = False;
6103 parm_num = map_parameter(pszParmName);
6104 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6105 /* invalid, parametric or no canidate for synonyms ... */
6106 goto done;
6109 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6110 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6111 parm_num = canon_num;
6112 goto done;
6116 done:
6117 if (inverse != NULL) {
6118 *inverse = loc_inverse;
6120 return parm_num;
6123 /***************************************************************************
6124 return true if parameter number parm1 is a synonym of parameter
6125 number parm2 (parm2 being the principal name).
6126 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6127 False otherwise.
6128 ***************************************************************************/
6130 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6132 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6133 (parm_table[parm1].flags & FLAG_HIDE) &&
6134 !(parm_table[parm2].flags & FLAG_HIDE))
6136 if (inverse != NULL) {
6137 if ((parm_table[parm1].type == P_BOOLREV) &&
6138 (parm_table[parm2].type == P_BOOL))
6140 *inverse = True;
6141 } else {
6142 *inverse = False;
6145 return True;
6147 return False;
6150 /***************************************************************************
6151 Show one parameter's name, type, [values,] and flags.
6152 (helper functions for show_parameter_list)
6153 ***************************************************************************/
6155 static void show_parameter(int parmIndex)
6157 int enumIndex, flagIndex;
6158 int parmIndex2;
6159 bool hadFlag;
6160 bool hadSyn;
6161 bool inverse;
6162 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6163 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6164 "P_ENUM", "P_SEP"};
6165 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6166 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6167 FLAG_HIDE, FLAG_DOS_STRING};
6168 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6169 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6170 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6172 printf("%s=%s", parm_table[parmIndex].label,
6173 type[parm_table[parmIndex].type]);
6174 if (parm_table[parmIndex].type == P_ENUM) {
6175 printf(",");
6176 for (enumIndex=0;
6177 parm_table[parmIndex].enum_list[enumIndex].name;
6178 enumIndex++)
6180 printf("%s%s",
6181 enumIndex ? "|" : "",
6182 parm_table[parmIndex].enum_list[enumIndex].name);
6185 printf(",");
6186 hadFlag = False;
6187 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6188 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6189 printf("%s%s",
6190 hadFlag ? "|" : "",
6191 flag_names[flagIndex]);
6192 hadFlag = True;
6196 /* output synonyms */
6197 hadSyn = False;
6198 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6199 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6200 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6201 parm_table[parmIndex2].label);
6202 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6203 if (!hadSyn) {
6204 printf(" (synonyms: ");
6205 hadSyn = True;
6206 } else {
6207 printf(", ");
6209 printf("%s%s", parm_table[parmIndex2].label,
6210 inverse ? "[i]" : "");
6213 if (hadSyn) {
6214 printf(")");
6217 printf("\n");
6220 /***************************************************************************
6221 Show all parameter's name, type, [values,] and flags.
6222 ***************************************************************************/
6224 void show_parameter_list(void)
6226 int classIndex, parmIndex;
6227 const char *section_names[] = { "local", "global", NULL};
6229 for (classIndex=0; section_names[classIndex]; classIndex++) {
6230 printf("[%s]\n", section_names[classIndex]);
6231 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6232 if (parm_table[parmIndex].p_class == classIndex) {
6233 show_parameter(parmIndex);
6239 /***************************************************************************
6240 Set a boolean variable from the text value stored in the passed string.
6241 Returns True in success, False if the passed string does not correctly
6242 represent a boolean.
6243 ***************************************************************************/
6245 static bool set_boolean(bool *pb, const char *pszParmValue)
6247 bool bRetval;
6248 bool value;
6250 bRetval = True;
6251 value = False;
6252 if (strwicmp(pszParmValue, "yes") == 0 ||
6253 strwicmp(pszParmValue, "true") == 0 ||
6254 strwicmp(pszParmValue, "1") == 0)
6255 value = True;
6256 else if (strwicmp(pszParmValue, "no") == 0 ||
6257 strwicmp(pszParmValue, "False") == 0 ||
6258 strwicmp(pszParmValue, "0") == 0)
6259 value = False;
6260 else {
6261 DEBUG(2,
6262 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6263 pszParmValue));
6264 bRetval = False;
6267 if ((pb != NULL) && (bRetval != False)) {
6268 *pb = value;
6271 return (bRetval);
6275 /***************************************************************************
6276 Check if a given string correctly represents a boolean value.
6277 ***************************************************************************/
6279 bool lp_string_is_valid_boolean(const char *parm_value)
6281 return set_boolean(NULL, parm_value);
6284 /***************************************************************************
6285 Get the standard string representation of a boolean value ("yes" or "no")
6286 ***************************************************************************/
6288 static const char *get_boolean(bool bool_value)
6290 static const char *yes_str = "yes";
6291 static const char *no_str = "no";
6293 return (bool_value ? yes_str : no_str);
6296 /***************************************************************************
6297 Provide the string of the negated boolean value associated to the boolean
6298 given as a string. Returns False if the passed string does not correctly
6299 represent a boolean.
6300 ***************************************************************************/
6302 bool lp_invert_boolean(const char *str, const char **inverse_str)
6304 bool val;
6306 if (!set_boolean(&val, str)) {
6307 return False;
6310 *inverse_str = get_boolean(!val);
6311 return True;
6314 /***************************************************************************
6315 Provide the canonical string representation of a boolean value given
6316 as a string. Return True on success, False if the string given does
6317 not correctly represent a boolean.
6318 ***************************************************************************/
6320 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6322 bool val;
6324 if (!set_boolean(&val, str)) {
6325 return False;
6328 *canon_str = get_boolean(val);
6329 return True;
6332 /***************************************************************************
6333 Find a service by name. Otherwise works like get_service.
6334 ***************************************************************************/
6336 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6338 int iService = -1;
6339 char *canon_name;
6340 TDB_DATA data;
6342 if (ServiceHash == NULL) {
6343 return -1;
6346 canon_name = canonicalize_servicename(pszServiceName);
6348 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6350 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6351 iService = *(int *)data.dptr;
6354 TALLOC_FREE(canon_name);
6356 if ((iService != -1) && (LP_SNUM_OK(iService))
6357 && (pserviceDest != NULL)) {
6358 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6361 return (iService);
6364 /***************************************************************************
6365 Copy a service structure to another.
6366 If pcopymapDest is NULL then copy all fields
6367 ***************************************************************************/
6369 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6370 struct bitmap *pcopymapDest)
6372 int i;
6373 bool bcopyall = (pcopymapDest == NULL);
6374 param_opt_struct *data, *pdata, *paramo;
6375 bool not_added;
6377 for (i = 0; parm_table[i].label; i++)
6378 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6379 (bcopyall || bitmap_query(pcopymapDest,i))) {
6380 void *def_ptr = parm_table[i].ptr;
6381 void *src_ptr =
6382 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6383 &sDefault);
6384 void *dest_ptr =
6385 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6386 &sDefault);
6388 switch (parm_table[i].type) {
6389 case P_BOOL:
6390 case P_BOOLREV:
6391 *(bool *)dest_ptr = *(bool *)src_ptr;
6392 break;
6394 case P_INTEGER:
6395 case P_ENUM:
6396 case P_OCTAL:
6397 *(int *)dest_ptr = *(int *)src_ptr;
6398 break;
6400 case P_CHAR:
6401 *(char *)dest_ptr = *(char *)src_ptr;
6402 break;
6404 case P_STRING:
6405 string_set((char **)dest_ptr,
6406 *(char **)src_ptr);
6407 break;
6409 case P_USTRING:
6410 string_set((char **)dest_ptr,
6411 *(char **)src_ptr);
6412 strupper_m(*(char **)dest_ptr);
6413 break;
6414 case P_LIST:
6415 TALLOC_FREE(*((char ***)dest_ptr));
6416 str_list_copy(NULL, (char ***)dest_ptr,
6417 *(const char ***)src_ptr);
6418 break;
6419 default:
6420 break;
6424 if (bcopyall) {
6425 init_copymap(pserviceDest);
6426 if (pserviceSource->copymap)
6427 bitmap_copy(pserviceDest->copymap,
6428 pserviceSource->copymap);
6431 data = pserviceSource->param_opt;
6432 while (data) {
6433 not_added = True;
6434 pdata = pserviceDest->param_opt;
6435 /* Traverse destination */
6436 while (pdata) {
6437 /* If we already have same option, override it */
6438 if (strcmp(pdata->key, data->key) == 0) {
6439 string_free(&pdata->value);
6440 TALLOC_FREE(data->list);
6441 pdata->value = SMB_STRDUP(data->value);
6442 not_added = False;
6443 break;
6445 pdata = pdata->next;
6447 if (not_added) {
6448 paramo = SMB_XMALLOC_P(param_opt_struct);
6449 paramo->key = SMB_STRDUP(data->key);
6450 paramo->value = SMB_STRDUP(data->value);
6451 paramo->list = NULL;
6452 DLIST_ADD(pserviceDest->param_opt, paramo);
6454 data = data->next;
6458 /***************************************************************************
6459 Check a service for consistency. Return False if the service is in any way
6460 incomplete or faulty, else True.
6461 ***************************************************************************/
6463 bool service_ok(int iService)
6465 bool bRetval;
6467 bRetval = True;
6468 if (ServicePtrs[iService]->szService[0] == '\0') {
6469 DEBUG(0, ("The following message indicates an internal error:\n"));
6470 DEBUG(0, ("No service name in service entry.\n"));
6471 bRetval = False;
6474 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6475 /* I can't see why you'd want a non-printable printer service... */
6476 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6477 if (!ServicePtrs[iService]->bPrint_ok) {
6478 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6479 ServicePtrs[iService]->szService));
6480 ServicePtrs[iService]->bPrint_ok = True;
6482 /* [printers] service must also be non-browsable. */
6483 if (ServicePtrs[iService]->bBrowseable)
6484 ServicePtrs[iService]->bBrowseable = False;
6487 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6488 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6489 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6491 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6492 ServicePtrs[iService]->szService));
6493 ServicePtrs[iService]->bAvailable = False;
6496 /* If a service is flagged unavailable, log the fact at level 1. */
6497 if (!ServicePtrs[iService]->bAvailable)
6498 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6499 ServicePtrs[iService]->szService));
6501 return (bRetval);
6504 static struct smbconf_ctx *lp_smbconf_ctx(void)
6506 WERROR werr;
6507 static struct smbconf_ctx *conf_ctx = NULL;
6509 if (conf_ctx == NULL) {
6510 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6511 if (!W_ERROR_IS_OK(werr)) {
6512 DEBUG(1, ("error initializing registry configuration: "
6513 "%s\n", dos_errstr(werr)));
6514 conf_ctx = NULL;
6518 return conf_ctx;
6521 static bool process_registry_service(struct smbconf_service *service)
6523 uint32_t count;
6524 bool ret;
6526 if (service == NULL) {
6527 return false;
6530 ret = do_section(service->name, NULL);
6531 if (ret != true) {
6532 return false;
6534 for (count = 0; count < service->num_params; count++) {
6535 ret = do_parameter(service->param_names[count],
6536 service->param_values[count],
6537 NULL);
6538 if (ret != true) {
6539 return false;
6542 return true;
6546 * process_registry_globals
6548 static bool process_registry_globals(void)
6550 WERROR werr;
6551 struct smbconf_service *service = NULL;
6552 TALLOC_CTX *mem_ctx = talloc_stackframe();
6553 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6554 bool ret = false;
6556 if (conf_ctx == NULL) {
6557 goto done;
6560 ret = do_parameter("registry shares", "yes", NULL);
6561 if (!ret) {
6562 goto done;
6565 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6566 /* nothing to read from the registry yet but make sure lp_load
6567 * doesn't return false */
6568 ret = true;
6569 goto done;
6572 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6573 if (!W_ERROR_IS_OK(werr)) {
6574 goto done;
6577 ret = process_registry_service(service);
6578 if (!ret) {
6579 goto done;
6582 /* store the csn */
6583 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6585 done:
6586 TALLOC_FREE(mem_ctx);
6587 return ret;
6590 static bool process_registry_shares(void)
6592 WERROR werr;
6593 uint32_t count;
6594 struct smbconf_service **service = NULL;
6595 uint32_t num_shares = 0;
6596 TALLOC_CTX *mem_ctx = talloc_stackframe();
6597 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6598 bool ret = false;
6600 if (conf_ctx == NULL) {
6601 goto done;
6604 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6605 if (!W_ERROR_IS_OK(werr)) {
6606 goto done;
6609 ret = true;
6611 for (count = 0; count < num_shares; count++) {
6612 if (strequal(service[count]->name, GLOBAL_NAME)) {
6613 continue;
6615 ret = process_registry_service(service[count]);
6616 if (!ret) {
6617 goto done;
6621 /* store the csn */
6622 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6624 done:
6625 TALLOC_FREE(mem_ctx);
6626 return ret;
6629 static struct file_lists {
6630 struct file_lists *next;
6631 char *name;
6632 char *subfname;
6633 time_t modtime;
6634 } *file_lists = NULL;
6636 /*******************************************************************
6637 Keep a linked list of all config files so we know when one has changed
6638 it's date and needs to be reloaded.
6639 ********************************************************************/
6641 static void add_to_file_list(const char *fname, const char *subfname)
6643 struct file_lists *f = file_lists;
6645 while (f) {
6646 if (f->name && !strcmp(f->name, fname))
6647 break;
6648 f = f->next;
6651 if (!f) {
6652 f = SMB_MALLOC_P(struct file_lists);
6653 if (!f)
6654 return;
6655 f->next = file_lists;
6656 f->name = SMB_STRDUP(fname);
6657 if (!f->name) {
6658 SAFE_FREE(f);
6659 return;
6661 f->subfname = SMB_STRDUP(subfname);
6662 if (!f->subfname) {
6663 SAFE_FREE(f);
6664 return;
6666 file_lists = f;
6667 f->modtime = file_modtime(subfname);
6668 } else {
6669 time_t t = file_modtime(subfname);
6670 if (t)
6671 f->modtime = t;
6676 * Utility function for outsiders to check if we're running on registry.
6678 bool lp_config_backend_is_registry(void)
6680 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6684 * Utility function to check if the config backend is FILE.
6686 bool lp_config_backend_is_file(void)
6688 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6691 /*******************************************************************
6692 Check if a config file has changed date.
6693 ********************************************************************/
6695 bool lp_file_list_changed(void)
6697 struct file_lists *f = file_lists;
6699 DEBUG(6, ("lp_file_list_changed()\n"));
6701 if (lp_config_backend_is_registry()) {
6702 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6704 if (conf_ctx == NULL) {
6705 return false;
6707 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6708 DEBUGADD(6, ("registry config changed\n"));
6709 return true;
6713 while (f) {
6714 char *n2 = NULL;
6715 time_t mod_time;
6717 n2 = alloc_sub_basic(get_current_username(),
6718 current_user_info.domain,
6719 f->name);
6720 if (!n2) {
6721 return false;
6723 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6724 f->name, n2, ctime(&f->modtime)));
6726 mod_time = file_modtime(n2);
6728 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6729 DEBUGADD(6,
6730 ("file %s modified: %s\n", n2,
6731 ctime(&mod_time)));
6732 f->modtime = mod_time;
6733 SAFE_FREE(f->subfname);
6734 f->subfname = n2; /* Passing ownership of
6735 return from alloc_sub_basic
6736 above. */
6737 return true;
6739 SAFE_FREE(n2);
6740 f = f->next;
6742 return (False);
6746 /***************************************************************************
6747 Run standard_sub_basic on netbios name... needed because global_myname
6748 is not accessed through any lp_ macro.
6749 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6750 ***************************************************************************/
6752 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6754 bool ret;
6755 char *netbios_name = alloc_sub_basic(get_current_username(),
6756 current_user_info.domain,
6757 pszParmValue);
6759 ret = set_global_myname(netbios_name);
6760 SAFE_FREE(netbios_name);
6761 string_set(&Globals.szNetbiosName,global_myname());
6763 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6764 global_myname()));
6766 return ret;
6769 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6771 if (strcmp(*ptr, pszParmValue) != 0) {
6772 string_set(ptr, pszParmValue);
6773 init_iconv();
6775 return True;
6780 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6782 bool ret;
6784 ret = set_global_myworkgroup(pszParmValue);
6785 string_set(&Globals.szWorkgroup,lp_workgroup());
6787 return ret;
6790 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6792 bool ret;
6794 ret = set_global_scope(pszParmValue);
6795 string_set(&Globals.szNetbiosScope,global_scope());
6797 return ret;
6800 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6802 TALLOC_FREE(Globals.szNetbiosAliases);
6803 Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6804 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6807 /***************************************************************************
6808 Handle the include operation.
6809 ***************************************************************************/
6810 static bool bAllowIncludeRegistry = true;
6812 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6814 char *fname;
6816 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6817 if (!bAllowIncludeRegistry) {
6818 return true;
6820 if (bInGlobalSection) {
6821 return process_registry_globals();
6822 } else {
6823 DEBUG(1, ("\"include = registry\" only effective "
6824 "in %s section\n", GLOBAL_NAME));
6825 return false;
6829 fname = alloc_sub_basic(get_current_username(),
6830 current_user_info.domain,
6831 pszParmValue);
6833 add_to_file_list(pszParmValue, fname);
6835 string_set(ptr, fname);
6837 if (file_exist(fname, NULL)) {
6838 bool ret = pm_process(fname, do_section, do_parameter, NULL);
6839 SAFE_FREE(fname);
6840 return ret;
6843 DEBUG(2, ("Can't find include file %s\n", fname));
6844 SAFE_FREE(fname);
6845 return false;
6848 /***************************************************************************
6849 Handle the interpretation of the copy parameter.
6850 ***************************************************************************/
6852 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6854 bool bRetval;
6855 int iTemp;
6856 struct service serviceTemp;
6858 string_set(ptr, pszParmValue);
6860 init_service(&serviceTemp);
6862 bRetval = False;
6864 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6866 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6867 if (iTemp == iServiceIndex) {
6868 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6869 } else {
6870 copy_service(ServicePtrs[iServiceIndex],
6871 &serviceTemp,
6872 ServicePtrs[iServiceIndex]->copymap);
6873 bRetval = True;
6875 } else {
6876 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6877 bRetval = False;
6880 free_service(&serviceTemp);
6881 return (bRetval);
6884 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6886 Globals.ldap_debug_level = lp_int(pszParmValue);
6887 init_ldap_debugging();
6888 return true;
6891 /***************************************************************************
6892 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6893 parameters is:
6895 [global]
6897 idmap uid = 1000-1999
6898 idmap gid = 700-899
6900 We only do simple parsing checks here. The strings are parsed into useful
6901 structures in the idmap daemon code.
6903 ***************************************************************************/
6905 /* Some lp_ routines to return idmap [ug]id information */
6907 static uid_t idmap_uid_low, idmap_uid_high;
6908 static gid_t idmap_gid_low, idmap_gid_high;
6910 bool lp_idmap_uid(uid_t *low, uid_t *high)
6912 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6913 return False;
6915 if (low)
6916 *low = idmap_uid_low;
6918 if (high)
6919 *high = idmap_uid_high;
6921 return True;
6924 bool lp_idmap_gid(gid_t *low, gid_t *high)
6926 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6927 return False;
6929 if (low)
6930 *low = idmap_gid_low;
6932 if (high)
6933 *high = idmap_gid_high;
6935 return True;
6938 /* Do some simple checks on "idmap [ug]id" parameter values */
6940 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6942 uint32 low, high;
6944 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6945 return False;
6947 /* Parse OK */
6949 string_set(ptr, pszParmValue);
6951 idmap_uid_low = low;
6952 idmap_uid_high = high;
6954 return True;
6957 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6959 uint32 low, high;
6961 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6962 return False;
6964 /* Parse OK */
6966 string_set(ptr, pszParmValue);
6968 idmap_gid_low = low;
6969 idmap_gid_high = high;
6971 return True;
6974 /***************************************************************************
6975 Handle the DEBUG level list.
6976 ***************************************************************************/
6978 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
6980 string_set(ptr, pszParmValueIn);
6981 return debug_parse_levels(pszParmValueIn);
6984 /***************************************************************************
6985 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
6986 ***************************************************************************/
6988 static const char *append_ldap_suffix( const char *str )
6990 const char *suffix_string;
6993 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
6994 Globals.szLdapSuffix );
6995 if ( !suffix_string ) {
6996 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
6997 return "";
7000 return suffix_string;
7003 const char *lp_ldap_machine_suffix(void)
7005 if (Globals.szLdapMachineSuffix[0])
7006 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7008 return lp_string(Globals.szLdapSuffix);
7011 const char *lp_ldap_user_suffix(void)
7013 if (Globals.szLdapUserSuffix[0])
7014 return append_ldap_suffix(Globals.szLdapUserSuffix);
7016 return lp_string(Globals.szLdapSuffix);
7019 const char *lp_ldap_group_suffix(void)
7021 if (Globals.szLdapGroupSuffix[0])
7022 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7024 return lp_string(Globals.szLdapSuffix);
7027 const char *lp_ldap_idmap_suffix(void)
7029 if (Globals.szLdapIdmapSuffix[0])
7030 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7032 return lp_string(Globals.szLdapSuffix);
7035 /****************************************************************************
7036 set the value for a P_ENUM
7037 ***************************************************************************/
7039 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7040 int *ptr )
7042 int i;
7044 for (i = 0; parm->enum_list[i].name; i++) {
7045 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7046 *ptr = parm->enum_list[i].value;
7047 break;
7052 /***************************************************************************
7053 ***************************************************************************/
7055 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7057 static int parm_num = -1;
7058 struct service *s;
7060 if ( parm_num == -1 )
7061 parm_num = map_parameter( "printing" );
7063 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7065 if ( snum < 0 )
7066 s = &sDefault;
7067 else
7068 s = ServicePtrs[snum];
7070 init_printer_values( s );
7072 return True;
7076 /***************************************************************************
7077 Initialise a copymap.
7078 ***************************************************************************/
7080 static void init_copymap(struct service *pservice)
7082 int i;
7083 if (pservice->copymap) {
7084 bitmap_free(pservice->copymap);
7086 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7087 if (!pservice->copymap)
7088 DEBUG(0,
7089 ("Couldn't allocate copymap!! (size %d)\n",
7090 (int)NUMPARAMETERS));
7091 else
7092 for (i = 0; i < NUMPARAMETERS; i++)
7093 bitmap_set(pservice->copymap, i);
7096 /***************************************************************************
7097 Return the local pointer to a parameter given the service number and the
7098 pointer into the default structure.
7099 ***************************************************************************/
7101 void *lp_local_ptr(int snum, void *ptr)
7103 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7106 /***************************************************************************
7107 Process a parameter for a particular service number. If snum < 0
7108 then assume we are in the globals.
7109 ***************************************************************************/
7111 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7113 int parmnum, i, slen;
7114 void *parm_ptr = NULL; /* where we are going to store the result */
7115 void *def_ptr = NULL;
7116 char *param_key = NULL;
7117 char *sep;
7118 param_opt_struct *paramo, *data;
7119 bool not_added;
7121 parmnum = map_parameter(pszParmName);
7123 if (parmnum < 0) {
7124 if ((sep=strchr(pszParmName, ':')) != NULL) {
7125 TALLOC_CTX *frame = talloc_stackframe();
7127 *sep = '\0';
7128 param_key = talloc_asprintf(frame, "%s:", pszParmName);
7129 if (!param_key) {
7130 TALLOC_FREE(frame);
7131 return false;
7133 slen = strlen(param_key);
7134 param_key = talloc_asprintf_append(param_key, sep+1);
7135 if (!param_key) {
7136 TALLOC_FREE(frame);
7137 return false;
7139 trim_char(param_key+slen, ' ', ' ');
7140 not_added = True;
7141 data = (snum < 0) ? Globals.param_opt :
7142 ServicePtrs[snum]->param_opt;
7143 /* Traverse destination */
7144 while (data) {
7145 /* If we already have same option, override it */
7146 if (strcmp(data->key, param_key) == 0) {
7147 string_free(&data->value);
7148 TALLOC_FREE(data->list);
7149 data->value = SMB_STRDUP(pszParmValue);
7150 not_added = False;
7151 break;
7153 data = data->next;
7155 if (not_added) {
7156 paramo = SMB_XMALLOC_P(param_opt_struct);
7157 paramo->key = SMB_STRDUP(param_key);
7158 paramo->value = SMB_STRDUP(pszParmValue);
7159 paramo->list = NULL;
7160 if (snum < 0) {
7161 DLIST_ADD(Globals.param_opt, paramo);
7162 } else {
7163 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
7167 *sep = ':';
7168 TALLOC_FREE(frame);
7169 return (True);
7171 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7172 return (True);
7175 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7176 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7177 pszParmName));
7180 def_ptr = parm_table[parmnum].ptr;
7182 /* we might point at a service, the default service or a global */
7183 if (snum < 0) {
7184 parm_ptr = def_ptr;
7185 } else {
7186 if (parm_table[parmnum].p_class == P_GLOBAL) {
7187 DEBUG(0,
7188 ("Global parameter %s found in service section!\n",
7189 pszParmName));
7190 return (True);
7192 parm_ptr =
7193 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7194 &sDefault);
7197 if (snum >= 0) {
7198 if (!ServicePtrs[snum]->copymap)
7199 init_copymap(ServicePtrs[snum]);
7201 /* this handles the aliases - set the copymap for other entries with
7202 the same data pointer */
7203 for (i = 0; parm_table[i].label; i++)
7204 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7205 bitmap_clear(ServicePtrs[snum]->copymap, i);
7208 /* if it is a special case then go ahead */
7209 if (parm_table[parmnum].special) {
7210 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
7211 return (True);
7214 /* now switch on the type of variable it is */
7215 switch (parm_table[parmnum].type)
7217 case P_BOOL:
7218 *(bool *)parm_ptr = lp_bool(pszParmValue);
7219 break;
7221 case P_BOOLREV:
7222 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7223 break;
7225 case P_INTEGER:
7226 *(int *)parm_ptr = lp_int(pszParmValue);
7227 break;
7229 case P_CHAR:
7230 *(char *)parm_ptr = *pszParmValue;
7231 break;
7233 case P_OCTAL:
7234 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7235 if ( i != 1 ) {
7236 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7238 break;
7240 case P_LIST:
7241 TALLOC_FREE(*((char ***)parm_ptr));
7242 *(char ***)parm_ptr = str_list_make(
7243 NULL, pszParmValue, NULL);
7244 break;
7246 case P_STRING:
7247 string_set((char **)parm_ptr, pszParmValue);
7248 break;
7250 case P_USTRING:
7251 string_set((char **)parm_ptr, pszParmValue);
7252 strupper_m(*(char **)parm_ptr);
7253 break;
7255 case P_ENUM:
7256 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7257 break;
7258 case P_SEP:
7259 break;
7262 return (True);
7265 /***************************************************************************
7266 Process a parameter.
7267 ***************************************************************************/
7269 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7270 void *userdata)
7272 if (!bInGlobalSection && bGlobalOnly)
7273 return (True);
7275 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7277 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7278 pszParmName, pszParmValue));
7281 /***************************************************************************
7282 Print a parameter of the specified type.
7283 ***************************************************************************/
7285 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7287 int i;
7288 switch (p->type)
7290 case P_ENUM:
7291 for (i = 0; p->enum_list[i].name; i++) {
7292 if (*(int *)ptr == p->enum_list[i].value) {
7293 fprintf(f, "%s",
7294 p->enum_list[i].name);
7295 break;
7298 break;
7300 case P_BOOL:
7301 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7302 break;
7304 case P_BOOLREV:
7305 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7306 break;
7308 case P_INTEGER:
7309 fprintf(f, "%d", *(int *)ptr);
7310 break;
7312 case P_CHAR:
7313 fprintf(f, "%c", *(char *)ptr);
7314 break;
7316 case P_OCTAL: {
7317 char *o = octal_string(*(int *)ptr);
7318 fprintf(f, "%s", o);
7319 TALLOC_FREE(o);
7320 break;
7323 case P_LIST:
7324 if ((char ***)ptr && *(char ***)ptr) {
7325 char **list = *(char ***)ptr;
7326 for (; *list; list++) {
7327 /* surround strings with whitespace in double quotes */
7328 if ( strchr_m( *list, ' ' ) )
7329 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7330 else
7331 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7334 break;
7336 case P_STRING:
7337 case P_USTRING:
7338 if (*(char **)ptr) {
7339 fprintf(f, "%s", *(char **)ptr);
7341 break;
7342 case P_SEP:
7343 break;
7347 /***************************************************************************
7348 Check if two parameters are equal.
7349 ***************************************************************************/
7351 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7353 switch (type) {
7354 case P_BOOL:
7355 case P_BOOLREV:
7356 return (*((bool *)ptr1) == *((bool *)ptr2));
7358 case P_INTEGER:
7359 case P_ENUM:
7360 case P_OCTAL:
7361 return (*((int *)ptr1) == *((int *)ptr2));
7363 case P_CHAR:
7364 return (*((char *)ptr1) == *((char *)ptr2));
7366 case P_LIST:
7367 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7369 case P_STRING:
7370 case P_USTRING:
7372 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7373 if (p1 && !*p1)
7374 p1 = NULL;
7375 if (p2 && !*p2)
7376 p2 = NULL;
7377 return (p1 == p2 || strequal(p1, p2));
7379 case P_SEP:
7380 break;
7382 return (False);
7385 /***************************************************************************
7386 Initialize any local varients in the sDefault table.
7387 ***************************************************************************/
7389 void init_locals(void)
7391 /* None as yet. */
7394 /***************************************************************************
7395 Process a new section (service). At this stage all sections are services.
7396 Later we'll have special sections that permit server parameters to be set.
7397 Returns True on success, False on failure.
7398 ***************************************************************************/
7400 static bool do_section(const char *pszSectionName, void *userdata)
7402 bool bRetval;
7403 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7404 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7405 bRetval = False;
7407 /* if we were in a global section then do the local inits */
7408 if (bInGlobalSection && !isglobal)
7409 init_locals();
7411 /* if we've just struck a global section, note the fact. */
7412 bInGlobalSection = isglobal;
7414 /* check for multiple global sections */
7415 if (bInGlobalSection) {
7416 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7417 return (True);
7420 if (!bInGlobalSection && bGlobalOnly)
7421 return (True);
7423 /* if we have a current service, tidy it up before moving on */
7424 bRetval = True;
7426 if (iServiceIndex >= 0)
7427 bRetval = service_ok(iServiceIndex);
7429 /* if all is still well, move to the next record in the services array */
7430 if (bRetval) {
7431 /* We put this here to avoid an odd message order if messages are */
7432 /* issued by the post-processing of a previous section. */
7433 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7435 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7436 < 0) {
7437 DEBUG(0, ("Failed to add a new service\n"));
7438 return (False);
7442 return (bRetval);
7446 /***************************************************************************
7447 Determine if a partcular base parameter is currentl set to the default value.
7448 ***************************************************************************/
7450 static bool is_default(int i)
7452 if (!defaults_saved)
7453 return False;
7454 switch (parm_table[i].type) {
7455 case P_LIST:
7456 return str_list_compare (parm_table[i].def.lvalue,
7457 *(char ***)parm_table[i].ptr);
7458 case P_STRING:
7459 case P_USTRING:
7460 return strequal(parm_table[i].def.svalue,
7461 *(char **)parm_table[i].ptr);
7462 case P_BOOL:
7463 case P_BOOLREV:
7464 return parm_table[i].def.bvalue ==
7465 *(bool *)parm_table[i].ptr;
7466 case P_CHAR:
7467 return parm_table[i].def.cvalue ==
7468 *(char *)parm_table[i].ptr;
7469 case P_INTEGER:
7470 case P_OCTAL:
7471 case P_ENUM:
7472 return parm_table[i].def.ivalue ==
7473 *(int *)parm_table[i].ptr;
7474 case P_SEP:
7475 break;
7477 return False;
7480 /***************************************************************************
7481 Display the contents of the global structure.
7482 ***************************************************************************/
7484 static void dump_globals(FILE *f)
7486 int i;
7487 param_opt_struct *data;
7489 fprintf(f, "[global]\n");
7491 for (i = 0; parm_table[i].label; i++)
7492 if (parm_table[i].p_class == P_GLOBAL &&
7493 parm_table[i].ptr &&
7494 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7495 if (defaults_saved && is_default(i))
7496 continue;
7497 fprintf(f, "\t%s = ", parm_table[i].label);
7498 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7499 fprintf(f, "\n");
7501 if (Globals.param_opt != NULL) {
7502 data = Globals.param_opt;
7503 while(data) {
7504 fprintf(f, "\t%s = %s\n", data->key, data->value);
7505 data = data->next;
7511 /***************************************************************************
7512 Return True if a local parameter is currently set to the global default.
7513 ***************************************************************************/
7515 bool lp_is_default(int snum, struct parm_struct *parm)
7517 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7519 return equal_parameter(parm->type,
7520 ((char *)ServicePtrs[snum]) + pdiff,
7521 ((char *)&sDefault) + pdiff);
7524 /***************************************************************************
7525 Display the contents of a single services record.
7526 ***************************************************************************/
7528 static void dump_a_service(struct service *pService, FILE * f)
7530 int i;
7531 param_opt_struct *data;
7533 if (pService != &sDefault)
7534 fprintf(f, "[%s]\n", pService->szService);
7536 for (i = 0; parm_table[i].label; i++) {
7538 if (parm_table[i].p_class == P_LOCAL &&
7539 parm_table[i].ptr &&
7540 (*parm_table[i].label != '-') &&
7541 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7544 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7546 if (pService == &sDefault) {
7547 if (defaults_saved && is_default(i))
7548 continue;
7549 } else {
7550 if (equal_parameter(parm_table[i].type,
7551 ((char *)pService) +
7552 pdiff,
7553 ((char *)&sDefault) +
7554 pdiff))
7555 continue;
7558 fprintf(f, "\t%s = ", parm_table[i].label);
7559 print_parameter(&parm_table[i],
7560 ((char *)pService) + pdiff, f);
7561 fprintf(f, "\n");
7565 if (pService->param_opt != NULL) {
7566 data = pService->param_opt;
7567 while(data) {
7568 fprintf(f, "\t%s = %s\n", data->key, data->value);
7569 data = data->next;
7574 /***************************************************************************
7575 Display the contents of a parameter of a single services record.
7576 ***************************************************************************/
7578 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7580 int i;
7581 bool result = False;
7582 parm_class p_class;
7583 unsigned flag = 0;
7584 fstring local_parm_name;
7585 char *parm_opt;
7586 const char *parm_opt_value;
7588 /* check for parametrical option */
7589 fstrcpy( local_parm_name, parm_name);
7590 parm_opt = strchr( local_parm_name, ':');
7592 if (parm_opt) {
7593 *parm_opt = '\0';
7594 parm_opt++;
7595 if (strlen(parm_opt)) {
7596 parm_opt_value = lp_parm_const_string( snum,
7597 local_parm_name, parm_opt, NULL);
7598 if (parm_opt_value) {
7599 printf( "%s\n", parm_opt_value);
7600 result = True;
7603 return result;
7606 /* check for a key and print the value */
7607 if (isGlobal) {
7608 p_class = P_GLOBAL;
7609 flag = FLAG_GLOBAL;
7610 } else
7611 p_class = P_LOCAL;
7613 for (i = 0; parm_table[i].label; i++) {
7614 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7615 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7616 parm_table[i].ptr &&
7617 (*parm_table[i].label != '-') &&
7618 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7620 void *ptr;
7622 if (isGlobal) {
7623 ptr = parm_table[i].ptr;
7624 } else {
7625 struct service *pService = ServicePtrs[snum];
7626 ptr = ((char *)pService) +
7627 PTR_DIFF(parm_table[i].ptr, &sDefault);
7630 print_parameter(&parm_table[i],
7631 ptr, f);
7632 fprintf(f, "\n");
7633 result = True;
7634 break;
7638 return result;
7641 /***************************************************************************
7642 Return info about the requested parameter (given as a string).
7643 Return NULL when the string is not a valid parameter name.
7644 ***************************************************************************/
7646 struct parm_struct *lp_get_parameter(const char *param_name)
7648 int num = map_parameter(param_name);
7650 if (num < 0) {
7651 return NULL;
7654 return &parm_table[num];
7657 /***************************************************************************
7658 Return info about the next parameter in a service.
7659 snum==GLOBAL_SECTION_SNUM gives the globals.
7660 Return NULL when out of parameters.
7661 ***************************************************************************/
7663 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7665 if (snum < 0) {
7666 /* do the globals */
7667 for (; parm_table[*i].label; (*i)++) {
7668 if (parm_table[*i].p_class == P_SEPARATOR)
7669 return &parm_table[(*i)++];
7671 if (!parm_table[*i].ptr
7672 || (*parm_table[*i].label == '-'))
7673 continue;
7675 if ((*i) > 0
7676 && (parm_table[*i].ptr ==
7677 parm_table[(*i) - 1].ptr))
7678 continue;
7680 if (is_default(*i) && !allparameters)
7681 continue;
7683 return &parm_table[(*i)++];
7685 } else {
7686 struct service *pService = ServicePtrs[snum];
7688 for (; parm_table[*i].label; (*i)++) {
7689 if (parm_table[*i].p_class == P_SEPARATOR)
7690 return &parm_table[(*i)++];
7692 if (parm_table[*i].p_class == P_LOCAL &&
7693 parm_table[*i].ptr &&
7694 (*parm_table[*i].label != '-') &&
7695 ((*i) == 0 ||
7696 (parm_table[*i].ptr !=
7697 parm_table[(*i) - 1].ptr)))
7699 int pdiff =
7700 PTR_DIFF(parm_table[*i].ptr,
7701 &sDefault);
7703 if (allparameters ||
7704 !equal_parameter(parm_table[*i].type,
7705 ((char *)pService) +
7706 pdiff,
7707 ((char *)&sDefault) +
7708 pdiff))
7710 return &parm_table[(*i)++];
7716 return NULL;
7720 #if 0
7721 /***************************************************************************
7722 Display the contents of a single copy structure.
7723 ***************************************************************************/
7724 static void dump_copy_map(bool *pcopymap)
7726 int i;
7727 if (!pcopymap)
7728 return;
7730 printf("\n\tNon-Copied parameters:\n");
7732 for (i = 0; parm_table[i].label; i++)
7733 if (parm_table[i].p_class == P_LOCAL &&
7734 parm_table[i].ptr && !pcopymap[i] &&
7735 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7737 printf("\t\t%s\n", parm_table[i].label);
7740 #endif
7742 /***************************************************************************
7743 Return TRUE if the passed service number is within range.
7744 ***************************************************************************/
7746 bool lp_snum_ok(int iService)
7748 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7751 /***************************************************************************
7752 Auto-load some home services.
7753 ***************************************************************************/
7755 static void lp_add_auto_services(char *str)
7757 char *s;
7758 char *p;
7759 int homes;
7760 char *saveptr;
7762 if (!str)
7763 return;
7765 s = SMB_STRDUP(str);
7766 if (!s)
7767 return;
7769 homes = lp_servicenumber(HOMES_NAME);
7771 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7772 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7773 char *home;
7775 if (lp_servicenumber(p) >= 0)
7776 continue;
7778 home = get_user_home_dir(talloc_tos(), p);
7780 if (home && homes >= 0)
7781 lp_add_home(p, homes, p, home);
7783 TALLOC_FREE(home);
7785 SAFE_FREE(s);
7788 /***************************************************************************
7789 Auto-load one printer.
7790 ***************************************************************************/
7792 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
7794 int printers = lp_servicenumber(PRINTERS_NAME);
7795 int i;
7797 if (lp_servicenumber(name) < 0) {
7798 lp_add_printer(name, printers);
7799 if ((i = lp_servicenumber(name)) >= 0) {
7800 string_set(&ServicePtrs[i]->comment, comment);
7801 ServicePtrs[i]->autoloaded = True;
7806 /***************************************************************************
7807 Have we loaded a services file yet?
7808 ***************************************************************************/
7810 bool lp_loaded(void)
7812 return (bLoaded);
7815 /***************************************************************************
7816 Unload unused services.
7817 ***************************************************************************/
7819 void lp_killunused(bool (*snumused) (int))
7821 int i;
7822 for (i = 0; i < iNumServices; i++) {
7823 if (!VALID(i))
7824 continue;
7826 /* don't kill autoloaded or usershare services */
7827 if ( ServicePtrs[i]->autoloaded ||
7828 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7829 continue;
7832 if (!snumused || !snumused(i)) {
7833 free_service_byindex(i);
7839 * Kill all except autoloaded and usershare services - convenience wrapper
7841 void lp_kill_all_services(void)
7843 lp_killunused(NULL);
7846 /***************************************************************************
7847 Unload a service.
7848 ***************************************************************************/
7850 void lp_killservice(int iServiceIn)
7852 if (VALID(iServiceIn)) {
7853 free_service_byindex(iServiceIn);
7857 /***************************************************************************
7858 Save the curent values of all global and sDefault parameters into the
7859 defaults union. This allows swat and testparm to show only the
7860 changed (ie. non-default) parameters.
7861 ***************************************************************************/
7863 static void lp_save_defaults(void)
7865 int i;
7866 for (i = 0; parm_table[i].label; i++) {
7867 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7868 continue;
7869 switch (parm_table[i].type) {
7870 case P_LIST:
7871 str_list_copy(
7872 NULL, &(parm_table[i].def.lvalue),
7873 *(const char ***)parm_table[i].ptr);
7874 break;
7875 case P_STRING:
7876 case P_USTRING:
7877 if (parm_table[i].ptr) {
7878 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7879 } else {
7880 parm_table[i].def.svalue = NULL;
7882 break;
7883 case P_BOOL:
7884 case P_BOOLREV:
7885 parm_table[i].def.bvalue =
7886 *(bool *)parm_table[i].ptr;
7887 break;
7888 case P_CHAR:
7889 parm_table[i].def.cvalue =
7890 *(char *)parm_table[i].ptr;
7891 break;
7892 case P_INTEGER:
7893 case P_OCTAL:
7894 case P_ENUM:
7895 parm_table[i].def.ivalue =
7896 *(int *)parm_table[i].ptr;
7897 break;
7898 case P_SEP:
7899 break;
7902 defaults_saved = True;
7905 /*******************************************************************
7906 Set the server type we will announce as via nmbd.
7907 ********************************************************************/
7909 static const struct srv_role_tab {
7910 uint32 role;
7911 const char *role_str;
7912 } srv_role_tab [] = {
7913 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7914 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7915 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7916 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7917 { 0, NULL }
7920 const char* server_role_str(uint32 role)
7922 int i = 0;
7923 for (i=0; srv_role_tab[i].role_str; i++) {
7924 if (role == srv_role_tab[i].role) {
7925 return srv_role_tab[i].role_str;
7928 return NULL;
7931 static void set_server_role(void)
7933 server_role = ROLE_STANDALONE;
7935 switch (lp_security()) {
7936 case SEC_SHARE:
7937 if (lp_domain_logons())
7938 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7939 break;
7940 case SEC_SERVER:
7941 if (lp_domain_logons())
7942 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7943 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7944 server_role = ROLE_STANDALONE;
7945 break;
7946 case SEC_DOMAIN:
7947 if (lp_domain_logons()) {
7948 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7949 server_role = ROLE_DOMAIN_BDC;
7950 break;
7952 server_role = ROLE_DOMAIN_MEMBER;
7953 break;
7954 case SEC_ADS:
7955 if (lp_domain_logons()) {
7956 server_role = ROLE_DOMAIN_PDC;
7957 break;
7959 server_role = ROLE_DOMAIN_MEMBER;
7960 break;
7961 case SEC_USER:
7962 if (lp_domain_logons()) {
7964 if (Globals.iDomainMaster) /* auto or yes */
7965 server_role = ROLE_DOMAIN_PDC;
7966 else
7967 server_role = ROLE_DOMAIN_BDC;
7969 break;
7970 default:
7971 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7972 break;
7975 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
7978 /***********************************************************
7979 If we should send plaintext/LANMAN passwords in the clinet
7980 ************************************************************/
7982 static void set_allowed_client_auth(void)
7984 if (Globals.bClientNTLMv2Auth) {
7985 Globals.bClientLanManAuth = False;
7987 if (!Globals.bClientLanManAuth) {
7988 Globals.bClientPlaintextAuth = False;
7992 /***************************************************************************
7993 JRA.
7994 The following code allows smbd to read a user defined share file.
7995 Yes, this is my intent. Yes, I'm comfortable with that...
7997 THE FOLLOWING IS SECURITY CRITICAL CODE.
7999 It washes your clothes, it cleans your house, it guards you while you sleep...
8000 Do not f%^k with it....
8001 ***************************************************************************/
8003 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8005 /***************************************************************************
8006 Check allowed stat state of a usershare file.
8007 Ensure we print out who is dicking with us so the admin can
8008 get their sorry ass fired.
8009 ***************************************************************************/
8011 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8013 if (!S_ISREG(psbuf->st_mode)) {
8014 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8015 "not a regular file\n",
8016 fname, (unsigned int)psbuf->st_uid ));
8017 return False;
8020 /* Ensure this doesn't have the other write bit set. */
8021 if (psbuf->st_mode & S_IWOTH) {
8022 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8023 "public write. Refusing to allow as a usershare file.\n",
8024 fname, (unsigned int)psbuf->st_uid ));
8025 return False;
8028 /* Should be 10k or less. */
8029 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8030 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8031 "too large (%u) to be a user share file.\n",
8032 fname, (unsigned int)psbuf->st_uid,
8033 (unsigned int)psbuf->st_size ));
8034 return False;
8037 return True;
8040 /***************************************************************************
8041 Parse the contents of a usershare file.
8042 ***************************************************************************/
8044 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8045 SMB_STRUCT_STAT *psbuf,
8046 const char *servicename,
8047 int snum,
8048 char **lines,
8049 int numlines,
8050 char **pp_sharepath,
8051 char **pp_comment,
8052 SEC_DESC **ppsd,
8053 bool *pallow_guest)
8055 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8056 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8057 int us_vers;
8058 SMB_STRUCT_DIR *dp;
8059 SMB_STRUCT_STAT sbuf;
8060 char *sharepath = NULL;
8061 char *comment = NULL;
8063 *pp_sharepath = NULL;
8064 *pp_comment = NULL;
8066 *pallow_guest = False;
8068 if (numlines < 4) {
8069 return USERSHARE_MALFORMED_FILE;
8072 if (strcmp(lines[0], "#VERSION 1") == 0) {
8073 us_vers = 1;
8074 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8075 us_vers = 2;
8076 if (numlines < 5) {
8077 return USERSHARE_MALFORMED_FILE;
8079 } else {
8080 return USERSHARE_BAD_VERSION;
8083 if (strncmp(lines[1], "path=", 5) != 0) {
8084 return USERSHARE_MALFORMED_PATH;
8087 sharepath = talloc_strdup(ctx, &lines[1][5]);
8088 if (!sharepath) {
8089 return USERSHARE_POSIX_ERR;
8091 trim_string(sharepath, " ", " ");
8093 if (strncmp(lines[2], "comment=", 8) != 0) {
8094 return USERSHARE_MALFORMED_COMMENT_DEF;
8097 comment = talloc_strdup(ctx, &lines[2][8]);
8098 if (!comment) {
8099 return USERSHARE_POSIX_ERR;
8101 trim_string(comment, " ", " ");
8102 trim_char(comment, '"', '"');
8104 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8105 return USERSHARE_MALFORMED_ACL_DEF;
8108 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8109 return USERSHARE_ACL_ERR;
8112 if (us_vers == 2) {
8113 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8114 return USERSHARE_MALFORMED_ACL_DEF;
8116 if (lines[4][9] == 'y') {
8117 *pallow_guest = True;
8121 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8122 /* Path didn't change, no checks needed. */
8123 *pp_sharepath = sharepath;
8124 *pp_comment = comment;
8125 return USERSHARE_OK;
8128 /* The path *must* be absolute. */
8129 if (sharepath[0] != '/') {
8130 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8131 servicename, sharepath));
8132 return USERSHARE_PATH_NOT_ABSOLUTE;
8135 /* If there is a usershare prefix deny list ensure one of these paths
8136 doesn't match the start of the user given path. */
8137 if (prefixdenylist) {
8138 int i;
8139 for ( i=0; prefixdenylist[i]; i++ ) {
8140 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8141 servicename, i, prefixdenylist[i], sharepath ));
8142 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8143 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8144 "usershare prefix deny list entries.\n",
8145 servicename, sharepath));
8146 return USERSHARE_PATH_IS_DENIED;
8151 /* If there is a usershare prefix allow list ensure one of these paths
8152 does match the start of the user given path. */
8154 if (prefixallowlist) {
8155 int i;
8156 for ( i=0; prefixallowlist[i]; i++ ) {
8157 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8158 servicename, i, prefixallowlist[i], sharepath ));
8159 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8160 break;
8163 if (prefixallowlist[i] == NULL) {
8164 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8165 "usershare prefix allow list entries.\n",
8166 servicename, sharepath));
8167 return USERSHARE_PATH_NOT_ALLOWED;
8171 /* Ensure this is pointing to a directory. */
8172 dp = sys_opendir(sharepath);
8174 if (!dp) {
8175 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8176 servicename, sharepath));
8177 return USERSHARE_PATH_NOT_DIRECTORY;
8180 /* Ensure the owner of the usershare file has permission to share
8181 this directory. */
8183 if (sys_stat(sharepath, &sbuf) == -1) {
8184 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8185 servicename, sharepath, strerror(errno) ));
8186 sys_closedir(dp);
8187 return USERSHARE_POSIX_ERR;
8190 sys_closedir(dp);
8192 if (!S_ISDIR(sbuf.st_mode)) {
8193 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8194 servicename, sharepath ));
8195 return USERSHARE_PATH_NOT_DIRECTORY;
8198 /* Check if sharing is restricted to owner-only. */
8199 /* psbuf is the stat of the usershare definition file,
8200 sbuf is the stat of the target directory to be shared. */
8202 if (lp_usershare_owner_only()) {
8203 /* root can share anything. */
8204 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8205 return USERSHARE_PATH_NOT_ALLOWED;
8209 *pp_sharepath = sharepath;
8210 *pp_comment = comment;
8211 return USERSHARE_OK;
8214 /***************************************************************************
8215 Deal with a usershare file.
8216 Returns:
8217 >= 0 - snum
8218 -1 - Bad name, invalid contents.
8219 - service name already existed and not a usershare, problem
8220 with permissions to share directory etc.
8221 ***************************************************************************/
8223 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8225 SMB_STRUCT_STAT sbuf;
8226 SMB_STRUCT_STAT lsbuf;
8227 char *fname = NULL;
8228 char *sharepath = NULL;
8229 char *comment = NULL;
8230 fstring service_name;
8231 char **lines = NULL;
8232 int numlines = 0;
8233 int fd = -1;
8234 int iService = -1;
8235 TALLOC_CTX *ctx = NULL;
8236 SEC_DESC *psd = NULL;
8237 bool guest_ok = False;
8239 /* Ensure share name doesn't contain invalid characters. */
8240 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8241 DEBUG(0,("process_usershare_file: share name %s contains "
8242 "invalid characters (any of %s)\n",
8243 file_name, INVALID_SHARENAME_CHARS ));
8244 return -1;
8247 fstrcpy(service_name, file_name);
8249 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8252 /* Minimize the race condition by doing an lstat before we
8253 open and fstat. Ensure this isn't a symlink link. */
8255 if (sys_lstat(fname, &lsbuf) != 0) {
8256 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8257 fname, strerror(errno) ));
8258 SAFE_FREE(fname);
8259 return -1;
8262 /* This must be a regular file, not a symlink, directory or
8263 other strange filetype. */
8264 if (!check_usershare_stat(fname, &lsbuf)) {
8265 SAFE_FREE(fname);
8266 return -1;
8270 char *canon_name = canonicalize_servicename(service_name);
8271 TDB_DATA data = dbwrap_fetch_bystring(
8272 ServiceHash, canon_name, canon_name);
8274 iService = -1;
8276 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8277 iService = *(int *)data.dptr;
8279 TALLOC_FREE(canon_name);
8282 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8283 /* Nothing changed - Mark valid and return. */
8284 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8285 service_name ));
8286 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8287 SAFE_FREE(fname);
8288 return iService;
8291 /* Try and open the file read only - no symlinks allowed. */
8292 #ifdef O_NOFOLLOW
8293 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8294 #else
8295 fd = sys_open(fname, O_RDONLY, 0);
8296 #endif
8298 if (fd == -1) {
8299 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8300 fname, strerror(errno) ));
8301 SAFE_FREE(fname);
8302 return -1;
8305 /* Now fstat to be *SURE* it's a regular file. */
8306 if (sys_fstat(fd, &sbuf) != 0) {
8307 close(fd);
8308 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8309 fname, strerror(errno) ));
8310 SAFE_FREE(fname);
8311 return -1;
8314 /* Is it the same dev/inode as was lstated ? */
8315 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8316 close(fd);
8317 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8318 "Symlink spoofing going on ?\n", fname ));
8319 SAFE_FREE(fname);
8320 return -1;
8323 /* This must be a regular file, not a symlink, directory or
8324 other strange filetype. */
8325 if (!check_usershare_stat(fname, &sbuf)) {
8326 SAFE_FREE(fname);
8327 return -1;
8330 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8332 close(fd);
8333 if (lines == NULL) {
8334 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8335 fname, (unsigned int)sbuf.st_uid ));
8336 SAFE_FREE(fname);
8337 return -1;
8340 SAFE_FREE(fname);
8342 /* Should we allow printers to be shared... ? */
8343 ctx = talloc_init("usershare_sd_xctx");
8344 if (!ctx) {
8345 file_lines_free(lines);
8346 return 1;
8349 if (parse_usershare_file(ctx, &sbuf, service_name,
8350 iService, lines, numlines, &sharepath,
8351 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8352 talloc_destroy(ctx);
8353 file_lines_free(lines);
8354 return -1;
8357 file_lines_free(lines);
8359 /* Everything ok - add the service possibly using a template. */
8360 if (iService < 0) {
8361 const struct service *sp = &sDefault;
8362 if (snum_template != -1) {
8363 sp = ServicePtrs[snum_template];
8366 if ((iService = add_a_service(sp, service_name)) < 0) {
8367 DEBUG(0, ("process_usershare_file: Failed to add "
8368 "new service %s\n", service_name));
8369 talloc_destroy(ctx);
8370 return -1;
8373 /* Read only is controlled by usershare ACL below. */
8374 ServicePtrs[iService]->bRead_only = False;
8377 /* Write the ACL of the new/modified share. */
8378 if (!set_share_security(service_name, psd)) {
8379 DEBUG(0, ("process_usershare_file: Failed to set share "
8380 "security for user share %s\n",
8381 service_name ));
8382 lp_remove_service(iService);
8383 talloc_destroy(ctx);
8384 return -1;
8387 /* If from a template it may be marked invalid. */
8388 ServicePtrs[iService]->valid = True;
8390 /* Set the service as a valid usershare. */
8391 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8393 /* Set guest access. */
8394 if (lp_usershare_allow_guests()) {
8395 ServicePtrs[iService]->bGuest_ok = guest_ok;
8398 /* And note when it was loaded. */
8399 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8400 string_set(&ServicePtrs[iService]->szPath, sharepath);
8401 string_set(&ServicePtrs[iService]->comment, comment);
8403 talloc_destroy(ctx);
8405 return iService;
8408 /***************************************************************************
8409 Checks if a usershare entry has been modified since last load.
8410 ***************************************************************************/
8412 static bool usershare_exists(int iService, time_t *last_mod)
8414 SMB_STRUCT_STAT lsbuf;
8415 const char *usersharepath = Globals.szUsersharePath;
8416 char *fname;
8418 if (asprintf(&fname, "%s/%s",
8419 usersharepath,
8420 ServicePtrs[iService]->szService) < 0) {
8421 return false;
8424 if (sys_lstat(fname, &lsbuf) != 0) {
8425 SAFE_FREE(fname);
8426 return false;
8429 if (!S_ISREG(lsbuf.st_mode)) {
8430 SAFE_FREE(fname);
8431 return false;
8434 SAFE_FREE(fname);
8435 *last_mod = lsbuf.st_mtime;
8436 return true;
8439 /***************************************************************************
8440 Load a usershare service by name. Returns a valid servicenumber or -1.
8441 ***************************************************************************/
8443 int load_usershare_service(const char *servicename)
8445 SMB_STRUCT_STAT sbuf;
8446 const char *usersharepath = Globals.szUsersharePath;
8447 int max_user_shares = Globals.iUsershareMaxShares;
8448 int snum_template = -1;
8450 if (*usersharepath == 0 || max_user_shares == 0) {
8451 return -1;
8454 if (sys_stat(usersharepath, &sbuf) != 0) {
8455 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8456 usersharepath, strerror(errno) ));
8457 return -1;
8460 if (!S_ISDIR(sbuf.st_mode)) {
8461 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8462 usersharepath ));
8463 return -1;
8467 * This directory must be owned by root, and have the 't' bit set.
8468 * It also must not be writable by "other".
8471 #ifdef S_ISVTX
8472 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8473 #else
8474 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8475 #endif
8476 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8477 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8478 usersharepath ));
8479 return -1;
8482 /* Ensure the template share exists if it's set. */
8483 if (Globals.szUsershareTemplateShare[0]) {
8484 /* We can't use lp_servicenumber here as we are recommending that
8485 template shares have -valid=False set. */
8486 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8487 if (ServicePtrs[snum_template]->szService &&
8488 strequal(ServicePtrs[snum_template]->szService,
8489 Globals.szUsershareTemplateShare)) {
8490 break;
8494 if (snum_template == -1) {
8495 DEBUG(0,("load_usershare_service: usershare template share %s "
8496 "does not exist.\n",
8497 Globals.szUsershareTemplateShare ));
8498 return -1;
8502 return process_usershare_file(usersharepath, servicename, snum_template);
8505 /***************************************************************************
8506 Load all user defined shares from the user share directory.
8507 We only do this if we're enumerating the share list.
8508 This is the function that can delete usershares that have
8509 been removed.
8510 ***************************************************************************/
8512 int load_usershare_shares(void)
8514 SMB_STRUCT_DIR *dp;
8515 SMB_STRUCT_STAT sbuf;
8516 SMB_STRUCT_DIRENT *de;
8517 int num_usershares = 0;
8518 int max_user_shares = Globals.iUsershareMaxShares;
8519 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8520 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8521 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8522 int iService;
8523 int snum_template = -1;
8524 const char *usersharepath = Globals.szUsersharePath;
8525 int ret = lp_numservices();
8527 if (max_user_shares == 0 || *usersharepath == '\0') {
8528 return lp_numservices();
8531 if (sys_stat(usersharepath, &sbuf) != 0) {
8532 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8533 usersharepath, strerror(errno) ));
8534 return ret;
8538 * This directory must be owned by root, and have the 't' bit set.
8539 * It also must not be writable by "other".
8542 #ifdef S_ISVTX
8543 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8544 #else
8545 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8546 #endif
8547 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8548 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8549 usersharepath ));
8550 return ret;
8553 /* Ensure the template share exists if it's set. */
8554 if (Globals.szUsershareTemplateShare[0]) {
8555 /* We can't use lp_servicenumber here as we are recommending that
8556 template shares have -valid=False set. */
8557 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8558 if (ServicePtrs[snum_template]->szService &&
8559 strequal(ServicePtrs[snum_template]->szService,
8560 Globals.szUsershareTemplateShare)) {
8561 break;
8565 if (snum_template == -1) {
8566 DEBUG(0,("load_usershare_shares: usershare template share %s "
8567 "does not exist.\n",
8568 Globals.szUsershareTemplateShare ));
8569 return ret;
8573 /* Mark all existing usershares as pending delete. */
8574 for (iService = iNumServices - 1; iService >= 0; iService--) {
8575 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8576 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8580 dp = sys_opendir(usersharepath);
8581 if (!dp) {
8582 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8583 usersharepath, strerror(errno) ));
8584 return ret;
8587 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8588 (de = sys_readdir(dp));
8589 num_dir_entries++ ) {
8590 int r;
8591 const char *n = de->d_name;
8593 /* Ignore . and .. */
8594 if (*n == '.') {
8595 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8596 continue;
8600 if (n[0] == ':') {
8601 /* Temporary file used when creating a share. */
8602 num_tmp_dir_entries++;
8605 /* Allow 20% tmp entries. */
8606 if (num_tmp_dir_entries > allowed_tmp_entries) {
8607 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8608 "in directory %s\n",
8609 num_tmp_dir_entries, usersharepath));
8610 break;
8613 r = process_usershare_file(usersharepath, n, snum_template);
8614 if (r == 0) {
8615 /* Update the services count. */
8616 num_usershares++;
8617 if (num_usershares >= max_user_shares) {
8618 DEBUG(0,("load_usershare_shares: max user shares reached "
8619 "on file %s in directory %s\n",
8620 n, usersharepath ));
8621 break;
8623 } else if (r == -1) {
8624 num_bad_dir_entries++;
8627 /* Allow 20% bad entries. */
8628 if (num_bad_dir_entries > allowed_bad_entries) {
8629 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8630 "in directory %s\n",
8631 num_bad_dir_entries, usersharepath));
8632 break;
8635 /* Allow 20% bad entries. */
8636 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8637 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8638 "in directory %s\n",
8639 num_dir_entries, usersharepath));
8640 break;
8644 sys_closedir(dp);
8646 /* Sweep through and delete any non-refreshed usershares that are
8647 not currently in use. */
8648 for (iService = iNumServices - 1; iService >= 0; iService--) {
8649 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8650 if (conn_snum_used(iService)) {
8651 continue;
8653 /* Remove from the share ACL db. */
8654 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8655 lp_servicename(iService) ));
8656 delete_share_security(lp_servicename(iService));
8657 free_service_byindex(iService);
8661 return lp_numservices();
8664 /********************************************************
8665 Destroy global resources allocated in this file
8666 ********************************************************/
8668 void gfree_loadparm(void)
8670 struct file_lists *f;
8671 struct file_lists *next;
8672 int i;
8674 /* Free the file lists */
8676 f = file_lists;
8677 while( f ) {
8678 next = f->next;
8679 SAFE_FREE( f->name );
8680 SAFE_FREE( f->subfname );
8681 SAFE_FREE( f );
8682 f = next;
8684 file_lists = NULL;
8686 /* Free resources allocated to services */
8688 for ( i = 0; i < iNumServices; i++ ) {
8689 if ( VALID(i) ) {
8690 free_service_byindex(i);
8694 SAFE_FREE( ServicePtrs );
8695 iNumServices = 0;
8697 /* Now release all resources allocated to global
8698 parameters and the default service */
8700 for (i = 0; parm_table[i].label; i++)
8702 if ( parm_table[i].type == P_STRING
8703 || parm_table[i].type == P_USTRING )
8705 string_free( (char**)parm_table[i].ptr );
8707 else if (parm_table[i].type == P_LIST) {
8708 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8714 /***************************************************************************
8715 Allow client apps to specify that they are a client
8716 ***************************************************************************/
8717 void lp_set_in_client(bool b)
8719 in_client = b;
8723 /***************************************************************************
8724 Determine if we're running in a client app
8725 ***************************************************************************/
8726 bool lp_is_in_client(void)
8728 return in_client;
8734 /***************************************************************************
8735 Load the services array from the services file. Return True on success,
8736 False on failure.
8737 ***************************************************************************/
8739 bool lp_load_ex(const char *pszFname,
8740 bool global_only,
8741 bool save_defaults,
8742 bool add_ipc,
8743 bool initialize_globals,
8744 bool allow_include_registry,
8745 bool allow_registry_shares)
8747 char *n2 = NULL;
8748 bool bRetval;
8749 param_opt_struct *data, *pdata;
8751 bRetval = False;
8753 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8755 bInGlobalSection = True;
8756 bGlobalOnly = global_only;
8757 bAllowIncludeRegistry = allow_include_registry;
8759 init_globals(! initialize_globals);
8760 debug_init();
8762 if (save_defaults) {
8763 init_locals();
8764 lp_save_defaults();
8767 /* We get sections first, so have to start 'behind' to make up */
8768 iServiceIndex = -1;
8770 if (Globals.param_opt != NULL) {
8771 data = Globals.param_opt;
8772 while (data) {
8773 string_free(&data->key);
8774 string_free(&data->value);
8775 TALLOC_FREE(data->list);
8776 pdata = data->next;
8777 SAFE_FREE(data);
8778 data = pdata;
8780 Globals.param_opt = NULL;
8783 if (lp_config_backend_is_file()) {
8784 n2 = alloc_sub_basic(get_current_username(),
8785 current_user_info.domain,
8786 pszFname);
8787 if (!n2) {
8788 smb_panic("lp_load_ex: out of memory");
8791 add_to_file_list(pszFname, n2);
8793 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8794 SAFE_FREE(n2);
8796 /* finish up the last section */
8797 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8798 if (bRetval) {
8799 if (iServiceIndex >= 0) {
8800 bRetval = service_ok(iServiceIndex);
8804 if (lp_config_backend_is_registry()) {
8805 /* config backend changed to registry in config file */
8807 * We need to use this extra global variable here to
8808 * survive restart: init_globals uses this as a default
8809 * for ConfigBackend. Otherwise, init_globals would
8810 * send us into an endless loop here.
8812 config_backend = CONFIG_BACKEND_REGISTRY;
8813 /* start over */
8814 DEBUG(1, ("lp_load_ex: changing to config backend "
8815 "registry\n"));
8816 init_globals(false);
8817 lp_kill_all_services();
8818 return lp_load_ex(pszFname, global_only, save_defaults,
8819 add_ipc, initialize_globals,
8820 allow_include_registry,
8821 allow_registry_shares);
8823 } else if (lp_config_backend_is_registry()) {
8824 bRetval = process_registry_globals();
8825 } else {
8826 DEBUG(0, ("Illegal config backend given: %d\n",
8827 lp_config_backend()));
8828 bRetval = false;
8831 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8832 bRetval = process_registry_shares();
8835 lp_add_auto_services(lp_auto_services());
8837 if (add_ipc) {
8838 /* When 'restrict anonymous = 2' guest connections to ipc$
8839 are denied */
8840 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8841 if ( lp_enable_asu_support() ) {
8842 lp_add_ipc("ADMIN$", false);
8846 set_server_role();
8847 set_default_server_announce_type();
8848 set_allowed_client_auth();
8850 bLoaded = True;
8852 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8853 /* if bWINSsupport is true and we are in the client */
8854 if (lp_is_in_client() && Globals.bWINSsupport) {
8855 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8858 init_iconv();
8860 bAllowIncludeRegistry = true;
8862 return (bRetval);
8865 bool lp_load(const char *pszFname,
8866 bool global_only,
8867 bool save_defaults,
8868 bool add_ipc,
8869 bool initialize_globals)
8871 return lp_load_ex(pszFname,
8872 global_only,
8873 save_defaults,
8874 add_ipc,
8875 initialize_globals,
8876 true, false);
8879 bool lp_load_initial_only(const char *pszFname)
8881 return lp_load_ex(pszFname,
8882 true,
8883 false,
8884 false,
8885 true,
8886 false,
8887 false);
8890 bool lp_load_with_registry_shares(const char *pszFname,
8891 bool global_only,
8892 bool save_defaults,
8893 bool add_ipc,
8894 bool initialize_globals)
8896 return lp_load_ex(pszFname,
8897 global_only,
8898 save_defaults,
8899 add_ipc,
8900 initialize_globals,
8901 true,
8902 true);
8905 /***************************************************************************
8906 Return the max number of services.
8907 ***************************************************************************/
8909 int lp_numservices(void)
8911 return (iNumServices);
8914 /***************************************************************************
8915 Display the contents of the services array in human-readable form.
8916 ***************************************************************************/
8918 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8920 int iService;
8922 if (show_defaults)
8923 defaults_saved = False;
8925 dump_globals(f);
8927 dump_a_service(&sDefault, f);
8929 for (iService = 0; iService < maxtoprint; iService++) {
8930 fprintf(f,"\n");
8931 lp_dump_one(f, show_defaults, iService);
8935 /***************************************************************************
8936 Display the contents of one service in human-readable form.
8937 ***************************************************************************/
8939 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8941 if (VALID(snum)) {
8942 if (ServicePtrs[snum]->szService[0] == '\0')
8943 return;
8944 dump_a_service(ServicePtrs[snum], f);
8948 /***************************************************************************
8949 Return the number of the service with the given name, or -1 if it doesn't
8950 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8951 getservicebyname()! This works ONLY if all services have been loaded, and
8952 does not copy the found service.
8953 ***************************************************************************/
8955 int lp_servicenumber(const char *pszServiceName)
8957 int iService;
8958 fstring serviceName;
8960 if (!pszServiceName) {
8961 return GLOBAL_SECTION_SNUM;
8964 for (iService = iNumServices - 1; iService >= 0; iService--) {
8965 if (VALID(iService) && ServicePtrs[iService]->szService) {
8967 * The substitution here is used to support %U is
8968 * service names
8970 fstrcpy(serviceName, ServicePtrs[iService]->szService);
8971 standard_sub_basic(get_current_username(),
8972 current_user_info.domain,
8973 serviceName,sizeof(serviceName));
8974 if (strequal(serviceName, pszServiceName)) {
8975 break;
8980 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
8981 time_t last_mod;
8983 if (!usershare_exists(iService, &last_mod)) {
8984 /* Remove the share security tdb entry for it. */
8985 delete_share_security(lp_servicename(iService));
8986 /* Remove it from the array. */
8987 free_service_byindex(iService);
8988 /* Doesn't exist anymore. */
8989 return GLOBAL_SECTION_SNUM;
8992 /* Has it been modified ? If so delete and reload. */
8993 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
8994 /* Remove it from the array. */
8995 free_service_byindex(iService);
8996 /* and now reload it. */
8997 iService = load_usershare_service(pszServiceName);
9001 if (iService < 0) {
9002 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9003 return GLOBAL_SECTION_SNUM;
9006 return (iService);
9009 bool share_defined(const char *service_name)
9011 return (lp_servicenumber(service_name) != -1);
9014 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9015 const char *sharename)
9017 struct share_params *result;
9018 char *sname;
9019 int snum;
9021 if (!(sname = SMB_STRDUP(sharename))) {
9022 return NULL;
9025 snum = find_service(sname);
9026 SAFE_FREE(sname);
9028 if (snum < 0) {
9029 return NULL;
9032 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9033 DEBUG(0, ("talloc failed\n"));
9034 return NULL;
9037 result->service = snum;
9038 return result;
9041 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9043 struct share_iterator *result;
9045 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9046 DEBUG(0, ("talloc failed\n"));
9047 return NULL;
9050 result->next_id = 0;
9051 return result;
9054 struct share_params *next_share(struct share_iterator *list)
9056 struct share_params *result;
9058 while (!lp_snum_ok(list->next_id) &&
9059 (list->next_id < lp_numservices())) {
9060 list->next_id += 1;
9063 if (list->next_id >= lp_numservices()) {
9064 return NULL;
9067 if (!(result = TALLOC_P(list, struct share_params))) {
9068 DEBUG(0, ("talloc failed\n"));
9069 return NULL;
9072 result->service = list->next_id;
9073 list->next_id += 1;
9074 return result;
9077 struct share_params *next_printer(struct share_iterator *list)
9079 struct share_params *result;
9081 while ((result = next_share(list)) != NULL) {
9082 if (lp_print_ok(result->service)) {
9083 break;
9086 return result;
9090 * This is a hack for a transition period until we transformed all code from
9091 * service numbers to struct share_params.
9094 struct share_params *snum2params_static(int snum)
9096 static struct share_params result;
9097 result.service = snum;
9098 return &result;
9101 /*******************************************************************
9102 A useful volume label function.
9103 ********************************************************************/
9105 const char *volume_label(int snum)
9107 char *ret;
9108 const char *label = lp_volume(snum);
9109 if (!*label) {
9110 label = lp_servicename(snum);
9113 /* This returns a 33 byte guarenteed null terminated string. */
9114 ret = talloc_strndup(talloc_tos(), label, 32);
9115 if (!ret) {
9116 return "";
9118 return ret;
9121 /*******************************************************************
9122 Set the server type we will announce as via nmbd.
9123 ********************************************************************/
9125 static void set_default_server_announce_type(void)
9127 default_server_announce = 0;
9128 default_server_announce |= SV_TYPE_WORKSTATION;
9129 default_server_announce |= SV_TYPE_SERVER;
9130 default_server_announce |= SV_TYPE_SERVER_UNIX;
9132 /* note that the flag should be set only if we have a
9133 printer service but nmbd doesn't actually load the
9134 services so we can't tell --jerry */
9136 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9138 switch (lp_announce_as()) {
9139 case ANNOUNCE_AS_NT_SERVER:
9140 default_server_announce |= SV_TYPE_SERVER_NT;
9141 /* fall through... */
9142 case ANNOUNCE_AS_NT_WORKSTATION:
9143 default_server_announce |= SV_TYPE_NT;
9144 break;
9145 case ANNOUNCE_AS_WIN95:
9146 default_server_announce |= SV_TYPE_WIN95_PLUS;
9147 break;
9148 case ANNOUNCE_AS_WFW:
9149 default_server_announce |= SV_TYPE_WFW;
9150 break;
9151 default:
9152 break;
9155 switch (lp_server_role()) {
9156 case ROLE_DOMAIN_MEMBER:
9157 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9158 break;
9159 case ROLE_DOMAIN_PDC:
9160 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9161 break;
9162 case ROLE_DOMAIN_BDC:
9163 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9164 break;
9165 case ROLE_STANDALONE:
9166 default:
9167 break;
9169 if (lp_time_server())
9170 default_server_announce |= SV_TYPE_TIME_SOURCE;
9172 if (lp_host_msdfs())
9173 default_server_announce |= SV_TYPE_DFS_SERVER;
9176 /***********************************************************
9177 returns role of Samba server
9178 ************************************************************/
9180 int lp_server_role(void)
9182 return server_role;
9185 /***********************************************************
9186 If we are PDC then prefer us as DMB
9187 ************************************************************/
9189 bool lp_domain_master(void)
9191 if (Globals.iDomainMaster == Auto)
9192 return (lp_server_role() == ROLE_DOMAIN_PDC);
9194 return (bool)Globals.iDomainMaster;
9197 /***********************************************************
9198 If we are DMB then prefer us as LMB
9199 ************************************************************/
9201 bool lp_preferred_master(void)
9203 if (Globals.iPreferredMaster == Auto)
9204 return (lp_local_master() && lp_domain_master());
9206 return (bool)Globals.iPreferredMaster;
9209 /*******************************************************************
9210 Remove a service.
9211 ********************************************************************/
9213 void lp_remove_service(int snum)
9215 ServicePtrs[snum]->valid = False;
9216 invalid_services[num_invalid_services++] = snum;
9219 /*******************************************************************
9220 Copy a service.
9221 ********************************************************************/
9223 void lp_copy_service(int snum, const char *new_name)
9225 do_section(new_name, NULL);
9226 if (snum >= 0) {
9227 snum = lp_servicenumber(new_name);
9228 if (snum >= 0)
9229 lp_do_parameter(snum, "copy", lp_servicename(snum));
9234 /*******************************************************************
9235 Get the default server type we will announce as via nmbd.
9236 ********************************************************************/
9238 int lp_default_server_announce(void)
9240 return default_server_announce;
9243 /*******************************************************************
9244 Split the announce version into major and minor numbers.
9245 ********************************************************************/
9247 int lp_major_announce_version(void)
9249 static bool got_major = False;
9250 static int major_version = DEFAULT_MAJOR_VERSION;
9251 char *vers;
9252 char *p;
9254 if (got_major)
9255 return major_version;
9257 got_major = True;
9258 if ((vers = lp_announce_version()) == NULL)
9259 return major_version;
9261 if ((p = strchr_m(vers, '.')) == 0)
9262 return major_version;
9264 *p = '\0';
9265 major_version = atoi(vers);
9266 return major_version;
9269 int lp_minor_announce_version(void)
9271 static bool got_minor = False;
9272 static int minor_version = DEFAULT_MINOR_VERSION;
9273 char *vers;
9274 char *p;
9276 if (got_minor)
9277 return minor_version;
9279 got_minor = True;
9280 if ((vers = lp_announce_version()) == NULL)
9281 return minor_version;
9283 if ((p = strchr_m(vers, '.')) == 0)
9284 return minor_version;
9286 p++;
9287 minor_version = atoi(p);
9288 return minor_version;
9291 /***********************************************************
9292 Set the global name resolution order (used in smbclient).
9293 ************************************************************/
9295 void lp_set_name_resolve_order(const char *new_order)
9297 string_set(&Globals.szNameResolveOrder, new_order);
9300 const char *lp_printername(int snum)
9302 const char *ret = _lp_printername(snum);
9303 if (ret == NULL || (ret != NULL && *ret == '\0'))
9304 ret = lp_const_servicename(snum);
9306 return ret;
9310 /***********************************************************
9311 Allow daemons such as winbindd to fix their logfile name.
9312 ************************************************************/
9314 void lp_set_logfile(const char *name)
9316 string_set(&Globals.szLogFile, name);
9317 debug_set_logfile(name);
9320 /*******************************************************************
9321 Return the max print jobs per queue.
9322 ********************************************************************/
9324 int lp_maxprintjobs(int snum)
9326 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9327 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9328 maxjobs = PRINT_MAX_JOBID - 1;
9330 return maxjobs;
9333 const char *lp_printcapname(void)
9335 if ((Globals.szPrintcapname != NULL) &&
9336 (Globals.szPrintcapname[0] != '\0'))
9337 return Globals.szPrintcapname;
9339 if (sDefault.iPrinting == PRINT_CUPS) {
9340 #ifdef HAVE_CUPS
9341 return "cups";
9342 #else
9343 return "lpstat";
9344 #endif
9347 if (sDefault.iPrinting == PRINT_BSD)
9348 return "/etc/printcap";
9350 return PRINTCAP_NAME;
9353 /*******************************************************************
9354 Ensure we don't use sendfile if server smb signing is active.
9355 ********************************************************************/
9357 static uint32 spoolss_state;
9359 bool lp_disable_spoolss( void )
9361 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9362 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9364 return spoolss_state == SVCCTL_STOPPED ? True : False;
9367 void lp_set_spoolss_state( uint32 state )
9369 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9371 spoolss_state = state;
9374 uint32 lp_get_spoolss_state( void )
9376 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9379 /*******************************************************************
9380 Ensure we don't use sendfile if server smb signing is active.
9381 ********************************************************************/
9383 bool lp_use_sendfile(int snum)
9385 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9386 if (Protocol < PROTOCOL_NT1) {
9387 return False;
9389 return (_lp_use_sendfile(snum) &&
9390 (get_remote_arch() != RA_WIN95) &&
9391 !srv_is_signing_active());
9394 /*******************************************************************
9395 Turn off sendfile if we find the underlying OS doesn't support it.
9396 ********************************************************************/
9398 void set_use_sendfile(int snum, bool val)
9400 if (LP_SNUM_OK(snum))
9401 ServicePtrs[snum]->bUseSendfile = val;
9402 else
9403 sDefault.bUseSendfile = val;
9406 /*******************************************************************
9407 Turn off storing DOS attributes if this share doesn't support it.
9408 ********************************************************************/
9410 void set_store_dos_attributes(int snum, bool val)
9412 if (!LP_SNUM_OK(snum))
9413 return;
9414 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9417 void lp_set_mangling_method(const char *new_method)
9419 string_set(&Globals.szManglingMethod, new_method);
9422 /*******************************************************************
9423 Global state for POSIX pathname processing.
9424 ********************************************************************/
9426 static bool posix_pathnames;
9428 bool lp_posix_pathnames(void)
9430 return posix_pathnames;
9433 /*******************************************************************
9434 Change everything needed to ensure POSIX pathname processing (currently
9435 not much).
9436 ********************************************************************/
9438 void lp_set_posix_pathnames(void)
9440 posix_pathnames = True;
9443 /*******************************************************************
9444 Global state for POSIX lock processing - CIFS unix extensions.
9445 ********************************************************************/
9447 bool posix_default_lock_was_set;
9448 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9450 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9452 if (posix_default_lock_was_set) {
9453 return posix_cifsx_locktype;
9454 } else {
9455 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9459 /*******************************************************************
9460 ********************************************************************/
9462 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9464 posix_default_lock_was_set = True;
9465 posix_cifsx_locktype = val;
9468 int lp_min_receive_file_size(void)
9470 if (Globals.iminreceivefile < 0) {
9471 return 0;
9473 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9476 /*******************************************************************
9477 If socket address is an empty character string, it is necessary to
9478 define it as "0.0.0.0".
9479 ********************************************************************/
9481 const char *lp_socket_address(void)
9483 char *sock_addr = Globals.szSocketAddress;
9485 if (sock_addr[0] == '\0'){
9486 string_set(&Globals.szSocketAddress, "0.0.0.0");
9488 return Globals.szSocketAddress;