Fix circular dependency error with autoconf 2.6.3.
[Samba.git] / source / param / loadparm.c
blob0f35f191166090cb8d17488646fc36a0b5bc0911
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_ON;
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_socket_address, &Globals.szSocketAddress)
4991 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
4992 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
4993 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
4994 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
4995 * lp_passdb_backend() should be replace by the this macro again after
4996 * some releases.
4997 * */
4998 const char *lp_passdb_backend(void)
5000 char *delim, *quote;
5002 delim = strchr( Globals.szPassdbBackend, ' ');
5003 /* no space at all */
5004 if (delim == NULL) {
5005 goto out;
5008 quote = strchr(Globals.szPassdbBackend, '"');
5009 /* no quote char or non in the first part */
5010 if (quote == NULL || quote > delim) {
5011 *delim = '\0';
5012 goto warn;
5015 quote = strchr(quote+1, '"');
5016 if (quote == NULL) {
5017 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5018 goto out;
5019 } else if (*(quote+1) == '\0') {
5020 /* space, fitting quote char, and one backend only */
5021 goto out;
5022 } else {
5023 /* terminate string after the fitting quote char */
5024 *(quote+1) = '\0';
5027 warn:
5028 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5029 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5030 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5031 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5033 out:
5034 return Globals.szPassdbBackend;
5036 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5037 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5038 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5039 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5040 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5042 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5043 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5044 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5045 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5046 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5047 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5049 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5051 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5052 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5053 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5055 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5057 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5058 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5059 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5060 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5061 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5062 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5063 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5064 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5065 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5066 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5067 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5068 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5069 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5070 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5071 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5073 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
5074 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
5075 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5076 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5077 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5078 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5079 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5081 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5082 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5083 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5084 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5085 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5086 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5087 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5088 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5089 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5090 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5091 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5092 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5093 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5094 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5095 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5096 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5097 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5099 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5101 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5102 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5103 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5104 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5105 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5106 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5107 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5108 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5109 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5110 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5111 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5112 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5113 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5114 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5115 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5116 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5117 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5118 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5119 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5120 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5121 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5122 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5123 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5124 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5125 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5126 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5127 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5128 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5129 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5130 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5131 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5132 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5133 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5134 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5135 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5136 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5137 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5138 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5139 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5140 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5141 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5142 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5143 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5144 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5145 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5146 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5147 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5148 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5149 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5150 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5151 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5152 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5153 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5154 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5155 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5156 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5157 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5158 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5159 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5160 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5161 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5162 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5163 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5164 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5165 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5166 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5167 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5168 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5169 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5170 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5171 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5172 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5173 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5174 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5175 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5176 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5177 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5178 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5179 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5180 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5181 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5182 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5183 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5184 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5185 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5186 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5187 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5188 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5189 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5190 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5191 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5192 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5193 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5194 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5195 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5196 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5198 FN_LOCAL_STRING(lp_preexec, szPreExec)
5199 FN_LOCAL_STRING(lp_postexec, szPostExec)
5200 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5201 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5202 FN_LOCAL_STRING(lp_servicename, szService)
5203 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5204 FN_LOCAL_STRING(lp_pathname, szPath)
5205 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5206 FN_LOCAL_STRING(lp_username, szUsername)
5207 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5208 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5209 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5210 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5211 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5212 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5213 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5214 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5215 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5216 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5217 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5218 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5219 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5220 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5221 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5222 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5223 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5224 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5225 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5226 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5227 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5228 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5229 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5230 FN_LOCAL_STRING(lp_comment, comment)
5231 FN_LOCAL_STRING(lp_force_user, force_user)
5232 FN_LOCAL_STRING(lp_force_group, force_group)
5233 FN_LOCAL_LIST(lp_readlist, readlist)
5234 FN_LOCAL_LIST(lp_writelist, writelist)
5235 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5236 FN_LOCAL_STRING(lp_fstype, fstype)
5237 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5238 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5239 static FN_LOCAL_STRING(lp_volume, volume)
5240 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5241 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5242 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5243 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5244 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5245 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5246 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5247 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5248 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5249 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5250 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5251 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5252 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5253 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5254 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5255 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5256 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5257 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5258 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5259 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5260 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5261 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5262 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5263 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5264 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5265 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5266 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5267 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5268 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5269 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5270 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5271 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5272 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5273 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5274 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5275 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5276 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5277 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5278 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5279 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5280 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5281 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5282 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5283 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5284 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5285 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5286 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5287 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5288 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5289 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5290 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5291 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5292 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5293 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5294 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5295 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5296 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5297 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5298 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5299 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5300 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5301 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5302 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5303 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5304 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5305 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5306 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5307 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5308 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5309 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5310 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5311 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5312 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5313 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5314 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5315 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5316 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5317 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5318 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5319 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5320 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5321 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5322 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5323 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5324 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5325 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5326 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5327 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5328 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5329 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5330 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5331 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5332 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5333 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5334 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5335 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5336 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5338 /* local prototypes */
5340 static int map_parameter(const char *pszParmName);
5341 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5342 static bool set_boolean(bool *pb, const char *pszParmValue);
5343 static const char *get_boolean(bool bool_value);
5344 static int getservicebyname(const char *pszServiceName,
5345 struct service *pserviceDest);
5346 static void copy_service(struct service *pserviceDest,
5347 struct service *pserviceSource,
5348 struct bitmap *pcopymapDest);
5349 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5350 void *userdata);
5351 static bool do_section(const char *pszSectionName, void *userdata);
5352 static void init_copymap(struct service *pservice);
5353 static bool hash_a_service(const char *name, int number);
5354 static void free_service_byindex(int iService);
5355 static char * canonicalize_servicename(const char *name);
5356 static void show_parameter(int parmIndex);
5357 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5359 /* This is a helper function for parametrical options support. */
5360 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
5361 /* Actual parametrical functions are quite simple */
5362 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
5364 bool global_section = False;
5365 char* param_key;
5366 param_opt_struct *data;
5368 if (snum >= iNumServices) return NULL;
5370 if (snum < 0) {
5371 data = Globals.param_opt;
5372 global_section = True;
5373 } else {
5374 data = ServicePtrs[snum]->param_opt;
5377 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5378 DEBUG(0,("asprintf failed!\n"));
5379 return NULL;
5382 while (data) {
5383 if (strcmp(data->key, param_key) == 0) {
5384 string_free(&param_key);
5385 return data;
5387 data = data->next;
5390 if (!global_section) {
5391 /* Try to fetch the same option but from globals */
5392 /* but only if we are not already working with Globals */
5393 data = Globals.param_opt;
5394 while (data) {
5395 if (strcmp(data->key, param_key) == 0) {
5396 string_free(&param_key);
5397 return data;
5399 data = data->next;
5403 string_free(&param_key);
5405 return NULL;
5409 #define MISSING_PARAMETER(name) \
5410 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5412 /*******************************************************************
5413 convenience routine to return int parameters.
5414 ********************************************************************/
5415 static int lp_int(const char *s)
5418 if (!s || !*s) {
5419 MISSING_PARAMETER(lp_int);
5420 return (-1);
5423 return (int)strtol(s, NULL, 0);
5426 /*******************************************************************
5427 convenience routine to return unsigned long parameters.
5428 ********************************************************************/
5429 static unsigned long lp_ulong(const char *s)
5432 if (!s || !*s) {
5433 MISSING_PARAMETER(lp_ulong);
5434 return (0);
5437 return strtoul(s, NULL, 0);
5440 /*******************************************************************
5441 convenience routine to return boolean parameters.
5442 ********************************************************************/
5443 static bool lp_bool(const char *s)
5445 bool ret = False;
5447 if (!s || !*s) {
5448 MISSING_PARAMETER(lp_bool);
5449 return False;
5452 if (!set_boolean(&ret,s)) {
5453 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5454 return False;
5457 return ret;
5460 /*******************************************************************
5461 convenience routine to return enum parameters.
5462 ********************************************************************/
5463 static int lp_enum(const char *s,const struct enum_list *_enum)
5465 int i;
5467 if (!s || !*s || !_enum) {
5468 MISSING_PARAMETER(lp_enum);
5469 return (-1);
5472 for (i=0; _enum[i].name; i++) {
5473 if (strequal(_enum[i].name,s))
5474 return _enum[i].value;
5477 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5478 return (-1);
5481 #undef MISSING_PARAMETER
5483 /* DO NOT USE lp_parm_string ANYMORE!!!!
5484 * use lp_parm_const_string or lp_parm_talloc_string
5486 * lp_parm_string is only used to let old modules find this symbol
5488 #undef lp_parm_string
5489 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5490 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5492 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5495 /* Return parametric option from a given service. Type is a part of option before ':' */
5496 /* Parametric option has following syntax: 'Type: option = value' */
5497 /* the returned value is talloced on the talloc_tos() */
5498 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5500 param_opt_struct *data = get_parametrics(snum, type, option);
5502 if (data == NULL||data->value==NULL) {
5503 if (def) {
5504 return lp_string(def);
5505 } else {
5506 return NULL;
5510 return lp_string(data->value);
5513 /* Return parametric option from a given service. Type is a part of option before ':' */
5514 /* Parametric option has following syntax: 'Type: option = value' */
5515 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5517 param_opt_struct *data = get_parametrics(snum, type, option);
5519 if (data == NULL||data->value==NULL)
5520 return def;
5522 return data->value;
5525 /* Return parametric option from a given service. Type is a part of option before ':' */
5526 /* Parametric option has following syntax: 'Type: option = value' */
5528 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5530 param_opt_struct *data = get_parametrics(snum, type, option);
5532 if (data == NULL||data->value==NULL)
5533 return (const char **)def;
5535 if (data->list==NULL) {
5536 data->list = str_list_make(NULL, data->value, NULL);
5539 return (const char **)data->list;
5542 /* Return parametric option from a given service. Type is a part of option before ':' */
5543 /* Parametric option has following syntax: 'Type: option = value' */
5545 int lp_parm_int(int snum, const char *type, const char *option, int def)
5547 param_opt_struct *data = get_parametrics(snum, type, option);
5549 if (data && data->value && *data->value)
5550 return lp_int(data->value);
5552 return def;
5555 /* Return parametric option from a given service. Type is a part of option before ':' */
5556 /* Parametric option has following syntax: 'Type: option = value' */
5558 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5560 param_opt_struct *data = get_parametrics(snum, type, option);
5562 if (data && data->value && *data->value)
5563 return lp_ulong(data->value);
5565 return def;
5568 /* Return parametric option from a given service. Type is a part of option before ':' */
5569 /* Parametric option has following syntax: 'Type: option = value' */
5571 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5573 param_opt_struct *data = get_parametrics(snum, type, option);
5575 if (data && data->value && *data->value)
5576 return lp_bool(data->value);
5578 return def;
5581 /* Return parametric option from a given service. Type is a part of option before ':' */
5582 /* Parametric option has following syntax: 'Type: option = value' */
5584 int lp_parm_enum(int snum, const char *type, const char *option,
5585 const struct enum_list *_enum, int def)
5587 param_opt_struct *data = get_parametrics(snum, type, option);
5589 if (data && data->value && *data->value && _enum)
5590 return lp_enum(data->value, _enum);
5592 return def;
5596 /***************************************************************************
5597 Initialise a service to the defaults.
5598 ***************************************************************************/
5600 static void init_service(struct service *pservice)
5602 memset((char *)pservice, '\0', sizeof(struct service));
5603 copy_service(pservice, &sDefault, NULL);
5606 /***************************************************************************
5607 Free the dynamically allocated parts of a service struct.
5608 ***************************************************************************/
5610 static void free_service(struct service *pservice)
5612 int i;
5613 param_opt_struct *data, *pdata;
5614 if (!pservice)
5615 return;
5617 if (pservice->szService)
5618 DEBUG(5, ("free_service: Freeing service %s\n",
5619 pservice->szService));
5621 string_free(&pservice->szService);
5622 bitmap_free(pservice->copymap);
5624 for (i = 0; parm_table[i].label; i++) {
5625 if ((parm_table[i].type == P_STRING ||
5626 parm_table[i].type == P_USTRING) &&
5627 parm_table[i].p_class == P_LOCAL)
5628 string_free((char **)
5629 (((char *)pservice) +
5630 PTR_DIFF(parm_table[i].ptr, &sDefault)));
5631 else if (parm_table[i].type == P_LIST &&
5632 parm_table[i].p_class == P_LOCAL)
5633 TALLOC_FREE(*((char ***)
5634 (((char *)pservice) +
5635 PTR_DIFF(parm_table[i].ptr,
5636 &sDefault))));
5639 data = pservice->param_opt;
5640 if (data)
5641 DEBUG(5,("Freeing parametrics:\n"));
5642 while (data) {
5643 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5644 string_free(&data->key);
5645 string_free(&data->value);
5646 TALLOC_FREE(data->list);
5647 pdata = data->next;
5648 SAFE_FREE(data);
5649 data = pdata;
5652 ZERO_STRUCTP(pservice);
5656 /***************************************************************************
5657 remove a service indexed in the ServicePtrs array from the ServiceHash
5658 and free the dynamically allocated parts
5659 ***************************************************************************/
5661 static void free_service_byindex(int idx)
5663 if ( !LP_SNUM_OK(idx) )
5664 return;
5666 ServicePtrs[idx]->valid = False;
5667 invalid_services[num_invalid_services++] = idx;
5669 /* we have to cleanup the hash record */
5671 if (ServicePtrs[idx]->szService) {
5672 char *canon_name = canonicalize_servicename(
5673 ServicePtrs[idx]->szService );
5675 dbwrap_delete_bystring(ServiceHash, canon_name );
5676 TALLOC_FREE(canon_name);
5679 free_service(ServicePtrs[idx]);
5682 /***************************************************************************
5683 Add a new service to the services array initialising it with the given
5684 service.
5685 ***************************************************************************/
5687 static int add_a_service(const struct service *pservice, const char *name)
5689 int i;
5690 struct service tservice;
5691 int num_to_alloc = iNumServices + 1;
5692 param_opt_struct *data, *pdata;
5694 tservice = *pservice;
5696 /* it might already exist */
5697 if (name) {
5698 i = getservicebyname(name, NULL);
5699 if (i >= 0) {
5700 /* Clean all parametric options for service */
5701 /* They will be added during parsing again */
5702 data = ServicePtrs[i]->param_opt;
5703 while (data) {
5704 string_free(&data->key);
5705 string_free(&data->value);
5706 TALLOC_FREE(data->list);
5707 pdata = data->next;
5708 SAFE_FREE(data);
5709 data = pdata;
5711 ServicePtrs[i]->param_opt = NULL;
5712 return (i);
5716 /* find an invalid one */
5717 i = iNumServices;
5718 if (num_invalid_services > 0) {
5719 i = invalid_services[--num_invalid_services];
5722 /* if not, then create one */
5723 if (i == iNumServices) {
5724 struct service **tsp;
5725 int *tinvalid;
5727 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5728 if (tsp == NULL) {
5729 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5730 return (-1);
5732 ServicePtrs = tsp;
5733 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5734 if (!ServicePtrs[iNumServices]) {
5735 DEBUG(0,("add_a_service: out of memory!\n"));
5736 return (-1);
5738 iNumServices++;
5740 /* enlarge invalid_services here for now... */
5741 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5742 num_to_alloc);
5743 if (tinvalid == NULL) {
5744 DEBUG(0,("add_a_service: failed to enlarge "
5745 "invalid_services!\n"));
5746 return (-1);
5748 invalid_services = tinvalid;
5749 } else {
5750 free_service_byindex(i);
5753 ServicePtrs[i]->valid = True;
5755 init_service(ServicePtrs[i]);
5756 copy_service(ServicePtrs[i], &tservice, NULL);
5757 if (name)
5758 string_set(&ServicePtrs[i]->szService, name);
5760 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5761 i, ServicePtrs[i]->szService));
5763 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5764 return (-1);
5767 return (i);
5770 /***************************************************************************
5771 Convert a string to uppercase and remove whitespaces.
5772 ***************************************************************************/
5774 static char *canonicalize_servicename(const char *src)
5776 char *result;
5778 if ( !src ) {
5779 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5780 return NULL;
5783 result = talloc_strdup(talloc_tos(), src);
5784 SMB_ASSERT(result != NULL);
5786 strlower_m(result);
5787 return result;
5790 /***************************************************************************
5791 Add a name/index pair for the services array to the hash table.
5792 ***************************************************************************/
5794 static bool hash_a_service(const char *name, int idx)
5796 char *canon_name;
5798 if ( !ServiceHash ) {
5799 DEBUG(10,("hash_a_service: creating servicehash\n"));
5800 ServiceHash = db_open_rbt(NULL);
5801 if ( !ServiceHash ) {
5802 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5803 return False;
5807 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5808 idx, name));
5810 canon_name = canonicalize_servicename( name );
5812 dbwrap_store_bystring(ServiceHash, canon_name,
5813 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5814 TDB_REPLACE);
5816 TALLOC_FREE(canon_name);
5818 return True;
5821 /***************************************************************************
5822 Add a new home service, with the specified home directory, defaults coming
5823 from service ifrom.
5824 ***************************************************************************/
5826 bool lp_add_home(const char *pszHomename, int iDefaultService,
5827 const char *user, const char *pszHomedir)
5829 int i;
5831 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5833 if (i < 0)
5834 return (False);
5836 if (!(*(ServicePtrs[iDefaultService]->szPath))
5837 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5838 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5841 if (!(*(ServicePtrs[i]->comment))) {
5842 char *comment = NULL;
5843 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5844 return false;
5846 string_set(&ServicePtrs[i]->comment, comment);
5847 SAFE_FREE(comment);
5850 /* set the browseable flag from the global default */
5852 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5854 ServicePtrs[i]->autoloaded = True;
5856 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5857 user, ServicePtrs[i]->szPath ));
5859 return (True);
5862 /***************************************************************************
5863 Add a new service, based on an old one.
5864 ***************************************************************************/
5866 int lp_add_service(const char *pszService, int iDefaultService)
5868 if (iDefaultService < 0) {
5869 return add_a_service(&sDefault, pszService);
5872 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5875 /***************************************************************************
5876 Add the IPC service.
5877 ***************************************************************************/
5879 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5881 char *comment = NULL;
5882 int i = add_a_service(&sDefault, ipc_name);
5884 if (i < 0)
5885 return (False);
5887 if (asprintf(&comment, "IPC Service (%s)",
5888 Globals.szServerString) < 0) {
5889 return (False);
5892 string_set(&ServicePtrs[i]->szPath, tmpdir());
5893 string_set(&ServicePtrs[i]->szUsername, "");
5894 string_set(&ServicePtrs[i]->comment, comment);
5895 string_set(&ServicePtrs[i]->fstype, "IPC");
5896 ServicePtrs[i]->iMaxConnections = 0;
5897 ServicePtrs[i]->bAvailable = True;
5898 ServicePtrs[i]->bRead_only = True;
5899 ServicePtrs[i]->bGuest_only = False;
5900 ServicePtrs[i]->bAdministrative_share = True;
5901 ServicePtrs[i]->bGuest_ok = guest_ok;
5902 ServicePtrs[i]->bPrint_ok = False;
5903 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5905 DEBUG(3, ("adding IPC service\n"));
5907 SAFE_FREE(comment);
5908 return (True);
5911 /***************************************************************************
5912 Add a new printer service, with defaults coming from service iFrom.
5913 ***************************************************************************/
5915 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5917 const char *comment = "From Printcap";
5918 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5920 if (i < 0)
5921 return (False);
5923 /* note that we do NOT default the availability flag to True - */
5924 /* we take it from the default service passed. This allows all */
5925 /* dynamic printers to be disabled by disabling the [printers] */
5926 /* entry (if/when the 'available' keyword is implemented!). */
5928 /* the printer name is set to the service name. */
5929 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5930 string_set(&ServicePtrs[i]->comment, comment);
5932 /* set the browseable flag from the gloabl default */
5933 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5935 /* Printers cannot be read_only. */
5936 ServicePtrs[i]->bRead_only = False;
5937 /* No share modes on printer services. */
5938 ServicePtrs[i]->bShareModes = False;
5939 /* No oplocks on printer services. */
5940 ServicePtrs[i]->bOpLocks = False;
5941 /* Printer services must be printable. */
5942 ServicePtrs[i]->bPrint_ok = True;
5944 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5946 return (True);
5950 /***************************************************************************
5951 Check whether the given parameter name is valid.
5952 Parametric options (names containing a colon) are considered valid.
5953 ***************************************************************************/
5955 bool lp_parameter_is_valid(const char *pszParmName)
5957 return ((map_parameter(pszParmName) != -1) ||
5958 (strchr(pszParmName, ':') != NULL));
5961 /***************************************************************************
5962 Check whether the given name is the name of a global parameter.
5963 Returns True for strings belonging to parameters of class
5964 P_GLOBAL, False for all other strings, also for parametric options
5965 and strings not belonging to any option.
5966 ***************************************************************************/
5968 bool lp_parameter_is_global(const char *pszParmName)
5970 int num = map_parameter(pszParmName);
5972 if (num >= 0) {
5973 return (parm_table[num].p_class == P_GLOBAL);
5976 return False;
5979 /**************************************************************************
5980 Check whether the given name is the canonical name of a parameter.
5981 Returns False if it is not a valid parameter Name.
5982 For parametric options, True is returned.
5983 **************************************************************************/
5985 bool lp_parameter_is_canonical(const char *parm_name)
5987 if (!lp_parameter_is_valid(parm_name)) {
5988 return False;
5991 return (map_parameter(parm_name) ==
5992 map_parameter_canonical(parm_name, NULL));
5995 /**************************************************************************
5996 Determine the canonical name for a parameter.
5997 Indicate when it is an inverse (boolean) synonym instead of a
5998 "usual" synonym.
5999 **************************************************************************/
6001 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6002 bool *inverse)
6004 int num;
6006 if (!lp_parameter_is_valid(parm_name)) {
6007 *canon_parm = NULL;
6008 return False;
6011 num = map_parameter_canonical(parm_name, inverse);
6012 if (num < 0) {
6013 /* parametric option */
6014 *canon_parm = parm_name;
6015 } else {
6016 *canon_parm = parm_table[num].label;
6019 return True;
6023 /**************************************************************************
6024 Determine the canonical name for a parameter.
6025 Turn the value given into the inverse boolean expression when
6026 the synonym is an invers boolean synonym.
6028 Return True if parm_name is a valid parameter name and
6029 in case it is an invers boolean synonym, if the val string could
6030 successfully be converted to the reverse bool.
6031 Return false in all other cases.
6032 **************************************************************************/
6034 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6035 const char *val,
6036 const char **canon_parm,
6037 const char **canon_val)
6039 int num;
6040 bool inverse;
6042 if (!lp_parameter_is_valid(parm_name)) {
6043 *canon_parm = NULL;
6044 *canon_val = NULL;
6045 return False;
6048 num = map_parameter_canonical(parm_name, &inverse);
6049 if (num < 0) {
6050 /* parametric option */
6051 *canon_parm = parm_name;
6052 *canon_val = val;
6053 } else {
6054 *canon_parm = parm_table[num].label;
6055 if (inverse) {
6056 if (!lp_invert_boolean(val, canon_val)) {
6057 *canon_val = NULL;
6058 return False;
6060 } else {
6061 *canon_val = val;
6065 return True;
6068 /***************************************************************************
6069 Map a parameter's string representation to something we can use.
6070 Returns False if the parameter string is not recognised, else TRUE.
6071 ***************************************************************************/
6073 static int map_parameter(const char *pszParmName)
6075 int iIndex;
6077 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6078 return (-1);
6080 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6081 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6082 return (iIndex);
6084 /* Warn only if it isn't parametric option */
6085 if (strchr(pszParmName, ':') == NULL)
6086 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6087 /* We do return 'fail' for parametric options as well because they are
6088 stored in different storage
6090 return (-1);
6093 /***************************************************************************
6094 Map a parameter's string representation to the index of the canonical
6095 form of the parameter (it might be a synonym).
6096 Returns -1 if the parameter string is not recognised.
6097 ***************************************************************************/
6099 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6101 int parm_num, canon_num;
6102 bool loc_inverse = False;
6104 parm_num = map_parameter(pszParmName);
6105 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6106 /* invalid, parametric or no canidate for synonyms ... */
6107 goto done;
6110 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6111 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6112 parm_num = canon_num;
6113 goto done;
6117 done:
6118 if (inverse != NULL) {
6119 *inverse = loc_inverse;
6121 return parm_num;
6124 /***************************************************************************
6125 return true if parameter number parm1 is a synonym of parameter
6126 number parm2 (parm2 being the principal name).
6127 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6128 False otherwise.
6129 ***************************************************************************/
6131 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6133 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6134 (parm_table[parm1].flags & FLAG_HIDE) &&
6135 !(parm_table[parm2].flags & FLAG_HIDE))
6137 if (inverse != NULL) {
6138 if ((parm_table[parm1].type == P_BOOLREV) &&
6139 (parm_table[parm2].type == P_BOOL))
6141 *inverse = True;
6142 } else {
6143 *inverse = False;
6146 return True;
6148 return False;
6151 /***************************************************************************
6152 Show one parameter's name, type, [values,] and flags.
6153 (helper functions for show_parameter_list)
6154 ***************************************************************************/
6156 static void show_parameter(int parmIndex)
6158 int enumIndex, flagIndex;
6159 int parmIndex2;
6160 bool hadFlag;
6161 bool hadSyn;
6162 bool inverse;
6163 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6164 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6165 "P_ENUM", "P_SEP"};
6166 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6167 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6168 FLAG_HIDE, FLAG_DOS_STRING};
6169 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6170 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6171 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6173 printf("%s=%s", parm_table[parmIndex].label,
6174 type[parm_table[parmIndex].type]);
6175 if (parm_table[parmIndex].type == P_ENUM) {
6176 printf(",");
6177 for (enumIndex=0;
6178 parm_table[parmIndex].enum_list[enumIndex].name;
6179 enumIndex++)
6181 printf("%s%s",
6182 enumIndex ? "|" : "",
6183 parm_table[parmIndex].enum_list[enumIndex].name);
6186 printf(",");
6187 hadFlag = False;
6188 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6189 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6190 printf("%s%s",
6191 hadFlag ? "|" : "",
6192 flag_names[flagIndex]);
6193 hadFlag = True;
6197 /* output synonyms */
6198 hadSyn = False;
6199 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6200 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6201 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6202 parm_table[parmIndex2].label);
6203 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6204 if (!hadSyn) {
6205 printf(" (synonyms: ");
6206 hadSyn = True;
6207 } else {
6208 printf(", ");
6210 printf("%s%s", parm_table[parmIndex2].label,
6211 inverse ? "[i]" : "");
6214 if (hadSyn) {
6215 printf(")");
6218 printf("\n");
6221 /***************************************************************************
6222 Show all parameter's name, type, [values,] and flags.
6223 ***************************************************************************/
6225 void show_parameter_list(void)
6227 int classIndex, parmIndex;
6228 const char *section_names[] = { "local", "global", NULL};
6230 for (classIndex=0; section_names[classIndex]; classIndex++) {
6231 printf("[%s]\n", section_names[classIndex]);
6232 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6233 if (parm_table[parmIndex].p_class == classIndex) {
6234 show_parameter(parmIndex);
6240 /***************************************************************************
6241 Set a boolean variable from the text value stored in the passed string.
6242 Returns True in success, False if the passed string does not correctly
6243 represent a boolean.
6244 ***************************************************************************/
6246 static bool set_boolean(bool *pb, const char *pszParmValue)
6248 bool bRetval;
6249 bool value;
6251 bRetval = True;
6252 value = False;
6253 if (strwicmp(pszParmValue, "yes") == 0 ||
6254 strwicmp(pszParmValue, "true") == 0 ||
6255 strwicmp(pszParmValue, "1") == 0)
6256 value = True;
6257 else if (strwicmp(pszParmValue, "no") == 0 ||
6258 strwicmp(pszParmValue, "False") == 0 ||
6259 strwicmp(pszParmValue, "0") == 0)
6260 value = False;
6261 else {
6262 DEBUG(2,
6263 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6264 pszParmValue));
6265 bRetval = False;
6268 if ((pb != NULL) && (bRetval != False)) {
6269 *pb = value;
6272 return (bRetval);
6276 /***************************************************************************
6277 Check if a given string correctly represents a boolean value.
6278 ***************************************************************************/
6280 bool lp_string_is_valid_boolean(const char *parm_value)
6282 return set_boolean(NULL, parm_value);
6285 /***************************************************************************
6286 Get the standard string representation of a boolean value ("yes" or "no")
6287 ***************************************************************************/
6289 static const char *get_boolean(bool bool_value)
6291 static const char *yes_str = "yes";
6292 static const char *no_str = "no";
6294 return (bool_value ? yes_str : no_str);
6297 /***************************************************************************
6298 Provide the string of the negated boolean value associated to the boolean
6299 given as a string. Returns False if the passed string does not correctly
6300 represent a boolean.
6301 ***************************************************************************/
6303 bool lp_invert_boolean(const char *str, const char **inverse_str)
6305 bool val;
6307 if (!set_boolean(&val, str)) {
6308 return False;
6311 *inverse_str = get_boolean(!val);
6312 return True;
6315 /***************************************************************************
6316 Provide the canonical string representation of a boolean value given
6317 as a string. Return True on success, False if the string given does
6318 not correctly represent a boolean.
6319 ***************************************************************************/
6321 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6323 bool val;
6325 if (!set_boolean(&val, str)) {
6326 return False;
6329 *canon_str = get_boolean(val);
6330 return True;
6333 /***************************************************************************
6334 Find a service by name. Otherwise works like get_service.
6335 ***************************************************************************/
6337 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6339 int iService = -1;
6340 char *canon_name;
6341 TDB_DATA data;
6343 if (ServiceHash == NULL) {
6344 return -1;
6347 canon_name = canonicalize_servicename(pszServiceName);
6349 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6351 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6352 iService = *(int *)data.dptr;
6355 TALLOC_FREE(canon_name);
6357 if ((iService != -1) && (LP_SNUM_OK(iService))
6358 && (pserviceDest != NULL)) {
6359 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6362 return (iService);
6365 /***************************************************************************
6366 Copy a service structure to another.
6367 If pcopymapDest is NULL then copy all fields
6368 ***************************************************************************/
6370 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6371 struct bitmap *pcopymapDest)
6373 int i;
6374 bool bcopyall = (pcopymapDest == NULL);
6375 param_opt_struct *data, *pdata, *paramo;
6376 bool not_added;
6378 for (i = 0; parm_table[i].label; i++)
6379 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6380 (bcopyall || bitmap_query(pcopymapDest,i))) {
6381 void *def_ptr = parm_table[i].ptr;
6382 void *src_ptr =
6383 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6384 &sDefault);
6385 void *dest_ptr =
6386 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6387 &sDefault);
6389 switch (parm_table[i].type) {
6390 case P_BOOL:
6391 case P_BOOLREV:
6392 *(bool *)dest_ptr = *(bool *)src_ptr;
6393 break;
6395 case P_INTEGER:
6396 case P_ENUM:
6397 case P_OCTAL:
6398 *(int *)dest_ptr = *(int *)src_ptr;
6399 break;
6401 case P_CHAR:
6402 *(char *)dest_ptr = *(char *)src_ptr;
6403 break;
6405 case P_STRING:
6406 string_set((char **)dest_ptr,
6407 *(char **)src_ptr);
6408 break;
6410 case P_USTRING:
6411 string_set((char **)dest_ptr,
6412 *(char **)src_ptr);
6413 strupper_m(*(char **)dest_ptr);
6414 break;
6415 case P_LIST:
6416 TALLOC_FREE(*((char ***)dest_ptr));
6417 str_list_copy(NULL, (char ***)dest_ptr,
6418 *(const char ***)src_ptr);
6419 break;
6420 default:
6421 break;
6425 if (bcopyall) {
6426 init_copymap(pserviceDest);
6427 if (pserviceSource->copymap)
6428 bitmap_copy(pserviceDest->copymap,
6429 pserviceSource->copymap);
6432 data = pserviceSource->param_opt;
6433 while (data) {
6434 not_added = True;
6435 pdata = pserviceDest->param_opt;
6436 /* Traverse destination */
6437 while (pdata) {
6438 /* If we already have same option, override it */
6439 if (strcmp(pdata->key, data->key) == 0) {
6440 string_free(&pdata->value);
6441 TALLOC_FREE(data->list);
6442 pdata->value = SMB_STRDUP(data->value);
6443 not_added = False;
6444 break;
6446 pdata = pdata->next;
6448 if (not_added) {
6449 paramo = SMB_XMALLOC_P(param_opt_struct);
6450 paramo->key = SMB_STRDUP(data->key);
6451 paramo->value = SMB_STRDUP(data->value);
6452 paramo->list = NULL;
6453 DLIST_ADD(pserviceDest->param_opt, paramo);
6455 data = data->next;
6459 /***************************************************************************
6460 Check a service for consistency. Return False if the service is in any way
6461 incomplete or faulty, else True.
6462 ***************************************************************************/
6464 bool service_ok(int iService)
6466 bool bRetval;
6468 bRetval = True;
6469 if (ServicePtrs[iService]->szService[0] == '\0') {
6470 DEBUG(0, ("The following message indicates an internal error:\n"));
6471 DEBUG(0, ("No service name in service entry.\n"));
6472 bRetval = False;
6475 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6476 /* I can't see why you'd want a non-printable printer service... */
6477 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6478 if (!ServicePtrs[iService]->bPrint_ok) {
6479 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6480 ServicePtrs[iService]->szService));
6481 ServicePtrs[iService]->bPrint_ok = True;
6483 /* [printers] service must also be non-browsable. */
6484 if (ServicePtrs[iService]->bBrowseable)
6485 ServicePtrs[iService]->bBrowseable = False;
6488 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6489 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6490 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6492 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6493 ServicePtrs[iService]->szService));
6494 ServicePtrs[iService]->bAvailable = False;
6497 /* If a service is flagged unavailable, log the fact at level 1. */
6498 if (!ServicePtrs[iService]->bAvailable)
6499 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6500 ServicePtrs[iService]->szService));
6502 return (bRetval);
6505 static struct smbconf_ctx *lp_smbconf_ctx(void)
6507 WERROR werr;
6508 static struct smbconf_ctx *conf_ctx = NULL;
6510 if (conf_ctx == NULL) {
6511 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6512 if (!W_ERROR_IS_OK(werr)) {
6513 DEBUG(1, ("error initializing registry configuration: "
6514 "%s\n", dos_errstr(werr)));
6515 conf_ctx = NULL;
6519 return conf_ctx;
6522 static bool process_registry_service(struct smbconf_service *service)
6524 uint32_t count;
6525 bool ret;
6527 if (service == NULL) {
6528 return false;
6531 ret = do_section(service->name, NULL);
6532 if (ret != true) {
6533 return false;
6535 for (count = 0; count < service->num_params; count++) {
6536 ret = do_parameter(service->param_names[count],
6537 service->param_values[count],
6538 NULL);
6539 if (ret != true) {
6540 return false;
6543 return true;
6547 * process_registry_globals
6549 static bool process_registry_globals(void)
6551 WERROR werr;
6552 struct smbconf_service *service = NULL;
6553 TALLOC_CTX *mem_ctx = talloc_stackframe();
6554 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6555 bool ret = false;
6557 if (conf_ctx == NULL) {
6558 goto done;
6561 ret = do_parameter("registry shares", "yes", NULL);
6562 if (!ret) {
6563 goto done;
6566 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6567 /* nothing to read from the registry yet but make sure lp_load
6568 * doesn't return false */
6569 ret = true;
6570 goto done;
6573 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6574 if (!W_ERROR_IS_OK(werr)) {
6575 goto done;
6578 ret = process_registry_service(service);
6579 if (!ret) {
6580 goto done;
6583 /* store the csn */
6584 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6586 done:
6587 TALLOC_FREE(mem_ctx);
6588 return ret;
6591 static bool process_registry_shares(void)
6593 WERROR werr;
6594 uint32_t count;
6595 struct smbconf_service **service = NULL;
6596 uint32_t num_shares = 0;
6597 TALLOC_CTX *mem_ctx = talloc_stackframe();
6598 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6599 bool ret = false;
6601 if (conf_ctx == NULL) {
6602 goto done;
6605 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6606 if (!W_ERROR_IS_OK(werr)) {
6607 goto done;
6610 ret = true;
6612 for (count = 0; count < num_shares; count++) {
6613 if (strequal(service[count]->name, GLOBAL_NAME)) {
6614 continue;
6616 ret = process_registry_service(service[count]);
6617 if (!ret) {
6618 goto done;
6622 /* store the csn */
6623 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6625 done:
6626 TALLOC_FREE(mem_ctx);
6627 return ret;
6630 static struct file_lists {
6631 struct file_lists *next;
6632 char *name;
6633 char *subfname;
6634 time_t modtime;
6635 } *file_lists = NULL;
6637 /*******************************************************************
6638 Keep a linked list of all config files so we know when one has changed
6639 it's date and needs to be reloaded.
6640 ********************************************************************/
6642 static void add_to_file_list(const char *fname, const char *subfname)
6644 struct file_lists *f = file_lists;
6646 while (f) {
6647 if (f->name && !strcmp(f->name, fname))
6648 break;
6649 f = f->next;
6652 if (!f) {
6653 f = SMB_MALLOC_P(struct file_lists);
6654 if (!f)
6655 return;
6656 f->next = file_lists;
6657 f->name = SMB_STRDUP(fname);
6658 if (!f->name) {
6659 SAFE_FREE(f);
6660 return;
6662 f->subfname = SMB_STRDUP(subfname);
6663 if (!f->subfname) {
6664 SAFE_FREE(f);
6665 return;
6667 file_lists = f;
6668 f->modtime = file_modtime(subfname);
6669 } else {
6670 time_t t = file_modtime(subfname);
6671 if (t)
6672 f->modtime = t;
6677 * Utility function for outsiders to check if we're running on registry.
6679 bool lp_config_backend_is_registry(void)
6681 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6685 * Utility function to check if the config backend is FILE.
6687 bool lp_config_backend_is_file(void)
6689 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6692 /*******************************************************************
6693 Check if a config file has changed date.
6694 ********************************************************************/
6696 bool lp_file_list_changed(void)
6698 struct file_lists *f = file_lists;
6700 DEBUG(6, ("lp_file_list_changed()\n"));
6702 if (lp_config_backend_is_registry()) {
6703 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6705 if (conf_ctx == NULL) {
6706 return false;
6708 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6709 DEBUGADD(6, ("registry config changed\n"));
6710 return true;
6714 while (f) {
6715 char *n2 = NULL;
6716 time_t mod_time;
6718 n2 = alloc_sub_basic(get_current_username(),
6719 current_user_info.domain,
6720 f->name);
6721 if (!n2) {
6722 return false;
6724 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6725 f->name, n2, ctime(&f->modtime)));
6727 mod_time = file_modtime(n2);
6729 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6730 DEBUGADD(6,
6731 ("file %s modified: %s\n", n2,
6732 ctime(&mod_time)));
6733 f->modtime = mod_time;
6734 SAFE_FREE(f->subfname);
6735 f->subfname = n2; /* Passing ownership of
6736 return from alloc_sub_basic
6737 above. */
6738 return true;
6740 SAFE_FREE(n2);
6741 f = f->next;
6743 return (False);
6747 /***************************************************************************
6748 Run standard_sub_basic on netbios name... needed because global_myname
6749 is not accessed through any lp_ macro.
6750 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6751 ***************************************************************************/
6753 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6755 bool ret;
6756 char *netbios_name = alloc_sub_basic(get_current_username(),
6757 current_user_info.domain,
6758 pszParmValue);
6760 ret = set_global_myname(netbios_name);
6761 SAFE_FREE(netbios_name);
6762 string_set(&Globals.szNetbiosName,global_myname());
6764 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6765 global_myname()));
6767 return ret;
6770 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6772 if (strcmp(*ptr, pszParmValue) != 0) {
6773 string_set(ptr, pszParmValue);
6774 init_iconv();
6776 return True;
6781 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6783 bool ret;
6785 ret = set_global_myworkgroup(pszParmValue);
6786 string_set(&Globals.szWorkgroup,lp_workgroup());
6788 return ret;
6791 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6793 bool ret;
6795 ret = set_global_scope(pszParmValue);
6796 string_set(&Globals.szNetbiosScope,global_scope());
6798 return ret;
6801 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6803 TALLOC_FREE(Globals.szNetbiosAliases);
6804 Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6805 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6808 /***************************************************************************
6809 Handle the include operation.
6810 ***************************************************************************/
6811 static bool bAllowIncludeRegistry = true;
6813 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6815 char *fname;
6817 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6818 if (!bAllowIncludeRegistry) {
6819 return true;
6821 if (bInGlobalSection) {
6822 return process_registry_globals();
6823 } else {
6824 DEBUG(1, ("\"include = registry\" only effective "
6825 "in %s section\n", GLOBAL_NAME));
6826 return false;
6830 fname = alloc_sub_basic(get_current_username(),
6831 current_user_info.domain,
6832 pszParmValue);
6834 add_to_file_list(pszParmValue, fname);
6836 string_set(ptr, fname);
6838 if (file_exist(fname, NULL)) {
6839 bool ret = pm_process(fname, do_section, do_parameter, NULL);
6840 SAFE_FREE(fname);
6841 return ret;
6844 DEBUG(2, ("Can't find include file %s\n", fname));
6845 SAFE_FREE(fname);
6846 return false;
6849 /***************************************************************************
6850 Handle the interpretation of the copy parameter.
6851 ***************************************************************************/
6853 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6855 bool bRetval;
6856 int iTemp;
6857 struct service serviceTemp;
6859 string_set(ptr, pszParmValue);
6861 init_service(&serviceTemp);
6863 bRetval = False;
6865 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6867 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6868 if (iTemp == iServiceIndex) {
6869 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6870 } else {
6871 copy_service(ServicePtrs[iServiceIndex],
6872 &serviceTemp,
6873 ServicePtrs[iServiceIndex]->copymap);
6874 bRetval = True;
6876 } else {
6877 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6878 bRetval = False;
6881 free_service(&serviceTemp);
6882 return (bRetval);
6885 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6887 Globals.ldap_debug_level = lp_int(pszParmValue);
6888 init_ldap_debugging();
6889 return true;
6892 /***************************************************************************
6893 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6894 parameters is:
6896 [global]
6898 idmap uid = 1000-1999
6899 idmap gid = 700-899
6901 We only do simple parsing checks here. The strings are parsed into useful
6902 structures in the idmap daemon code.
6904 ***************************************************************************/
6906 /* Some lp_ routines to return idmap [ug]id information */
6908 static uid_t idmap_uid_low, idmap_uid_high;
6909 static gid_t idmap_gid_low, idmap_gid_high;
6911 bool lp_idmap_uid(uid_t *low, uid_t *high)
6913 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6914 return False;
6916 if (low)
6917 *low = idmap_uid_low;
6919 if (high)
6920 *high = idmap_uid_high;
6922 return True;
6925 bool lp_idmap_gid(gid_t *low, gid_t *high)
6927 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6928 return False;
6930 if (low)
6931 *low = idmap_gid_low;
6933 if (high)
6934 *high = idmap_gid_high;
6936 return True;
6939 /* Do some simple checks on "idmap [ug]id" parameter values */
6941 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6943 uint32 low, high;
6945 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6946 return False;
6948 /* Parse OK */
6950 string_set(ptr, pszParmValue);
6952 idmap_uid_low = low;
6953 idmap_uid_high = high;
6955 return True;
6958 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6960 uint32 low, high;
6962 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6963 return False;
6965 /* Parse OK */
6967 string_set(ptr, pszParmValue);
6969 idmap_gid_low = low;
6970 idmap_gid_high = high;
6972 return True;
6975 /***************************************************************************
6976 Handle the DEBUG level list.
6977 ***************************************************************************/
6979 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
6981 string_set(ptr, pszParmValueIn);
6982 return debug_parse_levels(pszParmValueIn);
6985 /***************************************************************************
6986 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
6987 ***************************************************************************/
6989 static const char *append_ldap_suffix( const char *str )
6991 const char *suffix_string;
6994 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
6995 Globals.szLdapSuffix );
6996 if ( !suffix_string ) {
6997 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
6998 return "";
7001 return suffix_string;
7004 const char *lp_ldap_machine_suffix(void)
7006 if (Globals.szLdapMachineSuffix[0])
7007 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7009 return lp_string(Globals.szLdapSuffix);
7012 const char *lp_ldap_user_suffix(void)
7014 if (Globals.szLdapUserSuffix[0])
7015 return append_ldap_suffix(Globals.szLdapUserSuffix);
7017 return lp_string(Globals.szLdapSuffix);
7020 const char *lp_ldap_group_suffix(void)
7022 if (Globals.szLdapGroupSuffix[0])
7023 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7025 return lp_string(Globals.szLdapSuffix);
7028 const char *lp_ldap_idmap_suffix(void)
7030 if (Globals.szLdapIdmapSuffix[0])
7031 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7033 return lp_string(Globals.szLdapSuffix);
7036 /****************************************************************************
7037 set the value for a P_ENUM
7038 ***************************************************************************/
7040 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7041 int *ptr )
7043 int i;
7045 for (i = 0; parm->enum_list[i].name; i++) {
7046 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7047 *ptr = parm->enum_list[i].value;
7048 break;
7053 /***************************************************************************
7054 ***************************************************************************/
7056 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7058 static int parm_num = -1;
7059 struct service *s;
7061 if ( parm_num == -1 )
7062 parm_num = map_parameter( "printing" );
7064 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7066 if ( snum < 0 )
7067 s = &sDefault;
7068 else
7069 s = ServicePtrs[snum];
7071 init_printer_values( s );
7073 return True;
7077 /***************************************************************************
7078 Initialise a copymap.
7079 ***************************************************************************/
7081 static void init_copymap(struct service *pservice)
7083 int i;
7084 if (pservice->copymap) {
7085 bitmap_free(pservice->copymap);
7087 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7088 if (!pservice->copymap)
7089 DEBUG(0,
7090 ("Couldn't allocate copymap!! (size %d)\n",
7091 (int)NUMPARAMETERS));
7092 else
7093 for (i = 0; i < NUMPARAMETERS; i++)
7094 bitmap_set(pservice->copymap, i);
7097 /***************************************************************************
7098 Return the local pointer to a parameter given the service number and the
7099 pointer into the default structure.
7100 ***************************************************************************/
7102 void *lp_local_ptr(int snum, void *ptr)
7104 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7107 /***************************************************************************
7108 Process a parameter for a particular service number. If snum < 0
7109 then assume we are in the globals.
7110 ***************************************************************************/
7112 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7114 int parmnum, i, slen;
7115 void *parm_ptr = NULL; /* where we are going to store the result */
7116 void *def_ptr = NULL;
7117 char *param_key = NULL;
7118 char *sep;
7119 param_opt_struct *paramo, *data;
7120 bool not_added;
7122 parmnum = map_parameter(pszParmName);
7124 if (parmnum < 0) {
7125 if ((sep=strchr(pszParmName, ':')) != NULL) {
7126 TALLOC_CTX *frame = talloc_stackframe();
7128 *sep = '\0';
7129 param_key = talloc_asprintf(frame, "%s:", pszParmName);
7130 if (!param_key) {
7131 TALLOC_FREE(frame);
7132 return false;
7134 slen = strlen(param_key);
7135 param_key = talloc_asprintf_append(param_key, sep+1);
7136 if (!param_key) {
7137 TALLOC_FREE(frame);
7138 return false;
7140 trim_char(param_key+slen, ' ', ' ');
7141 not_added = True;
7142 data = (snum < 0) ? Globals.param_opt :
7143 ServicePtrs[snum]->param_opt;
7144 /* Traverse destination */
7145 while (data) {
7146 /* If we already have same option, override it */
7147 if (strcmp(data->key, param_key) == 0) {
7148 string_free(&data->value);
7149 TALLOC_FREE(data->list);
7150 data->value = SMB_STRDUP(pszParmValue);
7151 not_added = False;
7152 break;
7154 data = data->next;
7156 if (not_added) {
7157 paramo = SMB_XMALLOC_P(param_opt_struct);
7158 paramo->key = SMB_STRDUP(param_key);
7159 paramo->value = SMB_STRDUP(pszParmValue);
7160 paramo->list = NULL;
7161 if (snum < 0) {
7162 DLIST_ADD(Globals.param_opt, paramo);
7163 } else {
7164 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
7168 *sep = ':';
7169 TALLOC_FREE(frame);
7170 return (True);
7172 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
7173 return (True);
7176 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7177 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7178 pszParmName));
7181 def_ptr = parm_table[parmnum].ptr;
7183 /* we might point at a service, the default service or a global */
7184 if (snum < 0) {
7185 parm_ptr = def_ptr;
7186 } else {
7187 if (parm_table[parmnum].p_class == P_GLOBAL) {
7188 DEBUG(0,
7189 ("Global parameter %s found in service section!\n",
7190 pszParmName));
7191 return (True);
7193 parm_ptr =
7194 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7195 &sDefault);
7198 if (snum >= 0) {
7199 if (!ServicePtrs[snum]->copymap)
7200 init_copymap(ServicePtrs[snum]);
7202 /* this handles the aliases - set the copymap for other entries with
7203 the same data pointer */
7204 for (i = 0; parm_table[i].label; i++)
7205 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7206 bitmap_clear(ServicePtrs[snum]->copymap, i);
7209 /* if it is a special case then go ahead */
7210 if (parm_table[parmnum].special) {
7211 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
7212 return (True);
7215 /* now switch on the type of variable it is */
7216 switch (parm_table[parmnum].type)
7218 case P_BOOL:
7219 *(bool *)parm_ptr = lp_bool(pszParmValue);
7220 break;
7222 case P_BOOLREV:
7223 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7224 break;
7226 case P_INTEGER:
7227 *(int *)parm_ptr = lp_int(pszParmValue);
7228 break;
7230 case P_CHAR:
7231 *(char *)parm_ptr = *pszParmValue;
7232 break;
7234 case P_OCTAL:
7235 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7236 if ( i != 1 ) {
7237 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7239 break;
7241 case P_LIST:
7242 TALLOC_FREE(*((char ***)parm_ptr));
7243 *(char ***)parm_ptr = str_list_make(
7244 NULL, pszParmValue, NULL);
7245 break;
7247 case P_STRING:
7248 string_set((char **)parm_ptr, pszParmValue);
7249 break;
7251 case P_USTRING:
7252 string_set((char **)parm_ptr, pszParmValue);
7253 strupper_m(*(char **)parm_ptr);
7254 break;
7256 case P_ENUM:
7257 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7258 break;
7259 case P_SEP:
7260 break;
7263 return (True);
7266 /***************************************************************************
7267 Process a parameter.
7268 ***************************************************************************/
7270 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7271 void *userdata)
7273 if (!bInGlobalSection && bGlobalOnly)
7274 return (True);
7276 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7278 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7279 pszParmName, pszParmValue));
7282 /***************************************************************************
7283 Print a parameter of the specified type.
7284 ***************************************************************************/
7286 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7288 int i;
7289 switch (p->type)
7291 case P_ENUM:
7292 for (i = 0; p->enum_list[i].name; i++) {
7293 if (*(int *)ptr == p->enum_list[i].value) {
7294 fprintf(f, "%s",
7295 p->enum_list[i].name);
7296 break;
7299 break;
7301 case P_BOOL:
7302 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7303 break;
7305 case P_BOOLREV:
7306 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7307 break;
7309 case P_INTEGER:
7310 fprintf(f, "%d", *(int *)ptr);
7311 break;
7313 case P_CHAR:
7314 fprintf(f, "%c", *(char *)ptr);
7315 break;
7317 case P_OCTAL: {
7318 char *o = octal_string(*(int *)ptr);
7319 fprintf(f, "%s", o);
7320 TALLOC_FREE(o);
7321 break;
7324 case P_LIST:
7325 if ((char ***)ptr && *(char ***)ptr) {
7326 char **list = *(char ***)ptr;
7327 for (; *list; list++) {
7328 /* surround strings with whitespace in double quotes */
7329 if ( strchr_m( *list, ' ' ) )
7330 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7331 else
7332 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7335 break;
7337 case P_STRING:
7338 case P_USTRING:
7339 if (*(char **)ptr) {
7340 fprintf(f, "%s", *(char **)ptr);
7342 break;
7343 case P_SEP:
7344 break;
7348 /***************************************************************************
7349 Check if two parameters are equal.
7350 ***************************************************************************/
7352 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7354 switch (type) {
7355 case P_BOOL:
7356 case P_BOOLREV:
7357 return (*((bool *)ptr1) == *((bool *)ptr2));
7359 case P_INTEGER:
7360 case P_ENUM:
7361 case P_OCTAL:
7362 return (*((int *)ptr1) == *((int *)ptr2));
7364 case P_CHAR:
7365 return (*((char *)ptr1) == *((char *)ptr2));
7367 case P_LIST:
7368 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7370 case P_STRING:
7371 case P_USTRING:
7373 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7374 if (p1 && !*p1)
7375 p1 = NULL;
7376 if (p2 && !*p2)
7377 p2 = NULL;
7378 return (p1 == p2 || strequal(p1, p2));
7380 case P_SEP:
7381 break;
7383 return (False);
7386 /***************************************************************************
7387 Initialize any local varients in the sDefault table.
7388 ***************************************************************************/
7390 void init_locals(void)
7392 /* None as yet. */
7395 /***************************************************************************
7396 Process a new section (service). At this stage all sections are services.
7397 Later we'll have special sections that permit server parameters to be set.
7398 Returns True on success, False on failure.
7399 ***************************************************************************/
7401 static bool do_section(const char *pszSectionName, void *userdata)
7403 bool bRetval;
7404 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7405 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7406 bRetval = False;
7408 /* if we were in a global section then do the local inits */
7409 if (bInGlobalSection && !isglobal)
7410 init_locals();
7412 /* if we've just struck a global section, note the fact. */
7413 bInGlobalSection = isglobal;
7415 /* check for multiple global sections */
7416 if (bInGlobalSection) {
7417 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7418 return (True);
7421 if (!bInGlobalSection && bGlobalOnly)
7422 return (True);
7424 /* if we have a current service, tidy it up before moving on */
7425 bRetval = True;
7427 if (iServiceIndex >= 0)
7428 bRetval = service_ok(iServiceIndex);
7430 /* if all is still well, move to the next record in the services array */
7431 if (bRetval) {
7432 /* We put this here to avoid an odd message order if messages are */
7433 /* issued by the post-processing of a previous section. */
7434 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7436 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7437 < 0) {
7438 DEBUG(0, ("Failed to add a new service\n"));
7439 return (False);
7443 return (bRetval);
7447 /***************************************************************************
7448 Determine if a partcular base parameter is currentl set to the default value.
7449 ***************************************************************************/
7451 static bool is_default(int i)
7453 if (!defaults_saved)
7454 return False;
7455 switch (parm_table[i].type) {
7456 case P_LIST:
7457 return str_list_compare (parm_table[i].def.lvalue,
7458 *(char ***)parm_table[i].ptr);
7459 case P_STRING:
7460 case P_USTRING:
7461 return strequal(parm_table[i].def.svalue,
7462 *(char **)parm_table[i].ptr);
7463 case P_BOOL:
7464 case P_BOOLREV:
7465 return parm_table[i].def.bvalue ==
7466 *(bool *)parm_table[i].ptr;
7467 case P_CHAR:
7468 return parm_table[i].def.cvalue ==
7469 *(char *)parm_table[i].ptr;
7470 case P_INTEGER:
7471 case P_OCTAL:
7472 case P_ENUM:
7473 return parm_table[i].def.ivalue ==
7474 *(int *)parm_table[i].ptr;
7475 case P_SEP:
7476 break;
7478 return False;
7481 /***************************************************************************
7482 Display the contents of the global structure.
7483 ***************************************************************************/
7485 static void dump_globals(FILE *f)
7487 int i;
7488 param_opt_struct *data;
7490 fprintf(f, "[global]\n");
7492 for (i = 0; parm_table[i].label; i++)
7493 if (parm_table[i].p_class == P_GLOBAL &&
7494 parm_table[i].ptr &&
7495 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7496 if (defaults_saved && is_default(i))
7497 continue;
7498 fprintf(f, "\t%s = ", parm_table[i].label);
7499 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7500 fprintf(f, "\n");
7502 if (Globals.param_opt != NULL) {
7503 data = Globals.param_opt;
7504 while(data) {
7505 fprintf(f, "\t%s = %s\n", data->key, data->value);
7506 data = data->next;
7512 /***************************************************************************
7513 Return True if a local parameter is currently set to the global default.
7514 ***************************************************************************/
7516 bool lp_is_default(int snum, struct parm_struct *parm)
7518 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7520 return equal_parameter(parm->type,
7521 ((char *)ServicePtrs[snum]) + pdiff,
7522 ((char *)&sDefault) + pdiff);
7525 /***************************************************************************
7526 Display the contents of a single services record.
7527 ***************************************************************************/
7529 static void dump_a_service(struct service *pService, FILE * f)
7531 int i;
7532 param_opt_struct *data;
7534 if (pService != &sDefault)
7535 fprintf(f, "[%s]\n", pService->szService);
7537 for (i = 0; parm_table[i].label; i++) {
7539 if (parm_table[i].p_class == P_LOCAL &&
7540 parm_table[i].ptr &&
7541 (*parm_table[i].label != '-') &&
7542 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7545 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7547 if (pService == &sDefault) {
7548 if (defaults_saved && is_default(i))
7549 continue;
7550 } else {
7551 if (equal_parameter(parm_table[i].type,
7552 ((char *)pService) +
7553 pdiff,
7554 ((char *)&sDefault) +
7555 pdiff))
7556 continue;
7559 fprintf(f, "\t%s = ", parm_table[i].label);
7560 print_parameter(&parm_table[i],
7561 ((char *)pService) + pdiff, f);
7562 fprintf(f, "\n");
7566 if (pService->param_opt != NULL) {
7567 data = pService->param_opt;
7568 while(data) {
7569 fprintf(f, "\t%s = %s\n", data->key, data->value);
7570 data = data->next;
7575 /***************************************************************************
7576 Display the contents of a parameter of a single services record.
7577 ***************************************************************************/
7579 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7581 int i;
7582 bool result = False;
7583 parm_class p_class;
7584 unsigned flag = 0;
7585 fstring local_parm_name;
7586 char *parm_opt;
7587 const char *parm_opt_value;
7589 /* check for parametrical option */
7590 fstrcpy( local_parm_name, parm_name);
7591 parm_opt = strchr( local_parm_name, ':');
7593 if (parm_opt) {
7594 *parm_opt = '\0';
7595 parm_opt++;
7596 if (strlen(parm_opt)) {
7597 parm_opt_value = lp_parm_const_string( snum,
7598 local_parm_name, parm_opt, NULL);
7599 if (parm_opt_value) {
7600 printf( "%s\n", parm_opt_value);
7601 result = True;
7604 return result;
7607 /* check for a key and print the value */
7608 if (isGlobal) {
7609 p_class = P_GLOBAL;
7610 flag = FLAG_GLOBAL;
7611 } else
7612 p_class = P_LOCAL;
7614 for (i = 0; parm_table[i].label; i++) {
7615 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7616 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7617 parm_table[i].ptr &&
7618 (*parm_table[i].label != '-') &&
7619 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7621 void *ptr;
7623 if (isGlobal) {
7624 ptr = parm_table[i].ptr;
7625 } else {
7626 struct service *pService = ServicePtrs[snum];
7627 ptr = ((char *)pService) +
7628 PTR_DIFF(parm_table[i].ptr, &sDefault);
7631 print_parameter(&parm_table[i],
7632 ptr, f);
7633 fprintf(f, "\n");
7634 result = True;
7635 break;
7639 return result;
7642 /***************************************************************************
7643 Return info about the requested parameter (given as a string).
7644 Return NULL when the string is not a valid parameter name.
7645 ***************************************************************************/
7647 struct parm_struct *lp_get_parameter(const char *param_name)
7649 int num = map_parameter(param_name);
7651 if (num < 0) {
7652 return NULL;
7655 return &parm_table[num];
7658 /***************************************************************************
7659 Return info about the next parameter in a service.
7660 snum==GLOBAL_SECTION_SNUM gives the globals.
7661 Return NULL when out of parameters.
7662 ***************************************************************************/
7664 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7666 if (snum < 0) {
7667 /* do the globals */
7668 for (; parm_table[*i].label; (*i)++) {
7669 if (parm_table[*i].p_class == P_SEPARATOR)
7670 return &parm_table[(*i)++];
7672 if (!parm_table[*i].ptr
7673 || (*parm_table[*i].label == '-'))
7674 continue;
7676 if ((*i) > 0
7677 && (parm_table[*i].ptr ==
7678 parm_table[(*i) - 1].ptr))
7679 continue;
7681 if (is_default(*i) && !allparameters)
7682 continue;
7684 return &parm_table[(*i)++];
7686 } else {
7687 struct service *pService = ServicePtrs[snum];
7689 for (; parm_table[*i].label; (*i)++) {
7690 if (parm_table[*i].p_class == P_SEPARATOR)
7691 return &parm_table[(*i)++];
7693 if (parm_table[*i].p_class == P_LOCAL &&
7694 parm_table[*i].ptr &&
7695 (*parm_table[*i].label != '-') &&
7696 ((*i) == 0 ||
7697 (parm_table[*i].ptr !=
7698 parm_table[(*i) - 1].ptr)))
7700 int pdiff =
7701 PTR_DIFF(parm_table[*i].ptr,
7702 &sDefault);
7704 if (allparameters ||
7705 !equal_parameter(parm_table[*i].type,
7706 ((char *)pService) +
7707 pdiff,
7708 ((char *)&sDefault) +
7709 pdiff))
7711 return &parm_table[(*i)++];
7717 return NULL;
7721 #if 0
7722 /***************************************************************************
7723 Display the contents of a single copy structure.
7724 ***************************************************************************/
7725 static void dump_copy_map(bool *pcopymap)
7727 int i;
7728 if (!pcopymap)
7729 return;
7731 printf("\n\tNon-Copied parameters:\n");
7733 for (i = 0; parm_table[i].label; i++)
7734 if (parm_table[i].p_class == P_LOCAL &&
7735 parm_table[i].ptr && !pcopymap[i] &&
7736 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7738 printf("\t\t%s\n", parm_table[i].label);
7741 #endif
7743 /***************************************************************************
7744 Return TRUE if the passed service number is within range.
7745 ***************************************************************************/
7747 bool lp_snum_ok(int iService)
7749 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7752 /***************************************************************************
7753 Auto-load some home services.
7754 ***************************************************************************/
7756 static void lp_add_auto_services(char *str)
7758 char *s;
7759 char *p;
7760 int homes;
7761 char *saveptr;
7763 if (!str)
7764 return;
7766 s = SMB_STRDUP(str);
7767 if (!s)
7768 return;
7770 homes = lp_servicenumber(HOMES_NAME);
7772 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7773 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7774 char *home;
7776 if (lp_servicenumber(p) >= 0)
7777 continue;
7779 home = get_user_home_dir(talloc_tos(), p);
7781 if (home && homes >= 0)
7782 lp_add_home(p, homes, p, home);
7784 TALLOC_FREE(home);
7786 SAFE_FREE(s);
7789 /***************************************************************************
7790 Auto-load one printer.
7791 ***************************************************************************/
7793 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
7795 int printers = lp_servicenumber(PRINTERS_NAME);
7796 int i;
7798 if (lp_servicenumber(name) < 0) {
7799 lp_add_printer(name, printers);
7800 if ((i = lp_servicenumber(name)) >= 0) {
7801 string_set(&ServicePtrs[i]->comment, comment);
7802 ServicePtrs[i]->autoloaded = True;
7807 /***************************************************************************
7808 Have we loaded a services file yet?
7809 ***************************************************************************/
7811 bool lp_loaded(void)
7813 return (bLoaded);
7816 /***************************************************************************
7817 Unload unused services.
7818 ***************************************************************************/
7820 void lp_killunused(bool (*snumused) (int))
7822 int i;
7823 for (i = 0; i < iNumServices; i++) {
7824 if (!VALID(i))
7825 continue;
7827 /* don't kill autoloaded or usershare services */
7828 if ( ServicePtrs[i]->autoloaded ||
7829 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7830 continue;
7833 if (!snumused || !snumused(i)) {
7834 free_service_byindex(i);
7840 * Kill all except autoloaded and usershare services - convenience wrapper
7842 void lp_kill_all_services(void)
7844 lp_killunused(NULL);
7847 /***************************************************************************
7848 Unload a service.
7849 ***************************************************************************/
7851 void lp_killservice(int iServiceIn)
7853 if (VALID(iServiceIn)) {
7854 free_service_byindex(iServiceIn);
7858 /***************************************************************************
7859 Save the curent values of all global and sDefault parameters into the
7860 defaults union. This allows swat and testparm to show only the
7861 changed (ie. non-default) parameters.
7862 ***************************************************************************/
7864 static void lp_save_defaults(void)
7866 int i;
7867 for (i = 0; parm_table[i].label; i++) {
7868 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7869 continue;
7870 switch (parm_table[i].type) {
7871 case P_LIST:
7872 str_list_copy(
7873 NULL, &(parm_table[i].def.lvalue),
7874 *(const char ***)parm_table[i].ptr);
7875 break;
7876 case P_STRING:
7877 case P_USTRING:
7878 if (parm_table[i].ptr) {
7879 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7880 } else {
7881 parm_table[i].def.svalue = NULL;
7883 break;
7884 case P_BOOL:
7885 case P_BOOLREV:
7886 parm_table[i].def.bvalue =
7887 *(bool *)parm_table[i].ptr;
7888 break;
7889 case P_CHAR:
7890 parm_table[i].def.cvalue =
7891 *(char *)parm_table[i].ptr;
7892 break;
7893 case P_INTEGER:
7894 case P_OCTAL:
7895 case P_ENUM:
7896 parm_table[i].def.ivalue =
7897 *(int *)parm_table[i].ptr;
7898 break;
7899 case P_SEP:
7900 break;
7903 defaults_saved = True;
7906 /*******************************************************************
7907 Set the server type we will announce as via nmbd.
7908 ********************************************************************/
7910 static const struct srv_role_tab {
7911 uint32 role;
7912 const char *role_str;
7913 } srv_role_tab [] = {
7914 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7915 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7916 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7917 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7918 { 0, NULL }
7921 const char* server_role_str(uint32 role)
7923 int i = 0;
7924 for (i=0; srv_role_tab[i].role_str; i++) {
7925 if (role == srv_role_tab[i].role) {
7926 return srv_role_tab[i].role_str;
7929 return NULL;
7932 static void set_server_role(void)
7934 server_role = ROLE_STANDALONE;
7936 switch (lp_security()) {
7937 case SEC_SHARE:
7938 if (lp_domain_logons())
7939 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7940 break;
7941 case SEC_SERVER:
7942 if (lp_domain_logons())
7943 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7944 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7945 server_role = ROLE_STANDALONE;
7946 break;
7947 case SEC_DOMAIN:
7948 if (lp_domain_logons()) {
7949 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7950 server_role = ROLE_DOMAIN_BDC;
7951 break;
7953 server_role = ROLE_DOMAIN_MEMBER;
7954 break;
7955 case SEC_ADS:
7956 if (lp_domain_logons()) {
7957 server_role = ROLE_DOMAIN_PDC;
7958 break;
7960 server_role = ROLE_DOMAIN_MEMBER;
7961 break;
7962 case SEC_USER:
7963 if (lp_domain_logons()) {
7965 if (Globals.iDomainMaster) /* auto or yes */
7966 server_role = ROLE_DOMAIN_PDC;
7967 else
7968 server_role = ROLE_DOMAIN_BDC;
7970 break;
7971 default:
7972 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7973 break;
7976 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
7979 /***********************************************************
7980 If we should send plaintext/LANMAN passwords in the clinet
7981 ************************************************************/
7983 static void set_allowed_client_auth(void)
7985 if (Globals.bClientNTLMv2Auth) {
7986 Globals.bClientLanManAuth = False;
7988 if (!Globals.bClientLanManAuth) {
7989 Globals.bClientPlaintextAuth = False;
7993 /***************************************************************************
7994 JRA.
7995 The following code allows smbd to read a user defined share file.
7996 Yes, this is my intent. Yes, I'm comfortable with that...
7998 THE FOLLOWING IS SECURITY CRITICAL CODE.
8000 It washes your clothes, it cleans your house, it guards you while you sleep...
8001 Do not f%^k with it....
8002 ***************************************************************************/
8004 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8006 /***************************************************************************
8007 Check allowed stat state of a usershare file.
8008 Ensure we print out who is dicking with us so the admin can
8009 get their sorry ass fired.
8010 ***************************************************************************/
8012 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8014 if (!S_ISREG(psbuf->st_mode)) {
8015 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8016 "not a regular file\n",
8017 fname, (unsigned int)psbuf->st_uid ));
8018 return False;
8021 /* Ensure this doesn't have the other write bit set. */
8022 if (psbuf->st_mode & S_IWOTH) {
8023 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8024 "public write. Refusing to allow as a usershare file.\n",
8025 fname, (unsigned int)psbuf->st_uid ));
8026 return False;
8029 /* Should be 10k or less. */
8030 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8031 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8032 "too large (%u) to be a user share file.\n",
8033 fname, (unsigned int)psbuf->st_uid,
8034 (unsigned int)psbuf->st_size ));
8035 return False;
8038 return True;
8041 /***************************************************************************
8042 Parse the contents of a usershare file.
8043 ***************************************************************************/
8045 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8046 SMB_STRUCT_STAT *psbuf,
8047 const char *servicename,
8048 int snum,
8049 char **lines,
8050 int numlines,
8051 char **pp_sharepath,
8052 char **pp_comment,
8053 SEC_DESC **ppsd,
8054 bool *pallow_guest)
8056 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8057 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8058 int us_vers;
8059 SMB_STRUCT_DIR *dp;
8060 SMB_STRUCT_STAT sbuf;
8061 char *sharepath = NULL;
8062 char *comment = NULL;
8064 *pp_sharepath = NULL;
8065 *pp_comment = NULL;
8067 *pallow_guest = False;
8069 if (numlines < 4) {
8070 return USERSHARE_MALFORMED_FILE;
8073 if (strcmp(lines[0], "#VERSION 1") == 0) {
8074 us_vers = 1;
8075 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8076 us_vers = 2;
8077 if (numlines < 5) {
8078 return USERSHARE_MALFORMED_FILE;
8080 } else {
8081 return USERSHARE_BAD_VERSION;
8084 if (strncmp(lines[1], "path=", 5) != 0) {
8085 return USERSHARE_MALFORMED_PATH;
8088 sharepath = talloc_strdup(ctx, &lines[1][5]);
8089 if (!sharepath) {
8090 return USERSHARE_POSIX_ERR;
8092 trim_string(sharepath, " ", " ");
8094 if (strncmp(lines[2], "comment=", 8) != 0) {
8095 return USERSHARE_MALFORMED_COMMENT_DEF;
8098 comment = talloc_strdup(ctx, &lines[2][8]);
8099 if (!comment) {
8100 return USERSHARE_POSIX_ERR;
8102 trim_string(comment, " ", " ");
8103 trim_char(comment, '"', '"');
8105 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8106 return USERSHARE_MALFORMED_ACL_DEF;
8109 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8110 return USERSHARE_ACL_ERR;
8113 if (us_vers == 2) {
8114 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8115 return USERSHARE_MALFORMED_ACL_DEF;
8117 if (lines[4][9] == 'y') {
8118 *pallow_guest = True;
8122 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8123 /* Path didn't change, no checks needed. */
8124 *pp_sharepath = sharepath;
8125 *pp_comment = comment;
8126 return USERSHARE_OK;
8129 /* The path *must* be absolute. */
8130 if (sharepath[0] != '/') {
8131 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8132 servicename, sharepath));
8133 return USERSHARE_PATH_NOT_ABSOLUTE;
8136 /* If there is a usershare prefix deny list ensure one of these paths
8137 doesn't match the start of the user given path. */
8138 if (prefixdenylist) {
8139 int i;
8140 for ( i=0; prefixdenylist[i]; i++ ) {
8141 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8142 servicename, i, prefixdenylist[i], sharepath ));
8143 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8144 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8145 "usershare prefix deny list entries.\n",
8146 servicename, sharepath));
8147 return USERSHARE_PATH_IS_DENIED;
8152 /* If there is a usershare prefix allow list ensure one of these paths
8153 does match the start of the user given path. */
8155 if (prefixallowlist) {
8156 int i;
8157 for ( i=0; prefixallowlist[i]; i++ ) {
8158 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8159 servicename, i, prefixallowlist[i], sharepath ));
8160 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8161 break;
8164 if (prefixallowlist[i] == NULL) {
8165 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8166 "usershare prefix allow list entries.\n",
8167 servicename, sharepath));
8168 return USERSHARE_PATH_NOT_ALLOWED;
8172 /* Ensure this is pointing to a directory. */
8173 dp = sys_opendir(sharepath);
8175 if (!dp) {
8176 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8177 servicename, sharepath));
8178 return USERSHARE_PATH_NOT_DIRECTORY;
8181 /* Ensure the owner of the usershare file has permission to share
8182 this directory. */
8184 if (sys_stat(sharepath, &sbuf) == -1) {
8185 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8186 servicename, sharepath, strerror(errno) ));
8187 sys_closedir(dp);
8188 return USERSHARE_POSIX_ERR;
8191 sys_closedir(dp);
8193 if (!S_ISDIR(sbuf.st_mode)) {
8194 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8195 servicename, sharepath ));
8196 return USERSHARE_PATH_NOT_DIRECTORY;
8199 /* Check if sharing is restricted to owner-only. */
8200 /* psbuf is the stat of the usershare definition file,
8201 sbuf is the stat of the target directory to be shared. */
8203 if (lp_usershare_owner_only()) {
8204 /* root can share anything. */
8205 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8206 return USERSHARE_PATH_NOT_ALLOWED;
8210 *pp_sharepath = sharepath;
8211 *pp_comment = comment;
8212 return USERSHARE_OK;
8215 /***************************************************************************
8216 Deal with a usershare file.
8217 Returns:
8218 >= 0 - snum
8219 -1 - Bad name, invalid contents.
8220 - service name already existed and not a usershare, problem
8221 with permissions to share directory etc.
8222 ***************************************************************************/
8224 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8226 SMB_STRUCT_STAT sbuf;
8227 SMB_STRUCT_STAT lsbuf;
8228 char *fname = NULL;
8229 char *sharepath = NULL;
8230 char *comment = NULL;
8231 fstring service_name;
8232 char **lines = NULL;
8233 int numlines = 0;
8234 int fd = -1;
8235 int iService = -1;
8236 TALLOC_CTX *ctx = NULL;
8237 SEC_DESC *psd = NULL;
8238 bool guest_ok = False;
8240 /* Ensure share name doesn't contain invalid characters. */
8241 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8242 DEBUG(0,("process_usershare_file: share name %s contains "
8243 "invalid characters (any of %s)\n",
8244 file_name, INVALID_SHARENAME_CHARS ));
8245 return -1;
8248 fstrcpy(service_name, file_name);
8250 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8253 /* Minimize the race condition by doing an lstat before we
8254 open and fstat. Ensure this isn't a symlink link. */
8256 if (sys_lstat(fname, &lsbuf) != 0) {
8257 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8258 fname, strerror(errno) ));
8259 SAFE_FREE(fname);
8260 return -1;
8263 /* This must be a regular file, not a symlink, directory or
8264 other strange filetype. */
8265 if (!check_usershare_stat(fname, &lsbuf)) {
8266 SAFE_FREE(fname);
8267 return -1;
8271 char *canon_name = canonicalize_servicename(service_name);
8272 TDB_DATA data = dbwrap_fetch_bystring(
8273 ServiceHash, canon_name, canon_name);
8275 iService = -1;
8277 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8278 iService = *(int *)data.dptr;
8280 TALLOC_FREE(canon_name);
8283 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8284 /* Nothing changed - Mark valid and return. */
8285 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8286 service_name ));
8287 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8288 SAFE_FREE(fname);
8289 return iService;
8292 /* Try and open the file read only - no symlinks allowed. */
8293 #ifdef O_NOFOLLOW
8294 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8295 #else
8296 fd = sys_open(fname, O_RDONLY, 0);
8297 #endif
8299 if (fd == -1) {
8300 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8301 fname, strerror(errno) ));
8302 SAFE_FREE(fname);
8303 return -1;
8306 /* Now fstat to be *SURE* it's a regular file. */
8307 if (sys_fstat(fd, &sbuf) != 0) {
8308 close(fd);
8309 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8310 fname, strerror(errno) ));
8311 SAFE_FREE(fname);
8312 return -1;
8315 /* Is it the same dev/inode as was lstated ? */
8316 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8317 close(fd);
8318 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8319 "Symlink spoofing going on ?\n", fname ));
8320 SAFE_FREE(fname);
8321 return -1;
8324 /* This must be a regular file, not a symlink, directory or
8325 other strange filetype. */
8326 if (!check_usershare_stat(fname, &sbuf)) {
8327 SAFE_FREE(fname);
8328 return -1;
8331 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8333 close(fd);
8334 if (lines == NULL) {
8335 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8336 fname, (unsigned int)sbuf.st_uid ));
8337 SAFE_FREE(fname);
8338 return -1;
8341 SAFE_FREE(fname);
8343 /* Should we allow printers to be shared... ? */
8344 ctx = talloc_init("usershare_sd_xctx");
8345 if (!ctx) {
8346 file_lines_free(lines);
8347 return 1;
8350 if (parse_usershare_file(ctx, &sbuf, service_name,
8351 iService, lines, numlines, &sharepath,
8352 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8353 talloc_destroy(ctx);
8354 file_lines_free(lines);
8355 return -1;
8358 file_lines_free(lines);
8360 /* Everything ok - add the service possibly using a template. */
8361 if (iService < 0) {
8362 const struct service *sp = &sDefault;
8363 if (snum_template != -1) {
8364 sp = ServicePtrs[snum_template];
8367 if ((iService = add_a_service(sp, service_name)) < 0) {
8368 DEBUG(0, ("process_usershare_file: Failed to add "
8369 "new service %s\n", service_name));
8370 talloc_destroy(ctx);
8371 return -1;
8374 /* Read only is controlled by usershare ACL below. */
8375 ServicePtrs[iService]->bRead_only = False;
8378 /* Write the ACL of the new/modified share. */
8379 if (!set_share_security(service_name, psd)) {
8380 DEBUG(0, ("process_usershare_file: Failed to set share "
8381 "security for user share %s\n",
8382 service_name ));
8383 lp_remove_service(iService);
8384 talloc_destroy(ctx);
8385 return -1;
8388 /* If from a template it may be marked invalid. */
8389 ServicePtrs[iService]->valid = True;
8391 /* Set the service as a valid usershare. */
8392 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8394 /* Set guest access. */
8395 if (lp_usershare_allow_guests()) {
8396 ServicePtrs[iService]->bGuest_ok = guest_ok;
8399 /* And note when it was loaded. */
8400 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8401 string_set(&ServicePtrs[iService]->szPath, sharepath);
8402 string_set(&ServicePtrs[iService]->comment, comment);
8404 talloc_destroy(ctx);
8406 return iService;
8409 /***************************************************************************
8410 Checks if a usershare entry has been modified since last load.
8411 ***************************************************************************/
8413 static bool usershare_exists(int iService, time_t *last_mod)
8415 SMB_STRUCT_STAT lsbuf;
8416 const char *usersharepath = Globals.szUsersharePath;
8417 char *fname;
8419 if (asprintf(&fname, "%s/%s",
8420 usersharepath,
8421 ServicePtrs[iService]->szService) < 0) {
8422 return false;
8425 if (sys_lstat(fname, &lsbuf) != 0) {
8426 SAFE_FREE(fname);
8427 return false;
8430 if (!S_ISREG(lsbuf.st_mode)) {
8431 SAFE_FREE(fname);
8432 return false;
8435 SAFE_FREE(fname);
8436 *last_mod = lsbuf.st_mtime;
8437 return true;
8440 /***************************************************************************
8441 Load a usershare service by name. Returns a valid servicenumber or -1.
8442 ***************************************************************************/
8444 int load_usershare_service(const char *servicename)
8446 SMB_STRUCT_STAT sbuf;
8447 const char *usersharepath = Globals.szUsersharePath;
8448 int max_user_shares = Globals.iUsershareMaxShares;
8449 int snum_template = -1;
8451 if (*usersharepath == 0 || max_user_shares == 0) {
8452 return -1;
8455 if (sys_stat(usersharepath, &sbuf) != 0) {
8456 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8457 usersharepath, strerror(errno) ));
8458 return -1;
8461 if (!S_ISDIR(sbuf.st_mode)) {
8462 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8463 usersharepath ));
8464 return -1;
8468 * This directory must be owned by root, and have the 't' bit set.
8469 * It also must not be writable by "other".
8472 #ifdef S_ISVTX
8473 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8474 #else
8475 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8476 #endif
8477 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8478 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8479 usersharepath ));
8480 return -1;
8483 /* Ensure the template share exists if it's set. */
8484 if (Globals.szUsershareTemplateShare[0]) {
8485 /* We can't use lp_servicenumber here as we are recommending that
8486 template shares have -valid=False set. */
8487 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8488 if (ServicePtrs[snum_template]->szService &&
8489 strequal(ServicePtrs[snum_template]->szService,
8490 Globals.szUsershareTemplateShare)) {
8491 break;
8495 if (snum_template == -1) {
8496 DEBUG(0,("load_usershare_service: usershare template share %s "
8497 "does not exist.\n",
8498 Globals.szUsershareTemplateShare ));
8499 return -1;
8503 return process_usershare_file(usersharepath, servicename, snum_template);
8506 /***************************************************************************
8507 Load all user defined shares from the user share directory.
8508 We only do this if we're enumerating the share list.
8509 This is the function that can delete usershares that have
8510 been removed.
8511 ***************************************************************************/
8513 int load_usershare_shares(void)
8515 SMB_STRUCT_DIR *dp;
8516 SMB_STRUCT_STAT sbuf;
8517 SMB_STRUCT_DIRENT *de;
8518 int num_usershares = 0;
8519 int max_user_shares = Globals.iUsershareMaxShares;
8520 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8521 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8522 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8523 int iService;
8524 int snum_template = -1;
8525 const char *usersharepath = Globals.szUsersharePath;
8526 int ret = lp_numservices();
8528 if (max_user_shares == 0 || *usersharepath == '\0') {
8529 return lp_numservices();
8532 if (sys_stat(usersharepath, &sbuf) != 0) {
8533 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8534 usersharepath, strerror(errno) ));
8535 return ret;
8539 * This directory must be owned by root, and have the 't' bit set.
8540 * It also must not be writable by "other".
8543 #ifdef S_ISVTX
8544 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8545 #else
8546 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8547 #endif
8548 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8549 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8550 usersharepath ));
8551 return ret;
8554 /* Ensure the template share exists if it's set. */
8555 if (Globals.szUsershareTemplateShare[0]) {
8556 /* We can't use lp_servicenumber here as we are recommending that
8557 template shares have -valid=False set. */
8558 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8559 if (ServicePtrs[snum_template]->szService &&
8560 strequal(ServicePtrs[snum_template]->szService,
8561 Globals.szUsershareTemplateShare)) {
8562 break;
8566 if (snum_template == -1) {
8567 DEBUG(0,("load_usershare_shares: usershare template share %s "
8568 "does not exist.\n",
8569 Globals.szUsershareTemplateShare ));
8570 return ret;
8574 /* Mark all existing usershares as pending delete. */
8575 for (iService = iNumServices - 1; iService >= 0; iService--) {
8576 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8577 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8581 dp = sys_opendir(usersharepath);
8582 if (!dp) {
8583 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8584 usersharepath, strerror(errno) ));
8585 return ret;
8588 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8589 (de = sys_readdir(dp));
8590 num_dir_entries++ ) {
8591 int r;
8592 const char *n = de->d_name;
8594 /* Ignore . and .. */
8595 if (*n == '.') {
8596 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8597 continue;
8601 if (n[0] == ':') {
8602 /* Temporary file used when creating a share. */
8603 num_tmp_dir_entries++;
8606 /* Allow 20% tmp entries. */
8607 if (num_tmp_dir_entries > allowed_tmp_entries) {
8608 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8609 "in directory %s\n",
8610 num_tmp_dir_entries, usersharepath));
8611 break;
8614 r = process_usershare_file(usersharepath, n, snum_template);
8615 if (r == 0) {
8616 /* Update the services count. */
8617 num_usershares++;
8618 if (num_usershares >= max_user_shares) {
8619 DEBUG(0,("load_usershare_shares: max user shares reached "
8620 "on file %s in directory %s\n",
8621 n, usersharepath ));
8622 break;
8624 } else if (r == -1) {
8625 num_bad_dir_entries++;
8628 /* Allow 20% bad entries. */
8629 if (num_bad_dir_entries > allowed_bad_entries) {
8630 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8631 "in directory %s\n",
8632 num_bad_dir_entries, usersharepath));
8633 break;
8636 /* Allow 20% bad entries. */
8637 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8638 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8639 "in directory %s\n",
8640 num_dir_entries, usersharepath));
8641 break;
8645 sys_closedir(dp);
8647 /* Sweep through and delete any non-refreshed usershares that are
8648 not currently in use. */
8649 for (iService = iNumServices - 1; iService >= 0; iService--) {
8650 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8651 if (conn_snum_used(iService)) {
8652 continue;
8654 /* Remove from the share ACL db. */
8655 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8656 lp_servicename(iService) ));
8657 delete_share_security(lp_servicename(iService));
8658 free_service_byindex(iService);
8662 return lp_numservices();
8665 /********************************************************
8666 Destroy global resources allocated in this file
8667 ********************************************************/
8669 void gfree_loadparm(void)
8671 struct file_lists *f;
8672 struct file_lists *next;
8673 int i;
8675 /* Free the file lists */
8677 f = file_lists;
8678 while( f ) {
8679 next = f->next;
8680 SAFE_FREE( f->name );
8681 SAFE_FREE( f->subfname );
8682 SAFE_FREE( f );
8683 f = next;
8685 file_lists = NULL;
8687 /* Free resources allocated to services */
8689 for ( i = 0; i < iNumServices; i++ ) {
8690 if ( VALID(i) ) {
8691 free_service_byindex(i);
8695 SAFE_FREE( ServicePtrs );
8696 iNumServices = 0;
8698 /* Now release all resources allocated to global
8699 parameters and the default service */
8701 for (i = 0; parm_table[i].label; i++)
8703 if ( parm_table[i].type == P_STRING
8704 || parm_table[i].type == P_USTRING )
8706 string_free( (char**)parm_table[i].ptr );
8708 else if (parm_table[i].type == P_LIST) {
8709 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8715 /***************************************************************************
8716 Allow client apps to specify that they are a client
8717 ***************************************************************************/
8718 void lp_set_in_client(bool b)
8720 in_client = b;
8724 /***************************************************************************
8725 Determine if we're running in a client app
8726 ***************************************************************************/
8727 bool lp_is_in_client(void)
8729 return in_client;
8735 /***************************************************************************
8736 Load the services array from the services file. Return True on success,
8737 False on failure.
8738 ***************************************************************************/
8740 bool lp_load_ex(const char *pszFname,
8741 bool global_only,
8742 bool save_defaults,
8743 bool add_ipc,
8744 bool initialize_globals,
8745 bool allow_include_registry,
8746 bool allow_registry_shares)
8748 char *n2 = NULL;
8749 bool bRetval;
8750 param_opt_struct *data, *pdata;
8752 bRetval = False;
8754 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8756 bInGlobalSection = True;
8757 bGlobalOnly = global_only;
8758 bAllowIncludeRegistry = allow_include_registry;
8760 init_globals(! initialize_globals);
8761 debug_init();
8763 if (save_defaults) {
8764 init_locals();
8765 lp_save_defaults();
8768 /* We get sections first, so have to start 'behind' to make up */
8769 iServiceIndex = -1;
8771 if (Globals.param_opt != NULL) {
8772 data = Globals.param_opt;
8773 while (data) {
8774 string_free(&data->key);
8775 string_free(&data->value);
8776 TALLOC_FREE(data->list);
8777 pdata = data->next;
8778 SAFE_FREE(data);
8779 data = pdata;
8781 Globals.param_opt = NULL;
8784 if (lp_config_backend_is_file()) {
8785 n2 = alloc_sub_basic(get_current_username(),
8786 current_user_info.domain,
8787 pszFname);
8788 if (!n2) {
8789 smb_panic("lp_load_ex: out of memory");
8792 add_to_file_list(pszFname, n2);
8794 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8795 SAFE_FREE(n2);
8797 /* finish up the last section */
8798 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8799 if (bRetval) {
8800 if (iServiceIndex >= 0) {
8801 bRetval = service_ok(iServiceIndex);
8805 if (lp_config_backend_is_registry()) {
8806 /* config backend changed to registry in config file */
8808 * We need to use this extra global variable here to
8809 * survive restart: init_globals uses this as a default
8810 * for ConfigBackend. Otherwise, init_globals would
8811 * send us into an endless loop here.
8813 config_backend = CONFIG_BACKEND_REGISTRY;
8814 /* start over */
8815 DEBUG(1, ("lp_load_ex: changing to config backend "
8816 "registry\n"));
8817 init_globals(false);
8818 lp_kill_all_services();
8819 return lp_load_ex(pszFname, global_only, save_defaults,
8820 add_ipc, initialize_globals,
8821 allow_include_registry,
8822 allow_registry_shares);
8824 } else if (lp_config_backend_is_registry()) {
8825 bRetval = process_registry_globals();
8826 } else {
8827 DEBUG(0, ("Illegal config backend given: %d\n",
8828 lp_config_backend()));
8829 bRetval = false;
8832 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8833 bRetval = process_registry_shares();
8836 lp_add_auto_services(lp_auto_services());
8838 if (add_ipc) {
8839 /* When 'restrict anonymous = 2' guest connections to ipc$
8840 are denied */
8841 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8842 if ( lp_enable_asu_support() ) {
8843 lp_add_ipc("ADMIN$", false);
8847 set_server_role();
8848 set_default_server_announce_type();
8849 set_allowed_client_auth();
8851 bLoaded = True;
8853 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8854 /* if bWINSsupport is true and we are in the client */
8855 if (lp_is_in_client() && Globals.bWINSsupport) {
8856 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8859 init_iconv();
8861 bAllowIncludeRegistry = true;
8863 return (bRetval);
8866 bool lp_load(const char *pszFname,
8867 bool global_only,
8868 bool save_defaults,
8869 bool add_ipc,
8870 bool initialize_globals)
8872 return lp_load_ex(pszFname,
8873 global_only,
8874 save_defaults,
8875 add_ipc,
8876 initialize_globals,
8877 true, false);
8880 bool lp_load_initial_only(const char *pszFname)
8882 return lp_load_ex(pszFname,
8883 true,
8884 false,
8885 false,
8886 true,
8887 false,
8888 false);
8891 bool lp_load_with_registry_shares(const char *pszFname,
8892 bool global_only,
8893 bool save_defaults,
8894 bool add_ipc,
8895 bool initialize_globals)
8897 return lp_load_ex(pszFname,
8898 global_only,
8899 save_defaults,
8900 add_ipc,
8901 initialize_globals,
8902 true,
8903 true);
8906 /***************************************************************************
8907 Return the max number of services.
8908 ***************************************************************************/
8910 int lp_numservices(void)
8912 return (iNumServices);
8915 /***************************************************************************
8916 Display the contents of the services array in human-readable form.
8917 ***************************************************************************/
8919 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8921 int iService;
8923 if (show_defaults)
8924 defaults_saved = False;
8926 dump_globals(f);
8928 dump_a_service(&sDefault, f);
8930 for (iService = 0; iService < maxtoprint; iService++) {
8931 fprintf(f,"\n");
8932 lp_dump_one(f, show_defaults, iService);
8936 /***************************************************************************
8937 Display the contents of one service in human-readable form.
8938 ***************************************************************************/
8940 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8942 if (VALID(snum)) {
8943 if (ServicePtrs[snum]->szService[0] == '\0')
8944 return;
8945 dump_a_service(ServicePtrs[snum], f);
8949 /***************************************************************************
8950 Return the number of the service with the given name, or -1 if it doesn't
8951 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8952 getservicebyname()! This works ONLY if all services have been loaded, and
8953 does not copy the found service.
8954 ***************************************************************************/
8956 int lp_servicenumber(const char *pszServiceName)
8958 int iService;
8959 fstring serviceName;
8961 if (!pszServiceName) {
8962 return GLOBAL_SECTION_SNUM;
8965 for (iService = iNumServices - 1; iService >= 0; iService--) {
8966 if (VALID(iService) && ServicePtrs[iService]->szService) {
8968 * The substitution here is used to support %U is
8969 * service names
8971 fstrcpy(serviceName, ServicePtrs[iService]->szService);
8972 standard_sub_basic(get_current_username(),
8973 current_user_info.domain,
8974 serviceName,sizeof(serviceName));
8975 if (strequal(serviceName, pszServiceName)) {
8976 break;
8981 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
8982 time_t last_mod;
8984 if (!usershare_exists(iService, &last_mod)) {
8985 /* Remove the share security tdb entry for it. */
8986 delete_share_security(lp_servicename(iService));
8987 /* Remove it from the array. */
8988 free_service_byindex(iService);
8989 /* Doesn't exist anymore. */
8990 return GLOBAL_SECTION_SNUM;
8993 /* Has it been modified ? If so delete and reload. */
8994 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
8995 /* Remove it from the array. */
8996 free_service_byindex(iService);
8997 /* and now reload it. */
8998 iService = load_usershare_service(pszServiceName);
9002 if (iService < 0) {
9003 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9004 return GLOBAL_SECTION_SNUM;
9007 return (iService);
9010 bool share_defined(const char *service_name)
9012 return (lp_servicenumber(service_name) != -1);
9015 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9016 const char *sharename)
9018 struct share_params *result;
9019 char *sname;
9020 int snum;
9022 if (!(sname = SMB_STRDUP(sharename))) {
9023 return NULL;
9026 snum = find_service(sname);
9027 SAFE_FREE(sname);
9029 if (snum < 0) {
9030 return NULL;
9033 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9034 DEBUG(0, ("talloc failed\n"));
9035 return NULL;
9038 result->service = snum;
9039 return result;
9042 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9044 struct share_iterator *result;
9046 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9047 DEBUG(0, ("talloc failed\n"));
9048 return NULL;
9051 result->next_id = 0;
9052 return result;
9055 struct share_params *next_share(struct share_iterator *list)
9057 struct share_params *result;
9059 while (!lp_snum_ok(list->next_id) &&
9060 (list->next_id < lp_numservices())) {
9061 list->next_id += 1;
9064 if (list->next_id >= lp_numservices()) {
9065 return NULL;
9068 if (!(result = TALLOC_P(list, struct share_params))) {
9069 DEBUG(0, ("talloc failed\n"));
9070 return NULL;
9073 result->service = list->next_id;
9074 list->next_id += 1;
9075 return result;
9078 struct share_params *next_printer(struct share_iterator *list)
9080 struct share_params *result;
9082 while ((result = next_share(list)) != NULL) {
9083 if (lp_print_ok(result->service)) {
9084 break;
9087 return result;
9091 * This is a hack for a transition period until we transformed all code from
9092 * service numbers to struct share_params.
9095 struct share_params *snum2params_static(int snum)
9097 static struct share_params result;
9098 result.service = snum;
9099 return &result;
9102 /*******************************************************************
9103 A useful volume label function.
9104 ********************************************************************/
9106 const char *volume_label(int snum)
9108 char *ret;
9109 const char *label = lp_volume(snum);
9110 if (!*label) {
9111 label = lp_servicename(snum);
9114 /* This returns a 33 byte guarenteed null terminated string. */
9115 ret = talloc_strndup(talloc_tos(), label, 32);
9116 if (!ret) {
9117 return "";
9119 return ret;
9122 /*******************************************************************
9123 Set the server type we will announce as via nmbd.
9124 ********************************************************************/
9126 static void set_default_server_announce_type(void)
9128 default_server_announce = 0;
9129 default_server_announce |= SV_TYPE_WORKSTATION;
9130 default_server_announce |= SV_TYPE_SERVER;
9131 default_server_announce |= SV_TYPE_SERVER_UNIX;
9133 /* note that the flag should be set only if we have a
9134 printer service but nmbd doesn't actually load the
9135 services so we can't tell --jerry */
9137 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9139 switch (lp_announce_as()) {
9140 case ANNOUNCE_AS_NT_SERVER:
9141 default_server_announce |= SV_TYPE_SERVER_NT;
9142 /* fall through... */
9143 case ANNOUNCE_AS_NT_WORKSTATION:
9144 default_server_announce |= SV_TYPE_NT;
9145 break;
9146 case ANNOUNCE_AS_WIN95:
9147 default_server_announce |= SV_TYPE_WIN95_PLUS;
9148 break;
9149 case ANNOUNCE_AS_WFW:
9150 default_server_announce |= SV_TYPE_WFW;
9151 break;
9152 default:
9153 break;
9156 switch (lp_server_role()) {
9157 case ROLE_DOMAIN_MEMBER:
9158 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9159 break;
9160 case ROLE_DOMAIN_PDC:
9161 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9162 break;
9163 case ROLE_DOMAIN_BDC:
9164 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9165 break;
9166 case ROLE_STANDALONE:
9167 default:
9168 break;
9170 if (lp_time_server())
9171 default_server_announce |= SV_TYPE_TIME_SOURCE;
9173 if (lp_host_msdfs())
9174 default_server_announce |= SV_TYPE_DFS_SERVER;
9177 /***********************************************************
9178 returns role of Samba server
9179 ************************************************************/
9181 int lp_server_role(void)
9183 return server_role;
9186 /***********************************************************
9187 If we are PDC then prefer us as DMB
9188 ************************************************************/
9190 bool lp_domain_master(void)
9192 if (Globals.iDomainMaster == Auto)
9193 return (lp_server_role() == ROLE_DOMAIN_PDC);
9195 return (bool)Globals.iDomainMaster;
9198 /***********************************************************
9199 If we are DMB then prefer us as LMB
9200 ************************************************************/
9202 bool lp_preferred_master(void)
9204 if (Globals.iPreferredMaster == Auto)
9205 return (lp_local_master() && lp_domain_master());
9207 return (bool)Globals.iPreferredMaster;
9210 /*******************************************************************
9211 Remove a service.
9212 ********************************************************************/
9214 void lp_remove_service(int snum)
9216 ServicePtrs[snum]->valid = False;
9217 invalid_services[num_invalid_services++] = snum;
9220 /*******************************************************************
9221 Copy a service.
9222 ********************************************************************/
9224 void lp_copy_service(int snum, const char *new_name)
9226 do_section(new_name, NULL);
9227 if (snum >= 0) {
9228 snum = lp_servicenumber(new_name);
9229 if (snum >= 0)
9230 lp_do_parameter(snum, "copy", lp_servicename(snum));
9235 /*******************************************************************
9236 Get the default server type we will announce as via nmbd.
9237 ********************************************************************/
9239 int lp_default_server_announce(void)
9241 return default_server_announce;
9244 /*******************************************************************
9245 Split the announce version into major and minor numbers.
9246 ********************************************************************/
9248 int lp_major_announce_version(void)
9250 static bool got_major = False;
9251 static int major_version = DEFAULT_MAJOR_VERSION;
9252 char *vers;
9253 char *p;
9255 if (got_major)
9256 return major_version;
9258 got_major = True;
9259 if ((vers = lp_announce_version()) == NULL)
9260 return major_version;
9262 if ((p = strchr_m(vers, '.')) == 0)
9263 return major_version;
9265 *p = '\0';
9266 major_version = atoi(vers);
9267 return major_version;
9270 int lp_minor_announce_version(void)
9272 static bool got_minor = False;
9273 static int minor_version = DEFAULT_MINOR_VERSION;
9274 char *vers;
9275 char *p;
9277 if (got_minor)
9278 return minor_version;
9280 got_minor = True;
9281 if ((vers = lp_announce_version()) == NULL)
9282 return minor_version;
9284 if ((p = strchr_m(vers, '.')) == 0)
9285 return minor_version;
9287 p++;
9288 minor_version = atoi(p);
9289 return minor_version;
9292 /***********************************************************
9293 Set the global name resolution order (used in smbclient).
9294 ************************************************************/
9296 void lp_set_name_resolve_order(const char *new_order)
9298 string_set(&Globals.szNameResolveOrder, new_order);
9301 const char *lp_printername(int snum)
9303 const char *ret = _lp_printername(snum);
9304 if (ret == NULL || (ret != NULL && *ret == '\0'))
9305 ret = lp_const_servicename(snum);
9307 return ret;
9311 /***********************************************************
9312 Allow daemons such as winbindd to fix their logfile name.
9313 ************************************************************/
9315 void lp_set_logfile(const char *name)
9317 string_set(&Globals.szLogFile, name);
9318 debug_set_logfile(name);
9321 /*******************************************************************
9322 Return the max print jobs per queue.
9323 ********************************************************************/
9325 int lp_maxprintjobs(int snum)
9327 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9328 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9329 maxjobs = PRINT_MAX_JOBID - 1;
9331 return maxjobs;
9334 const char *lp_printcapname(void)
9336 if ((Globals.szPrintcapname != NULL) &&
9337 (Globals.szPrintcapname[0] != '\0'))
9338 return Globals.szPrintcapname;
9340 if (sDefault.iPrinting == PRINT_CUPS) {
9341 #ifdef HAVE_CUPS
9342 return "cups";
9343 #else
9344 return "lpstat";
9345 #endif
9348 if (sDefault.iPrinting == PRINT_BSD)
9349 return "/etc/printcap";
9351 return PRINTCAP_NAME;
9354 /*******************************************************************
9355 Ensure we don't use sendfile if server smb signing is active.
9356 ********************************************************************/
9358 static uint32 spoolss_state;
9360 bool lp_disable_spoolss( void )
9362 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9363 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9365 return spoolss_state == SVCCTL_STOPPED ? True : False;
9368 void lp_set_spoolss_state( uint32 state )
9370 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9372 spoolss_state = state;
9375 uint32 lp_get_spoolss_state( void )
9377 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9380 /*******************************************************************
9381 Ensure we don't use sendfile if server smb signing is active.
9382 ********************************************************************/
9384 bool lp_use_sendfile(int snum)
9386 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9387 if (Protocol < PROTOCOL_NT1) {
9388 return False;
9390 return (_lp_use_sendfile(snum) &&
9391 (get_remote_arch() != RA_WIN95) &&
9392 !srv_is_signing_active());
9395 /*******************************************************************
9396 Turn off sendfile if we find the underlying OS doesn't support it.
9397 ********************************************************************/
9399 void set_use_sendfile(int snum, bool val)
9401 if (LP_SNUM_OK(snum))
9402 ServicePtrs[snum]->bUseSendfile = val;
9403 else
9404 sDefault.bUseSendfile = val;
9407 /*******************************************************************
9408 Turn off storing DOS attributes if this share doesn't support it.
9409 ********************************************************************/
9411 void set_store_dos_attributes(int snum, bool val)
9413 if (!LP_SNUM_OK(snum))
9414 return;
9415 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9418 void lp_set_mangling_method(const char *new_method)
9420 string_set(&Globals.szManglingMethod, new_method);
9423 /*******************************************************************
9424 Global state for POSIX pathname processing.
9425 ********************************************************************/
9427 static bool posix_pathnames;
9429 bool lp_posix_pathnames(void)
9431 return posix_pathnames;
9434 /*******************************************************************
9435 Change everything needed to ensure POSIX pathname processing (currently
9436 not much).
9437 ********************************************************************/
9439 void lp_set_posix_pathnames(void)
9441 posix_pathnames = True;
9444 /*******************************************************************
9445 Global state for POSIX lock processing - CIFS unix extensions.
9446 ********************************************************************/
9448 bool posix_default_lock_was_set;
9449 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9451 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9453 if (posix_default_lock_was_set) {
9454 return posix_cifsx_locktype;
9455 } else {
9456 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9460 /*******************************************************************
9461 ********************************************************************/
9463 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9465 posix_default_lock_was_set = True;
9466 posix_cifsx_locktype = val;
9469 int lp_min_receive_file_size(void)
9471 if (Globals.iminreceivefile < 0) {
9472 return 0;
9474 return MIN(Globals.iminreceivefile, BUFFER_SIZE);