testparm: Display warning if invalid values are used.
[Samba/ekacnet.git] / source / param / loadparm.c
blob6902bb0437d15c1a555639aa61d17b46e404c2d6
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 struct param_opt_struct {
101 struct param_opt_struct *prev, *next;
102 char *key;
103 char *value;
104 char **list;
108 * This structure describes global (ie., server-wide) parameters.
110 struct global {
111 int ConfigBackend;
112 char *smb_ports;
113 char *dos_charset;
114 char *unix_charset;
115 char *display_charset;
116 char *szPrintcapname;
117 char *szAddPortCommand;
118 char *szEnumPortsCommand;
119 char *szAddPrinterCommand;
120 char *szDeletePrinterCommand;
121 char *szOs2DriverMap;
122 char *szLockDir;
123 char *szPidDir;
124 char *szRootdir;
125 char *szDefaultService;
126 char *szGetQuota;
127 char *szSetQuota;
128 char *szMsgCommand;
129 char *szServerString;
130 char *szAutoServices;
131 char *szPasswdProgram;
132 char *szPasswdChat;
133 char *szLogFile;
134 char *szConfigFile;
135 char *szSMBPasswdFile;
136 char *szPrivateDir;
137 char *szPassdbBackend;
138 char **szPreloadModules;
139 char *szPasswordServer;
140 char *szSocketOptions;
141 char *szRealm;
142 char *szAfsUsernameMap;
143 int iAfsTokenLifetime;
144 char *szLogNtTokenCommand;
145 char *szUsernameMap;
146 char *szLogonScript;
147 char *szLogonPath;
148 char *szLogonDrive;
149 char *szLogonHome;
150 char **szWINSservers;
151 char **szInterfaces;
152 char *szRemoteAnnounce;
153 char *szRemoteBrowseSync;
154 char *szSocketAddress;
155 char *szNISHomeMapName;
156 char *szAnnounceVersion; /* This is initialised in init_globals */
157 char *szWorkgroup;
158 char *szNetbiosName;
159 char **szNetbiosAliases;
160 char *szNetbiosScope;
161 char *szNameResolveOrder;
162 char *szPanicAction;
163 char *szAddUserScript;
164 char *szRenameUserScript;
165 char *szDelUserScript;
166 char *szAddGroupScript;
167 char *szDelGroupScript;
168 char *szAddUserToGroupScript;
169 char *szDelUserFromGroupScript;
170 char *szSetPrimaryGroupScript;
171 char *szAddMachineScript;
172 char *szShutdownScript;
173 char *szAbortShutdownScript;
174 char *szUsernameMapScript;
175 char *szCheckPasswordScript;
176 char *szWINSHook;
177 char *szUtmpDir;
178 char *szWtmpDir;
179 bool bUtmp;
180 char *szIdmapUID;
181 char *szIdmapGID;
182 bool bPassdbExpandExplicit;
183 int AlgorithmicRidBase;
184 char *szTemplateHomedir;
185 char *szTemplateShell;
186 char *szWinbindSeparator;
187 bool bWinbindEnumUsers;
188 bool bWinbindEnumGroups;
189 bool bWinbindUseDefaultDomain;
190 bool bWinbindTrustedDomainsOnly;
191 bool bWinbindNestedGroups;
192 int winbind_expand_groups;
193 bool bWinbindRefreshTickets;
194 bool bWinbindOfflineLogon;
195 bool bWinbindNormalizeNames;
196 bool bWinbindRpcOnly;
197 char **szIdmapDomains;
198 char **szIdmapBackend; /* deprecated */
199 char *szIdmapAllocBackend;
200 char *szAddShareCommand;
201 char *szChangeShareCommand;
202 char *szDeleteShareCommand;
203 char **szEventLogs;
204 char *szGuestaccount;
205 char *szManglingMethod;
206 char **szServicesList;
207 char *szUsersharePath;
208 char *szUsershareTemplateShare;
209 char **szUsersharePrefixAllowList;
210 char **szUsersharePrefixDenyList;
211 int mangle_prefix;
212 int max_log_size;
213 char *szLogLevel;
214 int max_xmit;
215 int max_mux;
216 int max_open_files;
217 int open_files_db_hash_size;
218 int pwordlevel;
219 int unamelevel;
220 int deadtime;
221 bool getwd_cache;
222 int maxprotocol;
223 int minprotocol;
224 int security;
225 char **AuthMethods;
226 bool paranoid_server_security;
227 int maxdisksize;
228 int lpqcachetime;
229 int iMaxSmbdProcesses;
230 bool bDisableSpoolss;
231 int syslog;
232 int os_level;
233 bool enhanced_browsing;
234 int max_ttl;
235 int max_wins_ttl;
236 int min_wins_ttl;
237 int lm_announce;
238 int lm_interval;
239 int announce_as; /* This is initialised in init_globals */
240 int machine_password_timeout;
241 int map_to_guest;
242 int oplock_break_wait_time;
243 int winbind_cache_time;
244 int winbind_max_idle_children;
245 char **szWinbindNssInfo;
246 int iLockSpinTime;
247 char *szLdapMachineSuffix;
248 char *szLdapUserSuffix;
249 char *szLdapIdmapSuffix;
250 char *szLdapGroupSuffix;
251 int ldap_ssl;
252 char *szLdapSuffix;
253 char *szLdapAdminDn;
254 int ldap_debug_level;
255 int ldap_debug_threshold;
256 int iAclCompat;
257 char *szCupsServer;
258 char *szIPrintServer;
259 char *ctdbdSocket;
260 char **szClusterAddresses;
261 bool clustering;
262 int ldap_passwd_sync;
263 int ldap_replication_sleep;
264 int ldap_timeout; /* This is initialised in init_globals */
265 int ldap_connection_timeout;
266 int ldap_page_size;
267 bool ldap_delete_dn;
268 bool bMsAddPrinterWizard;
269 bool bDNSproxy;
270 bool bWINSsupport;
271 bool bWINSproxy;
272 bool bLocalMaster;
273 int iPreferredMaster;
274 int iDomainMaster;
275 bool bDomainLogons;
276 bool bEncryptPasswords;
277 bool bUpdateEncrypt;
278 int clientSchannel;
279 int serverSchannel;
280 bool bNullPasswords;
281 bool bObeyPamRestrictions;
282 bool bLoadPrinters;
283 int PrintcapCacheTime;
284 bool bLargeReadwrite;
285 bool bReadRaw;
286 bool bWriteRaw;
287 bool bSyslogOnly;
288 bool bBrowseList;
289 bool bNISHomeMap;
290 bool bTimeServer;
291 bool bBindInterfacesOnly;
292 bool bPamPasswordChange;
293 bool bUnixPasswdSync;
294 bool bPasswdChatDebug;
295 int iPasswdChatTimeout;
296 bool bTimestampLogs;
297 bool bNTSmbSupport;
298 bool bNTPipeSupport;
299 bool bNTStatusSupport;
300 bool bStatCache;
301 int iMaxStatCacheSize;
302 bool bKernelOplocks;
303 bool bAllowTrustedDomains;
304 bool bLanmanAuth;
305 bool bNTLMAuth;
306 bool bUseSpnego;
307 bool bClientLanManAuth;
308 bool bClientNTLMv2Auth;
309 bool bClientPlaintextAuth;
310 bool bClientUseSpnego;
311 bool bDebugPrefixTimestamp;
312 bool bDebugHiresTimestamp;
313 bool bDebugPid;
314 bool bDebugUid;
315 bool bDebugClass;
316 bool bEnableCoreFiles;
317 bool bHostMSDfs;
318 bool bUseMmap;
319 bool bHostnameLookups;
320 bool bUnixExtensions;
321 bool bDisableNetbios;
322 bool bUseKerberosKeytab;
323 bool bDeferSharingViolations;
324 bool bEnablePrivileges;
325 bool bASUSupport;
326 bool bUsershareOwnerOnly;
327 bool bUsershareAllowGuests;
328 bool bRegistryShares;
329 int restrict_anonymous;
330 int name_cache_timeout;
331 int client_signing;
332 int server_signing;
333 int client_ldap_sasl_wrapping;
334 int iUsershareMaxShares;
335 int iIdmapCacheTime;
336 int iIdmapNegativeCacheTime;
337 bool bResetOnZeroVC;
338 int iKeepalive;
339 int iminreceivefile;
340 struct param_opt_struct *param_opt;
343 static struct global Globals;
346 * This structure describes a single service.
348 struct service {
349 bool valid;
350 bool autoloaded;
351 int usershare;
352 time_t usershare_last_mod;
353 char *szService;
354 char *szPath;
355 char *szUsername;
356 char **szInvalidUsers;
357 char **szValidUsers;
358 char **szAdminUsers;
359 char *szCopy;
360 char *szInclude;
361 char *szPreExec;
362 char *szPostExec;
363 char *szRootPreExec;
364 char *szRootPostExec;
365 char *szCupsOptions;
366 char *szPrintcommand;
367 char *szLpqcommand;
368 char *szLprmcommand;
369 char *szLppausecommand;
370 char *szLpresumecommand;
371 char *szQueuepausecommand;
372 char *szQueueresumecommand;
373 char *szPrintername;
374 char *szPrintjobUsername;
375 char *szDontdescend;
376 char **szHostsallow;
377 char **szHostsdeny;
378 char *szMagicScript;
379 char *szMagicOutput;
380 char *szVetoFiles;
381 char *szHideFiles;
382 char *szVetoOplockFiles;
383 char *comment;
384 char *force_user;
385 char *force_group;
386 char **readlist;
387 char **writelist;
388 char **printer_admin;
389 char *volume;
390 char *fstype;
391 char **szVfsObjects;
392 char *szMSDfsProxy;
393 char *szAioWriteBehind;
394 char *szDfree;
395 int iMinPrintSpace;
396 int iMaxPrintJobs;
397 int iMaxReportedPrintJobs;
398 int iWriteCacheSize;
399 int iCreate_mask;
400 int iCreate_force_mode;
401 int iSecurity_mask;
402 int iSecurity_force_mode;
403 int iDir_mask;
404 int iDir_force_mode;
405 int iDir_Security_mask;
406 int iDir_Security_force_mode;
407 int iMaxConnections;
408 int iDefaultCase;
409 int iPrinting;
410 int iOplockContentionLimit;
411 int iCSCPolicy;
412 int iBlock_size;
413 int iDfreeCacheTime;
414 bool bPreexecClose;
415 bool bRootpreexecClose;
416 int iCaseSensitive;
417 bool bCasePreserve;
418 bool bShortCasePreserve;
419 bool bHideDotFiles;
420 bool bHideSpecialFiles;
421 bool bHideUnReadable;
422 bool bHideUnWriteableFiles;
423 bool bBrowseable;
424 bool bAvailable;
425 bool bRead_only;
426 bool bNo_set_dir;
427 bool bGuest_only;
428 bool bAdministrative_share;
429 bool bGuest_ok;
430 bool bPrint_ok;
431 bool bMap_system;
432 bool bMap_hidden;
433 bool bMap_archive;
434 bool bStoreDosAttributes;
435 bool bDmapiSupport;
436 bool bLocking;
437 int iStrictLocking;
438 bool bPosixLocking;
439 bool bShareModes;
440 bool bOpLocks;
441 bool bLevel2OpLocks;
442 bool bOnlyUser;
443 bool bMangledNames;
444 bool bWidelinks;
445 bool bSymlinks;
446 bool bSyncAlways;
447 bool bStrictAllocate;
448 bool bStrictSync;
449 char magic_char;
450 struct bitmap *copymap;
451 bool bDeleteReadonly;
452 bool bFakeOplocks;
453 bool bDeleteVetoFiles;
454 bool bDosFilemode;
455 bool bDosFiletimes;
456 bool bDosFiletimeResolution;
457 bool bFakeDirCreateTimes;
458 bool bBlockingLocks;
459 bool bInheritPerms;
460 bool bInheritACLS;
461 bool bInheritOwner;
462 bool bMSDfsRoot;
463 bool bUseClientDriver;
464 bool bDefaultDevmode;
465 bool bForcePrintername;
466 bool bNTAclSupport;
467 bool bForceUnknownAclUser;
468 bool bUseSendfile;
469 bool bProfileAcls;
470 bool bMap_acl_inherit;
471 bool bAfs_Share;
472 bool bEASupport;
473 bool bAclCheckPermissions;
474 bool bAclMapFullControl;
475 bool bAclGroupControl;
476 bool bChangeNotify;
477 bool bKernelChangeNotify;
478 int iallocation_roundup_size;
479 int iAioReadSize;
480 int iAioWriteSize;
481 int iMap_readonly;
482 int iDirectoryNameCacheSize;
483 int ismb_encrypt;
484 struct param_opt_struct *param_opt;
486 char dummy[3]; /* for alignment */
490 /* This is a default service used to prime a services structure */
491 static struct service sDefault = {
492 True, /* valid */
493 False, /* not autoloaded */
494 0, /* not a usershare */
495 (time_t)0, /* No last mod time */
496 NULL, /* szService */
497 NULL, /* szPath */
498 NULL, /* szUsername */
499 NULL, /* szInvalidUsers */
500 NULL, /* szValidUsers */
501 NULL, /* szAdminUsers */
502 NULL, /* szCopy */
503 NULL, /* szInclude */
504 NULL, /* szPreExec */
505 NULL, /* szPostExec */
506 NULL, /* szRootPreExec */
507 NULL, /* szRootPostExec */
508 NULL, /* szCupsOptions */
509 NULL, /* szPrintcommand */
510 NULL, /* szLpqcommand */
511 NULL, /* szLprmcommand */
512 NULL, /* szLppausecommand */
513 NULL, /* szLpresumecommand */
514 NULL, /* szQueuepausecommand */
515 NULL, /* szQueueresumecommand */
516 NULL, /* szPrintername */
517 NULL, /* szPrintjobUsername */
518 NULL, /* szDontdescend */
519 NULL, /* szHostsallow */
520 NULL, /* szHostsdeny */
521 NULL, /* szMagicScript */
522 NULL, /* szMagicOutput */
523 NULL, /* szVetoFiles */
524 NULL, /* szHideFiles */
525 NULL, /* szVetoOplockFiles */
526 NULL, /* comment */
527 NULL, /* force user */
528 NULL, /* force group */
529 NULL, /* readlist */
530 NULL, /* writelist */
531 NULL, /* printer admin */
532 NULL, /* volume */
533 NULL, /* fstype */
534 NULL, /* vfs objects */
535 NULL, /* szMSDfsProxy */
536 NULL, /* szAioWriteBehind */
537 NULL, /* szDfree */
538 0, /* iMinPrintSpace */
539 1000, /* iMaxPrintJobs */
540 0, /* iMaxReportedPrintJobs */
541 0, /* iWriteCacheSize */
542 0744, /* iCreate_mask */
543 0000, /* iCreate_force_mode */
544 0777, /* iSecurity_mask */
545 0, /* iSecurity_force_mode */
546 0755, /* iDir_mask */
547 0000, /* iDir_force_mode */
548 0777, /* iDir_Security_mask */
549 0, /* iDir_Security_force_mode */
550 0, /* iMaxConnections */
551 CASE_LOWER, /* iDefaultCase */
552 DEFAULT_PRINTING, /* iPrinting */
553 2, /* iOplockContentionLimit */
554 0, /* iCSCPolicy */
555 1024, /* iBlock_size */
556 0, /* iDfreeCacheTime */
557 False, /* bPreexecClose */
558 False, /* bRootpreexecClose */
559 Auto, /* case sensitive */
560 True, /* case preserve */
561 True, /* short case preserve */
562 True, /* bHideDotFiles */
563 False, /* bHideSpecialFiles */
564 False, /* bHideUnReadable */
565 False, /* bHideUnWriteableFiles */
566 True, /* bBrowseable */
567 True, /* bAvailable */
568 True, /* bRead_only */
569 True, /* bNo_set_dir */
570 False, /* bGuest_only */
571 False, /* bAdministrative_share */
572 False, /* bGuest_ok */
573 False, /* bPrint_ok */
574 False, /* bMap_system */
575 False, /* bMap_hidden */
576 True, /* bMap_archive */
577 False, /* bStoreDosAttributes */
578 False, /* bDmapiSupport */
579 True, /* bLocking */
580 Auto, /* iStrictLocking */
581 True, /* bPosixLocking */
582 True, /* bShareModes */
583 True, /* bOpLocks */
584 True, /* bLevel2OpLocks */
585 False, /* bOnlyUser */
586 True, /* bMangledNames */
587 True, /* bWidelinks */
588 True, /* bSymlinks */
589 False, /* bSyncAlways */
590 False, /* bStrictAllocate */
591 False, /* bStrictSync */
592 '~', /* magic char */
593 NULL, /* copymap */
594 False, /* bDeleteReadonly */
595 False, /* bFakeOplocks */
596 False, /* bDeleteVetoFiles */
597 False, /* bDosFilemode */
598 True, /* bDosFiletimes */
599 False, /* bDosFiletimeResolution */
600 False, /* bFakeDirCreateTimes */
601 True, /* bBlockingLocks */
602 False, /* bInheritPerms */
603 False, /* bInheritACLS */
604 False, /* bInheritOwner */
605 False, /* bMSDfsRoot */
606 False, /* bUseClientDriver */
607 True, /* bDefaultDevmode */
608 False, /* bForcePrintername */
609 True, /* bNTAclSupport */
610 False, /* bForceUnknownAclUser */
611 False, /* bUseSendfile */
612 False, /* bProfileAcls */
613 False, /* bMap_acl_inherit */
614 False, /* bAfs_Share */
615 False, /* bEASupport */
616 True, /* bAclCheckPermissions */
617 True, /* bAclMapFullControl */
618 False, /* bAclGroupControl */
619 True, /* bChangeNotify */
620 True, /* bKernelChangeNotify */
621 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
622 0, /* iAioReadSize */
623 0, /* iAioWriteSize */
624 MAP_READONLY_YES, /* iMap_readonly */
625 #ifdef BROKEN_DIRECTORY_HANDLING
626 0, /* iDirectoryNameCacheSize */
627 #else
628 100, /* iDirectoryNameCacheSize */
629 #endif
630 Auto, /* ismb_encrypt */
631 NULL, /* Parametric options */
633 "" /* dummy */
636 /* local variables */
637 static struct service **ServicePtrs = NULL;
638 static int iNumServices = 0;
639 static int iServiceIndex = 0;
640 static struct db_context *ServiceHash;
641 static int *invalid_services = NULL;
642 static int num_invalid_services = 0;
643 static bool bInGlobalSection = True;
644 static bool bGlobalOnly = False;
645 static int server_role;
646 static int default_server_announce;
648 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
650 /* prototypes for the special type handlers */
651 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
652 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
653 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
654 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
655 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
656 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
657 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
658 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
659 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
660 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
661 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
662 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
664 static void set_server_role(void);
665 static void set_default_server_announce_type(void);
666 static void set_allowed_client_auth(void);
668 static const struct enum_list enum_protocol[] = {
669 {PROTOCOL_NT1, "NT1"},
670 {PROTOCOL_LANMAN2, "LANMAN2"},
671 {PROTOCOL_LANMAN1, "LANMAN1"},
672 {PROTOCOL_CORE, "CORE"},
673 {PROTOCOL_COREPLUS, "COREPLUS"},
674 {PROTOCOL_COREPLUS, "CORE+"},
675 {-1, NULL}
678 static const struct enum_list enum_security[] = {
679 {SEC_SHARE, "SHARE"},
680 {SEC_USER, "USER"},
681 {SEC_SERVER, "SERVER"},
682 {SEC_DOMAIN, "DOMAIN"},
683 #ifdef HAVE_ADS
684 {SEC_ADS, "ADS"},
685 #endif
686 {-1, NULL}
689 static const struct enum_list enum_printing[] = {
690 {PRINT_SYSV, "sysv"},
691 {PRINT_AIX, "aix"},
692 {PRINT_HPUX, "hpux"},
693 {PRINT_BSD, "bsd"},
694 {PRINT_QNX, "qnx"},
695 {PRINT_PLP, "plp"},
696 {PRINT_LPRNG, "lprng"},
697 {PRINT_CUPS, "cups"},
698 {PRINT_IPRINT, "iprint"},
699 {PRINT_LPRNT, "nt"},
700 {PRINT_LPROS2, "os2"},
701 #ifdef DEVELOPER
702 {PRINT_TEST, "test"},
703 {PRINT_VLP, "vlp"},
704 #endif /* DEVELOPER */
705 {-1, NULL}
708 static const struct enum_list enum_ldap_sasl_wrapping[] = {
709 {0, "plain"},
710 {ADS_AUTH_SASL_SIGN, "sign"},
711 {ADS_AUTH_SASL_SEAL, "seal"},
712 {-1, NULL}
715 static const struct enum_list enum_ldap_ssl[] = {
716 {LDAP_SSL_OFF, "no"},
717 {LDAP_SSL_OFF, "No"},
718 {LDAP_SSL_OFF, "off"},
719 {LDAP_SSL_OFF, "Off"},
720 {LDAP_SSL_START_TLS, "start tls"},
721 {LDAP_SSL_START_TLS, "Start_tls"},
722 {-1, NULL}
725 static const struct enum_list enum_ldap_passwd_sync[] = {
726 {LDAP_PASSWD_SYNC_OFF, "no"},
727 {LDAP_PASSWD_SYNC_OFF, "No"},
728 {LDAP_PASSWD_SYNC_OFF, "off"},
729 {LDAP_PASSWD_SYNC_OFF, "Off"},
730 {LDAP_PASSWD_SYNC_ON, "Yes"},
731 {LDAP_PASSWD_SYNC_ON, "yes"},
732 {LDAP_PASSWD_SYNC_ON, "on"},
733 {LDAP_PASSWD_SYNC_ON, "On"},
734 {LDAP_PASSWD_SYNC_ONLY, "Only"},
735 {LDAP_PASSWD_SYNC_ONLY, "only"},
736 {-1, NULL}
739 /* Types of machine we can announce as. */
740 #define ANNOUNCE_AS_NT_SERVER 1
741 #define ANNOUNCE_AS_WIN95 2
742 #define ANNOUNCE_AS_WFW 3
743 #define ANNOUNCE_AS_NT_WORKSTATION 4
745 static const struct enum_list enum_announce_as[] = {
746 {ANNOUNCE_AS_NT_SERVER, "NT"},
747 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
748 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
749 {ANNOUNCE_AS_WIN95, "win95"},
750 {ANNOUNCE_AS_WFW, "WfW"},
751 {-1, NULL}
754 static const struct enum_list enum_map_readonly[] = {
755 {MAP_READONLY_NO, "no"},
756 {MAP_READONLY_NO, "false"},
757 {MAP_READONLY_NO, "0"},
758 {MAP_READONLY_YES, "yes"},
759 {MAP_READONLY_YES, "true"},
760 {MAP_READONLY_YES, "1"},
761 {MAP_READONLY_PERMISSIONS, "permissions"},
762 {MAP_READONLY_PERMISSIONS, "perms"},
763 {-1, NULL}
766 static const struct enum_list enum_case[] = {
767 {CASE_LOWER, "lower"},
768 {CASE_UPPER, "upper"},
769 {-1, NULL}
772 static const struct enum_list enum_bool_auto[] = {
773 {False, "No"},
774 {False, "False"},
775 {False, "0"},
776 {True, "Yes"},
777 {True, "True"},
778 {True, "1"},
779 {Auto, "Auto"},
780 {-1, NULL}
783 /* Client-side offline caching policy types */
784 #define CSC_POLICY_MANUAL 0
785 #define CSC_POLICY_DOCUMENTS 1
786 #define CSC_POLICY_PROGRAMS 2
787 #define CSC_POLICY_DISABLE 3
789 static const struct enum_list enum_csc_policy[] = {
790 {CSC_POLICY_MANUAL, "manual"},
791 {CSC_POLICY_DOCUMENTS, "documents"},
792 {CSC_POLICY_PROGRAMS, "programs"},
793 {CSC_POLICY_DISABLE, "disable"},
794 {-1, NULL}
797 /* SMB signing types. */
798 static const struct enum_list enum_smb_signing_vals[] = {
799 {False, "No"},
800 {False, "False"},
801 {False, "0"},
802 {False, "Off"},
803 {False, "disabled"},
804 {True, "Yes"},
805 {True, "True"},
806 {True, "1"},
807 {True, "On"},
808 {True, "enabled"},
809 {Auto, "auto"},
810 {Required, "required"},
811 {Required, "mandatory"},
812 {Required, "force"},
813 {Required, "forced"},
814 {Required, "enforced"},
815 {-1, NULL}
818 /* ACL compatibility options. */
819 static const struct enum_list enum_acl_compat_vals[] = {
820 { ACL_COMPAT_AUTO, "auto" },
821 { ACL_COMPAT_WINNT, "winnt" },
822 { ACL_COMPAT_WIN2K, "win2k" },
823 { -1, NULL}
827 Do you want session setups at user level security with a invalid
828 password to be rejected or allowed in as guest? WinNT rejects them
829 but it can be a pain as it means "net view" needs to use a password
831 You have 3 choices in the setting of map_to_guest:
833 "Never" means session setups with an invalid password
834 are rejected. This is the default.
836 "Bad User" means session setups with an invalid password
837 are rejected, unless the username does not exist, in which case it
838 is treated as a guest login
840 "Bad Password" means session setups with an invalid password
841 are treated as a guest login
843 Note that map_to_guest only has an effect in user or server
844 level security.
847 static const struct enum_list enum_map_to_guest[] = {
848 {NEVER_MAP_TO_GUEST, "Never"},
849 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
850 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
851 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
852 {-1, NULL}
855 /* Config backend options */
857 static const struct enum_list enum_config_backend[] = {
858 {CONFIG_BACKEND_FILE, "file"},
859 {CONFIG_BACKEND_REGISTRY, "registry"},
860 {-1, NULL}
863 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
865 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
866 * screen in SWAT. This is used to exclude parameters as well as to squash all
867 * parameters that have been duplicated by pseudonyms.
869 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
870 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
871 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
872 * respective views.
874 * NOTE2: Handling of duplicated (synonym) paramters:
875 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
876 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
877 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
878 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
881 static struct parm_struct parm_table[] = {
882 {N_("Base Options"), P_SEP, P_SEPARATOR},
885 .label = "dos charset",
886 .type = P_STRING,
887 .p_class = P_GLOBAL,
888 .ptr = &Globals.dos_charset,
889 .special = handle_charset,
890 .enum_list = NULL,
891 .flags = FLAG_ADVANCED
894 .label = "unix charset",
895 .type = P_STRING,
896 .p_class = P_GLOBAL,
897 .ptr = &Globals.unix_charset,
898 .special = handle_charset,
899 .enum_list = NULL,
900 .flags = FLAG_ADVANCED
903 .label = "display charset",
904 .type = P_STRING,
905 .p_class = P_GLOBAL,
906 .ptr = &Globals.display_charset,
907 .special = handle_charset,
908 .enum_list = NULL,
909 .flags = FLAG_ADVANCED
912 .label = "comment",
913 .type = P_STRING,
914 .p_class = P_LOCAL,
915 .ptr = &sDefault.comment,
916 .special = NULL,
917 .enum_list = NULL,
918 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
921 .label = "path",
922 .type = P_STRING,
923 .p_class = P_LOCAL,
924 .ptr = &sDefault.szPath,
925 .special = NULL,
926 .enum_list = NULL,
927 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
930 .label = "directory",
931 .type = P_STRING,
932 .p_class = P_LOCAL,
933 .ptr = &sDefault.szPath,
934 .special = NULL,
935 .enum_list = NULL,
936 .flags = FLAG_HIDE,
939 .label = "workgroup",
940 .type = P_USTRING,
941 .p_class = P_GLOBAL,
942 .ptr = &Globals.szWorkgroup,
943 .special = handle_workgroup,
944 .enum_list = NULL,
945 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
947 #ifdef WITH_ADS
949 .label = "realm",
950 .type = P_USTRING,
951 .p_class = P_GLOBAL,
952 .ptr = &Globals.szRealm,
953 .special = NULL,
954 .enum_list = NULL,
955 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
957 #endif
959 .label = "netbios name",
960 .type = P_USTRING,
961 .p_class = P_GLOBAL,
962 .ptr = &Globals.szNetbiosName,
963 .special = handle_netbios_name,
964 .enum_list = NULL,
965 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
968 .label = "netbios aliases",
969 .type = P_LIST,
970 .p_class = P_GLOBAL,
971 .ptr = &Globals.szNetbiosAliases,
972 .special = handle_netbios_aliases,
973 .enum_list = NULL,
974 .flags = FLAG_ADVANCED,
977 .label = "netbios scope",
978 .type = P_USTRING,
979 .p_class = P_GLOBAL,
980 .ptr = &Globals.szNetbiosScope,
981 .special = handle_netbios_scope,
982 .enum_list = NULL,
983 .flags = FLAG_ADVANCED,
986 .label = "server string",
987 .type = P_STRING,
988 .p_class = P_GLOBAL,
989 .ptr = &Globals.szServerString,
990 .special = NULL,
991 .enum_list = NULL,
992 .flags = FLAG_BASIC | FLAG_ADVANCED,
995 .label = "interfaces",
996 .type = P_LIST,
997 .p_class = P_GLOBAL,
998 .ptr = &Globals.szInterfaces,
999 .special = NULL,
1000 .enum_list = NULL,
1001 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1004 .label = "bind interfaces only",
1005 .type = P_BOOL,
1006 .p_class = P_GLOBAL,
1007 .ptr = &Globals.bBindInterfacesOnly,
1008 .special = NULL,
1009 .enum_list = NULL,
1010 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1013 .label = "config backend",
1014 .type = P_ENUM,
1015 .p_class = P_GLOBAL,
1016 .ptr = &Globals.ConfigBackend,
1017 .special = NULL,
1018 .enum_list = enum_config_backend,
1019 .flags = FLAG_ADVANCED,
1022 {N_("Security Options"), P_SEP, P_SEPARATOR},
1025 .label = "security",
1026 .type = P_ENUM,
1027 .p_class = P_GLOBAL,
1028 .ptr = &Globals.security,
1029 .special = NULL,
1030 .enum_list = enum_security,
1031 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1034 .label = "auth methods",
1035 .type = P_LIST,
1036 .p_class = P_GLOBAL,
1037 .ptr = &Globals.AuthMethods,
1038 .special = NULL,
1039 .enum_list = NULL,
1040 .flags = FLAG_ADVANCED,
1043 .label = "encrypt passwords",
1044 .type = P_BOOL,
1045 .p_class = P_GLOBAL,
1046 .ptr = &Globals.bEncryptPasswords,
1047 .special = NULL,
1048 .enum_list = NULL,
1049 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1052 .label = "update encrypted",
1053 .type = P_BOOL,
1054 .p_class = P_GLOBAL,
1055 .ptr = &Globals.bUpdateEncrypt,
1056 .special = NULL,
1057 .enum_list = NULL,
1058 .flags = FLAG_ADVANCED,
1061 .label = "client schannel",
1062 .type = P_ENUM,
1063 .p_class = P_GLOBAL,
1064 .ptr = &Globals.clientSchannel,
1065 .special = NULL,
1066 .enum_list = enum_bool_auto,
1067 .flags = FLAG_BASIC | FLAG_ADVANCED,
1070 .label = "server schannel",
1071 .type = P_ENUM,
1072 .p_class = P_GLOBAL,
1073 .ptr = &Globals.serverSchannel,
1074 .special = NULL,
1075 .enum_list = enum_bool_auto,
1076 .flags = FLAG_BASIC | FLAG_ADVANCED,
1079 .label = "allow trusted domains",
1080 .type = P_BOOL,
1081 .p_class = P_GLOBAL,
1082 .ptr = &Globals.bAllowTrustedDomains,
1083 .special = NULL,
1084 .enum_list = NULL,
1085 .flags = FLAG_ADVANCED,
1088 .label = "map to guest",
1089 .type = P_ENUM,
1090 .p_class = P_GLOBAL,
1091 .ptr = &Globals.map_to_guest,
1092 .special = NULL,
1093 .enum_list = enum_map_to_guest,
1094 .flags = FLAG_ADVANCED,
1097 .label = "null passwords",
1098 .type = P_BOOL,
1099 .p_class = P_GLOBAL,
1100 .ptr = &Globals.bNullPasswords,
1101 .special = NULL,
1102 .enum_list = NULL,
1103 .flags = FLAG_ADVANCED,
1106 .label = "obey pam restrictions",
1107 .type = P_BOOL,
1108 .p_class = P_GLOBAL,
1109 .ptr = &Globals.bObeyPamRestrictions,
1110 .special = NULL,
1111 .enum_list = NULL,
1112 .flags = FLAG_ADVANCED,
1115 .label = "password server",
1116 .type = P_STRING,
1117 .p_class = P_GLOBAL,
1118 .ptr = &Globals.szPasswordServer,
1119 .special = NULL,
1120 .enum_list = NULL,
1121 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1124 .label = "smb passwd file",
1125 .type = P_STRING,
1126 .p_class = P_GLOBAL,
1127 .ptr = &Globals.szSMBPasswdFile,
1128 .special = NULL,
1129 .enum_list = NULL,
1130 .flags = FLAG_ADVANCED,
1133 .label = "private dir",
1134 .type = P_STRING,
1135 .p_class = P_GLOBAL,
1136 .ptr = &Globals.szPrivateDir,
1137 .special = NULL,
1138 .enum_list = NULL,
1139 .flags = FLAG_ADVANCED,
1142 .label = "passdb backend",
1143 .type = P_STRING,
1144 .p_class = P_GLOBAL,
1145 .ptr = &Globals.szPassdbBackend,
1146 .special = NULL,
1147 .enum_list = NULL,
1148 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1151 .label = "algorithmic rid base",
1152 .type = P_INTEGER,
1153 .p_class = P_GLOBAL,
1154 .ptr = &Globals.AlgorithmicRidBase,
1155 .special = NULL,
1156 .enum_list = NULL,
1157 .flags = FLAG_ADVANCED,
1160 .label = "root directory",
1161 .type = P_STRING,
1162 .p_class = P_GLOBAL,
1163 .ptr = &Globals.szRootdir,
1164 .special = NULL,
1165 .enum_list = NULL,
1166 .flags = FLAG_ADVANCED,
1169 .label = "root dir",
1170 .type = P_STRING,
1171 .p_class = P_GLOBAL,
1172 .ptr = &Globals.szRootdir,
1173 .special = NULL,
1174 .enum_list = NULL,
1175 .flags = FLAG_HIDE,
1178 .label = "root",
1179 .type = P_STRING,
1180 .p_class = P_GLOBAL,
1181 .ptr = &Globals.szRootdir,
1182 .special = NULL,
1183 .enum_list = NULL,
1184 .flags = FLAG_HIDE,
1187 .label = "guest account",
1188 .type = P_STRING,
1189 .p_class = P_GLOBAL,
1190 .ptr = &Globals.szGuestaccount,
1191 .special = NULL,
1192 .enum_list = NULL,
1193 .flags = FLAG_BASIC | FLAG_ADVANCED,
1196 .label = "enable privileges",
1197 .type = P_BOOL,
1198 .p_class = P_GLOBAL,
1199 .ptr = &Globals.bEnablePrivileges,
1200 .special = NULL,
1201 .enum_list = NULL,
1202 .flags = FLAG_ADVANCED,
1206 .label = "pam password change",
1207 .type = P_BOOL,
1208 .p_class = P_GLOBAL,
1209 .ptr = &Globals.bPamPasswordChange,
1210 .special = NULL,
1211 .enum_list = NULL,
1212 .flags = FLAG_ADVANCED,
1215 .label = "passwd program",
1216 .type = P_STRING,
1217 .p_class = P_GLOBAL,
1218 .ptr = &Globals.szPasswdProgram,
1219 .special = NULL,
1220 .enum_list = NULL,
1221 .flags = FLAG_ADVANCED,
1224 .label = "passwd chat",
1225 .type = P_STRING,
1226 .p_class = P_GLOBAL,
1227 .ptr = &Globals.szPasswdChat,
1228 .special = NULL,
1229 .enum_list = NULL,
1230 .flags = FLAG_ADVANCED,
1233 .label = "passwd chat debug",
1234 .type = P_BOOL,
1235 .p_class = P_GLOBAL,
1236 .ptr = &Globals.bPasswdChatDebug,
1237 .special = NULL,
1238 .enum_list = NULL,
1239 .flags = FLAG_ADVANCED,
1242 .label = "passwd chat timeout",
1243 .type = P_INTEGER,
1244 .p_class = P_GLOBAL,
1245 .ptr = &Globals.iPasswdChatTimeout,
1246 .special = NULL,
1247 .enum_list = NULL,
1248 .flags = FLAG_ADVANCED,
1251 .label = "check password script",
1252 .type = P_STRING,
1253 .p_class = P_GLOBAL,
1254 .ptr = &Globals.szCheckPasswordScript,
1255 .special = NULL,
1256 .enum_list = NULL,
1257 .flags = FLAG_ADVANCED,
1260 .label = "username map",
1261 .type = P_STRING,
1262 .p_class = P_GLOBAL,
1263 .ptr = &Globals.szUsernameMap,
1264 .special = NULL,
1265 .enum_list = NULL,
1266 .flags = FLAG_ADVANCED,
1269 .label = "password level",
1270 .type = P_INTEGER,
1271 .p_class = P_GLOBAL,
1272 .ptr = &Globals.pwordlevel,
1273 .special = NULL,
1274 .enum_list = NULL,
1275 .flags = FLAG_ADVANCED,
1278 .label = "username level",
1279 .type = P_INTEGER,
1280 .p_class = P_GLOBAL,
1281 .ptr = &Globals.unamelevel,
1282 .special = NULL,
1283 .enum_list = NULL,
1284 .flags = FLAG_ADVANCED,
1287 .label = "unix password sync",
1288 .type = P_BOOL,
1289 .p_class = P_GLOBAL,
1290 .ptr = &Globals.bUnixPasswdSync,
1291 .special = NULL,
1292 .enum_list = NULL,
1293 .flags = FLAG_ADVANCED,
1296 .label = "restrict anonymous",
1297 .type = P_INTEGER,
1298 .p_class = P_GLOBAL,
1299 .ptr = &Globals.restrict_anonymous,
1300 .special = NULL,
1301 .enum_list = NULL,
1302 .flags = FLAG_ADVANCED,
1305 .label = "lanman auth",
1306 .type = P_BOOL,
1307 .p_class = P_GLOBAL,
1308 .ptr = &Globals.bLanmanAuth,
1309 .special = NULL,
1310 .enum_list = NULL,
1311 .flags = FLAG_ADVANCED,
1314 .label = "ntlm auth",
1315 .type = P_BOOL,
1316 .p_class = P_GLOBAL,
1317 .ptr = &Globals.bNTLMAuth,
1318 .special = NULL,
1319 .enum_list = NULL,
1320 .flags = FLAG_ADVANCED,
1323 .label = "client NTLMv2 auth",
1324 .type = P_BOOL,
1325 .p_class = P_GLOBAL,
1326 .ptr = &Globals.bClientNTLMv2Auth,
1327 .special = NULL,
1328 .enum_list = NULL,
1329 .flags = FLAG_ADVANCED,
1332 .label = "client lanman auth",
1333 .type = P_BOOL,
1334 .p_class = P_GLOBAL,
1335 .ptr = &Globals.bClientLanManAuth,
1336 .special = NULL,
1337 .enum_list = NULL,
1338 .flags = FLAG_ADVANCED,
1341 .label = "client plaintext auth",
1342 .type = P_BOOL,
1343 .p_class = P_GLOBAL,
1344 .ptr = &Globals.bClientPlaintextAuth,
1345 .special = NULL,
1346 .enum_list = NULL,
1347 .flags = FLAG_ADVANCED,
1350 .label = "username",
1351 .type = P_STRING,
1352 .p_class = P_LOCAL,
1353 .ptr = &sDefault.szUsername,
1354 .special = NULL,
1355 .enum_list = NULL,
1356 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1359 .label = "user",
1360 .type = P_STRING,
1361 .p_class = P_LOCAL,
1362 .ptr = &sDefault.szUsername,
1363 .special = NULL,
1364 .enum_list = NULL,
1365 .flags = FLAG_HIDE,
1368 .label = "users",
1369 .type = P_STRING,
1370 .p_class = P_LOCAL,
1371 .ptr = &sDefault.szUsername,
1372 .special = NULL,
1373 .enum_list = NULL,
1374 .flags = FLAG_HIDE,
1377 .label = "invalid users",
1378 .type = P_LIST,
1379 .p_class = P_LOCAL,
1380 .ptr = &sDefault.szInvalidUsers,
1381 .special = NULL,
1382 .enum_list = NULL,
1383 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1386 .label = "valid users",
1387 .type = P_LIST,
1388 .p_class = P_LOCAL,
1389 .ptr = &sDefault.szValidUsers,
1390 .special = NULL,
1391 .enum_list = NULL,
1392 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1395 .label = "admin users",
1396 .type = P_LIST,
1397 .p_class = P_LOCAL,
1398 .ptr = &sDefault.szAdminUsers,
1399 .special = NULL,
1400 .enum_list = NULL,
1401 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1404 .label = "read list",
1405 .type = P_LIST,
1406 .p_class = P_LOCAL,
1407 .ptr = &sDefault.readlist,
1408 .special = NULL,
1409 .enum_list = NULL,
1410 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1413 .label = "write list",
1414 .type = P_LIST,
1415 .p_class = P_LOCAL,
1416 .ptr = &sDefault.writelist,
1417 .special = NULL,
1418 .enum_list = NULL,
1419 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1422 .label = "printer admin",
1423 .type = P_LIST,
1424 .p_class = P_LOCAL,
1425 .ptr = &sDefault.printer_admin,
1426 .special = NULL,
1427 .enum_list = NULL,
1428 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1431 .label = "force user",
1432 .type = P_STRING,
1433 .p_class = P_LOCAL,
1434 .ptr = &sDefault.force_user,
1435 .special = NULL,
1436 .enum_list = NULL,
1437 .flags = FLAG_ADVANCED | FLAG_SHARE,
1440 .label = "force group",
1441 .type = P_STRING,
1442 .p_class = P_LOCAL,
1443 .ptr = &sDefault.force_group,
1444 .special = NULL,
1445 .enum_list = NULL,
1446 .flags = FLAG_ADVANCED | FLAG_SHARE,
1449 .label = "group",
1450 .type = P_STRING,
1451 .p_class = P_LOCAL,
1452 .ptr = &sDefault.force_group,
1453 .special = NULL,
1454 .enum_list = NULL,
1455 .flags = FLAG_ADVANCED,
1458 .label = "read only",
1459 .type = P_BOOL,
1460 .p_class = P_LOCAL,
1461 .ptr = &sDefault.bRead_only,
1462 .special = NULL,
1463 .enum_list = NULL,
1464 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1467 .label = "write ok",
1468 .type = P_BOOLREV,
1469 .p_class = P_LOCAL,
1470 .ptr = &sDefault.bRead_only,
1471 .special = NULL,
1472 .enum_list = NULL,
1473 .flags = FLAG_HIDE,
1476 .label = "writeable",
1477 .type = P_BOOLREV,
1478 .p_class = P_LOCAL,
1479 .ptr = &sDefault.bRead_only,
1480 .special = NULL,
1481 .enum_list = NULL,
1482 .flags = FLAG_HIDE,
1485 .label = "writable",
1486 .type = P_BOOLREV,
1487 .p_class = P_LOCAL,
1488 .ptr = &sDefault.bRead_only,
1489 .special = NULL,
1490 .enum_list = NULL,
1491 .flags = FLAG_HIDE,
1494 .label = "acl check permissions",
1495 .type = P_BOOL,
1496 .p_class = P_LOCAL,
1497 .ptr = &sDefault.bAclCheckPermissions,
1498 .special = NULL,
1499 .enum_list = NULL,
1500 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1503 .label = "acl group control",
1504 .type = P_BOOL,
1505 .p_class = P_LOCAL,
1506 .ptr = &sDefault.bAclGroupControl,
1507 .special = NULL,
1508 .enum_list = NULL,
1509 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1512 .label = "acl map full control",
1513 .type = P_BOOL,
1514 .p_class = P_LOCAL,
1515 .ptr = &sDefault.bAclMapFullControl,
1516 .special = NULL,
1517 .enum_list = NULL,
1518 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1521 .label = "create mask",
1522 .type = P_OCTAL,
1523 .p_class = P_LOCAL,
1524 .ptr = &sDefault.iCreate_mask,
1525 .special = NULL,
1526 .enum_list = NULL,
1527 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1530 .label = "create mode",
1531 .type = P_OCTAL,
1532 .p_class = P_LOCAL,
1533 .ptr = &sDefault.iCreate_mask,
1534 .special = NULL,
1535 .enum_list = NULL,
1536 .flags = FLAG_HIDE,
1539 .label = "force create mode",
1540 .type = P_OCTAL,
1541 .p_class = P_LOCAL,
1542 .ptr = &sDefault.iCreate_force_mode,
1543 .special = NULL,
1544 .enum_list = NULL,
1545 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1548 .label = "security mask",
1549 .type = P_OCTAL,
1550 .p_class = P_LOCAL,
1551 .ptr = &sDefault.iSecurity_mask,
1552 .special = NULL,
1553 .enum_list = NULL,
1554 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1557 .label = "force security mode",
1558 .type = P_OCTAL,
1559 .p_class = P_LOCAL,
1560 .ptr = &sDefault.iSecurity_force_mode,
1561 .special = NULL,
1562 .enum_list = NULL,
1563 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1566 .label = "directory mask",
1567 .type = P_OCTAL,
1568 .p_class = P_LOCAL,
1569 .ptr = &sDefault.iDir_mask,
1570 .special = NULL,
1571 .enum_list = NULL,
1572 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1575 .label = "directory mode",
1576 .type = P_OCTAL,
1577 .p_class = P_LOCAL,
1578 .ptr = &sDefault.iDir_mask,
1579 .special = NULL,
1580 .enum_list = NULL,
1581 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1584 .label = "force directory mode",
1585 .type = P_OCTAL,
1586 .p_class = P_LOCAL,
1587 .ptr = &sDefault.iDir_force_mode,
1588 .special = NULL,
1589 .enum_list = NULL,
1590 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1593 .label = "directory security mask",
1594 .type = P_OCTAL,
1595 .p_class = P_LOCAL,
1596 .ptr = &sDefault.iDir_Security_mask,
1597 .special = NULL,
1598 .enum_list = NULL,
1599 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1602 .label = "force directory security mode",
1603 .type = P_OCTAL,
1604 .p_class = P_LOCAL,
1605 .ptr = &sDefault.iDir_Security_force_mode,
1606 .special = NULL,
1607 .enum_list = NULL,
1608 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1611 .label = "force unknown acl user",
1612 .type = P_BOOL,
1613 .p_class = P_LOCAL,
1614 .ptr = &sDefault.bForceUnknownAclUser,
1615 .special = NULL,
1616 .enum_list = NULL,
1617 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1620 .label = "inherit permissions",
1621 .type = P_BOOL,
1622 .p_class = P_LOCAL,
1623 .ptr = &sDefault.bInheritPerms,
1624 .special = NULL,
1625 .enum_list = NULL,
1626 .flags = FLAG_ADVANCED | FLAG_SHARE,
1629 .label = "inherit acls",
1630 .type = P_BOOL,
1631 .p_class = P_LOCAL,
1632 .ptr = &sDefault.bInheritACLS,
1633 .special = NULL,
1634 .enum_list = NULL,
1635 .flags = FLAG_ADVANCED | FLAG_SHARE,
1638 .label = "inherit owner",
1639 .type = P_BOOL,
1640 .p_class = P_LOCAL,
1641 .ptr = &sDefault.bInheritOwner,
1642 .special = NULL,
1643 .enum_list = NULL,
1644 .flags = FLAG_ADVANCED | FLAG_SHARE,
1647 .label = "guest only",
1648 .type = P_BOOL,
1649 .p_class = P_LOCAL,
1650 .ptr = &sDefault.bGuest_only,
1651 .special = NULL,
1652 .enum_list = NULL,
1653 .flags = FLAG_ADVANCED | FLAG_SHARE,
1656 .label = "only guest",
1657 .type = P_BOOL,
1658 .p_class = P_LOCAL,
1659 .ptr = &sDefault.bGuest_only,
1660 .special = NULL,
1661 .enum_list = NULL,
1662 .flags = FLAG_HIDE,
1665 .label = "administrative share",
1666 .type = P_BOOL,
1667 .p_class = P_LOCAL,
1668 .ptr = &sDefault.bAdministrative_share,
1669 .special = NULL,
1670 .enum_list = NULL,
1671 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1675 .label = "guest ok",
1676 .type = P_BOOL,
1677 .p_class = P_LOCAL,
1678 .ptr = &sDefault.bGuest_ok,
1679 .special = NULL,
1680 .enum_list = NULL,
1681 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1684 .label = "public",
1685 .type = P_BOOL,
1686 .p_class = P_LOCAL,
1687 .ptr = &sDefault.bGuest_ok,
1688 .special = NULL,
1689 .enum_list = NULL,
1690 .flags = FLAG_HIDE,
1693 .label = "only user",
1694 .type = P_BOOL,
1695 .p_class = P_LOCAL,
1696 .ptr = &sDefault.bOnlyUser,
1697 .special = NULL,
1698 .enum_list = NULL,
1699 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1702 .label = "hosts allow",
1703 .type = P_LIST,
1704 .p_class = P_LOCAL,
1705 .ptr = &sDefault.szHostsallow,
1706 .special = NULL,
1707 .enum_list = NULL,
1708 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1711 .label = "allow hosts",
1712 .type = P_LIST,
1713 .p_class = P_LOCAL,
1714 .ptr = &sDefault.szHostsallow,
1715 .special = NULL,
1716 .enum_list = NULL,
1717 .flags = FLAG_HIDE,
1720 .label = "hosts deny",
1721 .type = P_LIST,
1722 .p_class = P_LOCAL,
1723 .ptr = &sDefault.szHostsdeny,
1724 .special = NULL,
1725 .enum_list = NULL,
1726 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1729 .label = "deny hosts",
1730 .type = P_LIST,
1731 .p_class = P_LOCAL,
1732 .ptr = &sDefault.szHostsdeny,
1733 .special = NULL,
1734 .enum_list = NULL,
1735 .flags = FLAG_HIDE,
1738 .label = "preload modules",
1739 .type = P_LIST,
1740 .p_class = P_GLOBAL,
1741 .ptr = &Globals.szPreloadModules,
1742 .special = NULL,
1743 .enum_list = NULL,
1744 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1747 .label = "use kerberos keytab",
1748 .type = P_BOOL,
1749 .p_class = P_GLOBAL,
1750 .ptr = &Globals.bUseKerberosKeytab,
1751 .special = NULL,
1752 .enum_list = NULL,
1753 .flags = FLAG_ADVANCED,
1756 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1759 .label = "log level",
1760 .type = P_STRING,
1761 .p_class = P_GLOBAL,
1762 .ptr = &Globals.szLogLevel,
1763 .special = handle_debug_list,
1764 .enum_list = NULL,
1765 .flags = FLAG_ADVANCED,
1768 .label = "debuglevel",
1769 .type = P_STRING,
1770 .p_class = P_GLOBAL,
1771 .ptr = &Globals.szLogLevel,
1772 .special = handle_debug_list,
1773 .enum_list = NULL,
1774 .flags = FLAG_HIDE,
1777 .label = "syslog",
1778 .type = P_INTEGER,
1779 .p_class = P_GLOBAL,
1780 .ptr = &Globals.syslog,
1781 .special = NULL,
1782 .enum_list = NULL,
1783 .flags = FLAG_ADVANCED,
1786 .label = "syslog only",
1787 .type = P_BOOL,
1788 .p_class = P_GLOBAL,
1789 .ptr = &Globals.bSyslogOnly,
1790 .special = NULL,
1791 .enum_list = NULL,
1792 .flags = FLAG_ADVANCED,
1795 .label = "log file",
1796 .type = P_STRING,
1797 .p_class = P_GLOBAL,
1798 .ptr = &Globals.szLogFile,
1799 .special = NULL,
1800 .enum_list = NULL,
1801 .flags = FLAG_ADVANCED,
1804 .label = "max log size",
1805 .type = P_INTEGER,
1806 .p_class = P_GLOBAL,
1807 .ptr = &Globals.max_log_size,
1808 .special = NULL,
1809 .enum_list = NULL,
1810 .flags = FLAG_ADVANCED,
1813 .label = "debug timestamp",
1814 .type = P_BOOL,
1815 .p_class = P_GLOBAL,
1816 .ptr = &Globals.bTimestampLogs,
1817 .special = NULL,
1818 .enum_list = NULL,
1819 .flags = FLAG_ADVANCED,
1822 .label = "timestamp logs",
1823 .type = P_BOOL,
1824 .p_class = P_GLOBAL,
1825 .ptr = &Globals.bTimestampLogs,
1826 .special = NULL,
1827 .enum_list = NULL,
1828 .flags = FLAG_ADVANCED,
1831 .label = "debug prefix timestamp",
1832 .type = P_BOOL,
1833 .p_class = P_GLOBAL,
1834 .ptr = &Globals.bDebugPrefixTimestamp,
1835 .special = NULL,
1836 .enum_list = NULL,
1837 .flags = FLAG_ADVANCED,
1840 .label = "debug hires timestamp",
1841 .type = P_BOOL,
1842 .p_class = P_GLOBAL,
1843 .ptr = &Globals.bDebugHiresTimestamp,
1844 .special = NULL,
1845 .enum_list = NULL,
1846 .flags = FLAG_ADVANCED,
1849 .label = "debug pid",
1850 .type = P_BOOL,
1851 .p_class = P_GLOBAL,
1852 .ptr = &Globals.bDebugPid,
1853 .special = NULL,
1854 .enum_list = NULL,
1855 .flags = FLAG_ADVANCED,
1858 .label = "debug uid",
1859 .type = P_BOOL,
1860 .p_class = P_GLOBAL,
1861 .ptr = &Globals.bDebugUid,
1862 .special = NULL,
1863 .enum_list = NULL,
1864 .flags = FLAG_ADVANCED,
1867 .label = "debug class",
1868 .type = P_BOOL,
1869 .p_class = P_GLOBAL,
1870 .ptr = &Globals.bDebugClass,
1871 .special = NULL,
1872 .enum_list = NULL,
1873 .flags = FLAG_ADVANCED,
1876 .label = "enable core files",
1877 .type = P_BOOL,
1878 .p_class = P_GLOBAL,
1879 .ptr = &Globals.bEnableCoreFiles,
1880 .special = NULL,
1881 .enum_list = NULL,
1882 .flags = FLAG_ADVANCED,
1885 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1888 .label = "allocation roundup size",
1889 .type = P_INTEGER,
1890 .p_class = P_LOCAL,
1891 .ptr = &sDefault.iallocation_roundup_size,
1892 .special = NULL,
1893 .enum_list = NULL,
1894 .flags = FLAG_ADVANCED,
1897 .label = "aio read size",
1898 .type = P_INTEGER,
1899 .p_class = P_LOCAL,
1900 .ptr = &sDefault.iAioReadSize,
1901 .special = NULL,
1902 .enum_list = NULL,
1903 .flags = FLAG_ADVANCED,
1906 .label = "aio write size",
1907 .type = P_INTEGER,
1908 .p_class = P_LOCAL,
1909 .ptr = &sDefault.iAioWriteSize,
1910 .special = NULL,
1911 .enum_list = NULL,
1912 .flags = FLAG_ADVANCED,
1915 .label = "aio write behind",
1916 .type = P_STRING,
1917 .p_class = P_LOCAL,
1918 .ptr = &sDefault.szAioWriteBehind,
1919 .special = NULL,
1920 .enum_list = NULL,
1921 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1924 .label = "smb ports",
1925 .type = P_STRING,
1926 .p_class = P_GLOBAL,
1927 .ptr = &Globals.smb_ports,
1928 .special = NULL,
1929 .enum_list = NULL,
1930 .flags = FLAG_ADVANCED,
1933 .label = "large readwrite",
1934 .type = P_BOOL,
1935 .p_class = P_GLOBAL,
1936 .ptr = &Globals.bLargeReadwrite,
1937 .special = NULL,
1938 .enum_list = NULL,
1939 .flags = FLAG_ADVANCED,
1942 .label = "max protocol",
1943 .type = P_ENUM,
1944 .p_class = P_GLOBAL,
1945 .ptr = &Globals.maxprotocol,
1946 .special = NULL,
1947 .enum_list = enum_protocol,
1948 .flags = FLAG_ADVANCED,
1951 .label = "protocol",
1952 .type = P_ENUM,
1953 .p_class = P_GLOBAL,
1954 .ptr = &Globals.maxprotocol,
1955 .special = NULL,
1956 .enum_list = enum_protocol,
1957 .flags = FLAG_ADVANCED,
1960 .label = "min protocol",
1961 .type = P_ENUM,
1962 .p_class = P_GLOBAL,
1963 .ptr = &Globals.minprotocol,
1964 .special = NULL,
1965 .enum_list = enum_protocol,
1966 .flags = FLAG_ADVANCED,
1969 .label = "min receivefile size",
1970 .type = P_INTEGER,
1971 .p_class = P_GLOBAL,
1972 .ptr = &Globals.iminreceivefile,
1973 .special = NULL,
1974 .enum_list = NULL,
1975 .flags = FLAG_ADVANCED,
1978 .label = "read raw",
1979 .type = P_BOOL,
1980 .p_class = P_GLOBAL,
1981 .ptr = &Globals.bReadRaw,
1982 .special = NULL,
1983 .enum_list = NULL,
1984 .flags = FLAG_ADVANCED,
1987 .label = "write raw",
1988 .type = P_BOOL,
1989 .p_class = P_GLOBAL,
1990 .ptr = &Globals.bWriteRaw,
1991 .special = NULL,
1992 .enum_list = NULL,
1993 .flags = FLAG_ADVANCED,
1996 .label = "disable netbios",
1997 .type = P_BOOL,
1998 .p_class = P_GLOBAL,
1999 .ptr = &Globals.bDisableNetbios,
2000 .special = NULL,
2001 .enum_list = NULL,
2002 .flags = FLAG_ADVANCED,
2005 .label = "reset on zero vc",
2006 .type = P_BOOL,
2007 .p_class = P_GLOBAL,
2008 .ptr = &Globals.bResetOnZeroVC,
2009 .special = NULL,
2010 .enum_list = NULL,
2011 .flags = FLAG_ADVANCED,
2014 .label = "acl compatibility",
2015 .type = P_ENUM,
2016 .p_class = P_GLOBAL,
2017 .ptr = &Globals.iAclCompat,
2018 .special = NULL,
2019 .enum_list = enum_acl_compat_vals,
2020 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2023 .label = "defer sharing violations",
2024 .type = P_BOOL,
2025 .p_class = P_GLOBAL,
2026 .ptr = &Globals.bDeferSharingViolations,
2027 .special = NULL,
2028 .enum_list = NULL,
2029 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2032 .label = "ea support",
2033 .type = P_BOOL,
2034 .p_class = P_LOCAL,
2035 .ptr = &sDefault.bEASupport,
2036 .special = NULL,
2037 .enum_list = NULL,
2038 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2041 .label = "nt acl support",
2042 .type = P_BOOL,
2043 .p_class = P_LOCAL,
2044 .ptr = &sDefault.bNTAclSupport,
2045 .special = NULL,
2046 .enum_list = NULL,
2047 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2050 .label = "nt pipe support",
2051 .type = P_BOOL,
2052 .p_class = P_GLOBAL,
2053 .ptr = &Globals.bNTPipeSupport,
2054 .special = NULL,
2055 .enum_list = NULL,
2056 .flags = FLAG_ADVANCED,
2059 .label = "nt status support",
2060 .type = P_BOOL,
2061 .p_class = P_GLOBAL,
2062 .ptr = &Globals.bNTStatusSupport,
2063 .special = NULL,
2064 .enum_list = NULL,
2065 .flags = FLAG_ADVANCED,
2068 .label = "profile acls",
2069 .type = P_BOOL,
2070 .p_class = P_LOCAL,
2071 .ptr = &sDefault.bProfileAcls,
2072 .special = NULL,
2073 .enum_list = NULL,
2074 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2077 .label = "announce version",
2078 .type = P_STRING,
2079 .p_class = P_GLOBAL,
2080 .ptr = &Globals.szAnnounceVersion,
2081 .special = NULL,
2082 .enum_list = NULL,
2083 .flags = FLAG_ADVANCED,
2086 .label = "announce as",
2087 .type = P_ENUM,
2088 .p_class = P_GLOBAL,
2089 .ptr = &Globals.announce_as,
2090 .special = NULL,
2091 .enum_list = enum_announce_as,
2092 .flags = FLAG_ADVANCED,
2095 .label = "map acl inherit",
2096 .type = P_BOOL,
2097 .p_class = P_LOCAL,
2098 .ptr = &sDefault.bMap_acl_inherit,
2099 .special = NULL,
2100 .enum_list = NULL,
2101 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2104 .label = "afs share",
2105 .type = P_BOOL,
2106 .p_class = P_LOCAL,
2107 .ptr = &sDefault.bAfs_Share,
2108 .special = NULL,
2109 .enum_list = NULL,
2110 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2113 .label = "max mux",
2114 .type = P_INTEGER,
2115 .p_class = P_GLOBAL,
2116 .ptr = &Globals.max_mux,
2117 .special = NULL,
2118 .enum_list = NULL,
2119 .flags = FLAG_ADVANCED,
2122 .label = "max xmit",
2123 .type = P_INTEGER,
2124 .p_class = P_GLOBAL,
2125 .ptr = &Globals.max_xmit,
2126 .special = NULL,
2127 .enum_list = NULL,
2128 .flags = FLAG_ADVANCED,
2131 .label = "name resolve order",
2132 .type = P_STRING,
2133 .p_class = P_GLOBAL,
2134 .ptr = &Globals.szNameResolveOrder,
2135 .special = NULL,
2136 .enum_list = NULL,
2137 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2140 .label = "max ttl",
2141 .type = P_INTEGER,
2142 .p_class = P_GLOBAL,
2143 .ptr = &Globals.max_ttl,
2144 .special = NULL,
2145 .enum_list = NULL,
2146 .flags = FLAG_ADVANCED,
2149 .label = "max wins ttl",
2150 .type = P_INTEGER,
2151 .p_class = P_GLOBAL,
2152 .ptr = &Globals.max_wins_ttl,
2153 .special = NULL,
2154 .enum_list = NULL,
2155 .flags = FLAG_ADVANCED,
2158 .label = "min wins ttl",
2159 .type = P_INTEGER,
2160 .p_class = P_GLOBAL,
2161 .ptr = &Globals.min_wins_ttl,
2162 .special = NULL,
2163 .enum_list = NULL,
2164 .flags = FLAG_ADVANCED,
2167 .label = "time server",
2168 .type = P_BOOL,
2169 .p_class = P_GLOBAL,
2170 .ptr = &Globals.bTimeServer,
2171 .special = NULL,
2172 .enum_list = NULL,
2173 .flags = FLAG_ADVANCED,
2176 .label = "unix extensions",
2177 .type = P_BOOL,
2178 .p_class = P_GLOBAL,
2179 .ptr = &Globals.bUnixExtensions,
2180 .special = NULL,
2181 .enum_list = NULL,
2182 .flags = FLAG_ADVANCED,
2185 .label = "use spnego",
2186 .type = P_BOOL,
2187 .p_class = P_GLOBAL,
2188 .ptr = &Globals.bUseSpnego,
2189 .special = NULL,
2190 .enum_list = NULL,
2191 .flags = FLAG_ADVANCED,
2194 .label = "client signing",
2195 .type = P_ENUM,
2196 .p_class = P_GLOBAL,
2197 .ptr = &Globals.client_signing,
2198 .special = NULL,
2199 .enum_list = enum_smb_signing_vals,
2200 .flags = FLAG_ADVANCED,
2203 .label = "server signing",
2204 .type = P_ENUM,
2205 .p_class = P_GLOBAL,
2206 .ptr = &Globals.server_signing,
2207 .special = NULL,
2208 .enum_list = enum_smb_signing_vals,
2209 .flags = FLAG_ADVANCED,
2212 .label = "smb encrypt",
2213 .type = P_ENUM,
2214 .p_class = P_LOCAL,
2215 .ptr = &sDefault.ismb_encrypt,
2216 .special = NULL,
2217 .enum_list = enum_smb_signing_vals,
2218 .flags = FLAG_ADVANCED,
2221 .label = "client use spnego",
2222 .type = P_BOOL,
2223 .p_class = P_GLOBAL,
2224 .ptr = &Globals.bClientUseSpnego,
2225 .special = NULL,
2226 .enum_list = NULL,
2227 .flags = FLAG_ADVANCED,
2230 .label = "client ldap sasl wrapping",
2231 .type = P_ENUM,
2232 .p_class = P_GLOBAL,
2233 .ptr = &Globals.client_ldap_sasl_wrapping,
2234 .special = NULL,
2235 .enum_list = enum_ldap_sasl_wrapping,
2236 .flags = FLAG_ADVANCED,
2239 .label = "enable asu support",
2240 .type = P_BOOL,
2241 .p_class = P_GLOBAL,
2242 .ptr = &Globals.bASUSupport,
2243 .special = NULL,
2244 .enum_list = NULL,
2245 .flags = FLAG_ADVANCED,
2248 .label = "svcctl list",
2249 .type = P_LIST,
2250 .p_class = P_GLOBAL,
2251 .ptr = &Globals.szServicesList,
2252 .special = NULL,
2253 .enum_list = NULL,
2254 .flags = FLAG_ADVANCED,
2257 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2260 .label = "block size",
2261 .type = P_INTEGER,
2262 .p_class = P_LOCAL,
2263 .ptr = &sDefault.iBlock_size,
2264 .special = NULL,
2265 .enum_list = NULL,
2266 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2269 .label = "deadtime",
2270 .type = P_INTEGER,
2271 .p_class = P_GLOBAL,
2272 .ptr = &Globals.deadtime,
2273 .special = NULL,
2274 .enum_list = NULL,
2275 .flags = FLAG_ADVANCED,
2278 .label = "getwd cache",
2279 .type = P_BOOL,
2280 .p_class = P_GLOBAL,
2281 .ptr = &Globals.getwd_cache,
2282 .special = NULL,
2283 .enum_list = NULL,
2284 .flags = FLAG_ADVANCED,
2287 .label = "keepalive",
2288 .type = P_INTEGER,
2289 .p_class = P_GLOBAL,
2290 .ptr = &Globals.iKeepalive,
2291 .special = NULL,
2292 .enum_list = NULL,
2293 .flags = FLAG_ADVANCED,
2296 .label = "change notify",
2297 .type = P_BOOL,
2298 .p_class = P_LOCAL,
2299 .ptr = &sDefault.bChangeNotify,
2300 .special = NULL,
2301 .enum_list = NULL,
2302 .flags = FLAG_ADVANCED | FLAG_SHARE,
2305 .label = "directory name cache size",
2306 .type = P_INTEGER,
2307 .p_class = P_LOCAL,
2308 .ptr = &sDefault.iDirectoryNameCacheSize,
2309 .special = NULL,
2310 .enum_list = NULL,
2311 .flags = FLAG_ADVANCED | FLAG_SHARE,
2314 .label = "kernel change notify",
2315 .type = P_BOOL,
2316 .p_class = P_LOCAL,
2317 .ptr = &sDefault.bKernelChangeNotify,
2318 .special = NULL,
2319 .enum_list = NULL,
2320 .flags = FLAG_ADVANCED | FLAG_SHARE,
2323 .label = "lpq cache time",
2324 .type = P_INTEGER,
2325 .p_class = P_GLOBAL,
2326 .ptr = &Globals.lpqcachetime,
2327 .special = NULL,
2328 .enum_list = NULL,
2329 .flags = FLAG_ADVANCED,
2332 .label = "max smbd processes",
2333 .type = P_INTEGER,
2334 .p_class = P_GLOBAL,
2335 .ptr = &Globals.iMaxSmbdProcesses,
2336 .special = NULL,
2337 .enum_list = NULL,
2338 .flags = FLAG_ADVANCED,
2341 .label = "max connections",
2342 .type = P_INTEGER,
2343 .p_class = P_LOCAL,
2344 .ptr = &sDefault.iMaxConnections,
2345 .special = NULL,
2346 .enum_list = NULL,
2347 .flags = FLAG_ADVANCED | FLAG_SHARE,
2350 .label = "paranoid server security",
2351 .type = P_BOOL,
2352 .p_class = P_GLOBAL,
2353 .ptr = &Globals.paranoid_server_security,
2354 .special = NULL,
2355 .enum_list = NULL,
2356 .flags = FLAG_ADVANCED,
2359 .label = "max disk size",
2360 .type = P_INTEGER,
2361 .p_class = P_GLOBAL,
2362 .ptr = &Globals.maxdisksize,
2363 .special = NULL,
2364 .enum_list = NULL,
2365 .flags = FLAG_ADVANCED,
2368 .label = "max open files",
2369 .type = P_INTEGER,
2370 .p_class = P_GLOBAL,
2371 .ptr = &Globals.max_open_files,
2372 .special = NULL,
2373 .enum_list = NULL,
2374 .flags = FLAG_ADVANCED,
2377 .label = "min print space",
2378 .type = P_INTEGER,
2379 .p_class = P_LOCAL,
2380 .ptr = &sDefault.iMinPrintSpace,
2381 .special = NULL,
2382 .enum_list = NULL,
2383 .flags = FLAG_ADVANCED | FLAG_PRINT,
2386 .label = "socket options",
2387 .type = P_STRING,
2388 .p_class = P_GLOBAL,
2389 .ptr = &Globals.szSocketOptions,
2390 .special = NULL,
2391 .enum_list = NULL,
2392 .flags = FLAG_ADVANCED,
2395 .label = "strict allocate",
2396 .type = P_BOOL,
2397 .p_class = P_LOCAL,
2398 .ptr = &sDefault.bStrictAllocate,
2399 .special = NULL,
2400 .enum_list = NULL,
2401 .flags = FLAG_ADVANCED | FLAG_SHARE,
2404 .label = "strict sync",
2405 .type = P_BOOL,
2406 .p_class = P_LOCAL,
2407 .ptr = &sDefault.bStrictSync,
2408 .special = NULL,
2409 .enum_list = NULL,
2410 .flags = FLAG_ADVANCED | FLAG_SHARE,
2413 .label = "sync always",
2414 .type = P_BOOL,
2415 .p_class = P_LOCAL,
2416 .ptr = &sDefault.bSyncAlways,
2417 .special = NULL,
2418 .enum_list = NULL,
2419 .flags = FLAG_ADVANCED | FLAG_SHARE,
2422 .label = "use mmap",
2423 .type = P_BOOL,
2424 .p_class = P_GLOBAL,
2425 .ptr = &Globals.bUseMmap,
2426 .special = NULL,
2427 .enum_list = NULL,
2428 .flags = FLAG_ADVANCED,
2431 .label = "use sendfile",
2432 .type = P_BOOL,
2433 .p_class = P_LOCAL,
2434 .ptr = &sDefault.bUseSendfile,
2435 .special = NULL,
2436 .enum_list = NULL,
2437 .flags = FLAG_ADVANCED | FLAG_SHARE,
2440 .label = "hostname lookups",
2441 .type = P_BOOL,
2442 .p_class = P_GLOBAL,
2443 .ptr = &Globals.bHostnameLookups,
2444 .special = NULL,
2445 .enum_list = NULL,
2446 .flags = FLAG_ADVANCED,
2449 .label = "write cache size",
2450 .type = P_INTEGER,
2451 .p_class = P_LOCAL,
2452 .ptr = &sDefault.iWriteCacheSize,
2453 .special = NULL,
2454 .enum_list = NULL,
2455 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2458 .label = "name cache timeout",
2459 .type = P_INTEGER,
2460 .p_class = P_GLOBAL,
2461 .ptr = &Globals.name_cache_timeout,
2462 .special = NULL,
2463 .enum_list = NULL,
2464 .flags = FLAG_ADVANCED,
2467 .label = "ctdbd socket",
2468 .type = P_STRING,
2469 .p_class = P_GLOBAL,
2470 .ptr = &Globals.ctdbdSocket,
2471 .special = NULL,
2472 .enum_list = NULL,
2473 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2476 .label = "cluster addresses",
2477 .type = P_LIST,
2478 .p_class = P_GLOBAL,
2479 .ptr = &Globals.szClusterAddresses,
2480 .special = NULL,
2481 .enum_list = NULL,
2482 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2485 .label = "clustering",
2486 .type = P_BOOL,
2487 .p_class = P_GLOBAL,
2488 .ptr = &Globals.clustering,
2489 .special = NULL,
2490 .enum_list = NULL,
2491 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2494 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2497 .label = "max reported print jobs",
2498 .type = P_INTEGER,
2499 .p_class = P_LOCAL,
2500 .ptr = &sDefault.iMaxReportedPrintJobs,
2501 .special = NULL,
2502 .enum_list = NULL,
2503 .flags = FLAG_ADVANCED | FLAG_PRINT,
2506 .label = "max print jobs",
2507 .type = P_INTEGER,
2508 .p_class = P_LOCAL,
2509 .ptr = &sDefault.iMaxPrintJobs,
2510 .special = NULL,
2511 .enum_list = NULL,
2512 .flags = FLAG_ADVANCED | FLAG_PRINT,
2515 .label = "load printers",
2516 .type = P_BOOL,
2517 .p_class = P_GLOBAL,
2518 .ptr = &Globals.bLoadPrinters,
2519 .special = NULL,
2520 .enum_list = NULL,
2521 .flags = FLAG_ADVANCED | FLAG_PRINT,
2524 .label = "printcap cache time",
2525 .type = P_INTEGER,
2526 .p_class = P_GLOBAL,
2527 .ptr = &Globals.PrintcapCacheTime,
2528 .special = NULL,
2529 .enum_list = NULL,
2530 .flags = FLAG_ADVANCED | FLAG_PRINT,
2533 .label = "printcap name",
2534 .type = P_STRING,
2535 .p_class = P_GLOBAL,
2536 .ptr = &Globals.szPrintcapname,
2537 .special = NULL,
2538 .enum_list = NULL,
2539 .flags = FLAG_ADVANCED | FLAG_PRINT,
2542 .label = "printcap",
2543 .type = P_STRING,
2544 .p_class = P_GLOBAL,
2545 .ptr = &Globals.szPrintcapname,
2546 .special = NULL,
2547 .enum_list = NULL,
2548 .flags = FLAG_HIDE,
2551 .label = "printable",
2552 .type = P_BOOL,
2553 .p_class = P_LOCAL,
2554 .ptr = &sDefault.bPrint_ok,
2555 .special = NULL,
2556 .enum_list = NULL,
2557 .flags = FLAG_ADVANCED | FLAG_PRINT,
2560 .label = "print ok",
2561 .type = P_BOOL,
2562 .p_class = P_LOCAL,
2563 .ptr = &sDefault.bPrint_ok,
2564 .special = NULL,
2565 .enum_list = NULL,
2566 .flags = FLAG_HIDE,
2569 .label = "printing",
2570 .type = P_ENUM,
2571 .p_class = P_LOCAL,
2572 .ptr = &sDefault.iPrinting,
2573 .special = handle_printing,
2574 .enum_list = enum_printing,
2575 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2578 .label = "cups options",
2579 .type = P_STRING,
2580 .p_class = P_LOCAL,
2581 .ptr = &sDefault.szCupsOptions,
2582 .special = NULL,
2583 .enum_list = NULL,
2584 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2587 .label = "cups server",
2588 .type = P_STRING,
2589 .p_class = P_GLOBAL,
2590 .ptr = &Globals.szCupsServer,
2591 .special = NULL,
2592 .enum_list = NULL,
2593 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2596 .label = "iprint server",
2597 .type = P_STRING,
2598 .p_class = P_GLOBAL,
2599 .ptr = &Globals.szIPrintServer,
2600 .special = NULL,
2601 .enum_list = NULL,
2602 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2605 .label = "print command",
2606 .type = P_STRING,
2607 .p_class = P_LOCAL,
2608 .ptr = &sDefault.szPrintcommand,
2609 .special = NULL,
2610 .enum_list = NULL,
2611 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2614 .label = "disable spoolss",
2615 .type = P_BOOL,
2616 .p_class = P_GLOBAL,
2617 .ptr = &Globals.bDisableSpoolss,
2618 .special = NULL,
2619 .enum_list = NULL,
2620 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2623 .label = "enable spoolss",
2624 .type = P_BOOLREV,
2625 .p_class = P_GLOBAL,
2626 .ptr = &Globals.bDisableSpoolss,
2627 .special = NULL,
2628 .enum_list = NULL,
2629 .flags = FLAG_HIDE,
2632 .label = "lpq command",
2633 .type = P_STRING,
2634 .p_class = P_LOCAL,
2635 .ptr = &sDefault.szLpqcommand,
2636 .special = NULL,
2637 .enum_list = NULL,
2638 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2641 .label = "lprm command",
2642 .type = P_STRING,
2643 .p_class = P_LOCAL,
2644 .ptr = &sDefault.szLprmcommand,
2645 .special = NULL,
2646 .enum_list = NULL,
2647 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2650 .label = "lppause command",
2651 .type = P_STRING,
2652 .p_class = P_LOCAL,
2653 .ptr = &sDefault.szLppausecommand,
2654 .special = NULL,
2655 .enum_list = NULL,
2656 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2659 .label = "lpresume command",
2660 .type = P_STRING,
2661 .p_class = P_LOCAL,
2662 .ptr = &sDefault.szLpresumecommand,
2663 .special = NULL,
2664 .enum_list = NULL,
2665 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2668 .label = "queuepause command",
2669 .type = P_STRING,
2670 .p_class = P_LOCAL,
2671 .ptr = &sDefault.szQueuepausecommand,
2672 .special = NULL,
2673 .enum_list = NULL,
2674 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2677 .label = "queueresume command",
2678 .type = P_STRING,
2679 .p_class = P_LOCAL,
2680 .ptr = &sDefault.szQueueresumecommand,
2681 .special = NULL,
2682 .enum_list = NULL,
2683 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2686 .label = "addport command",
2687 .type = P_STRING,
2688 .p_class = P_GLOBAL,
2689 .ptr = &Globals.szAddPortCommand,
2690 .special = NULL,
2691 .enum_list = NULL,
2692 .flags = FLAG_ADVANCED,
2695 .label = "enumports command",
2696 .type = P_STRING,
2697 .p_class = P_GLOBAL,
2698 .ptr = &Globals.szEnumPortsCommand,
2699 .special = NULL,
2700 .enum_list = NULL,
2701 .flags = FLAG_ADVANCED,
2704 .label = "addprinter command",
2705 .type = P_STRING,
2706 .p_class = P_GLOBAL,
2707 .ptr = &Globals.szAddPrinterCommand,
2708 .special = NULL,
2709 .enum_list = NULL,
2710 .flags = FLAG_ADVANCED,
2713 .label = "deleteprinter command",
2714 .type = P_STRING,
2715 .p_class = P_GLOBAL,
2716 .ptr = &Globals.szDeletePrinterCommand,
2717 .special = NULL,
2718 .enum_list = NULL,
2719 .flags = FLAG_ADVANCED,
2722 .label = "show add printer wizard",
2723 .type = P_BOOL,
2724 .p_class = P_GLOBAL,
2725 .ptr = &Globals.bMsAddPrinterWizard,
2726 .special = NULL,
2727 .enum_list = NULL,
2728 .flags = FLAG_ADVANCED,
2731 .label = "os2 driver map",
2732 .type = P_STRING,
2733 .p_class = P_GLOBAL,
2734 .ptr = &Globals.szOs2DriverMap,
2735 .special = NULL,
2736 .enum_list = NULL,
2737 .flags = FLAG_ADVANCED,
2741 .label = "printer name",
2742 .type = P_STRING,
2743 .p_class = P_LOCAL,
2744 .ptr = &sDefault.szPrintername,
2745 .special = NULL,
2746 .enum_list = NULL,
2747 .flags = FLAG_ADVANCED | FLAG_PRINT,
2750 .label = "printer",
2751 .type = P_STRING,
2752 .p_class = P_LOCAL,
2753 .ptr = &sDefault.szPrintername,
2754 .special = NULL,
2755 .enum_list = NULL,
2756 .flags = FLAG_HIDE,
2759 .label = "use client driver",
2760 .type = P_BOOL,
2761 .p_class = P_LOCAL,
2762 .ptr = &sDefault.bUseClientDriver,
2763 .special = NULL,
2764 .enum_list = NULL,
2765 .flags = FLAG_ADVANCED | FLAG_PRINT,
2768 .label = "default devmode",
2769 .type = P_BOOL,
2770 .p_class = P_LOCAL,
2771 .ptr = &sDefault.bDefaultDevmode,
2772 .special = NULL,
2773 .enum_list = NULL,
2774 .flags = FLAG_ADVANCED | FLAG_PRINT,
2777 .label = "force printername",
2778 .type = P_BOOL,
2779 .p_class = P_LOCAL,
2780 .ptr = &sDefault.bForcePrintername,
2781 .special = NULL,
2782 .enum_list = NULL,
2783 .flags = FLAG_ADVANCED | FLAG_PRINT,
2786 .label = "printjob username",
2787 .type = P_STRING,
2788 .p_class = P_LOCAL,
2789 .ptr = &sDefault.szPrintjobUsername,
2790 .special = NULL,
2791 .enum_list = NULL,
2792 .flags = FLAG_ADVANCED | FLAG_PRINT,
2795 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2798 .label = "mangling method",
2799 .type = P_STRING,
2800 .p_class = P_GLOBAL,
2801 .ptr = &Globals.szManglingMethod,
2802 .special = NULL,
2803 .enum_list = NULL,
2804 .flags = FLAG_ADVANCED,
2807 .label = "mangle prefix",
2808 .type = P_INTEGER,
2809 .p_class = P_GLOBAL,
2810 .ptr = &Globals.mangle_prefix,
2811 .special = NULL,
2812 .enum_list = NULL,
2813 .flags = FLAG_ADVANCED,
2817 .label = "default case",
2818 .type = P_ENUM,
2819 .p_class = P_LOCAL,
2820 .ptr = &sDefault.iDefaultCase,
2821 .special = NULL,
2822 .enum_list = enum_case,
2823 .flags = FLAG_ADVANCED | FLAG_SHARE,
2826 .label = "case sensitive",
2827 .type = P_ENUM,
2828 .p_class = P_LOCAL,
2829 .ptr = &sDefault.iCaseSensitive,
2830 .special = NULL,
2831 .enum_list = enum_bool_auto,
2832 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2835 .label = "casesignames",
2836 .type = P_ENUM,
2837 .p_class = P_LOCAL,
2838 .ptr = &sDefault.iCaseSensitive,
2839 .special = NULL,
2840 .enum_list = enum_bool_auto,
2841 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2844 .label = "preserve case",
2845 .type = P_BOOL,
2846 .p_class = P_LOCAL,
2847 .ptr = &sDefault.bCasePreserve,
2848 .special = NULL,
2849 .enum_list = NULL,
2850 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2853 .label = "short preserve case",
2854 .type = P_BOOL,
2855 .p_class = P_LOCAL,
2856 .ptr = &sDefault.bShortCasePreserve,
2857 .special = NULL,
2858 .enum_list = NULL,
2859 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2862 .label = "mangling char",
2863 .type = P_CHAR,
2864 .p_class = P_LOCAL,
2865 .ptr = &sDefault.magic_char,
2866 .special = NULL,
2867 .enum_list = NULL,
2868 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2871 .label = "hide dot files",
2872 .type = P_BOOL,
2873 .p_class = P_LOCAL,
2874 .ptr = &sDefault.bHideDotFiles,
2875 .special = NULL,
2876 .enum_list = NULL,
2877 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2880 .label = "hide special files",
2881 .type = P_BOOL,
2882 .p_class = P_LOCAL,
2883 .ptr = &sDefault.bHideSpecialFiles,
2884 .special = NULL,
2885 .enum_list = NULL,
2886 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2889 .label = "hide unreadable",
2890 .type = P_BOOL,
2891 .p_class = P_LOCAL,
2892 .ptr = &sDefault.bHideUnReadable,
2893 .special = NULL,
2894 .enum_list = NULL,
2895 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2898 .label = "hide unwriteable files",
2899 .type = P_BOOL,
2900 .p_class = P_LOCAL,
2901 .ptr = &sDefault.bHideUnWriteableFiles,
2902 .special = NULL,
2903 .enum_list = NULL,
2904 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2907 .label = "delete veto files",
2908 .type = P_BOOL,
2909 .p_class = P_LOCAL,
2910 .ptr = &sDefault.bDeleteVetoFiles,
2911 .special = NULL,
2912 .enum_list = NULL,
2913 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2916 .label = "veto files",
2917 .type = P_STRING,
2918 .p_class = P_LOCAL,
2919 .ptr = &sDefault.szVetoFiles,
2920 .special = NULL,
2921 .enum_list = NULL,
2922 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2925 .label = "hide files",
2926 .type = P_STRING,
2927 .p_class = P_LOCAL,
2928 .ptr = &sDefault.szHideFiles,
2929 .special = NULL,
2930 .enum_list = NULL,
2931 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2934 .label = "veto oplock files",
2935 .type = P_STRING,
2936 .p_class = P_LOCAL,
2937 .ptr = &sDefault.szVetoOplockFiles,
2938 .special = NULL,
2939 .enum_list = NULL,
2940 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2943 .label = "map archive",
2944 .type = P_BOOL,
2945 .p_class = P_LOCAL,
2946 .ptr = &sDefault.bMap_archive,
2947 .special = NULL,
2948 .enum_list = NULL,
2949 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2952 .label = "map hidden",
2953 .type = P_BOOL,
2954 .p_class = P_LOCAL,
2955 .ptr = &sDefault.bMap_hidden,
2956 .special = NULL,
2957 .enum_list = NULL,
2958 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2961 .label = "map system",
2962 .type = P_BOOL,
2963 .p_class = P_LOCAL,
2964 .ptr = &sDefault.bMap_system,
2965 .special = NULL,
2966 .enum_list = NULL,
2967 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2970 .label = "map readonly",
2971 .type = P_ENUM,
2972 .p_class = P_LOCAL,
2973 .ptr = &sDefault.iMap_readonly,
2974 .special = NULL,
2975 .enum_list = enum_map_readonly,
2976 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2979 .label = "mangled names",
2980 .type = P_BOOL,
2981 .p_class = P_LOCAL,
2982 .ptr = &sDefault.bMangledNames,
2983 .special = NULL,
2984 .enum_list = NULL,
2985 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2988 .label = "max stat cache size",
2989 .type = P_INTEGER,
2990 .p_class = P_GLOBAL,
2991 .ptr = &Globals.iMaxStatCacheSize,
2992 .special = NULL,
2993 .enum_list = NULL,
2994 .flags = FLAG_ADVANCED,
2997 .label = "stat cache",
2998 .type = P_BOOL,
2999 .p_class = P_GLOBAL,
3000 .ptr = &Globals.bStatCache,
3001 .special = NULL,
3002 .enum_list = NULL,
3003 .flags = FLAG_ADVANCED,
3006 .label = "store dos attributes",
3007 .type = P_BOOL,
3008 .p_class = P_LOCAL,
3009 .ptr = &sDefault.bStoreDosAttributes,
3010 .special = NULL,
3011 .enum_list = NULL,
3012 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3015 .label = "dmapi support",
3016 .type = P_BOOL,
3017 .p_class = P_LOCAL,
3018 .ptr = &sDefault.bDmapiSupport,
3019 .special = NULL,
3020 .enum_list = NULL,
3021 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3025 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3028 .label = "machine password timeout",
3029 .type = P_INTEGER,
3030 .p_class = P_GLOBAL,
3031 .ptr = &Globals.machine_password_timeout,
3032 .special = NULL,
3033 .enum_list = NULL,
3034 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3037 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3040 .label = "add user script",
3041 .type = P_STRING,
3042 .p_class = P_GLOBAL,
3043 .ptr = &Globals.szAddUserScript,
3044 .special = NULL,
3045 .enum_list = NULL,
3046 .flags = FLAG_ADVANCED,
3049 .label = "rename user script",
3050 .type = P_STRING,
3051 .p_class = P_GLOBAL,
3052 .ptr = &Globals.szRenameUserScript,
3053 .special = NULL,
3054 .enum_list = NULL,
3055 .flags = FLAG_ADVANCED,
3058 .label = "delete user script",
3059 .type = P_STRING,
3060 .p_class = P_GLOBAL,
3061 .ptr = &Globals.szDelUserScript,
3062 .special = NULL,
3063 .enum_list = NULL,
3064 .flags = FLAG_ADVANCED,
3067 .label = "add group script",
3068 .type = P_STRING,
3069 .p_class = P_GLOBAL,
3070 .ptr = &Globals.szAddGroupScript,
3071 .special = NULL,
3072 .enum_list = NULL,
3073 .flags = FLAG_ADVANCED,
3076 .label = "delete group script",
3077 .type = P_STRING,
3078 .p_class = P_GLOBAL,
3079 .ptr = &Globals.szDelGroupScript,
3080 .special = NULL,
3081 .enum_list = NULL,
3082 .flags = FLAG_ADVANCED,
3085 .label = "add user to group script",
3086 .type = P_STRING,
3087 .p_class = P_GLOBAL,
3088 .ptr = &Globals.szAddUserToGroupScript,
3089 .special = NULL,
3090 .enum_list = NULL,
3091 .flags = FLAG_ADVANCED,
3094 .label = "delete user from group script",
3095 .type = P_STRING,
3096 .p_class = P_GLOBAL,
3097 .ptr = &Globals.szDelUserFromGroupScript,
3098 .special = NULL,
3099 .enum_list = NULL,
3100 .flags = FLAG_ADVANCED,
3103 .label = "set primary group script",
3104 .type = P_STRING,
3105 .p_class = P_GLOBAL,
3106 .ptr = &Globals.szSetPrimaryGroupScript,
3107 .special = NULL,
3108 .enum_list = NULL,
3109 .flags = FLAG_ADVANCED,
3112 .label = "add machine script",
3113 .type = P_STRING,
3114 .p_class = P_GLOBAL,
3115 .ptr = &Globals.szAddMachineScript,
3116 .special = NULL,
3117 .enum_list = NULL,
3118 .flags = FLAG_ADVANCED,
3121 .label = "shutdown script",
3122 .type = P_STRING,
3123 .p_class = P_GLOBAL,
3124 .ptr = &Globals.szShutdownScript,
3125 .special = NULL,
3126 .enum_list = NULL,
3127 .flags = FLAG_ADVANCED,
3130 .label = "abort shutdown script",
3131 .type = P_STRING,
3132 .p_class = P_GLOBAL,
3133 .ptr = &Globals.szAbortShutdownScript,
3134 .special = NULL,
3135 .enum_list = NULL,
3136 .flags = FLAG_ADVANCED,
3139 .label = "username map script",
3140 .type = P_STRING,
3141 .p_class = P_GLOBAL,
3142 .ptr = &Globals.szUsernameMapScript,
3143 .special = NULL,
3144 .enum_list = NULL,
3145 .flags = FLAG_ADVANCED,
3148 .label = "logon script",
3149 .type = P_STRING,
3150 .p_class = P_GLOBAL,
3151 .ptr = &Globals.szLogonScript,
3152 .special = NULL,
3153 .enum_list = NULL,
3154 .flags = FLAG_ADVANCED,
3157 .label = "logon path",
3158 .type = P_STRING,
3159 .p_class = P_GLOBAL,
3160 .ptr = &Globals.szLogonPath,
3161 .special = NULL,
3162 .enum_list = NULL,
3163 .flags = FLAG_ADVANCED,
3166 .label = "logon drive",
3167 .type = P_STRING,
3168 .p_class = P_GLOBAL,
3169 .ptr = &Globals.szLogonDrive,
3170 .special = NULL,
3171 .enum_list = NULL,
3172 .flags = FLAG_ADVANCED,
3175 .label = "logon home",
3176 .type = P_STRING,
3177 .p_class = P_GLOBAL,
3178 .ptr = &Globals.szLogonHome,
3179 .special = NULL,
3180 .enum_list = NULL,
3181 .flags = FLAG_ADVANCED,
3184 .label = "domain logons",
3185 .type = P_BOOL,
3186 .p_class = P_GLOBAL,
3187 .ptr = &Globals.bDomainLogons,
3188 .special = NULL,
3189 .enum_list = NULL,
3190 .flags = FLAG_ADVANCED,
3193 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3196 .label = "os level",
3197 .type = P_INTEGER,
3198 .p_class = P_GLOBAL,
3199 .ptr = &Globals.os_level,
3200 .special = NULL,
3201 .enum_list = NULL,
3202 .flags = FLAG_BASIC | FLAG_ADVANCED,
3205 .label = "lm announce",
3206 .type = P_ENUM,
3207 .p_class = P_GLOBAL,
3208 .ptr = &Globals.lm_announce,
3209 .special = NULL,
3210 .enum_list = enum_bool_auto,
3211 .flags = FLAG_ADVANCED,
3214 .label = "lm interval",
3215 .type = P_INTEGER,
3216 .p_class = P_GLOBAL,
3217 .ptr = &Globals.lm_interval,
3218 .special = NULL,
3219 .enum_list = NULL,
3220 .flags = FLAG_ADVANCED,
3223 .label = "preferred master",
3224 .type = P_ENUM,
3225 .p_class = P_GLOBAL,
3226 .ptr = &Globals.iPreferredMaster,
3227 .special = NULL,
3228 .enum_list = enum_bool_auto,
3229 .flags = FLAG_BASIC | FLAG_ADVANCED,
3232 .label = "prefered master",
3233 .type = P_ENUM,
3234 .p_class = P_GLOBAL,
3235 .ptr = &Globals.iPreferredMaster,
3236 .special = NULL,
3237 .enum_list = enum_bool_auto,
3238 .flags = FLAG_HIDE,
3241 .label = "local master",
3242 .type = P_BOOL,
3243 .p_class = P_GLOBAL,
3244 .ptr = &Globals.bLocalMaster,
3245 .special = NULL,
3246 .enum_list = NULL,
3247 .flags = FLAG_BASIC | FLAG_ADVANCED,
3250 .label = "domain master",
3251 .type = P_ENUM,
3252 .p_class = P_GLOBAL,
3253 .ptr = &Globals.iDomainMaster,
3254 .special = NULL,
3255 .enum_list = enum_bool_auto,
3256 .flags = FLAG_BASIC | FLAG_ADVANCED,
3259 .label = "browse list",
3260 .type = P_BOOL,
3261 .p_class = P_GLOBAL,
3262 .ptr = &Globals.bBrowseList,
3263 .special = NULL,
3264 .enum_list = NULL,
3265 .flags = FLAG_ADVANCED,
3268 .label = "browseable",
3269 .type = P_BOOL,
3270 .p_class = P_LOCAL,
3271 .ptr = &sDefault.bBrowseable,
3272 .special = NULL,
3273 .enum_list = NULL,
3274 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3277 .label = "browsable",
3278 .type = P_BOOL,
3279 .p_class = P_LOCAL,
3280 .ptr = &sDefault.bBrowseable,
3281 .special = NULL,
3282 .enum_list = NULL,
3283 .flags = FLAG_HIDE,
3286 .label = "enhanced browsing",
3287 .type = P_BOOL,
3288 .p_class = P_GLOBAL,
3289 .ptr = &Globals.enhanced_browsing,
3290 .special = NULL,
3291 .enum_list = NULL,
3292 .flags = FLAG_ADVANCED,
3295 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3298 .label = "dns proxy",
3299 .type = P_BOOL,
3300 .p_class = P_GLOBAL,
3301 .ptr = &Globals.bDNSproxy,
3302 .special = NULL,
3303 .enum_list = NULL,
3304 .flags = FLAG_ADVANCED,
3307 .label = "wins proxy",
3308 .type = P_BOOL,
3309 .p_class = P_GLOBAL,
3310 .ptr = &Globals.bWINSproxy,
3311 .special = NULL,
3312 .enum_list = NULL,
3313 .flags = FLAG_ADVANCED,
3316 .label = "wins server",
3317 .type = P_LIST,
3318 .p_class = P_GLOBAL,
3319 .ptr = &Globals.szWINSservers,
3320 .special = NULL,
3321 .enum_list = NULL,
3322 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3325 .label = "wins support",
3326 .type = P_BOOL,
3327 .p_class = P_GLOBAL,
3328 .ptr = &Globals.bWINSsupport,
3329 .special = NULL,
3330 .enum_list = NULL,
3331 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3334 .label = "wins hook",
3335 .type = P_STRING,
3336 .p_class = P_GLOBAL,
3337 .ptr = &Globals.szWINSHook,
3338 .special = NULL,
3339 .enum_list = NULL,
3340 .flags = FLAG_ADVANCED,
3343 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3346 .label = "blocking locks",
3347 .type = P_BOOL,
3348 .p_class = P_LOCAL,
3349 .ptr = &sDefault.bBlockingLocks,
3350 .special = NULL,
3351 .enum_list = NULL,
3352 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3355 .label = "csc policy",
3356 .type = P_ENUM,
3357 .p_class = P_LOCAL,
3358 .ptr = &sDefault.iCSCPolicy,
3359 .special = NULL,
3360 .enum_list = enum_csc_policy,
3361 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3364 .label = "fake oplocks",
3365 .type = P_BOOL,
3366 .p_class = P_LOCAL,
3367 .ptr = &sDefault.bFakeOplocks,
3368 .special = NULL,
3369 .enum_list = NULL,
3370 .flags = FLAG_ADVANCED | FLAG_SHARE,
3373 .label = "kernel oplocks",
3374 .type = P_BOOL,
3375 .p_class = P_GLOBAL,
3376 .ptr = &Globals.bKernelOplocks,
3377 .special = NULL,
3378 .enum_list = NULL,
3379 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3382 .label = "locking",
3383 .type = P_BOOL,
3384 .p_class = P_LOCAL,
3385 .ptr = &sDefault.bLocking,
3386 .special = NULL,
3387 .enum_list = NULL,
3388 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3391 .label = "lock spin time",
3392 .type = P_INTEGER,
3393 .p_class = P_GLOBAL,
3394 .ptr = &Globals.iLockSpinTime,
3395 .special = NULL,
3396 .enum_list = NULL,
3397 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3400 .label = "oplocks",
3401 .type = P_BOOL,
3402 .p_class = P_LOCAL,
3403 .ptr = &sDefault.bOpLocks,
3404 .special = NULL,
3405 .enum_list = NULL,
3406 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3409 .label = "level2 oplocks",
3410 .type = P_BOOL,
3411 .p_class = P_LOCAL,
3412 .ptr = &sDefault.bLevel2OpLocks,
3413 .special = NULL,
3414 .enum_list = NULL,
3415 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3418 .label = "oplock break wait time",
3419 .type = P_INTEGER,
3420 .p_class = P_GLOBAL,
3421 .ptr = &Globals.oplock_break_wait_time,
3422 .special = NULL,
3423 .enum_list = NULL,
3424 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3427 .label = "oplock contention limit",
3428 .type = P_INTEGER,
3429 .p_class = P_LOCAL,
3430 .ptr = &sDefault.iOplockContentionLimit,
3431 .special = NULL,
3432 .enum_list = NULL,
3433 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3436 .label = "posix locking",
3437 .type = P_BOOL,
3438 .p_class = P_LOCAL,
3439 .ptr = &sDefault.bPosixLocking,
3440 .special = NULL,
3441 .enum_list = NULL,
3442 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3445 .label = "strict locking",
3446 .type = P_ENUM,
3447 .p_class = P_LOCAL,
3448 .ptr = &sDefault.iStrictLocking,
3449 .special = NULL,
3450 .enum_list = enum_bool_auto,
3451 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3454 .label = "share modes",
3455 .type = P_BOOL,
3456 .p_class = P_LOCAL,
3457 .ptr = &sDefault.bShareModes,
3458 .special = NULL,
3459 .enum_list = NULL,
3460 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3463 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3466 .label = "ldap admin dn",
3467 .type = P_STRING,
3468 .p_class = P_GLOBAL,
3469 .ptr = &Globals.szLdapAdminDn,
3470 .special = NULL,
3471 .enum_list = NULL,
3472 .flags = FLAG_ADVANCED,
3475 .label = "ldap delete dn",
3476 .type = P_BOOL,
3477 .p_class = P_GLOBAL,
3478 .ptr = &Globals.ldap_delete_dn,
3479 .special = NULL,
3480 .enum_list = NULL,
3481 .flags = FLAG_ADVANCED,
3484 .label = "ldap group suffix",
3485 .type = P_STRING,
3486 .p_class = P_GLOBAL,
3487 .ptr = &Globals.szLdapGroupSuffix,
3488 .special = NULL,
3489 .enum_list = NULL,
3490 .flags = FLAG_ADVANCED,
3493 .label = "ldap idmap suffix",
3494 .type = P_STRING,
3495 .p_class = P_GLOBAL,
3496 .ptr = &Globals.szLdapIdmapSuffix,
3497 .special = NULL,
3498 .enum_list = NULL,
3499 .flags = FLAG_ADVANCED,
3502 .label = "ldap machine suffix",
3503 .type = P_STRING,
3504 .p_class = P_GLOBAL,
3505 .ptr = &Globals.szLdapMachineSuffix,
3506 .special = NULL,
3507 .enum_list = NULL,
3508 .flags = FLAG_ADVANCED,
3511 .label = "ldap passwd sync",
3512 .type = P_ENUM,
3513 .p_class = P_GLOBAL,
3514 .ptr = &Globals.ldap_passwd_sync,
3515 .special = NULL,
3516 .enum_list = enum_ldap_passwd_sync,
3517 .flags = FLAG_ADVANCED,
3520 .label = "ldap password sync",
3521 .type = P_ENUM,
3522 .p_class = P_GLOBAL,
3523 .ptr = &Globals.ldap_passwd_sync,
3524 .special = NULL,
3525 .enum_list = enum_ldap_passwd_sync,
3526 .flags = FLAG_HIDE,
3529 .label = "ldap replication sleep",
3530 .type = P_INTEGER,
3531 .p_class = P_GLOBAL,
3532 .ptr = &Globals.ldap_replication_sleep,
3533 .special = NULL,
3534 .enum_list = NULL,
3535 .flags = FLAG_ADVANCED,
3538 .label = "ldap suffix",
3539 .type = P_STRING,
3540 .p_class = P_GLOBAL,
3541 .ptr = &Globals.szLdapSuffix,
3542 .special = NULL,
3543 .enum_list = NULL,
3544 .flags = FLAG_ADVANCED,
3547 .label = "ldap ssl",
3548 .type = P_ENUM,
3549 .p_class = P_GLOBAL,
3550 .ptr = &Globals.ldap_ssl,
3551 .special = NULL,
3552 .enum_list = enum_ldap_ssl,
3553 .flags = FLAG_ADVANCED,
3556 .label = "ldap timeout",
3557 .type = P_INTEGER,
3558 .p_class = P_GLOBAL,
3559 .ptr = &Globals.ldap_timeout,
3560 .special = NULL,
3561 .enum_list = NULL,
3562 .flags = FLAG_ADVANCED,
3565 .label = "ldap connection timeout",
3566 .type = P_INTEGER,
3567 .p_class = P_GLOBAL,
3568 .ptr = &Globals.ldap_connection_timeout,
3569 .special = NULL,
3570 .enum_list = NULL,
3571 .flags = FLAG_ADVANCED,
3574 .label = "ldap page size",
3575 .type = P_INTEGER,
3576 .p_class = P_GLOBAL,
3577 .ptr = &Globals.ldap_page_size,
3578 .special = NULL,
3579 .enum_list = NULL,
3580 .flags = FLAG_ADVANCED,
3583 .label = "ldap user suffix",
3584 .type = P_STRING,
3585 .p_class = P_GLOBAL,
3586 .ptr = &Globals.szLdapUserSuffix,
3587 .special = NULL,
3588 .enum_list = NULL,
3589 .flags = FLAG_ADVANCED,
3592 .label = "ldap debug level",
3593 .type = P_INTEGER,
3594 .p_class = P_GLOBAL,
3595 .ptr = &Globals.ldap_debug_level,
3596 .special = handle_ldap_debug_level,
3597 .enum_list = NULL,
3598 .flags = FLAG_ADVANCED,
3601 .label = "ldap debug threshold",
3602 .type = P_INTEGER,
3603 .p_class = P_GLOBAL,
3604 .ptr = &Globals.ldap_debug_threshold,
3605 .special = NULL,
3606 .enum_list = NULL,
3607 .flags = FLAG_ADVANCED,
3610 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3613 .label = "eventlog list",
3614 .type = P_LIST,
3615 .p_class = P_GLOBAL,
3616 .ptr = &Globals.szEventLogs,
3617 .special = NULL,
3618 .enum_list = NULL,
3619 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3622 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3625 .label = "add share command",
3626 .type = P_STRING,
3627 .p_class = P_GLOBAL,
3628 .ptr = &Globals.szAddShareCommand,
3629 .special = NULL,
3630 .enum_list = NULL,
3631 .flags = FLAG_ADVANCED,
3634 .label = "change share command",
3635 .type = P_STRING,
3636 .p_class = P_GLOBAL,
3637 .ptr = &Globals.szChangeShareCommand,
3638 .special = NULL,
3639 .enum_list = NULL,
3640 .flags = FLAG_ADVANCED,
3643 .label = "delete share command",
3644 .type = P_STRING,
3645 .p_class = P_GLOBAL,
3646 .ptr = &Globals.szDeleteShareCommand,
3647 .special = NULL,
3648 .enum_list = NULL,
3649 .flags = FLAG_ADVANCED,
3652 .label = "config file",
3653 .type = P_STRING,
3654 .p_class = P_GLOBAL,
3655 .ptr = &Globals.szConfigFile,
3656 .special = NULL,
3657 .enum_list = NULL,
3658 .flags = FLAG_HIDE,
3661 .label = "preload",
3662 .type = P_STRING,
3663 .p_class = P_GLOBAL,
3664 .ptr = &Globals.szAutoServices,
3665 .special = NULL,
3666 .enum_list = NULL,
3667 .flags = FLAG_ADVANCED,
3670 .label = "auto services",
3671 .type = P_STRING,
3672 .p_class = P_GLOBAL,
3673 .ptr = &Globals.szAutoServices,
3674 .special = NULL,
3675 .enum_list = NULL,
3676 .flags = FLAG_ADVANCED,
3679 .label = "lock directory",
3680 .type = P_STRING,
3681 .p_class = P_GLOBAL,
3682 .ptr = &Globals.szLockDir,
3683 .special = NULL,
3684 .enum_list = NULL,
3685 .flags = FLAG_ADVANCED,
3688 .label = "lock dir",
3689 .type = P_STRING,
3690 .p_class = P_GLOBAL,
3691 .ptr = &Globals.szLockDir,
3692 .special = NULL,
3693 .enum_list = NULL,
3694 .flags = FLAG_HIDE,
3697 .label = "pid directory",
3698 .type = P_STRING,
3699 .p_class = P_GLOBAL,
3700 .ptr = &Globals.szPidDir,
3701 .special = NULL,
3702 .enum_list = NULL,
3703 .flags = FLAG_ADVANCED,
3705 #ifdef WITH_UTMP
3707 .label = "utmp directory",
3708 .type = P_STRING,
3709 .p_class = P_GLOBAL,
3710 .ptr = &Globals.szUtmpDir,
3711 .special = NULL,
3712 .enum_list = NULL,
3713 .flags = FLAG_ADVANCED,
3716 .label = "wtmp directory",
3717 .type = P_STRING,
3718 .p_class = P_GLOBAL,
3719 .ptr = &Globals.szWtmpDir,
3720 .special = NULL,
3721 .enum_list = NULL,
3722 .flags = FLAG_ADVANCED,
3725 .label = "utmp",
3726 .type = P_BOOL,
3727 .p_class = P_GLOBAL,
3728 .ptr = &Globals.bUtmp,
3729 .special = NULL,
3730 .enum_list = NULL,
3731 .flags = FLAG_ADVANCED,
3733 #endif
3735 .label = "default service",
3736 .type = P_STRING,
3737 .p_class = P_GLOBAL,
3738 .ptr = &Globals.szDefaultService,
3739 .special = NULL,
3740 .enum_list = NULL,
3741 .flags = FLAG_ADVANCED,
3744 .label = "default",
3745 .type = P_STRING,
3746 .p_class = P_GLOBAL,
3747 .ptr = &Globals.szDefaultService,
3748 .special = NULL,
3749 .enum_list = NULL,
3750 .flags = FLAG_ADVANCED,
3753 .label = "message command",
3754 .type = P_STRING,
3755 .p_class = P_GLOBAL,
3756 .ptr = &Globals.szMsgCommand,
3757 .special = NULL,
3758 .enum_list = NULL,
3759 .flags = FLAG_ADVANCED,
3762 .label = "dfree cache time",
3763 .type = P_INTEGER,
3764 .p_class = P_LOCAL,
3765 .ptr = &sDefault.iDfreeCacheTime,
3766 .special = NULL,
3767 .enum_list = NULL,
3768 .flags = FLAG_ADVANCED,
3771 .label = "dfree command",
3772 .type = P_STRING,
3773 .p_class = P_LOCAL,
3774 .ptr = &sDefault.szDfree,
3775 .special = NULL,
3776 .enum_list = NULL,
3777 .flags = FLAG_ADVANCED,
3780 .label = "get quota command",
3781 .type = P_STRING,
3782 .p_class = P_GLOBAL,
3783 .ptr = &Globals.szGetQuota,
3784 .special = NULL,
3785 .enum_list = NULL,
3786 .flags = FLAG_ADVANCED,
3789 .label = "set quota command",
3790 .type = P_STRING,
3791 .p_class = P_GLOBAL,
3792 .ptr = &Globals.szSetQuota,
3793 .special = NULL,
3794 .enum_list = NULL,
3795 .flags = FLAG_ADVANCED,
3798 .label = "remote announce",
3799 .type = P_STRING,
3800 .p_class = P_GLOBAL,
3801 .ptr = &Globals.szRemoteAnnounce,
3802 .special = NULL,
3803 .enum_list = NULL,
3804 .flags = FLAG_ADVANCED,
3807 .label = "remote browse sync",
3808 .type = P_STRING,
3809 .p_class = P_GLOBAL,
3810 .ptr = &Globals.szRemoteBrowseSync,
3811 .special = NULL,
3812 .enum_list = NULL,
3813 .flags = FLAG_ADVANCED,
3816 .label = "socket address",
3817 .type = P_STRING,
3818 .p_class = P_GLOBAL,
3819 .ptr = &Globals.szSocketAddress,
3820 .special = NULL,
3821 .enum_list = NULL,
3822 .flags = FLAG_ADVANCED,
3825 .label = "homedir map",
3826 .type = P_STRING,
3827 .p_class = P_GLOBAL,
3828 .ptr = &Globals.szNISHomeMapName,
3829 .special = NULL,
3830 .enum_list = NULL,
3831 .flags = FLAG_ADVANCED,
3834 .label = "afs username map",
3835 .type = P_STRING,
3836 .p_class = P_GLOBAL,
3837 .ptr = &Globals.szAfsUsernameMap,
3838 .special = NULL,
3839 .enum_list = NULL,
3840 .flags = FLAG_ADVANCED,
3843 .label = "afs token lifetime",
3844 .type = P_INTEGER,
3845 .p_class = P_GLOBAL,
3846 .ptr = &Globals.iAfsTokenLifetime,
3847 .special = NULL,
3848 .enum_list = NULL,
3849 .flags = FLAG_ADVANCED,
3852 .label = "log nt token command",
3853 .type = P_STRING,
3854 .p_class = P_GLOBAL,
3855 .ptr = &Globals.szLogNtTokenCommand,
3856 .special = NULL,
3857 .enum_list = NULL,
3858 .flags = FLAG_ADVANCED,
3861 .label = "time offset",
3862 .type = P_INTEGER,
3863 .p_class = P_GLOBAL,
3864 .ptr = &extra_time_offset,
3865 .special = NULL,
3866 .enum_list = NULL,
3867 .flags = FLAG_ADVANCED,
3870 .label = "NIS homedir",
3871 .type = P_BOOL,
3872 .p_class = P_GLOBAL,
3873 .ptr = &Globals.bNISHomeMap,
3874 .special = NULL,
3875 .enum_list = NULL,
3876 .flags = FLAG_ADVANCED,
3879 .label = "-valid",
3880 .type = P_BOOL,
3881 .p_class = P_LOCAL,
3882 .ptr = &sDefault.valid,
3883 .special = NULL,
3884 .enum_list = NULL,
3885 .flags = FLAG_HIDE,
3888 .label = "copy",
3889 .type = P_STRING,
3890 .p_class = P_LOCAL,
3891 .ptr = &sDefault.szCopy,
3892 .special = handle_copy,
3893 .enum_list = NULL,
3894 .flags = FLAG_HIDE,
3897 .label = "include",
3898 .type = P_STRING,
3899 .p_class = P_LOCAL,
3900 .ptr = &sDefault.szInclude,
3901 .special = handle_include,
3902 .enum_list = NULL,
3903 .flags = FLAG_HIDE,
3906 .label = "preexec",
3907 .type = P_STRING,
3908 .p_class = P_LOCAL,
3909 .ptr = &sDefault.szPreExec,
3910 .special = NULL,
3911 .enum_list = NULL,
3912 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3915 .label = "exec",
3916 .type = P_STRING,
3917 .p_class = P_LOCAL,
3918 .ptr = &sDefault.szPreExec,
3919 .special = NULL,
3920 .enum_list = NULL,
3921 .flags = FLAG_ADVANCED,
3924 .label = "preexec close",
3925 .type = P_BOOL,
3926 .p_class = P_LOCAL,
3927 .ptr = &sDefault.bPreexecClose,
3928 .special = NULL,
3929 .enum_list = NULL,
3930 .flags = FLAG_ADVANCED | FLAG_SHARE,
3933 .label = "postexec",
3934 .type = P_STRING,
3935 .p_class = P_LOCAL,
3936 .ptr = &sDefault.szPostExec,
3937 .special = NULL,
3938 .enum_list = NULL,
3939 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3942 .label = "root preexec",
3943 .type = P_STRING,
3944 .p_class = P_LOCAL,
3945 .ptr = &sDefault.szRootPreExec,
3946 .special = NULL,
3947 .enum_list = NULL,
3948 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3951 .label = "root preexec close",
3952 .type = P_BOOL,
3953 .p_class = P_LOCAL,
3954 .ptr = &sDefault.bRootpreexecClose,
3955 .special = NULL,
3956 .enum_list = NULL,
3957 .flags = FLAG_ADVANCED | FLAG_SHARE,
3960 .label = "root postexec",
3961 .type = P_STRING,
3962 .p_class = P_LOCAL,
3963 .ptr = &sDefault.szRootPostExec,
3964 .special = NULL,
3965 .enum_list = NULL,
3966 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3969 .label = "available",
3970 .type = P_BOOL,
3971 .p_class = P_LOCAL,
3972 .ptr = &sDefault.bAvailable,
3973 .special = NULL,
3974 .enum_list = NULL,
3975 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3978 .label = "registry shares",
3979 .type = P_BOOL,
3980 .p_class = P_GLOBAL,
3981 .ptr = &Globals.bRegistryShares,
3982 .special = NULL,
3983 .enum_list = NULL,
3984 .flags = FLAG_ADVANCED,
3987 .label = "usershare allow guests",
3988 .type = P_BOOL,
3989 .p_class = P_GLOBAL,
3990 .ptr = &Globals.bUsershareAllowGuests,
3991 .special = NULL,
3992 .enum_list = NULL,
3993 .flags = FLAG_ADVANCED,
3996 .label = "usershare max shares",
3997 .type = P_INTEGER,
3998 .p_class = P_GLOBAL,
3999 .ptr = &Globals.iUsershareMaxShares,
4000 .special = NULL,
4001 .enum_list = NULL,
4002 .flags = FLAG_ADVANCED,
4005 .label = "usershare owner only",
4006 .type = P_BOOL,
4007 .p_class = P_GLOBAL,
4008 .ptr = &Globals.bUsershareOwnerOnly,
4009 .special = NULL,
4010 .enum_list = NULL,
4011 .flags = FLAG_ADVANCED,
4014 .label = "usershare path",
4015 .type = P_STRING,
4016 .p_class = P_GLOBAL,
4017 .ptr = &Globals.szUsersharePath,
4018 .special = NULL,
4019 .enum_list = NULL,
4020 .flags = FLAG_ADVANCED,
4023 .label = "usershare prefix allow list",
4024 .type = P_LIST,
4025 .p_class = P_GLOBAL,
4026 .ptr = &Globals.szUsersharePrefixAllowList,
4027 .special = NULL,
4028 .enum_list = NULL,
4029 .flags = FLAG_ADVANCED,
4032 .label = "usershare prefix deny list",
4033 .type = P_LIST,
4034 .p_class = P_GLOBAL,
4035 .ptr = &Globals.szUsersharePrefixDenyList,
4036 .special = NULL,
4037 .enum_list = NULL,
4038 .flags = FLAG_ADVANCED,
4041 .label = "usershare template share",
4042 .type = P_STRING,
4043 .p_class = P_GLOBAL,
4044 .ptr = &Globals.szUsershareTemplateShare,
4045 .special = NULL,
4046 .enum_list = NULL,
4047 .flags = FLAG_ADVANCED,
4050 .label = "volume",
4051 .type = P_STRING,
4052 .p_class = P_LOCAL,
4053 .ptr = &sDefault.volume,
4054 .special = NULL,
4055 .enum_list = NULL,
4056 .flags = FLAG_ADVANCED | FLAG_SHARE,
4059 .label = "fstype",
4060 .type = P_STRING,
4061 .p_class = P_LOCAL,
4062 .ptr = &sDefault.fstype,
4063 .special = NULL,
4064 .enum_list = NULL,
4065 .flags = FLAG_ADVANCED | FLAG_SHARE,
4068 .label = "set directory",
4069 .type = P_BOOLREV,
4070 .p_class = P_LOCAL,
4071 .ptr = &sDefault.bNo_set_dir,
4072 .special = NULL,
4073 .enum_list = NULL,
4074 .flags = FLAG_ADVANCED | FLAG_SHARE,
4077 .label = "wide links",
4078 .type = P_BOOL,
4079 .p_class = P_LOCAL,
4080 .ptr = &sDefault.bWidelinks,
4081 .special = NULL,
4082 .enum_list = NULL,
4083 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4086 .label = "follow symlinks",
4087 .type = P_BOOL,
4088 .p_class = P_LOCAL,
4089 .ptr = &sDefault.bSymlinks,
4090 .special = NULL,
4091 .enum_list = NULL,
4092 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4095 .label = "dont descend",
4096 .type = P_STRING,
4097 .p_class = P_LOCAL,
4098 .ptr = &sDefault.szDontdescend,
4099 .special = NULL,
4100 .enum_list = NULL,
4101 .flags = FLAG_ADVANCED | FLAG_SHARE,
4104 .label = "magic script",
4105 .type = P_STRING,
4106 .p_class = P_LOCAL,
4107 .ptr = &sDefault.szMagicScript,
4108 .special = NULL,
4109 .enum_list = NULL,
4110 .flags = FLAG_ADVANCED | FLAG_SHARE,
4113 .label = "magic output",
4114 .type = P_STRING,
4115 .p_class = P_LOCAL,
4116 .ptr = &sDefault.szMagicOutput,
4117 .special = NULL,
4118 .enum_list = NULL,
4119 .flags = FLAG_ADVANCED | FLAG_SHARE,
4122 .label = "delete readonly",
4123 .type = P_BOOL,
4124 .p_class = P_LOCAL,
4125 .ptr = &sDefault.bDeleteReadonly,
4126 .special = NULL,
4127 .enum_list = NULL,
4128 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4131 .label = "dos filemode",
4132 .type = P_BOOL,
4133 .p_class = P_LOCAL,
4134 .ptr = &sDefault.bDosFilemode,
4135 .special = NULL,
4136 .enum_list = NULL,
4137 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4140 .label = "dos filetimes",
4141 .type = P_BOOL,
4142 .p_class = P_LOCAL,
4143 .ptr = &sDefault.bDosFiletimes,
4144 .special = NULL,
4145 .enum_list = NULL,
4146 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4149 .label = "dos filetime resolution",
4150 .type = P_BOOL,
4151 .p_class = P_LOCAL,
4152 .ptr = &sDefault.bDosFiletimeResolution,
4153 .special = NULL,
4154 .enum_list = NULL,
4155 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4158 .label = "fake directory create times",
4159 .type = P_BOOL,
4160 .p_class = P_LOCAL,
4161 .ptr = &sDefault.bFakeDirCreateTimes,
4162 .special = NULL,
4163 .enum_list = NULL,
4164 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4167 .label = "panic action",
4168 .type = P_STRING,
4169 .p_class = P_GLOBAL,
4170 .ptr = &Globals.szPanicAction,
4171 .special = NULL,
4172 .enum_list = NULL,
4173 .flags = FLAG_ADVANCED,
4176 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4179 .label = "vfs objects",
4180 .type = P_LIST,
4181 .p_class = P_LOCAL,
4182 .ptr = &sDefault.szVfsObjects,
4183 .special = NULL,
4184 .enum_list = NULL,
4185 .flags = FLAG_ADVANCED | FLAG_SHARE,
4188 .label = "vfs object",
4189 .type = P_LIST,
4190 .p_class = P_LOCAL,
4191 .ptr = &sDefault.szVfsObjects,
4192 .special = NULL,
4193 .enum_list = NULL,
4194 .flags = FLAG_HIDE,
4198 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4201 .label = "msdfs root",
4202 .type = P_BOOL,
4203 .p_class = P_LOCAL,
4204 .ptr = &sDefault.bMSDfsRoot,
4205 .special = NULL,
4206 .enum_list = NULL,
4207 .flags = FLAG_ADVANCED | FLAG_SHARE,
4210 .label = "msdfs proxy",
4211 .type = P_STRING,
4212 .p_class = P_LOCAL,
4213 .ptr = &sDefault.szMSDfsProxy,
4214 .special = NULL,
4215 .enum_list = NULL,
4216 .flags = FLAG_ADVANCED | FLAG_SHARE,
4219 .label = "host msdfs",
4220 .type = P_BOOL,
4221 .p_class = P_GLOBAL,
4222 .ptr = &Globals.bHostMSDfs,
4223 .special = NULL,
4224 .enum_list = NULL,
4225 .flags = FLAG_ADVANCED,
4228 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4231 .label = "passdb expand explicit",
4232 .type = P_BOOL,
4233 .p_class = P_GLOBAL,
4234 .ptr = &Globals.bPassdbExpandExplicit,
4235 .special = NULL,
4236 .enum_list = NULL,
4237 .flags = FLAG_ADVANCED,
4240 .label = "idmap domains",
4241 .type = P_LIST,
4242 .p_class = P_GLOBAL,
4243 .ptr = &Globals.szIdmapDomains,
4244 .special = NULL,
4245 .enum_list = NULL,
4246 .flags = FLAG_ADVANCED,
4249 .label = "idmap backend",
4250 .type = P_LIST,
4251 .p_class = P_GLOBAL,
4252 .ptr = &Globals.szIdmapBackend,
4253 .special = NULL,
4254 .enum_list = NULL,
4255 .flags = FLAG_ADVANCED,
4258 .label = "idmap alloc backend",
4259 .type = P_STRING,
4260 .p_class = P_GLOBAL,
4261 .ptr = &Globals.szIdmapAllocBackend,
4262 .special = NULL,
4263 .enum_list = NULL,
4264 .flags = FLAG_ADVANCED,
4267 .label = "idmap cache time",
4268 .type = P_INTEGER,
4269 .p_class = P_GLOBAL,
4270 .ptr = &Globals.iIdmapCacheTime,
4271 .special = NULL,
4272 .enum_list = NULL,
4273 .flags = FLAG_ADVANCED,
4276 .label = "idmap negative cache time",
4277 .type = P_INTEGER,
4278 .p_class = P_GLOBAL,
4279 .ptr = &Globals.iIdmapNegativeCacheTime,
4280 .special = NULL,
4281 .enum_list = NULL,
4282 .flags = FLAG_ADVANCED,
4285 .label = "idmap uid",
4286 .type = P_STRING,
4287 .p_class = P_GLOBAL,
4288 .ptr = &Globals.szIdmapUID,
4289 .special = handle_idmap_uid,
4290 .enum_list = NULL,
4291 .flags = FLAG_ADVANCED,
4294 .label = "winbind uid",
4295 .type = P_STRING,
4296 .p_class = P_GLOBAL,
4297 .ptr = &Globals.szIdmapUID,
4298 .special = handle_idmap_uid,
4299 .enum_list = NULL,
4300 .flags = FLAG_HIDE,
4303 .label = "idmap gid",
4304 .type = P_STRING,
4305 .p_class = P_GLOBAL,
4306 .ptr = &Globals.szIdmapGID,
4307 .special = handle_idmap_gid,
4308 .enum_list = NULL,
4309 .flags = FLAG_ADVANCED,
4312 .label = "winbind gid",
4313 .type = P_STRING,
4314 .p_class = P_GLOBAL,
4315 .ptr = &Globals.szIdmapGID,
4316 .special = handle_idmap_gid,
4317 .enum_list = NULL,
4318 .flags = FLAG_HIDE,
4321 .label = "template homedir",
4322 .type = P_STRING,
4323 .p_class = P_GLOBAL,
4324 .ptr = &Globals.szTemplateHomedir,
4325 .special = NULL,
4326 .enum_list = NULL,
4327 .flags = FLAG_ADVANCED,
4330 .label = "template shell",
4331 .type = P_STRING,
4332 .p_class = P_GLOBAL,
4333 .ptr = &Globals.szTemplateShell,
4334 .special = NULL,
4335 .enum_list = NULL,
4336 .flags = FLAG_ADVANCED,
4339 .label = "winbind separator",
4340 .type = P_STRING,
4341 .p_class = P_GLOBAL,
4342 .ptr = &Globals.szWinbindSeparator,
4343 .special = NULL,
4344 .enum_list = NULL,
4345 .flags = FLAG_ADVANCED,
4348 .label = "winbind cache time",
4349 .type = P_INTEGER,
4350 .p_class = P_GLOBAL,
4351 .ptr = &Globals.winbind_cache_time,
4352 .special = NULL,
4353 .enum_list = NULL,
4354 .flags = FLAG_ADVANCED,
4357 .label = "winbind enum users",
4358 .type = P_BOOL,
4359 .p_class = P_GLOBAL,
4360 .ptr = &Globals.bWinbindEnumUsers,
4361 .special = NULL,
4362 .enum_list = NULL,
4363 .flags = FLAG_ADVANCED,
4366 .label = "winbind enum groups",
4367 .type = P_BOOL,
4368 .p_class = P_GLOBAL,
4369 .ptr = &Globals.bWinbindEnumGroups,
4370 .special = NULL,
4371 .enum_list = NULL,
4372 .flags = FLAG_ADVANCED,
4375 .label = "winbind use default domain",
4376 .type = P_BOOL,
4377 .p_class = P_GLOBAL,
4378 .ptr = &Globals.bWinbindUseDefaultDomain,
4379 .special = NULL,
4380 .enum_list = NULL,
4381 .flags = FLAG_ADVANCED,
4384 .label = "winbind trusted domains only",
4385 .type = P_BOOL,
4386 .p_class = P_GLOBAL,
4387 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4388 .special = NULL,
4389 .enum_list = NULL,
4390 .flags = FLAG_ADVANCED,
4393 .label = "winbind nested groups",
4394 .type = P_BOOL,
4395 .p_class = P_GLOBAL,
4396 .ptr = &Globals.bWinbindNestedGroups,
4397 .special = NULL,
4398 .enum_list = NULL,
4399 .flags = FLAG_ADVANCED,
4402 .label = "winbind expand groups",
4403 .type = P_INTEGER,
4404 .p_class = P_GLOBAL,
4405 .ptr = &Globals.winbind_expand_groups,
4406 .special = NULL,
4407 .enum_list = NULL,
4408 .flags = FLAG_ADVANCED,
4411 .label = "winbind nss info",
4412 .type = P_LIST,
4413 .p_class = P_GLOBAL,
4414 .ptr = &Globals.szWinbindNssInfo,
4415 .special = NULL,
4416 .enum_list = NULL,
4417 .flags = FLAG_ADVANCED,
4420 .label = "winbind refresh tickets",
4421 .type = P_BOOL,
4422 .p_class = P_GLOBAL,
4423 .ptr = &Globals.bWinbindRefreshTickets,
4424 .special = NULL,
4425 .enum_list = NULL,
4426 .flags = FLAG_ADVANCED,
4429 .label = "winbind offline logon",
4430 .type = P_BOOL,
4431 .p_class = P_GLOBAL,
4432 .ptr = &Globals.bWinbindOfflineLogon,
4433 .special = NULL,
4434 .enum_list = NULL,
4435 .flags = FLAG_ADVANCED,
4438 .label = "winbind normalize names",
4439 .type = P_BOOL,
4440 .p_class = P_GLOBAL,
4441 .ptr = &Globals.bWinbindNormalizeNames,
4442 .special = NULL,
4443 .enum_list = NULL,
4444 .flags = FLAG_ADVANCED,
4447 .label = "winbind rpc only",
4448 .type = P_BOOL,
4449 .p_class = P_GLOBAL,
4450 .ptr = &Globals.bWinbindRpcOnly,
4451 .special = NULL,
4452 .enum_list = NULL,
4453 .flags = FLAG_ADVANCED,
4456 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4459 /***************************************************************************
4460 Initialise the sDefault parameter structure for the printer values.
4461 ***************************************************************************/
4463 static void init_printer_values(struct service *pService)
4465 /* choose defaults depending on the type of printing */
4466 switch (pService->iPrinting) {
4467 case PRINT_BSD:
4468 case PRINT_AIX:
4469 case PRINT_LPRNT:
4470 case PRINT_LPROS2:
4471 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4472 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4473 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4474 break;
4476 case PRINT_LPRNG:
4477 case PRINT_PLP:
4478 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4479 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4480 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4481 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4482 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4483 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4484 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4485 break;
4487 case PRINT_CUPS:
4488 case PRINT_IPRINT:
4489 #ifdef HAVE_CUPS
4490 /* set the lpq command to contain the destination printer
4491 name only. This is used by cups_queue_get() */
4492 string_set(&pService->szLpqcommand, "%p");
4493 string_set(&pService->szLprmcommand, "");
4494 string_set(&pService->szPrintcommand, "");
4495 string_set(&pService->szLppausecommand, "");
4496 string_set(&pService->szLpresumecommand, "");
4497 string_set(&pService->szQueuepausecommand, "");
4498 string_set(&pService->szQueueresumecommand, "");
4499 #else
4500 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4501 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4502 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4503 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4504 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4505 string_set(&pService->szQueuepausecommand, "disable '%p'");
4506 string_set(&pService->szQueueresumecommand, "enable '%p'");
4507 #endif /* HAVE_CUPS */
4508 break;
4510 case PRINT_SYSV:
4511 case PRINT_HPUX:
4512 string_set(&pService->szLpqcommand, "lpstat -o%p");
4513 string_set(&pService->szLprmcommand, "cancel %p-%j");
4514 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4515 string_set(&pService->szQueuepausecommand, "disable %p");
4516 string_set(&pService->szQueueresumecommand, "enable %p");
4517 #ifndef HPUX
4518 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4519 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4520 #endif /* HPUX */
4521 break;
4523 case PRINT_QNX:
4524 string_set(&pService->szLpqcommand, "lpq -P%p");
4525 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4526 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4527 break;
4529 #ifdef DEVELOPER
4530 case PRINT_TEST:
4531 case PRINT_VLP:
4532 string_set(&pService->szPrintcommand, "vlp print %p %s");
4533 string_set(&pService->szLpqcommand, "vlp lpq %p");
4534 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4535 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4536 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4537 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4538 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4539 break;
4540 #endif /* DEVELOPER */
4545 /***************************************************************************
4546 Initialise the global parameter structure.
4547 ***************************************************************************/
4549 static void init_globals(bool first_time_only)
4551 static bool done_init = False;
4552 char *s = NULL;
4553 int i;
4555 /* If requested to initialize only once and we've already done it... */
4556 if (first_time_only && done_init) {
4557 /* ... then we have nothing more to do */
4558 return;
4561 if (!done_init) {
4562 /* The logfile can be set before this is invoked. Free it if so. */
4563 if (Globals.szLogFile != NULL) {
4564 string_free(&Globals.szLogFile);
4565 Globals.szLogFile = NULL;
4567 done_init = True;
4568 } else {
4569 for (i = 0; parm_table[i].label; i++) {
4570 if ((parm_table[i].type == P_STRING ||
4571 parm_table[i].type == P_USTRING) &&
4572 parm_table[i].ptr)
4574 string_free((char **)parm_table[i].ptr);
4579 memset((void *)&Globals, '\0', sizeof(Globals));
4581 for (i = 0; parm_table[i].label; i++) {
4582 if ((parm_table[i].type == P_STRING ||
4583 parm_table[i].type == P_USTRING) &&
4584 parm_table[i].ptr)
4586 string_set((char **)parm_table[i].ptr, "");
4590 string_set(&sDefault.fstype, FSTYPE_STRING);
4591 string_set(&sDefault.szPrintjobUsername, "%U");
4593 init_printer_values(&sDefault);
4596 DEBUG(3, ("Initialising global parameters\n"));
4598 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4599 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4601 /* use the new 'hash2' method by default, with a prefix of 1 */
4602 string_set(&Globals.szManglingMethod, "hash2");
4603 Globals.mangle_prefix = 1;
4605 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4607 /* using UTF8 by default allows us to support all chars */
4608 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4610 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4611 /* If the system supports nl_langinfo(), try to grab the value
4612 from the user's locale */
4613 string_set(&Globals.display_charset, "LOCALE");
4614 #else
4615 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4616 #endif
4618 /* Use codepage 850 as a default for the dos character set */
4619 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4622 * Allow the default PASSWD_CHAT to be overridden in local.h.
4624 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4626 set_global_myname(myhostname());
4627 string_set(&Globals.szNetbiosName,global_myname());
4629 set_global_myworkgroup(WORKGROUP);
4630 string_set(&Globals.szWorkgroup, lp_workgroup());
4632 string_set(&Globals.szPasswdProgram, "");
4633 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4634 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4635 string_set(&Globals.szSocketAddress, "0.0.0.0");
4637 if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
4638 smb_panic("init_globals: ENOMEM");
4640 string_set(&Globals.szServerString, s);
4641 SAFE_FREE(s);
4642 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4643 DEFAULT_MINOR_VERSION) < 0) {
4644 smb_panic("init_globals: ENOMEM");
4646 string_set(&Globals.szAnnounceVersion, s);
4647 SAFE_FREE(s);
4648 #ifdef DEVELOPER
4649 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4650 #endif
4652 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4654 string_set(&Globals.szLogonDrive, "");
4655 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4656 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4657 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4659 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4660 string_set(&Globals.szPasswordServer, "*");
4662 Globals.AlgorithmicRidBase = BASE_RID;
4664 Globals.bLoadPrinters = True;
4665 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4667 Globals.ConfigBackend = config_backend;
4669 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4670 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4671 Globals.max_xmit = 0x4104;
4672 Globals.max_mux = 50; /* This is *needed* for profile support. */
4673 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4674 Globals.bDisableSpoolss = False;
4675 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4676 Globals.pwordlevel = 0;
4677 Globals.unamelevel = 0;
4678 Globals.deadtime = 0;
4679 Globals.getwd_cache = true;
4680 Globals.bLargeReadwrite = True;
4681 Globals.max_log_size = 5000;
4682 Globals.max_open_files = MAX_OPEN_FILES;
4683 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4684 Globals.maxprotocol = PROTOCOL_NT1;
4685 Globals.minprotocol = PROTOCOL_CORE;
4686 Globals.security = SEC_USER;
4687 Globals.paranoid_server_security = True;
4688 Globals.bEncryptPasswords = True;
4689 Globals.bUpdateEncrypt = False;
4690 Globals.clientSchannel = Auto;
4691 Globals.serverSchannel = Auto;
4692 Globals.bReadRaw = True;
4693 Globals.bWriteRaw = True;
4694 Globals.bNullPasswords = False;
4695 Globals.bObeyPamRestrictions = False;
4696 Globals.syslog = 1;
4697 Globals.bSyslogOnly = False;
4698 Globals.bTimestampLogs = True;
4699 string_set(&Globals.szLogLevel, "0");
4700 Globals.bDebugPrefixTimestamp = False;
4701 Globals.bDebugHiresTimestamp = False;
4702 Globals.bDebugPid = False;
4703 Globals.bDebugUid = False;
4704 Globals.bDebugClass = False;
4705 Globals.bEnableCoreFiles = True;
4706 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4707 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4708 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4709 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4710 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4711 Globals.lm_interval = 60;
4712 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4713 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4714 Globals.bNISHomeMap = False;
4715 #ifdef WITH_NISPLUS_HOME
4716 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4717 #else
4718 string_set(&Globals.szNISHomeMapName, "auto.home");
4719 #endif
4720 #endif
4721 Globals.bTimeServer = False;
4722 Globals.bBindInterfacesOnly = False;
4723 Globals.bUnixPasswdSync = False;
4724 Globals.bPamPasswordChange = False;
4725 Globals.bPasswdChatDebug = False;
4726 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4727 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4728 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4729 Globals.bStatCache = True; /* use stat cache by default */
4730 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4731 Globals.restrict_anonymous = 0;
4732 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4733 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4734 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4735 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4736 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4737 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4739 Globals.map_to_guest = 0; /* By Default, "Never" */
4740 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4741 Globals.enhanced_browsing = true;
4742 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4743 #ifdef MMAP_BLACKLIST
4744 Globals.bUseMmap = False;
4745 #else
4746 Globals.bUseMmap = True;
4747 #endif
4748 Globals.bUnixExtensions = True;
4749 Globals.bResetOnZeroVC = False;
4751 /* hostname lookups can be very expensive and are broken on
4752 a large number of sites (tridge) */
4753 Globals.bHostnameLookups = False;
4755 string_set(&Globals.szPassdbBackend, "smbpasswd");
4756 string_set(&Globals.szLdapSuffix, "");
4757 string_set(&Globals.szLdapMachineSuffix, "");
4758 string_set(&Globals.szLdapUserSuffix, "");
4759 string_set(&Globals.szLdapGroupSuffix, "");
4760 string_set(&Globals.szLdapIdmapSuffix, "");
4762 string_set(&Globals.szLdapAdminDn, "");
4763 Globals.ldap_ssl = LDAP_SSL_ON;
4764 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4765 Globals.ldap_delete_dn = False;
4766 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4767 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4768 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4769 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4771 Globals.ldap_debug_level = 0;
4772 Globals.ldap_debug_threshold = 10;
4774 /* This is what we tell the afs client. in reality we set the token
4775 * to never expire, though, when this runs out the afs client will
4776 * forget the token. Set to 0 to get NEVERDATE.*/
4777 Globals.iAfsTokenLifetime = 604800;
4779 /* these parameters are set to defaults that are more appropriate
4780 for the increasing samba install base:
4782 as a member of the workgroup, that will possibly become a
4783 _local_ master browser (lm = True). this is opposed to a forced
4784 local master browser startup (pm = True).
4786 doesn't provide WINS server service by default (wsupp = False),
4787 and doesn't provide domain master browser services by default, either.
4791 Globals.bMsAddPrinterWizard = True;
4792 Globals.os_level = 20;
4793 Globals.bLocalMaster = True;
4794 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4795 Globals.bDomainLogons = False;
4796 Globals.bBrowseList = True;
4797 Globals.bWINSsupport = False;
4798 Globals.bWINSproxy = False;
4800 Globals.bDNSproxy = True;
4802 /* this just means to use them if they exist */
4803 Globals.bKernelOplocks = True;
4805 Globals.bAllowTrustedDomains = True;
4807 string_set(&Globals.szTemplateShell, "/bin/false");
4808 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4809 string_set(&Globals.szWinbindSeparator, "\\");
4811 string_set(&Globals.szCupsServer, "");
4812 string_set(&Globals.szIPrintServer, "");
4814 string_set(&Globals.ctdbdSocket, "");
4815 Globals.szClusterAddresses = NULL;
4816 Globals.clustering = False;
4818 Globals.winbind_cache_time = 300; /* 5 minutes */
4819 Globals.bWinbindEnumUsers = False;
4820 Globals.bWinbindEnumGroups = False;
4821 Globals.bWinbindUseDefaultDomain = False;
4822 Globals.bWinbindTrustedDomainsOnly = False;
4823 Globals.bWinbindNestedGroups = True;
4824 Globals.winbind_expand_groups = 1;
4825 Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
4826 Globals.bWinbindRefreshTickets = False;
4827 Globals.bWinbindOfflineLogon = False;
4829 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
4830 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4832 Globals.bPassdbExpandExplicit = False;
4834 Globals.name_cache_timeout = 660; /* In seconds */
4836 Globals.bUseSpnego = True;
4837 Globals.bClientUseSpnego = True;
4839 Globals.client_signing = Auto;
4840 Globals.server_signing = False;
4842 Globals.bDeferSharingViolations = True;
4843 string_set(&Globals.smb_ports, SMB_PORTS);
4845 Globals.bEnablePrivileges = True;
4846 Globals.bHostMSDfs = True;
4847 Globals.bASUSupport = False;
4849 /* User defined shares. */
4850 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4851 smb_panic("init_globals: ENOMEM");
4853 string_set(&Globals.szUsersharePath, s);
4854 SAFE_FREE(s);
4855 string_set(&Globals.szUsershareTemplateShare, "");
4856 Globals.iUsershareMaxShares = 0;
4857 /* By default disallow sharing of directories not owned by the sharer. */
4858 Globals.bUsershareOwnerOnly = True;
4859 /* By default disallow guest access to usershares. */
4860 Globals.bUsershareAllowGuests = False;
4862 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4864 /* By default no shares out of the registry */
4865 Globals.bRegistryShares = False;
4867 Globals.iminreceivefile = 0;
4870 /*******************************************************************
4871 Convenience routine to grab string parameters into temporary memory
4872 and run standard_sub_basic on them. The buffers can be written to by
4873 callers without affecting the source string.
4874 ********************************************************************/
4876 static char *lp_string(const char *s)
4878 char *ret;
4879 TALLOC_CTX *ctx = talloc_tos();
4881 /* The follow debug is useful for tracking down memory problems
4882 especially if you have an inner loop that is calling a lp_*()
4883 function that returns a string. Perhaps this debug should be
4884 present all the time? */
4886 #if 0
4887 DEBUG(10, ("lp_string(%s)\n", s));
4888 #endif
4890 ret = talloc_sub_basic(ctx,
4891 get_current_username(),
4892 current_user_info.domain,
4894 if (trim_char(ret, '\"', '\"')) {
4895 if (strchr(ret,'\"') != NULL) {
4896 TALLOC_FREE(ret);
4897 ret = talloc_sub_basic(ctx,
4898 get_current_username(),
4899 current_user_info.domain,
4903 return ret;
4907 In this section all the functions that are used to access the
4908 parameters from the rest of the program are defined
4911 #define FN_GLOBAL_STRING(fn_name,ptr) \
4912 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4913 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4914 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4915 #define FN_GLOBAL_LIST(fn_name,ptr) \
4916 const char **fn_name(void) {return(*(const char ***)(ptr));}
4917 #define FN_GLOBAL_BOOL(fn_name,ptr) \
4918 bool fn_name(void) {return(*(bool *)(ptr));}
4919 #define FN_GLOBAL_CHAR(fn_name,ptr) \
4920 char fn_name(void) {return(*(char *)(ptr));}
4921 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
4922 int fn_name(void) {return(*(int *)(ptr));}
4924 #define FN_LOCAL_STRING(fn_name,val) \
4925 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
4926 #define FN_LOCAL_CONST_STRING(fn_name,val) \
4927 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
4928 #define FN_LOCAL_LIST(fn_name,val) \
4929 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4930 #define FN_LOCAL_BOOL(fn_name,val) \
4931 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4932 #define FN_LOCAL_INTEGER(fn_name,val) \
4933 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4935 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
4936 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4937 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
4938 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4939 #define FN_LOCAL_PARM_STRING(fn_name,val) \
4940 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));}
4941 #define FN_LOCAL_CHAR(fn_name,val) \
4942 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4944 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
4945 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
4946 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
4947 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
4948 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
4949 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
4950 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
4951 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
4952 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
4953 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
4954 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
4955 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
4956 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
4957 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
4958 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
4959 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
4960 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
4961 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
4962 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
4963 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
4964 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
4965 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
4966 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
4967 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
4968 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
4969 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
4970 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
4971 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
4972 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
4973 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
4974 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
4975 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
4976 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
4977 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
4978 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
4979 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
4980 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
4981 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
4982 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
4983 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
4984 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
4985 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
4986 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
4987 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
4988 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
4989 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
4990 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
4991 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
4992 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
4993 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
4994 * lp_passdb_backend() should be replace by the this macro again after
4995 * some releases.
4996 * */
4997 const char *lp_passdb_backend(void)
4999 char *delim, *quote;
5001 delim = strchr( Globals.szPassdbBackend, ' ');
5002 /* no space at all */
5003 if (delim == NULL) {
5004 goto out;
5007 quote = strchr(Globals.szPassdbBackend, '"');
5008 /* no quote char or non in the first part */
5009 if (quote == NULL || quote > delim) {
5010 *delim = '\0';
5011 goto warn;
5014 quote = strchr(quote+1, '"');
5015 if (quote == NULL) {
5016 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5017 goto out;
5018 } else if (*(quote+1) == '\0') {
5019 /* space, fitting quote char, and one backend only */
5020 goto out;
5021 } else {
5022 /* terminate string after the fitting quote char */
5023 *(quote+1) = '\0';
5026 warn:
5027 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5028 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5029 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5030 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5032 out:
5033 return Globals.szPassdbBackend;
5035 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5036 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5037 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5038 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5039 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5041 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5042 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5043 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5044 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5045 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5046 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5048 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5050 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5051 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5052 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5054 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5056 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5057 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5058 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5059 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5060 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5061 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5062 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5063 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5064 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5065 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5066 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5067 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5068 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5069 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5070 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5072 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
5073 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
5074 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5075 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5076 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5077 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5078 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5080 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5081 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5082 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5083 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5084 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5085 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5086 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5087 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5088 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5089 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5090 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5091 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5092 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5093 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5094 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5095 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5096 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5098 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5100 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5101 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5102 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5103 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5104 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5105 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5106 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5107 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5108 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5109 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5110 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5111 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5112 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5113 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5114 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5115 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5116 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5117 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5118 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5119 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5120 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5121 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5122 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5123 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5124 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5125 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5126 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5127 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5128 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5129 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5130 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5131 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5132 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5133 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5134 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5135 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5136 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5137 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5138 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5139 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5140 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5141 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5142 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5143 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5144 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5145 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5146 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5147 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5148 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5149 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5150 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5151 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5152 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5153 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5154 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5155 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5156 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5157 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5158 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5159 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5160 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5161 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5162 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5163 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5164 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5165 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5166 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5167 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5168 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5169 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5170 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5171 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5172 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5173 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5174 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5175 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5176 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5177 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5178 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5179 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5180 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5181 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5182 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5183 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5184 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5185 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5186 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5187 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5188 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5189 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5190 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5191 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5192 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5193 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5194 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5195 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5197 FN_LOCAL_STRING(lp_preexec, szPreExec)
5198 FN_LOCAL_STRING(lp_postexec, szPostExec)
5199 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5200 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5201 FN_LOCAL_STRING(lp_servicename, szService)
5202 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5203 FN_LOCAL_STRING(lp_pathname, szPath)
5204 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5205 FN_LOCAL_STRING(lp_username, szUsername)
5206 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5207 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5208 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5209 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5210 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5211 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5212 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5213 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5214 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5215 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5216 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5217 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5218 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5219 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5220 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5221 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5222 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5223 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5224 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5225 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5226 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5227 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5228 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5229 FN_LOCAL_STRING(lp_comment, comment)
5230 FN_LOCAL_STRING(lp_force_user, force_user)
5231 FN_LOCAL_STRING(lp_force_group, force_group)
5232 FN_LOCAL_LIST(lp_readlist, readlist)
5233 FN_LOCAL_LIST(lp_writelist, writelist)
5234 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5235 FN_LOCAL_STRING(lp_fstype, fstype)
5236 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5237 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5238 static FN_LOCAL_STRING(lp_volume, volume)
5239 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5240 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5241 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5242 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5243 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5244 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5245 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5246 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5247 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5248 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5249 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5250 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5251 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5252 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5253 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5254 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5255 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5256 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5257 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5258 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5259 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5260 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5261 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5262 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5263 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5264 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5265 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5266 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5267 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5268 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5269 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5270 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5271 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5272 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5273 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5274 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5275 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5276 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5277 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5278 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5279 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5280 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5281 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5282 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5283 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5284 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5285 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5286 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5287 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5288 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5289 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5290 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5291 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5292 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5293 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5294 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5295 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5296 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5297 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5298 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5299 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5300 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5301 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5302 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5303 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5304 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5305 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5306 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5307 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5308 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5309 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5310 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5311 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5312 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5313 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5314 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5315 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5316 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5317 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5318 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5319 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5320 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5321 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5322 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5323 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5324 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5325 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5326 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5327 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5328 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5329 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5330 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5331 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5332 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5333 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5334 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5335 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5337 /* local prototypes */
5339 static int map_parameter(const char *pszParmName);
5340 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5341 static bool set_boolean(bool *pb, const char *pszParmValue);
5342 static const char *get_boolean(bool bool_value);
5343 static int getservicebyname(const char *pszServiceName,
5344 struct service *pserviceDest);
5345 static void copy_service(struct service *pserviceDest,
5346 struct service *pserviceSource,
5347 struct bitmap *pcopymapDest);
5348 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5349 void *userdata);
5350 static bool do_section(const char *pszSectionName, void *userdata);
5351 static void init_copymap(struct service *pservice);
5352 static bool hash_a_service(const char *name, int number);
5353 static void free_service_byindex(int iService);
5354 static char * canonicalize_servicename(const char *name);
5355 static void show_parameter(int parmIndex);
5356 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5359 * This is a helper function for parametrical options support. It returns a
5360 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5361 * parametrical functions are quite simple
5363 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5364 const char *option)
5366 bool global_section = False;
5367 char* param_key;
5368 struct param_opt_struct *data;
5370 if (snum >= iNumServices) return NULL;
5372 if (snum < 0) {
5373 data = Globals.param_opt;
5374 global_section = True;
5375 } else {
5376 data = ServicePtrs[snum]->param_opt;
5379 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5380 DEBUG(0,("asprintf failed!\n"));
5381 return NULL;
5384 while (data) {
5385 if (strwicmp(data->key, param_key) == 0) {
5386 string_free(&param_key);
5387 return data;
5389 data = data->next;
5392 if (!global_section) {
5393 /* Try to fetch the same option but from globals */
5394 /* but only if we are not already working with Globals */
5395 data = Globals.param_opt;
5396 while (data) {
5397 if (strwicmp(data->key, param_key) == 0) {
5398 string_free(&param_key);
5399 return data;
5401 data = data->next;
5405 string_free(&param_key);
5407 return NULL;
5411 #define MISSING_PARAMETER(name) \
5412 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5414 /*******************************************************************
5415 convenience routine to return int parameters.
5416 ********************************************************************/
5417 static int lp_int(const char *s)
5420 if (!s || !*s) {
5421 MISSING_PARAMETER(lp_int);
5422 return (-1);
5425 return (int)strtol(s, NULL, 0);
5428 /*******************************************************************
5429 convenience routine to return unsigned long parameters.
5430 ********************************************************************/
5431 static unsigned long lp_ulong(const char *s)
5434 if (!s || !*s) {
5435 MISSING_PARAMETER(lp_ulong);
5436 return (0);
5439 return strtoul(s, NULL, 0);
5442 /*******************************************************************
5443 convenience routine to return boolean parameters.
5444 ********************************************************************/
5445 static bool lp_bool(const char *s)
5447 bool ret = False;
5449 if (!s || !*s) {
5450 MISSING_PARAMETER(lp_bool);
5451 return False;
5454 if (!set_boolean(&ret,s)) {
5455 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5456 return False;
5459 return ret;
5462 /*******************************************************************
5463 convenience routine to return enum parameters.
5464 ********************************************************************/
5465 static int lp_enum(const char *s,const struct enum_list *_enum)
5467 int i;
5469 if (!s || !*s || !_enum) {
5470 MISSING_PARAMETER(lp_enum);
5471 return (-1);
5474 for (i=0; _enum[i].name; i++) {
5475 if (strequal(_enum[i].name,s))
5476 return _enum[i].value;
5479 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5480 return (-1);
5483 #undef MISSING_PARAMETER
5485 /* DO NOT USE lp_parm_string ANYMORE!!!!
5486 * use lp_parm_const_string or lp_parm_talloc_string
5488 * lp_parm_string is only used to let old modules find this symbol
5490 #undef lp_parm_string
5491 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5492 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5494 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5497 /* Return parametric option from a given service. Type is a part of option before ':' */
5498 /* Parametric option has following syntax: 'Type: option = value' */
5499 /* the returned value is talloced on the talloc_tos() */
5500 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5502 struct param_opt_struct *data = get_parametrics(snum, type, option);
5504 if (data == NULL||data->value==NULL) {
5505 if (def) {
5506 return lp_string(def);
5507 } else {
5508 return NULL;
5512 return lp_string(data->value);
5515 /* Return parametric option from a given service. Type is a part of option before ':' */
5516 /* Parametric option has following syntax: 'Type: option = value' */
5517 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5519 struct param_opt_struct *data = get_parametrics(snum, type, option);
5521 if (data == NULL||data->value==NULL)
5522 return def;
5524 return data->value;
5527 /* Return parametric option from a given service. Type is a part of option before ':' */
5528 /* Parametric option has following syntax: 'Type: option = value' */
5530 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5532 struct param_opt_struct *data = get_parametrics(snum, type, option);
5534 if (data == NULL||data->value==NULL)
5535 return (const char **)def;
5537 if (data->list==NULL) {
5538 data->list = str_list_make(NULL, data->value, NULL);
5541 return (const char **)data->list;
5544 /* Return parametric option from a given service. Type is a part of option before ':' */
5545 /* Parametric option has following syntax: 'Type: option = value' */
5547 int lp_parm_int(int snum, const char *type, const char *option, int def)
5549 struct param_opt_struct *data = get_parametrics(snum, type, option);
5551 if (data && data->value && *data->value)
5552 return lp_int(data->value);
5554 return def;
5557 /* Return parametric option from a given service. Type is a part of option before ':' */
5558 /* Parametric option has following syntax: 'Type: option = value' */
5560 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5562 struct param_opt_struct *data = get_parametrics(snum, type, option);
5564 if (data && data->value && *data->value)
5565 return lp_ulong(data->value);
5567 return def;
5570 /* Return parametric option from a given service. Type is a part of option before ':' */
5571 /* Parametric option has following syntax: 'Type: option = value' */
5573 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5575 struct param_opt_struct *data = get_parametrics(snum, type, option);
5577 if (data && data->value && *data->value)
5578 return lp_bool(data->value);
5580 return def;
5583 /* Return parametric option from a given service. Type is a part of option before ':' */
5584 /* Parametric option has following syntax: 'Type: option = value' */
5586 int lp_parm_enum(int snum, const char *type, const char *option,
5587 const struct enum_list *_enum, int def)
5589 struct param_opt_struct *data = get_parametrics(snum, type, option);
5591 if (data && data->value && *data->value && _enum)
5592 return lp_enum(data->value, _enum);
5594 return def;
5598 /***************************************************************************
5599 Initialise a service to the defaults.
5600 ***************************************************************************/
5602 static void init_service(struct service *pservice)
5604 memset((char *)pservice, '\0', sizeof(struct service));
5605 copy_service(pservice, &sDefault, NULL);
5608 /***************************************************************************
5609 Free the dynamically allocated parts of a service struct.
5610 ***************************************************************************/
5612 static void free_service(struct service *pservice)
5614 int i;
5615 struct param_opt_struct *data, *pdata;
5616 if (!pservice)
5617 return;
5619 if (pservice->szService)
5620 DEBUG(5, ("free_service: Freeing service %s\n",
5621 pservice->szService));
5623 string_free(&pservice->szService);
5624 bitmap_free(pservice->copymap);
5626 for (i = 0; parm_table[i].label; i++) {
5627 if ((parm_table[i].type == P_STRING ||
5628 parm_table[i].type == P_USTRING) &&
5629 parm_table[i].p_class == P_LOCAL)
5630 string_free((char **)
5631 (((char *)pservice) +
5632 PTR_DIFF(parm_table[i].ptr, &sDefault)));
5633 else if (parm_table[i].type == P_LIST &&
5634 parm_table[i].p_class == P_LOCAL)
5635 TALLOC_FREE(*((char ***)
5636 (((char *)pservice) +
5637 PTR_DIFF(parm_table[i].ptr,
5638 &sDefault))));
5641 data = pservice->param_opt;
5642 if (data)
5643 DEBUG(5,("Freeing parametrics:\n"));
5644 while (data) {
5645 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5646 string_free(&data->key);
5647 string_free(&data->value);
5648 TALLOC_FREE(data->list);
5649 pdata = data->next;
5650 SAFE_FREE(data);
5651 data = pdata;
5654 ZERO_STRUCTP(pservice);
5658 /***************************************************************************
5659 remove a service indexed in the ServicePtrs array from the ServiceHash
5660 and free the dynamically allocated parts
5661 ***************************************************************************/
5663 static void free_service_byindex(int idx)
5665 if ( !LP_SNUM_OK(idx) )
5666 return;
5668 ServicePtrs[idx]->valid = False;
5669 invalid_services[num_invalid_services++] = idx;
5671 /* we have to cleanup the hash record */
5673 if (ServicePtrs[idx]->szService) {
5674 char *canon_name = canonicalize_servicename(
5675 ServicePtrs[idx]->szService );
5677 dbwrap_delete_bystring(ServiceHash, canon_name );
5678 TALLOC_FREE(canon_name);
5681 free_service(ServicePtrs[idx]);
5684 /***************************************************************************
5685 Add a new service to the services array initialising it with the given
5686 service.
5687 ***************************************************************************/
5689 static int add_a_service(const struct service *pservice, const char *name)
5691 int i;
5692 struct service tservice;
5693 int num_to_alloc = iNumServices + 1;
5694 struct param_opt_struct *data, *pdata;
5696 tservice = *pservice;
5698 /* it might already exist */
5699 if (name) {
5700 i = getservicebyname(name, NULL);
5701 if (i >= 0) {
5702 /* Clean all parametric options for service */
5703 /* They will be added during parsing again */
5704 data = ServicePtrs[i]->param_opt;
5705 while (data) {
5706 string_free(&data->key);
5707 string_free(&data->value);
5708 TALLOC_FREE(data->list);
5709 pdata = data->next;
5710 SAFE_FREE(data);
5711 data = pdata;
5713 ServicePtrs[i]->param_opt = NULL;
5714 return (i);
5718 /* find an invalid one */
5719 i = iNumServices;
5720 if (num_invalid_services > 0) {
5721 i = invalid_services[--num_invalid_services];
5724 /* if not, then create one */
5725 if (i == iNumServices) {
5726 struct service **tsp;
5727 int *tinvalid;
5729 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5730 if (tsp == NULL) {
5731 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5732 return (-1);
5734 ServicePtrs = tsp;
5735 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5736 if (!ServicePtrs[iNumServices]) {
5737 DEBUG(0,("add_a_service: out of memory!\n"));
5738 return (-1);
5740 iNumServices++;
5742 /* enlarge invalid_services here for now... */
5743 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5744 num_to_alloc);
5745 if (tinvalid == NULL) {
5746 DEBUG(0,("add_a_service: failed to enlarge "
5747 "invalid_services!\n"));
5748 return (-1);
5750 invalid_services = tinvalid;
5751 } else {
5752 free_service_byindex(i);
5755 ServicePtrs[i]->valid = True;
5757 init_service(ServicePtrs[i]);
5758 copy_service(ServicePtrs[i], &tservice, NULL);
5759 if (name)
5760 string_set(&ServicePtrs[i]->szService, name);
5762 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5763 i, ServicePtrs[i]->szService));
5765 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5766 return (-1);
5769 return (i);
5772 /***************************************************************************
5773 Convert a string to uppercase and remove whitespaces.
5774 ***************************************************************************/
5776 static char *canonicalize_servicename(const char *src)
5778 char *result;
5780 if ( !src ) {
5781 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5782 return NULL;
5785 result = talloc_strdup(talloc_tos(), src);
5786 SMB_ASSERT(result != NULL);
5788 strlower_m(result);
5789 return result;
5792 /***************************************************************************
5793 Add a name/index pair for the services array to the hash table.
5794 ***************************************************************************/
5796 static bool hash_a_service(const char *name, int idx)
5798 char *canon_name;
5800 if ( !ServiceHash ) {
5801 DEBUG(10,("hash_a_service: creating servicehash\n"));
5802 ServiceHash = db_open_rbt(NULL);
5803 if ( !ServiceHash ) {
5804 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5805 return False;
5809 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5810 idx, name));
5812 canon_name = canonicalize_servicename( name );
5814 dbwrap_store_bystring(ServiceHash, canon_name,
5815 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5816 TDB_REPLACE);
5818 TALLOC_FREE(canon_name);
5820 return True;
5823 /***************************************************************************
5824 Add a new home service, with the specified home directory, defaults coming
5825 from service ifrom.
5826 ***************************************************************************/
5828 bool lp_add_home(const char *pszHomename, int iDefaultService,
5829 const char *user, const char *pszHomedir)
5831 int i;
5833 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5835 if (i < 0)
5836 return (False);
5838 if (!(*(ServicePtrs[iDefaultService]->szPath))
5839 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5840 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5843 if (!(*(ServicePtrs[i]->comment))) {
5844 char *comment = NULL;
5845 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5846 return false;
5848 string_set(&ServicePtrs[i]->comment, comment);
5849 SAFE_FREE(comment);
5852 /* set the browseable flag from the global default */
5854 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5856 ServicePtrs[i]->autoloaded = True;
5858 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5859 user, ServicePtrs[i]->szPath ));
5861 return (True);
5864 /***************************************************************************
5865 Add a new service, based on an old one.
5866 ***************************************************************************/
5868 int lp_add_service(const char *pszService, int iDefaultService)
5870 if (iDefaultService < 0) {
5871 return add_a_service(&sDefault, pszService);
5874 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5877 /***************************************************************************
5878 Add the IPC service.
5879 ***************************************************************************/
5881 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5883 char *comment = NULL;
5884 int i = add_a_service(&sDefault, ipc_name);
5886 if (i < 0)
5887 return (False);
5889 if (asprintf(&comment, "IPC Service (%s)",
5890 Globals.szServerString) < 0) {
5891 return (False);
5894 string_set(&ServicePtrs[i]->szPath, tmpdir());
5895 string_set(&ServicePtrs[i]->szUsername, "");
5896 string_set(&ServicePtrs[i]->comment, comment);
5897 string_set(&ServicePtrs[i]->fstype, "IPC");
5898 ServicePtrs[i]->iMaxConnections = 0;
5899 ServicePtrs[i]->bAvailable = True;
5900 ServicePtrs[i]->bRead_only = True;
5901 ServicePtrs[i]->bGuest_only = False;
5902 ServicePtrs[i]->bAdministrative_share = True;
5903 ServicePtrs[i]->bGuest_ok = guest_ok;
5904 ServicePtrs[i]->bPrint_ok = False;
5905 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5907 DEBUG(3, ("adding IPC service\n"));
5909 SAFE_FREE(comment);
5910 return (True);
5913 /***************************************************************************
5914 Add a new printer service, with defaults coming from service iFrom.
5915 ***************************************************************************/
5917 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5919 const char *comment = "From Printcap";
5920 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5922 if (i < 0)
5923 return (False);
5925 /* note that we do NOT default the availability flag to True - */
5926 /* we take it from the default service passed. This allows all */
5927 /* dynamic printers to be disabled by disabling the [printers] */
5928 /* entry (if/when the 'available' keyword is implemented!). */
5930 /* the printer name is set to the service name. */
5931 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5932 string_set(&ServicePtrs[i]->comment, comment);
5934 /* set the browseable flag from the gloabl default */
5935 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5937 /* Printers cannot be read_only. */
5938 ServicePtrs[i]->bRead_only = False;
5939 /* No share modes on printer services. */
5940 ServicePtrs[i]->bShareModes = False;
5941 /* No oplocks on printer services. */
5942 ServicePtrs[i]->bOpLocks = False;
5943 /* Printer services must be printable. */
5944 ServicePtrs[i]->bPrint_ok = True;
5946 DEBUG(3, ("adding printer service %s\n", pszPrintername));
5948 return (True);
5952 /***************************************************************************
5953 Check whether the given parameter name is valid.
5954 Parametric options (names containing a colon) are considered valid.
5955 ***************************************************************************/
5957 bool lp_parameter_is_valid(const char *pszParmName)
5959 return ((map_parameter(pszParmName) != -1) ||
5960 (strchr(pszParmName, ':') != NULL));
5963 /***************************************************************************
5964 Check whether the given name is the name of a global parameter.
5965 Returns True for strings belonging to parameters of class
5966 P_GLOBAL, False for all other strings, also for parametric options
5967 and strings not belonging to any option.
5968 ***************************************************************************/
5970 bool lp_parameter_is_global(const char *pszParmName)
5972 int num = map_parameter(pszParmName);
5974 if (num >= 0) {
5975 return (parm_table[num].p_class == P_GLOBAL);
5978 return False;
5981 /**************************************************************************
5982 Check whether the given name is the canonical name of a parameter.
5983 Returns False if it is not a valid parameter Name.
5984 For parametric options, True is returned.
5985 **************************************************************************/
5987 bool lp_parameter_is_canonical(const char *parm_name)
5989 if (!lp_parameter_is_valid(parm_name)) {
5990 return False;
5993 return (map_parameter(parm_name) ==
5994 map_parameter_canonical(parm_name, NULL));
5997 /**************************************************************************
5998 Determine the canonical name for a parameter.
5999 Indicate when it is an inverse (boolean) synonym instead of a
6000 "usual" synonym.
6001 **************************************************************************/
6003 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6004 bool *inverse)
6006 int num;
6008 if (!lp_parameter_is_valid(parm_name)) {
6009 *canon_parm = NULL;
6010 return False;
6013 num = map_parameter_canonical(parm_name, inverse);
6014 if (num < 0) {
6015 /* parametric option */
6016 *canon_parm = parm_name;
6017 } else {
6018 *canon_parm = parm_table[num].label;
6021 return True;
6025 /**************************************************************************
6026 Determine the canonical name for a parameter.
6027 Turn the value given into the inverse boolean expression when
6028 the synonym is an invers boolean synonym.
6030 Return True if parm_name is a valid parameter name and
6031 in case it is an invers boolean synonym, if the val string could
6032 successfully be converted to the reverse bool.
6033 Return false in all other cases.
6034 **************************************************************************/
6036 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6037 const char *val,
6038 const char **canon_parm,
6039 const char **canon_val)
6041 int num;
6042 bool inverse;
6044 if (!lp_parameter_is_valid(parm_name)) {
6045 *canon_parm = NULL;
6046 *canon_val = NULL;
6047 return False;
6050 num = map_parameter_canonical(parm_name, &inverse);
6051 if (num < 0) {
6052 /* parametric option */
6053 *canon_parm = parm_name;
6054 *canon_val = val;
6055 } else {
6056 *canon_parm = parm_table[num].label;
6057 if (inverse) {
6058 if (!lp_invert_boolean(val, canon_val)) {
6059 *canon_val = NULL;
6060 return False;
6062 } else {
6063 *canon_val = val;
6067 return True;
6070 /***************************************************************************
6071 Map a parameter's string representation to something we can use.
6072 Returns False if the parameter string is not recognised, else TRUE.
6073 ***************************************************************************/
6075 static int map_parameter(const char *pszParmName)
6077 int iIndex;
6079 if (*pszParmName == '-')
6080 return (-1);
6082 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6083 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6084 return (iIndex);
6086 /* Warn only if it isn't parametric option */
6087 if (strchr(pszParmName, ':') == NULL)
6088 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6089 /* We do return 'fail' for parametric options as well because they are
6090 stored in different storage
6092 return (-1);
6095 /***************************************************************************
6096 Map a parameter's string representation to the index of the canonical
6097 form of the parameter (it might be a synonym).
6098 Returns -1 if the parameter string is not recognised.
6099 ***************************************************************************/
6101 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6103 int parm_num, canon_num;
6104 bool loc_inverse = False;
6106 parm_num = map_parameter(pszParmName);
6107 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6108 /* invalid, parametric or no canidate for synonyms ... */
6109 goto done;
6112 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6113 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6114 parm_num = canon_num;
6115 goto done;
6119 done:
6120 if (inverse != NULL) {
6121 *inverse = loc_inverse;
6123 return parm_num;
6126 /***************************************************************************
6127 return true if parameter number parm1 is a synonym of parameter
6128 number parm2 (parm2 being the principal name).
6129 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6130 False otherwise.
6131 ***************************************************************************/
6133 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6135 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6136 (parm_table[parm1].flags & FLAG_HIDE) &&
6137 !(parm_table[parm2].flags & FLAG_HIDE))
6139 if (inverse != NULL) {
6140 if ((parm_table[parm1].type == P_BOOLREV) &&
6141 (parm_table[parm2].type == P_BOOL))
6143 *inverse = True;
6144 } else {
6145 *inverse = False;
6148 return True;
6150 return False;
6153 /***************************************************************************
6154 Show one parameter's name, type, [values,] and flags.
6155 (helper functions for show_parameter_list)
6156 ***************************************************************************/
6158 static void show_parameter(int parmIndex)
6160 int enumIndex, flagIndex;
6161 int parmIndex2;
6162 bool hadFlag;
6163 bool hadSyn;
6164 bool inverse;
6165 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6166 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6167 "P_ENUM", "P_SEP"};
6168 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6169 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6170 FLAG_HIDE, FLAG_DOS_STRING};
6171 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6172 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6173 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6175 printf("%s=%s", parm_table[parmIndex].label,
6176 type[parm_table[parmIndex].type]);
6177 if (parm_table[parmIndex].type == P_ENUM) {
6178 printf(",");
6179 for (enumIndex=0;
6180 parm_table[parmIndex].enum_list[enumIndex].name;
6181 enumIndex++)
6183 printf("%s%s",
6184 enumIndex ? "|" : "",
6185 parm_table[parmIndex].enum_list[enumIndex].name);
6188 printf(",");
6189 hadFlag = False;
6190 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6191 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6192 printf("%s%s",
6193 hadFlag ? "|" : "",
6194 flag_names[flagIndex]);
6195 hadFlag = True;
6199 /* output synonyms */
6200 hadSyn = False;
6201 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6202 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6203 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6204 parm_table[parmIndex2].label);
6205 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6206 if (!hadSyn) {
6207 printf(" (synonyms: ");
6208 hadSyn = True;
6209 } else {
6210 printf(", ");
6212 printf("%s%s", parm_table[parmIndex2].label,
6213 inverse ? "[i]" : "");
6216 if (hadSyn) {
6217 printf(")");
6220 printf("\n");
6223 /***************************************************************************
6224 Show all parameter's name, type, [values,] and flags.
6225 ***************************************************************************/
6227 void show_parameter_list(void)
6229 int classIndex, parmIndex;
6230 const char *section_names[] = { "local", "global", NULL};
6232 for (classIndex=0; section_names[classIndex]; classIndex++) {
6233 printf("[%s]\n", section_names[classIndex]);
6234 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6235 if (parm_table[parmIndex].p_class == classIndex) {
6236 show_parameter(parmIndex);
6242 /***************************************************************************
6243 Set a boolean variable from the text value stored in the passed string.
6244 Returns True in success, False if the passed string does not correctly
6245 represent a boolean.
6246 ***************************************************************************/
6248 static bool set_boolean(bool *pb, const char *pszParmValue)
6250 bool bRetval;
6251 bool value;
6253 bRetval = True;
6254 value = False;
6255 if (strwicmp(pszParmValue, "yes") == 0 ||
6256 strwicmp(pszParmValue, "true") == 0 ||
6257 strwicmp(pszParmValue, "1") == 0)
6258 value = True;
6259 else if (strwicmp(pszParmValue, "no") == 0 ||
6260 strwicmp(pszParmValue, "False") == 0 ||
6261 strwicmp(pszParmValue, "0") == 0)
6262 value = False;
6263 else {
6264 DEBUG(2,
6265 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6266 pszParmValue));
6267 bRetval = False;
6270 if ((pb != NULL) && (bRetval != False)) {
6271 *pb = value;
6274 return (bRetval);
6278 /***************************************************************************
6279 Check if a given string correctly represents a boolean value.
6280 ***************************************************************************/
6282 bool lp_string_is_valid_boolean(const char *parm_value)
6284 return set_boolean(NULL, parm_value);
6287 /***************************************************************************
6288 Get the standard string representation of a boolean value ("yes" or "no")
6289 ***************************************************************************/
6291 static const char *get_boolean(bool bool_value)
6293 static const char *yes_str = "yes";
6294 static const char *no_str = "no";
6296 return (bool_value ? yes_str : no_str);
6299 /***************************************************************************
6300 Provide the string of the negated boolean value associated to the boolean
6301 given as a string. Returns False if the passed string does not correctly
6302 represent a boolean.
6303 ***************************************************************************/
6305 bool lp_invert_boolean(const char *str, const char **inverse_str)
6307 bool val;
6309 if (!set_boolean(&val, str)) {
6310 return False;
6313 *inverse_str = get_boolean(!val);
6314 return True;
6317 /***************************************************************************
6318 Provide the canonical string representation of a boolean value given
6319 as a string. Return True on success, False if the string given does
6320 not correctly represent a boolean.
6321 ***************************************************************************/
6323 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6325 bool val;
6327 if (!set_boolean(&val, str)) {
6328 return False;
6331 *canon_str = get_boolean(val);
6332 return True;
6335 /***************************************************************************
6336 Find a service by name. Otherwise works like get_service.
6337 ***************************************************************************/
6339 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6341 int iService = -1;
6342 char *canon_name;
6343 TDB_DATA data;
6345 if (ServiceHash == NULL) {
6346 return -1;
6349 canon_name = canonicalize_servicename(pszServiceName);
6351 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6353 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6354 iService = *(int *)data.dptr;
6357 TALLOC_FREE(canon_name);
6359 if ((iService != -1) && (LP_SNUM_OK(iService))
6360 && (pserviceDest != NULL)) {
6361 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6364 return (iService);
6367 /***************************************************************************
6368 Copy a service structure to another.
6369 If pcopymapDest is NULL then copy all fields
6370 ***************************************************************************/
6372 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6373 struct bitmap *pcopymapDest)
6375 int i;
6376 bool bcopyall = (pcopymapDest == NULL);
6377 struct param_opt_struct *data, *pdata, *paramo;
6378 bool not_added;
6380 for (i = 0; parm_table[i].label; i++)
6381 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6382 (bcopyall || bitmap_query(pcopymapDest,i))) {
6383 void *def_ptr = parm_table[i].ptr;
6384 void *src_ptr =
6385 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6386 &sDefault);
6387 void *dest_ptr =
6388 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6389 &sDefault);
6391 switch (parm_table[i].type) {
6392 case P_BOOL:
6393 case P_BOOLREV:
6394 *(bool *)dest_ptr = *(bool *)src_ptr;
6395 break;
6397 case P_INTEGER:
6398 case P_ENUM:
6399 case P_OCTAL:
6400 *(int *)dest_ptr = *(int *)src_ptr;
6401 break;
6403 case P_CHAR:
6404 *(char *)dest_ptr = *(char *)src_ptr;
6405 break;
6407 case P_STRING:
6408 string_set((char **)dest_ptr,
6409 *(char **)src_ptr);
6410 break;
6412 case P_USTRING:
6413 string_set((char **)dest_ptr,
6414 *(char **)src_ptr);
6415 strupper_m(*(char **)dest_ptr);
6416 break;
6417 case P_LIST:
6418 TALLOC_FREE(*((char ***)dest_ptr));
6419 str_list_copy(NULL, (char ***)dest_ptr,
6420 *(const char ***)src_ptr);
6421 break;
6422 default:
6423 break;
6427 if (bcopyall) {
6428 init_copymap(pserviceDest);
6429 if (pserviceSource->copymap)
6430 bitmap_copy(pserviceDest->copymap,
6431 pserviceSource->copymap);
6434 data = pserviceSource->param_opt;
6435 while (data) {
6436 not_added = True;
6437 pdata = pserviceDest->param_opt;
6438 /* Traverse destination */
6439 while (pdata) {
6440 /* If we already have same option, override it */
6441 if (strwicmp(pdata->key, data->key) == 0) {
6442 string_free(&pdata->value);
6443 TALLOC_FREE(data->list);
6444 pdata->value = SMB_STRDUP(data->value);
6445 not_added = False;
6446 break;
6448 pdata = pdata->next;
6450 if (not_added) {
6451 paramo = SMB_XMALLOC_P(struct param_opt_struct);
6452 paramo->key = SMB_STRDUP(data->key);
6453 paramo->value = SMB_STRDUP(data->value);
6454 paramo->list = NULL;
6455 DLIST_ADD(pserviceDest->param_opt, paramo);
6457 data = data->next;
6461 /***************************************************************************
6462 Check a service for consistency. Return False if the service is in any way
6463 incomplete or faulty, else True.
6464 ***************************************************************************/
6466 bool service_ok(int iService)
6468 bool bRetval;
6470 bRetval = True;
6471 if (ServicePtrs[iService]->szService[0] == '\0') {
6472 DEBUG(0, ("The following message indicates an internal error:\n"));
6473 DEBUG(0, ("No service name in service entry.\n"));
6474 bRetval = False;
6477 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6478 /* I can't see why you'd want a non-printable printer service... */
6479 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6480 if (!ServicePtrs[iService]->bPrint_ok) {
6481 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6482 ServicePtrs[iService]->szService));
6483 ServicePtrs[iService]->bPrint_ok = True;
6485 /* [printers] service must also be non-browsable. */
6486 if (ServicePtrs[iService]->bBrowseable)
6487 ServicePtrs[iService]->bBrowseable = False;
6490 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6491 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6492 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6494 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6495 ServicePtrs[iService]->szService));
6496 ServicePtrs[iService]->bAvailable = False;
6499 /* If a service is flagged unavailable, log the fact at level 1. */
6500 if (!ServicePtrs[iService]->bAvailable)
6501 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6502 ServicePtrs[iService]->szService));
6504 return (bRetval);
6507 static struct smbconf_ctx *lp_smbconf_ctx(void)
6509 WERROR werr;
6510 static struct smbconf_ctx *conf_ctx = NULL;
6512 if (conf_ctx == NULL) {
6513 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6514 if (!W_ERROR_IS_OK(werr)) {
6515 DEBUG(1, ("error initializing registry configuration: "
6516 "%s\n", dos_errstr(werr)));
6517 conf_ctx = NULL;
6521 return conf_ctx;
6524 static bool process_registry_service(struct smbconf_service *service)
6526 uint32_t count;
6527 bool ret;
6529 if (service == NULL) {
6530 return false;
6533 ret = do_section(service->name, NULL);
6534 if (ret != true) {
6535 return false;
6537 for (count = 0; count < service->num_params; count++) {
6538 ret = do_parameter(service->param_names[count],
6539 service->param_values[count],
6540 NULL);
6541 if (ret != true) {
6542 return false;
6545 return true;
6549 * process_registry_globals
6551 static bool process_registry_globals(void)
6553 WERROR werr;
6554 struct smbconf_service *service = NULL;
6555 TALLOC_CTX *mem_ctx = talloc_stackframe();
6556 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6557 bool ret = false;
6559 if (conf_ctx == NULL) {
6560 goto done;
6563 ret = do_parameter("registry shares", "yes", NULL);
6564 if (!ret) {
6565 goto done;
6568 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6569 /* nothing to read from the registry yet but make sure lp_load
6570 * doesn't return false */
6571 ret = true;
6572 goto done;
6575 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6576 if (!W_ERROR_IS_OK(werr)) {
6577 goto done;
6580 ret = process_registry_service(service);
6581 if (!ret) {
6582 goto done;
6585 /* store the csn */
6586 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6588 done:
6589 TALLOC_FREE(mem_ctx);
6590 return ret;
6593 static bool process_registry_shares(void)
6595 WERROR werr;
6596 uint32_t count;
6597 struct smbconf_service **service = NULL;
6598 uint32_t num_shares = 0;
6599 TALLOC_CTX *mem_ctx = talloc_stackframe();
6600 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6601 bool ret = false;
6603 if (conf_ctx == NULL) {
6604 goto done;
6607 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6608 if (!W_ERROR_IS_OK(werr)) {
6609 goto done;
6612 ret = true;
6614 for (count = 0; count < num_shares; count++) {
6615 if (strequal(service[count]->name, GLOBAL_NAME)) {
6616 continue;
6618 ret = process_registry_service(service[count]);
6619 if (!ret) {
6620 goto done;
6624 /* store the csn */
6625 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6627 done:
6628 TALLOC_FREE(mem_ctx);
6629 return ret;
6632 static struct file_lists {
6633 struct file_lists *next;
6634 char *name;
6635 char *subfname;
6636 time_t modtime;
6637 } *file_lists = NULL;
6639 /*******************************************************************
6640 Keep a linked list of all config files so we know when one has changed
6641 it's date and needs to be reloaded.
6642 ********************************************************************/
6644 static void add_to_file_list(const char *fname, const char *subfname)
6646 struct file_lists *f = file_lists;
6648 while (f) {
6649 if (f->name && !strcmp(f->name, fname))
6650 break;
6651 f = f->next;
6654 if (!f) {
6655 f = SMB_MALLOC_P(struct file_lists);
6656 if (!f)
6657 return;
6658 f->next = file_lists;
6659 f->name = SMB_STRDUP(fname);
6660 if (!f->name) {
6661 SAFE_FREE(f);
6662 return;
6664 f->subfname = SMB_STRDUP(subfname);
6665 if (!f->subfname) {
6666 SAFE_FREE(f);
6667 return;
6669 file_lists = f;
6670 f->modtime = file_modtime(subfname);
6671 } else {
6672 time_t t = file_modtime(subfname);
6673 if (t)
6674 f->modtime = t;
6679 * Utility function for outsiders to check if we're running on registry.
6681 bool lp_config_backend_is_registry(void)
6683 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6687 * Utility function to check if the config backend is FILE.
6689 bool lp_config_backend_is_file(void)
6691 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6694 /*******************************************************************
6695 Check if a config file has changed date.
6696 ********************************************************************/
6698 bool lp_file_list_changed(void)
6700 struct file_lists *f = file_lists;
6702 DEBUG(6, ("lp_file_list_changed()\n"));
6704 if (lp_config_backend_is_registry()) {
6705 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6707 if (conf_ctx == NULL) {
6708 return false;
6710 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6711 DEBUGADD(6, ("registry config changed\n"));
6712 return true;
6716 while (f) {
6717 char *n2 = NULL;
6718 time_t mod_time;
6720 n2 = alloc_sub_basic(get_current_username(),
6721 current_user_info.domain,
6722 f->name);
6723 if (!n2) {
6724 return false;
6726 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6727 f->name, n2, ctime(&f->modtime)));
6729 mod_time = file_modtime(n2);
6731 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6732 DEBUGADD(6,
6733 ("file %s modified: %s\n", n2,
6734 ctime(&mod_time)));
6735 f->modtime = mod_time;
6736 SAFE_FREE(f->subfname);
6737 f->subfname = n2; /* Passing ownership of
6738 return from alloc_sub_basic
6739 above. */
6740 return true;
6742 SAFE_FREE(n2);
6743 f = f->next;
6745 return (False);
6749 /***************************************************************************
6750 Run standard_sub_basic on netbios name... needed because global_myname
6751 is not accessed through any lp_ macro.
6752 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6753 ***************************************************************************/
6755 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6757 bool ret;
6758 char *netbios_name = alloc_sub_basic(get_current_username(),
6759 current_user_info.domain,
6760 pszParmValue);
6762 ret = set_global_myname(netbios_name);
6763 SAFE_FREE(netbios_name);
6764 string_set(&Globals.szNetbiosName,global_myname());
6766 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6767 global_myname()));
6769 return ret;
6772 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6774 if (strcmp(*ptr, pszParmValue) != 0) {
6775 string_set(ptr, pszParmValue);
6776 init_iconv();
6778 return True;
6783 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6785 bool ret;
6787 ret = set_global_myworkgroup(pszParmValue);
6788 string_set(&Globals.szWorkgroup,lp_workgroup());
6790 return ret;
6793 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6795 bool ret;
6797 ret = set_global_scope(pszParmValue);
6798 string_set(&Globals.szNetbiosScope,global_scope());
6800 return ret;
6803 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6805 TALLOC_FREE(Globals.szNetbiosAliases);
6806 Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
6807 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6810 /***************************************************************************
6811 Handle the include operation.
6812 ***************************************************************************/
6813 static bool bAllowIncludeRegistry = true;
6815 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6817 char *fname;
6819 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6820 if (!bAllowIncludeRegistry) {
6821 return true;
6823 if (bInGlobalSection) {
6824 return process_registry_globals();
6825 } else {
6826 DEBUG(1, ("\"include = registry\" only effective "
6827 "in %s section\n", GLOBAL_NAME));
6828 return false;
6832 fname = alloc_sub_basic(get_current_username(),
6833 current_user_info.domain,
6834 pszParmValue);
6836 add_to_file_list(pszParmValue, fname);
6838 string_set(ptr, fname);
6840 if (file_exist(fname, NULL)) {
6841 bool ret = pm_process(fname, do_section, do_parameter, NULL);
6842 SAFE_FREE(fname);
6843 return ret;
6846 DEBUG(2, ("Can't find include file %s\n", fname));
6847 SAFE_FREE(fname);
6848 return true;
6851 /***************************************************************************
6852 Handle the interpretation of the copy parameter.
6853 ***************************************************************************/
6855 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6857 bool bRetval;
6858 int iTemp;
6859 struct service serviceTemp;
6861 string_set(ptr, pszParmValue);
6863 init_service(&serviceTemp);
6865 bRetval = False;
6867 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6869 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6870 if (iTemp == iServiceIndex) {
6871 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6872 } else {
6873 copy_service(ServicePtrs[iServiceIndex],
6874 &serviceTemp,
6875 ServicePtrs[iServiceIndex]->copymap);
6876 bRetval = True;
6878 } else {
6879 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6880 bRetval = False;
6883 free_service(&serviceTemp);
6884 return (bRetval);
6887 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6889 Globals.ldap_debug_level = lp_int(pszParmValue);
6890 init_ldap_debugging();
6891 return true;
6894 /***************************************************************************
6895 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6896 parameters is:
6898 [global]
6900 idmap uid = 1000-1999
6901 idmap gid = 700-899
6903 We only do simple parsing checks here. The strings are parsed into useful
6904 structures in the idmap daemon code.
6906 ***************************************************************************/
6908 /* Some lp_ routines to return idmap [ug]id information */
6910 static uid_t idmap_uid_low, idmap_uid_high;
6911 static gid_t idmap_gid_low, idmap_gid_high;
6913 bool lp_idmap_uid(uid_t *low, uid_t *high)
6915 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6916 return False;
6918 if (low)
6919 *low = idmap_uid_low;
6921 if (high)
6922 *high = idmap_uid_high;
6924 return True;
6927 bool lp_idmap_gid(gid_t *low, gid_t *high)
6929 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6930 return False;
6932 if (low)
6933 *low = idmap_gid_low;
6935 if (high)
6936 *high = idmap_gid_high;
6938 return True;
6941 /* Do some simple checks on "idmap [ug]id" parameter values */
6943 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6945 uint32 low, high;
6947 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6948 return False;
6950 /* Parse OK */
6952 string_set(ptr, pszParmValue);
6954 idmap_uid_low = low;
6955 idmap_uid_high = high;
6957 return True;
6960 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
6962 uint32 low, high;
6964 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
6965 return False;
6967 /* Parse OK */
6969 string_set(ptr, pszParmValue);
6971 idmap_gid_low = low;
6972 idmap_gid_high = high;
6974 return True;
6977 /***************************************************************************
6978 Handle the DEBUG level list.
6979 ***************************************************************************/
6981 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
6983 string_set(ptr, pszParmValueIn);
6984 return debug_parse_levels(pszParmValueIn);
6987 /***************************************************************************
6988 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
6989 ***************************************************************************/
6991 static const char *append_ldap_suffix( const char *str )
6993 const char *suffix_string;
6996 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
6997 Globals.szLdapSuffix );
6998 if ( !suffix_string ) {
6999 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7000 return "";
7003 return suffix_string;
7006 const char *lp_ldap_machine_suffix(void)
7008 if (Globals.szLdapMachineSuffix[0])
7009 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7011 return lp_string(Globals.szLdapSuffix);
7014 const char *lp_ldap_user_suffix(void)
7016 if (Globals.szLdapUserSuffix[0])
7017 return append_ldap_suffix(Globals.szLdapUserSuffix);
7019 return lp_string(Globals.szLdapSuffix);
7022 const char *lp_ldap_group_suffix(void)
7024 if (Globals.szLdapGroupSuffix[0])
7025 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7027 return lp_string(Globals.szLdapSuffix);
7030 const char *lp_ldap_idmap_suffix(void)
7032 if (Globals.szLdapIdmapSuffix[0])
7033 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7035 return lp_string(Globals.szLdapSuffix);
7038 /****************************************************************************
7039 set the value for a P_ENUM
7040 ***************************************************************************/
7042 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7043 int *ptr )
7045 int i;
7047 for (i = 0; parm->enum_list[i].name; i++) {
7048 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7049 *ptr = parm->enum_list[i].value;
7050 return;
7053 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7054 pszParmValue, parm->label));
7057 /***************************************************************************
7058 ***************************************************************************/
7060 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7062 static int parm_num = -1;
7063 struct service *s;
7065 if ( parm_num == -1 )
7066 parm_num = map_parameter( "printing" );
7068 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7070 if ( snum < 0 )
7071 s = &sDefault;
7072 else
7073 s = ServicePtrs[snum];
7075 init_printer_values( s );
7077 return True;
7081 /***************************************************************************
7082 Initialise a copymap.
7083 ***************************************************************************/
7085 static void init_copymap(struct service *pservice)
7087 int i;
7088 if (pservice->copymap) {
7089 bitmap_free(pservice->copymap);
7091 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7092 if (!pservice->copymap)
7093 DEBUG(0,
7094 ("Couldn't allocate copymap!! (size %d)\n",
7095 (int)NUMPARAMETERS));
7096 else
7097 for (i = 0; i < NUMPARAMETERS; i++)
7098 bitmap_set(pservice->copymap, i);
7101 /***************************************************************************
7102 Return the local pointer to a parameter given the service number and the
7103 pointer into the default structure.
7104 ***************************************************************************/
7106 void *lp_local_ptr(int snum, void *ptr)
7108 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7111 /***************************************************************************
7112 Process a parameter for a particular service number. If snum < 0
7113 then assume we are in the globals.
7114 ***************************************************************************/
7116 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7118 int parmnum, i;
7119 void *parm_ptr = NULL; /* where we are going to store the result */
7120 void *def_ptr = NULL;
7121 struct param_opt_struct *paramo, *data;
7122 bool not_added;
7124 parmnum = map_parameter(pszParmName);
7126 if (parmnum < 0) {
7127 TALLOC_CTX *frame;
7129 if (strchr(pszParmName, ':') == NULL) {
7130 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7131 pszParmName));
7132 return (True);
7136 * We've got a parametric option
7139 frame = talloc_stackframe();
7141 not_added = True;
7142 data = (snum < 0)
7143 ? Globals.param_opt : ServicePtrs[snum]->param_opt;
7144 /* Traverse destination */
7145 while (data) {
7146 /* If we already have same option, override it */
7147 if (strwicmp(data->key, pszParmName) == 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(struct param_opt_struct);
7158 paramo->key = SMB_STRDUP(pszParmName);
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,
7165 paramo);
7169 TALLOC_FREE(frame);
7170 return (True);
7173 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7174 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7175 pszParmName));
7178 def_ptr = parm_table[parmnum].ptr;
7180 /* we might point at a service, the default service or a global */
7181 if (snum < 0) {
7182 parm_ptr = def_ptr;
7183 } else {
7184 if (parm_table[parmnum].p_class == P_GLOBAL) {
7185 DEBUG(0,
7186 ("Global parameter %s found in service section!\n",
7187 pszParmName));
7188 return (True);
7190 parm_ptr =
7191 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7192 &sDefault);
7195 if (snum >= 0) {
7196 if (!ServicePtrs[snum]->copymap)
7197 init_copymap(ServicePtrs[snum]);
7199 /* this handles the aliases - set the copymap for other entries with
7200 the same data pointer */
7201 for (i = 0; parm_table[i].label; i++)
7202 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7203 bitmap_clear(ServicePtrs[snum]->copymap, i);
7206 /* if it is a special case then go ahead */
7207 if (parm_table[parmnum].special) {
7208 return parm_table[parmnum].special(snum, pszParmValue,
7209 (char **)parm_ptr);
7212 /* now switch on the type of variable it is */
7213 switch (parm_table[parmnum].type)
7215 case P_BOOL:
7216 *(bool *)parm_ptr = lp_bool(pszParmValue);
7217 break;
7219 case P_BOOLREV:
7220 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7221 break;
7223 case P_INTEGER:
7224 *(int *)parm_ptr = lp_int(pszParmValue);
7225 break;
7227 case P_CHAR:
7228 *(char *)parm_ptr = *pszParmValue;
7229 break;
7231 case P_OCTAL:
7232 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7233 if ( i != 1 ) {
7234 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7236 break;
7238 case P_LIST:
7239 TALLOC_FREE(*((char ***)parm_ptr));
7240 *(char ***)parm_ptr = str_list_make(
7241 NULL, pszParmValue, NULL);
7242 break;
7244 case P_STRING:
7245 string_set((char **)parm_ptr, pszParmValue);
7246 break;
7248 case P_USTRING:
7249 string_set((char **)parm_ptr, pszParmValue);
7250 strupper_m(*(char **)parm_ptr);
7251 break;
7253 case P_ENUM:
7254 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7255 break;
7256 case P_SEP:
7257 break;
7260 return (True);
7263 /***************************************************************************
7264 Process a parameter.
7265 ***************************************************************************/
7267 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7268 void *userdata)
7270 if (!bInGlobalSection && bGlobalOnly)
7271 return (True);
7273 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7275 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7276 pszParmName, pszParmValue));
7279 /***************************************************************************
7280 Print a parameter of the specified type.
7281 ***************************************************************************/
7283 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7285 int i;
7286 switch (p->type)
7288 case P_ENUM:
7289 for (i = 0; p->enum_list[i].name; i++) {
7290 if (*(int *)ptr == p->enum_list[i].value) {
7291 fprintf(f, "%s",
7292 p->enum_list[i].name);
7293 break;
7296 break;
7298 case P_BOOL:
7299 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7300 break;
7302 case P_BOOLREV:
7303 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7304 break;
7306 case P_INTEGER:
7307 fprintf(f, "%d", *(int *)ptr);
7308 break;
7310 case P_CHAR:
7311 fprintf(f, "%c", *(char *)ptr);
7312 break;
7314 case P_OCTAL: {
7315 char *o = octal_string(*(int *)ptr);
7316 fprintf(f, "%s", o);
7317 TALLOC_FREE(o);
7318 break;
7321 case P_LIST:
7322 if ((char ***)ptr && *(char ***)ptr) {
7323 char **list = *(char ***)ptr;
7324 for (; *list; list++) {
7325 /* surround strings with whitespace in double quotes */
7326 if ( strchr_m( *list, ' ' ) )
7327 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7328 else
7329 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7332 break;
7334 case P_STRING:
7335 case P_USTRING:
7336 if (*(char **)ptr) {
7337 fprintf(f, "%s", *(char **)ptr);
7339 break;
7340 case P_SEP:
7341 break;
7345 /***************************************************************************
7346 Check if two parameters are equal.
7347 ***************************************************************************/
7349 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7351 switch (type) {
7352 case P_BOOL:
7353 case P_BOOLREV:
7354 return (*((bool *)ptr1) == *((bool *)ptr2));
7356 case P_INTEGER:
7357 case P_ENUM:
7358 case P_OCTAL:
7359 return (*((int *)ptr1) == *((int *)ptr2));
7361 case P_CHAR:
7362 return (*((char *)ptr1) == *((char *)ptr2));
7364 case P_LIST:
7365 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7367 case P_STRING:
7368 case P_USTRING:
7370 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7371 if (p1 && !*p1)
7372 p1 = NULL;
7373 if (p2 && !*p2)
7374 p2 = NULL;
7375 return (p1 == p2 || strequal(p1, p2));
7377 case P_SEP:
7378 break;
7380 return (False);
7383 /***************************************************************************
7384 Initialize any local varients in the sDefault table.
7385 ***************************************************************************/
7387 void init_locals(void)
7389 /* None as yet. */
7392 /***************************************************************************
7393 Process a new section (service). At this stage all sections are services.
7394 Later we'll have special sections that permit server parameters to be set.
7395 Returns True on success, False on failure.
7396 ***************************************************************************/
7398 static bool do_section(const char *pszSectionName, void *userdata)
7400 bool bRetval;
7401 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7402 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7403 bRetval = False;
7405 /* if we were in a global section then do the local inits */
7406 if (bInGlobalSection && !isglobal)
7407 init_locals();
7409 /* if we've just struck a global section, note the fact. */
7410 bInGlobalSection = isglobal;
7412 /* check for multiple global sections */
7413 if (bInGlobalSection) {
7414 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7415 return (True);
7418 if (!bInGlobalSection && bGlobalOnly)
7419 return (True);
7421 /* if we have a current service, tidy it up before moving on */
7422 bRetval = True;
7424 if (iServiceIndex >= 0)
7425 bRetval = service_ok(iServiceIndex);
7427 /* if all is still well, move to the next record in the services array */
7428 if (bRetval) {
7429 /* We put this here to avoid an odd message order if messages are */
7430 /* issued by the post-processing of a previous section. */
7431 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7433 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7434 < 0) {
7435 DEBUG(0, ("Failed to add a new service\n"));
7436 return (False);
7440 return (bRetval);
7444 /***************************************************************************
7445 Determine if a partcular base parameter is currentl set to the default value.
7446 ***************************************************************************/
7448 static bool is_default(int i)
7450 if (!defaults_saved)
7451 return False;
7452 switch (parm_table[i].type) {
7453 case P_LIST:
7454 return str_list_compare (parm_table[i].def.lvalue,
7455 *(char ***)parm_table[i].ptr);
7456 case P_STRING:
7457 case P_USTRING:
7458 return strequal(parm_table[i].def.svalue,
7459 *(char **)parm_table[i].ptr);
7460 case P_BOOL:
7461 case P_BOOLREV:
7462 return parm_table[i].def.bvalue ==
7463 *(bool *)parm_table[i].ptr;
7464 case P_CHAR:
7465 return parm_table[i].def.cvalue ==
7466 *(char *)parm_table[i].ptr;
7467 case P_INTEGER:
7468 case P_OCTAL:
7469 case P_ENUM:
7470 return parm_table[i].def.ivalue ==
7471 *(int *)parm_table[i].ptr;
7472 case P_SEP:
7473 break;
7475 return False;
7478 /***************************************************************************
7479 Display the contents of the global structure.
7480 ***************************************************************************/
7482 static void dump_globals(FILE *f)
7484 int i;
7485 struct param_opt_struct *data;
7487 fprintf(f, "[global]\n");
7489 for (i = 0; parm_table[i].label; i++)
7490 if (parm_table[i].p_class == P_GLOBAL &&
7491 parm_table[i].ptr &&
7492 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7493 if (defaults_saved && is_default(i))
7494 continue;
7495 fprintf(f, "\t%s = ", parm_table[i].label);
7496 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7497 fprintf(f, "\n");
7499 if (Globals.param_opt != NULL) {
7500 data = Globals.param_opt;
7501 while(data) {
7502 fprintf(f, "\t%s = %s\n", data->key, data->value);
7503 data = data->next;
7509 /***************************************************************************
7510 Return True if a local parameter is currently set to the global default.
7511 ***************************************************************************/
7513 bool lp_is_default(int snum, struct parm_struct *parm)
7515 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7517 return equal_parameter(parm->type,
7518 ((char *)ServicePtrs[snum]) + pdiff,
7519 ((char *)&sDefault) + pdiff);
7522 /***************************************************************************
7523 Display the contents of a single services record.
7524 ***************************************************************************/
7526 static void dump_a_service(struct service *pService, FILE * f)
7528 int i;
7529 struct param_opt_struct *data;
7531 if (pService != &sDefault)
7532 fprintf(f, "[%s]\n", pService->szService);
7534 for (i = 0; parm_table[i].label; i++) {
7536 if (parm_table[i].p_class == P_LOCAL &&
7537 parm_table[i].ptr &&
7538 (*parm_table[i].label != '-') &&
7539 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7542 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7544 if (pService == &sDefault) {
7545 if (defaults_saved && is_default(i))
7546 continue;
7547 } else {
7548 if (equal_parameter(parm_table[i].type,
7549 ((char *)pService) +
7550 pdiff,
7551 ((char *)&sDefault) +
7552 pdiff))
7553 continue;
7556 fprintf(f, "\t%s = ", parm_table[i].label);
7557 print_parameter(&parm_table[i],
7558 ((char *)pService) + pdiff, f);
7559 fprintf(f, "\n");
7563 if (pService->param_opt != NULL) {
7564 data = pService->param_opt;
7565 while(data) {
7566 fprintf(f, "\t%s = %s\n", data->key, data->value);
7567 data = data->next;
7572 /***************************************************************************
7573 Display the contents of a parameter of a single services record.
7574 ***************************************************************************/
7576 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7578 int i;
7579 bool result = False;
7580 parm_class p_class;
7581 unsigned flag = 0;
7582 fstring local_parm_name;
7583 char *parm_opt;
7584 const char *parm_opt_value;
7586 /* check for parametrical option */
7587 fstrcpy( local_parm_name, parm_name);
7588 parm_opt = strchr( local_parm_name, ':');
7590 if (parm_opt) {
7591 *parm_opt = '\0';
7592 parm_opt++;
7593 if (strlen(parm_opt)) {
7594 parm_opt_value = lp_parm_const_string( snum,
7595 local_parm_name, parm_opt, NULL);
7596 if (parm_opt_value) {
7597 printf( "%s\n", parm_opt_value);
7598 result = True;
7601 return result;
7604 /* check for a key and print the value */
7605 if (isGlobal) {
7606 p_class = P_GLOBAL;
7607 flag = FLAG_GLOBAL;
7608 } else
7609 p_class = P_LOCAL;
7611 for (i = 0; parm_table[i].label; i++) {
7612 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7613 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7614 parm_table[i].ptr &&
7615 (*parm_table[i].label != '-') &&
7616 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7618 void *ptr;
7620 if (isGlobal) {
7621 ptr = parm_table[i].ptr;
7622 } else {
7623 struct service *pService = ServicePtrs[snum];
7624 ptr = ((char *)pService) +
7625 PTR_DIFF(parm_table[i].ptr, &sDefault);
7628 print_parameter(&parm_table[i],
7629 ptr, f);
7630 fprintf(f, "\n");
7631 result = True;
7632 break;
7636 return result;
7639 /***************************************************************************
7640 Return info about the requested parameter (given as a string).
7641 Return NULL when the string is not a valid parameter name.
7642 ***************************************************************************/
7644 struct parm_struct *lp_get_parameter(const char *param_name)
7646 int num = map_parameter(param_name);
7648 if (num < 0) {
7649 return NULL;
7652 return &parm_table[num];
7655 /***************************************************************************
7656 Return info about the next parameter in a service.
7657 snum==GLOBAL_SECTION_SNUM gives the globals.
7658 Return NULL when out of parameters.
7659 ***************************************************************************/
7661 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7663 if (snum < 0) {
7664 /* do the globals */
7665 for (; parm_table[*i].label; (*i)++) {
7666 if (parm_table[*i].p_class == P_SEPARATOR)
7667 return &parm_table[(*i)++];
7669 if (!parm_table[*i].ptr
7670 || (*parm_table[*i].label == '-'))
7671 continue;
7673 if ((*i) > 0
7674 && (parm_table[*i].ptr ==
7675 parm_table[(*i) - 1].ptr))
7676 continue;
7678 if (is_default(*i) && !allparameters)
7679 continue;
7681 return &parm_table[(*i)++];
7683 } else {
7684 struct service *pService = ServicePtrs[snum];
7686 for (; parm_table[*i].label; (*i)++) {
7687 if (parm_table[*i].p_class == P_SEPARATOR)
7688 return &parm_table[(*i)++];
7690 if (parm_table[*i].p_class == P_LOCAL &&
7691 parm_table[*i].ptr &&
7692 (*parm_table[*i].label != '-') &&
7693 ((*i) == 0 ||
7694 (parm_table[*i].ptr !=
7695 parm_table[(*i) - 1].ptr)))
7697 int pdiff =
7698 PTR_DIFF(parm_table[*i].ptr,
7699 &sDefault);
7701 if (allparameters ||
7702 !equal_parameter(parm_table[*i].type,
7703 ((char *)pService) +
7704 pdiff,
7705 ((char *)&sDefault) +
7706 pdiff))
7708 return &parm_table[(*i)++];
7714 return NULL;
7718 #if 0
7719 /***************************************************************************
7720 Display the contents of a single copy structure.
7721 ***************************************************************************/
7722 static void dump_copy_map(bool *pcopymap)
7724 int i;
7725 if (!pcopymap)
7726 return;
7728 printf("\n\tNon-Copied parameters:\n");
7730 for (i = 0; parm_table[i].label; i++)
7731 if (parm_table[i].p_class == P_LOCAL &&
7732 parm_table[i].ptr && !pcopymap[i] &&
7733 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7735 printf("\t\t%s\n", parm_table[i].label);
7738 #endif
7740 /***************************************************************************
7741 Return TRUE if the passed service number is within range.
7742 ***************************************************************************/
7744 bool lp_snum_ok(int iService)
7746 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7749 /***************************************************************************
7750 Auto-load some home services.
7751 ***************************************************************************/
7753 static void lp_add_auto_services(char *str)
7755 char *s;
7756 char *p;
7757 int homes;
7758 char *saveptr;
7760 if (!str)
7761 return;
7763 s = SMB_STRDUP(str);
7764 if (!s)
7765 return;
7767 homes = lp_servicenumber(HOMES_NAME);
7769 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7770 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7771 char *home;
7773 if (lp_servicenumber(p) >= 0)
7774 continue;
7776 home = get_user_home_dir(talloc_tos(), p);
7778 if (home && homes >= 0)
7779 lp_add_home(p, homes, p, home);
7781 TALLOC_FREE(home);
7783 SAFE_FREE(s);
7786 /***************************************************************************
7787 Auto-load one printer.
7788 ***************************************************************************/
7790 void lp_add_one_printer(char *name, char *comment)
7792 int printers = lp_servicenumber(PRINTERS_NAME);
7793 int i;
7795 if (lp_servicenumber(name) < 0) {
7796 lp_add_printer(name, printers);
7797 if ((i = lp_servicenumber(name)) >= 0) {
7798 string_set(&ServicePtrs[i]->comment, comment);
7799 ServicePtrs[i]->autoloaded = True;
7804 /***************************************************************************
7805 Have we loaded a services file yet?
7806 ***************************************************************************/
7808 bool lp_loaded(void)
7810 return (bLoaded);
7813 /***************************************************************************
7814 Unload unused services.
7815 ***************************************************************************/
7817 void lp_killunused(bool (*snumused) (int))
7819 int i;
7820 for (i = 0; i < iNumServices; i++) {
7821 if (!VALID(i))
7822 continue;
7824 /* don't kill autoloaded or usershare services */
7825 if ( ServicePtrs[i]->autoloaded ||
7826 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7827 continue;
7830 if (!snumused || !snumused(i)) {
7831 free_service_byindex(i);
7837 * Kill all except autoloaded and usershare services - convenience wrapper
7839 void lp_kill_all_services(void)
7841 lp_killunused(NULL);
7844 /***************************************************************************
7845 Unload a service.
7846 ***************************************************************************/
7848 void lp_killservice(int iServiceIn)
7850 if (VALID(iServiceIn)) {
7851 free_service_byindex(iServiceIn);
7855 /***************************************************************************
7856 Save the curent values of all global and sDefault parameters into the
7857 defaults union. This allows swat and testparm to show only the
7858 changed (ie. non-default) parameters.
7859 ***************************************************************************/
7861 static void lp_save_defaults(void)
7863 int i;
7864 for (i = 0; parm_table[i].label; i++) {
7865 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7866 continue;
7867 switch (parm_table[i].type) {
7868 case P_LIST:
7869 str_list_copy(
7870 NULL, &(parm_table[i].def.lvalue),
7871 *(const char ***)parm_table[i].ptr);
7872 break;
7873 case P_STRING:
7874 case P_USTRING:
7875 if (parm_table[i].ptr) {
7876 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7877 } else {
7878 parm_table[i].def.svalue = NULL;
7880 break;
7881 case P_BOOL:
7882 case P_BOOLREV:
7883 parm_table[i].def.bvalue =
7884 *(bool *)parm_table[i].ptr;
7885 break;
7886 case P_CHAR:
7887 parm_table[i].def.cvalue =
7888 *(char *)parm_table[i].ptr;
7889 break;
7890 case P_INTEGER:
7891 case P_OCTAL:
7892 case P_ENUM:
7893 parm_table[i].def.ivalue =
7894 *(int *)parm_table[i].ptr;
7895 break;
7896 case P_SEP:
7897 break;
7900 defaults_saved = True;
7903 /*******************************************************************
7904 Set the server type we will announce as via nmbd.
7905 ********************************************************************/
7907 static const struct srv_role_tab {
7908 uint32 role;
7909 const char *role_str;
7910 } srv_role_tab [] = {
7911 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7912 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7913 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7914 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7915 { 0, NULL }
7918 const char* server_role_str(uint32 role)
7920 int i = 0;
7921 for (i=0; srv_role_tab[i].role_str; i++) {
7922 if (role == srv_role_tab[i].role) {
7923 return srv_role_tab[i].role_str;
7926 return NULL;
7929 static void set_server_role(void)
7931 server_role = ROLE_STANDALONE;
7933 switch (lp_security()) {
7934 case SEC_SHARE:
7935 if (lp_domain_logons())
7936 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7937 break;
7938 case SEC_SERVER:
7939 if (lp_domain_logons())
7940 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7941 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7942 server_role = ROLE_STANDALONE;
7943 break;
7944 case SEC_DOMAIN:
7945 if (lp_domain_logons()) {
7946 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7947 server_role = ROLE_DOMAIN_BDC;
7948 break;
7950 server_role = ROLE_DOMAIN_MEMBER;
7951 break;
7952 case SEC_ADS:
7953 if (lp_domain_logons()) {
7954 server_role = ROLE_DOMAIN_PDC;
7955 break;
7957 server_role = ROLE_DOMAIN_MEMBER;
7958 break;
7959 case SEC_USER:
7960 if (lp_domain_logons()) {
7962 if (Globals.iDomainMaster) /* auto or yes */
7963 server_role = ROLE_DOMAIN_PDC;
7964 else
7965 server_role = ROLE_DOMAIN_BDC;
7967 break;
7968 default:
7969 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7970 break;
7973 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
7976 /***********************************************************
7977 If we should send plaintext/LANMAN passwords in the clinet
7978 ************************************************************/
7980 static void set_allowed_client_auth(void)
7982 if (Globals.bClientNTLMv2Auth) {
7983 Globals.bClientLanManAuth = False;
7985 if (!Globals.bClientLanManAuth) {
7986 Globals.bClientPlaintextAuth = False;
7990 /***************************************************************************
7991 JRA.
7992 The following code allows smbd to read a user defined share file.
7993 Yes, this is my intent. Yes, I'm comfortable with that...
7995 THE FOLLOWING IS SECURITY CRITICAL CODE.
7997 It washes your clothes, it cleans your house, it guards you while you sleep...
7998 Do not f%^k with it....
7999 ***************************************************************************/
8001 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8003 /***************************************************************************
8004 Check allowed stat state of a usershare file.
8005 Ensure we print out who is dicking with us so the admin can
8006 get their sorry ass fired.
8007 ***************************************************************************/
8009 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8011 if (!S_ISREG(psbuf->st_mode)) {
8012 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8013 "not a regular file\n",
8014 fname, (unsigned int)psbuf->st_uid ));
8015 return False;
8018 /* Ensure this doesn't have the other write bit set. */
8019 if (psbuf->st_mode & S_IWOTH) {
8020 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8021 "public write. Refusing to allow as a usershare file.\n",
8022 fname, (unsigned int)psbuf->st_uid ));
8023 return False;
8026 /* Should be 10k or less. */
8027 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8028 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8029 "too large (%u) to be a user share file.\n",
8030 fname, (unsigned int)psbuf->st_uid,
8031 (unsigned int)psbuf->st_size ));
8032 return False;
8035 return True;
8038 /***************************************************************************
8039 Parse the contents of a usershare file.
8040 ***************************************************************************/
8042 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8043 SMB_STRUCT_STAT *psbuf,
8044 const char *servicename,
8045 int snum,
8046 char **lines,
8047 int numlines,
8048 char **pp_sharepath,
8049 char **pp_comment,
8050 SEC_DESC **ppsd,
8051 bool *pallow_guest)
8053 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8054 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8055 int us_vers;
8056 SMB_STRUCT_DIR *dp;
8057 SMB_STRUCT_STAT sbuf;
8058 char *sharepath = NULL;
8059 char *comment = NULL;
8061 *pp_sharepath = NULL;
8062 *pp_comment = NULL;
8064 *pallow_guest = False;
8066 if (numlines < 4) {
8067 return USERSHARE_MALFORMED_FILE;
8070 if (strcmp(lines[0], "#VERSION 1") == 0) {
8071 us_vers = 1;
8072 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8073 us_vers = 2;
8074 if (numlines < 5) {
8075 return USERSHARE_MALFORMED_FILE;
8077 } else {
8078 return USERSHARE_BAD_VERSION;
8081 if (strncmp(lines[1], "path=", 5) != 0) {
8082 return USERSHARE_MALFORMED_PATH;
8085 sharepath = talloc_strdup(ctx, &lines[1][5]);
8086 if (!sharepath) {
8087 return USERSHARE_POSIX_ERR;
8089 trim_string(sharepath, " ", " ");
8091 if (strncmp(lines[2], "comment=", 8) != 0) {
8092 return USERSHARE_MALFORMED_COMMENT_DEF;
8095 comment = talloc_strdup(ctx, &lines[2][8]);
8096 if (!comment) {
8097 return USERSHARE_POSIX_ERR;
8099 trim_string(comment, " ", " ");
8100 trim_char(comment, '"', '"');
8102 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8103 return USERSHARE_MALFORMED_ACL_DEF;
8106 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8107 return USERSHARE_ACL_ERR;
8110 if (us_vers == 2) {
8111 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8112 return USERSHARE_MALFORMED_ACL_DEF;
8114 if (lines[4][9] == 'y') {
8115 *pallow_guest = True;
8119 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8120 /* Path didn't change, no checks needed. */
8121 *pp_sharepath = sharepath;
8122 *pp_comment = comment;
8123 return USERSHARE_OK;
8126 /* The path *must* be absolute. */
8127 if (sharepath[0] != '/') {
8128 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8129 servicename, sharepath));
8130 return USERSHARE_PATH_NOT_ABSOLUTE;
8133 /* If there is a usershare prefix deny list ensure one of these paths
8134 doesn't match the start of the user given path. */
8135 if (prefixdenylist) {
8136 int i;
8137 for ( i=0; prefixdenylist[i]; i++ ) {
8138 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8139 servicename, i, prefixdenylist[i], sharepath ));
8140 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8141 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8142 "usershare prefix deny list entries.\n",
8143 servicename, sharepath));
8144 return USERSHARE_PATH_IS_DENIED;
8149 /* If there is a usershare prefix allow list ensure one of these paths
8150 does match the start of the user given path. */
8152 if (prefixallowlist) {
8153 int i;
8154 for ( i=0; prefixallowlist[i]; i++ ) {
8155 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8156 servicename, i, prefixallowlist[i], sharepath ));
8157 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8158 break;
8161 if (prefixallowlist[i] == NULL) {
8162 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8163 "usershare prefix allow list entries.\n",
8164 servicename, sharepath));
8165 return USERSHARE_PATH_NOT_ALLOWED;
8169 /* Ensure this is pointing to a directory. */
8170 dp = sys_opendir(sharepath);
8172 if (!dp) {
8173 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8174 servicename, sharepath));
8175 return USERSHARE_PATH_NOT_DIRECTORY;
8178 /* Ensure the owner of the usershare file has permission to share
8179 this directory. */
8181 if (sys_stat(sharepath, &sbuf) == -1) {
8182 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8183 servicename, sharepath, strerror(errno) ));
8184 sys_closedir(dp);
8185 return USERSHARE_POSIX_ERR;
8188 sys_closedir(dp);
8190 if (!S_ISDIR(sbuf.st_mode)) {
8191 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8192 servicename, sharepath ));
8193 return USERSHARE_PATH_NOT_DIRECTORY;
8196 /* Check if sharing is restricted to owner-only. */
8197 /* psbuf is the stat of the usershare definition file,
8198 sbuf is the stat of the target directory to be shared. */
8200 if (lp_usershare_owner_only()) {
8201 /* root can share anything. */
8202 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8203 return USERSHARE_PATH_NOT_ALLOWED;
8207 *pp_sharepath = sharepath;
8208 *pp_comment = comment;
8209 return USERSHARE_OK;
8212 /***************************************************************************
8213 Deal with a usershare file.
8214 Returns:
8215 >= 0 - snum
8216 -1 - Bad name, invalid contents.
8217 - service name already existed and not a usershare, problem
8218 with permissions to share directory etc.
8219 ***************************************************************************/
8221 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8223 SMB_STRUCT_STAT sbuf;
8224 SMB_STRUCT_STAT lsbuf;
8225 char *fname = NULL;
8226 char *sharepath = NULL;
8227 char *comment = NULL;
8228 fstring service_name;
8229 char **lines = NULL;
8230 int numlines = 0;
8231 int fd = -1;
8232 int iService = -1;
8233 TALLOC_CTX *ctx = NULL;
8234 SEC_DESC *psd = NULL;
8235 bool guest_ok = False;
8237 /* Ensure share name doesn't contain invalid characters. */
8238 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8239 DEBUG(0,("process_usershare_file: share name %s contains "
8240 "invalid characters (any of %s)\n",
8241 file_name, INVALID_SHARENAME_CHARS ));
8242 return -1;
8245 fstrcpy(service_name, file_name);
8247 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8250 /* Minimize the race condition by doing an lstat before we
8251 open and fstat. Ensure this isn't a symlink link. */
8253 if (sys_lstat(fname, &lsbuf) != 0) {
8254 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8255 fname, strerror(errno) ));
8256 SAFE_FREE(fname);
8257 return -1;
8260 /* This must be a regular file, not a symlink, directory or
8261 other strange filetype. */
8262 if (!check_usershare_stat(fname, &lsbuf)) {
8263 SAFE_FREE(fname);
8264 return -1;
8268 char *canon_name = canonicalize_servicename(service_name);
8269 TDB_DATA data = dbwrap_fetch_bystring(
8270 ServiceHash, canon_name, canon_name);
8272 iService = -1;
8274 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8275 iService = *(int *)data.dptr;
8277 TALLOC_FREE(canon_name);
8280 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8281 /* Nothing changed - Mark valid and return. */
8282 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8283 service_name ));
8284 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8285 SAFE_FREE(fname);
8286 return iService;
8289 /* Try and open the file read only - no symlinks allowed. */
8290 #ifdef O_NOFOLLOW
8291 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8292 #else
8293 fd = sys_open(fname, O_RDONLY, 0);
8294 #endif
8296 if (fd == -1) {
8297 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8298 fname, strerror(errno) ));
8299 SAFE_FREE(fname);
8300 return -1;
8303 /* Now fstat to be *SURE* it's a regular file. */
8304 if (sys_fstat(fd, &sbuf) != 0) {
8305 close(fd);
8306 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8307 fname, strerror(errno) ));
8308 SAFE_FREE(fname);
8309 return -1;
8312 /* Is it the same dev/inode as was lstated ? */
8313 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8314 close(fd);
8315 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8316 "Symlink spoofing going on ?\n", fname ));
8317 SAFE_FREE(fname);
8318 return -1;
8321 /* This must be a regular file, not a symlink, directory or
8322 other strange filetype. */
8323 if (!check_usershare_stat(fname, &sbuf)) {
8324 SAFE_FREE(fname);
8325 return -1;
8328 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8330 close(fd);
8331 if (lines == NULL) {
8332 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8333 fname, (unsigned int)sbuf.st_uid ));
8334 SAFE_FREE(fname);
8335 return -1;
8338 SAFE_FREE(fname);
8340 /* Should we allow printers to be shared... ? */
8341 ctx = talloc_init("usershare_sd_xctx");
8342 if (!ctx) {
8343 file_lines_free(lines);
8344 return 1;
8347 if (parse_usershare_file(ctx, &sbuf, service_name,
8348 iService, lines, numlines, &sharepath,
8349 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8350 talloc_destroy(ctx);
8351 file_lines_free(lines);
8352 return -1;
8355 file_lines_free(lines);
8357 /* Everything ok - add the service possibly using a template. */
8358 if (iService < 0) {
8359 const struct service *sp = &sDefault;
8360 if (snum_template != -1) {
8361 sp = ServicePtrs[snum_template];
8364 if ((iService = add_a_service(sp, service_name)) < 0) {
8365 DEBUG(0, ("process_usershare_file: Failed to add "
8366 "new service %s\n", service_name));
8367 talloc_destroy(ctx);
8368 return -1;
8371 /* Read only is controlled by usershare ACL below. */
8372 ServicePtrs[iService]->bRead_only = False;
8375 /* Write the ACL of the new/modified share. */
8376 if (!set_share_security(service_name, psd)) {
8377 DEBUG(0, ("process_usershare_file: Failed to set share "
8378 "security for user share %s\n",
8379 service_name ));
8380 lp_remove_service(iService);
8381 talloc_destroy(ctx);
8382 return -1;
8385 /* If from a template it may be marked invalid. */
8386 ServicePtrs[iService]->valid = True;
8388 /* Set the service as a valid usershare. */
8389 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8391 /* Set guest access. */
8392 if (lp_usershare_allow_guests()) {
8393 ServicePtrs[iService]->bGuest_ok = guest_ok;
8396 /* And note when it was loaded. */
8397 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8398 string_set(&ServicePtrs[iService]->szPath, sharepath);
8399 string_set(&ServicePtrs[iService]->comment, comment);
8401 talloc_destroy(ctx);
8403 return iService;
8406 /***************************************************************************
8407 Checks if a usershare entry has been modified since last load.
8408 ***************************************************************************/
8410 static bool usershare_exists(int iService, time_t *last_mod)
8412 SMB_STRUCT_STAT lsbuf;
8413 const char *usersharepath = Globals.szUsersharePath;
8414 char *fname;
8416 if (asprintf(&fname, "%s/%s",
8417 usersharepath,
8418 ServicePtrs[iService]->szService) < 0) {
8419 return false;
8422 if (sys_lstat(fname, &lsbuf) != 0) {
8423 SAFE_FREE(fname);
8424 return false;
8427 if (!S_ISREG(lsbuf.st_mode)) {
8428 SAFE_FREE(fname);
8429 return false;
8432 SAFE_FREE(fname);
8433 *last_mod = lsbuf.st_mtime;
8434 return true;
8437 /***************************************************************************
8438 Load a usershare service by name. Returns a valid servicenumber or -1.
8439 ***************************************************************************/
8441 int load_usershare_service(const char *servicename)
8443 SMB_STRUCT_STAT sbuf;
8444 const char *usersharepath = Globals.szUsersharePath;
8445 int max_user_shares = Globals.iUsershareMaxShares;
8446 int snum_template = -1;
8448 if (*usersharepath == 0 || max_user_shares == 0) {
8449 return -1;
8452 if (sys_stat(usersharepath, &sbuf) != 0) {
8453 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8454 usersharepath, strerror(errno) ));
8455 return -1;
8458 if (!S_ISDIR(sbuf.st_mode)) {
8459 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8460 usersharepath ));
8461 return -1;
8465 * This directory must be owned by root, and have the 't' bit set.
8466 * It also must not be writable by "other".
8469 #ifdef S_ISVTX
8470 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8471 #else
8472 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8473 #endif
8474 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8475 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8476 usersharepath ));
8477 return -1;
8480 /* Ensure the template share exists if it's set. */
8481 if (Globals.szUsershareTemplateShare[0]) {
8482 /* We can't use lp_servicenumber here as we are recommending that
8483 template shares have -valid=False set. */
8484 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8485 if (ServicePtrs[snum_template]->szService &&
8486 strequal(ServicePtrs[snum_template]->szService,
8487 Globals.szUsershareTemplateShare)) {
8488 break;
8492 if (snum_template == -1) {
8493 DEBUG(0,("load_usershare_service: usershare template share %s "
8494 "does not exist.\n",
8495 Globals.szUsershareTemplateShare ));
8496 return -1;
8500 return process_usershare_file(usersharepath, servicename, snum_template);
8503 /***************************************************************************
8504 Load all user defined shares from the user share directory.
8505 We only do this if we're enumerating the share list.
8506 This is the function that can delete usershares that have
8507 been removed.
8508 ***************************************************************************/
8510 int load_usershare_shares(void)
8512 SMB_STRUCT_DIR *dp;
8513 SMB_STRUCT_STAT sbuf;
8514 SMB_STRUCT_DIRENT *de;
8515 int num_usershares = 0;
8516 int max_user_shares = Globals.iUsershareMaxShares;
8517 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8518 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8519 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8520 int iService;
8521 int snum_template = -1;
8522 const char *usersharepath = Globals.szUsersharePath;
8523 int ret = lp_numservices();
8525 if (max_user_shares == 0 || *usersharepath == '\0') {
8526 return lp_numservices();
8529 if (sys_stat(usersharepath, &sbuf) != 0) {
8530 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8531 usersharepath, strerror(errno) ));
8532 return ret;
8536 * This directory must be owned by root, and have the 't' bit set.
8537 * It also must not be writable by "other".
8540 #ifdef S_ISVTX
8541 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8542 #else
8543 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8544 #endif
8545 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8546 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8547 usersharepath ));
8548 return ret;
8551 /* Ensure the template share exists if it's set. */
8552 if (Globals.szUsershareTemplateShare[0]) {
8553 /* We can't use lp_servicenumber here as we are recommending that
8554 template shares have -valid=False set. */
8555 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8556 if (ServicePtrs[snum_template]->szService &&
8557 strequal(ServicePtrs[snum_template]->szService,
8558 Globals.szUsershareTemplateShare)) {
8559 break;
8563 if (snum_template == -1) {
8564 DEBUG(0,("load_usershare_shares: usershare template share %s "
8565 "does not exist.\n",
8566 Globals.szUsershareTemplateShare ));
8567 return ret;
8571 /* Mark all existing usershares as pending delete. */
8572 for (iService = iNumServices - 1; iService >= 0; iService--) {
8573 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8574 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8578 dp = sys_opendir(usersharepath);
8579 if (!dp) {
8580 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8581 usersharepath, strerror(errno) ));
8582 return ret;
8585 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8586 (de = sys_readdir(dp));
8587 num_dir_entries++ ) {
8588 int r;
8589 const char *n = de->d_name;
8591 /* Ignore . and .. */
8592 if (*n == '.') {
8593 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8594 continue;
8598 if (n[0] == ':') {
8599 /* Temporary file used when creating a share. */
8600 num_tmp_dir_entries++;
8603 /* Allow 20% tmp entries. */
8604 if (num_tmp_dir_entries > allowed_tmp_entries) {
8605 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8606 "in directory %s\n",
8607 num_tmp_dir_entries, usersharepath));
8608 break;
8611 r = process_usershare_file(usersharepath, n, snum_template);
8612 if (r == 0) {
8613 /* Update the services count. */
8614 num_usershares++;
8615 if (num_usershares >= max_user_shares) {
8616 DEBUG(0,("load_usershare_shares: max user shares reached "
8617 "on file %s in directory %s\n",
8618 n, usersharepath ));
8619 break;
8621 } else if (r == -1) {
8622 num_bad_dir_entries++;
8625 /* Allow 20% bad entries. */
8626 if (num_bad_dir_entries > allowed_bad_entries) {
8627 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8628 "in directory %s\n",
8629 num_bad_dir_entries, usersharepath));
8630 break;
8633 /* Allow 20% bad entries. */
8634 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8635 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8636 "in directory %s\n",
8637 num_dir_entries, usersharepath));
8638 break;
8642 sys_closedir(dp);
8644 /* Sweep through and delete any non-refreshed usershares that are
8645 not currently in use. */
8646 for (iService = iNumServices - 1; iService >= 0; iService--) {
8647 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8648 if (conn_snum_used(iService)) {
8649 continue;
8651 /* Remove from the share ACL db. */
8652 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8653 lp_servicename(iService) ));
8654 delete_share_security(lp_servicename(iService));
8655 free_service_byindex(iService);
8659 return lp_numservices();
8662 /********************************************************
8663 Destroy global resources allocated in this file
8664 ********************************************************/
8666 void gfree_loadparm(void)
8668 struct file_lists *f;
8669 struct file_lists *next;
8670 int i;
8672 /* Free the file lists */
8674 f = file_lists;
8675 while( f ) {
8676 next = f->next;
8677 SAFE_FREE( f->name );
8678 SAFE_FREE( f->subfname );
8679 SAFE_FREE( f );
8680 f = next;
8683 /* Free resources allocated to services */
8685 for ( i = 0; i < iNumServices; i++ ) {
8686 if ( VALID(i) ) {
8687 free_service_byindex(i);
8691 SAFE_FREE( ServicePtrs );
8692 iNumServices = 0;
8694 /* Now release all resources allocated to global
8695 parameters and the default service */
8697 for (i = 0; parm_table[i].label; i++)
8699 if ( parm_table[i].type == P_STRING
8700 || parm_table[i].type == P_USTRING )
8702 string_free( (char**)parm_table[i].ptr );
8704 else if (parm_table[i].type == P_LIST) {
8705 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8711 /***************************************************************************
8712 Allow client apps to specify that they are a client
8713 ***************************************************************************/
8714 void lp_set_in_client(bool b)
8716 in_client = b;
8720 /***************************************************************************
8721 Determine if we're running in a client app
8722 ***************************************************************************/
8723 bool lp_is_in_client(void)
8725 return in_client;
8731 /***************************************************************************
8732 Load the services array from the services file. Return True on success,
8733 False on failure.
8734 ***************************************************************************/
8736 bool lp_load_ex(const char *pszFname,
8737 bool global_only,
8738 bool save_defaults,
8739 bool add_ipc,
8740 bool initialize_globals,
8741 bool allow_include_registry,
8742 bool allow_registry_shares)
8744 char *n2 = NULL;
8745 bool bRetval;
8746 struct param_opt_struct *data, *pdata;
8748 bRetval = False;
8750 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8752 bInGlobalSection = True;
8753 bGlobalOnly = global_only;
8754 bAllowIncludeRegistry = allow_include_registry;
8756 init_globals(! initialize_globals);
8757 debug_init();
8759 if (save_defaults) {
8760 init_locals();
8761 lp_save_defaults();
8764 /* We get sections first, so have to start 'behind' to make up */
8765 iServiceIndex = -1;
8767 if (Globals.param_opt != NULL) {
8768 data = Globals.param_opt;
8769 while (data) {
8770 string_free(&data->key);
8771 string_free(&data->value);
8772 TALLOC_FREE(data->list);
8773 pdata = data->next;
8774 SAFE_FREE(data);
8775 data = pdata;
8777 Globals.param_opt = NULL;
8780 if (lp_config_backend_is_file()) {
8781 n2 = alloc_sub_basic(get_current_username(),
8782 current_user_info.domain,
8783 pszFname);
8784 if (!n2) {
8785 smb_panic("lp_load_ex: out of memory");
8788 add_to_file_list(pszFname, n2);
8790 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8791 SAFE_FREE(n2);
8793 /* finish up the last section */
8794 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8795 if (bRetval) {
8796 if (iServiceIndex >= 0) {
8797 bRetval = service_ok(iServiceIndex);
8801 if (lp_config_backend_is_registry()) {
8802 /* config backend changed to registry in config file */
8804 * We need to use this extra global variable here to
8805 * survive restart: init_globals uses this as a default
8806 * for ConfigBackend. Otherwise, init_globals would
8807 * send us into an endless loop here.
8809 config_backend = CONFIG_BACKEND_REGISTRY;
8810 /* start over */
8811 DEBUG(1, ("lp_load_ex: changing to config backend "
8812 "registry\n"));
8813 init_globals(false);
8814 lp_kill_all_services();
8815 return lp_load_ex(pszFname, global_only, save_defaults,
8816 add_ipc, initialize_globals,
8817 allow_include_registry,
8818 allow_registry_shares);
8820 } else if (lp_config_backend_is_registry()) {
8821 bRetval = process_registry_globals();
8822 } else {
8823 DEBUG(0, ("Illegal config backend given: %d\n",
8824 lp_config_backend()));
8825 bRetval = false;
8828 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8829 bRetval = process_registry_shares();
8832 lp_add_auto_services(lp_auto_services());
8834 if (add_ipc) {
8835 /* When 'restrict anonymous = 2' guest connections to ipc$
8836 are denied */
8837 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8838 if ( lp_enable_asu_support() ) {
8839 lp_add_ipc("ADMIN$", false);
8843 set_server_role();
8844 set_default_server_announce_type();
8845 set_allowed_client_auth();
8847 bLoaded = True;
8849 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8850 /* if bWINSsupport is true and we are in the client */
8851 if (lp_is_in_client() && Globals.bWINSsupport) {
8852 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8855 init_iconv();
8857 bAllowIncludeRegistry = true;
8859 return (bRetval);
8862 bool lp_load(const char *pszFname,
8863 bool global_only,
8864 bool save_defaults,
8865 bool add_ipc,
8866 bool initialize_globals)
8868 return lp_load_ex(pszFname,
8869 global_only,
8870 save_defaults,
8871 add_ipc,
8872 initialize_globals,
8873 true, false);
8876 bool lp_load_initial_only(const char *pszFname)
8878 return lp_load_ex(pszFname,
8879 true,
8880 false,
8881 false,
8882 true,
8883 false,
8884 false);
8887 bool lp_load_with_registry_shares(const char *pszFname,
8888 bool global_only,
8889 bool save_defaults,
8890 bool add_ipc,
8891 bool initialize_globals)
8893 return lp_load_ex(pszFname,
8894 global_only,
8895 save_defaults,
8896 add_ipc,
8897 initialize_globals,
8898 true,
8899 true);
8902 /***************************************************************************
8903 Return the max number of services.
8904 ***************************************************************************/
8906 int lp_numservices(void)
8908 return (iNumServices);
8911 /***************************************************************************
8912 Display the contents of the services array in human-readable form.
8913 ***************************************************************************/
8915 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8917 int iService;
8919 if (show_defaults)
8920 defaults_saved = False;
8922 dump_globals(f);
8924 dump_a_service(&sDefault, f);
8926 for (iService = 0; iService < maxtoprint; iService++) {
8927 fprintf(f,"\n");
8928 lp_dump_one(f, show_defaults, iService);
8932 /***************************************************************************
8933 Display the contents of one service in human-readable form.
8934 ***************************************************************************/
8936 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8938 if (VALID(snum)) {
8939 if (ServicePtrs[snum]->szService[0] == '\0')
8940 return;
8941 dump_a_service(ServicePtrs[snum], f);
8945 /***************************************************************************
8946 Return the number of the service with the given name, or -1 if it doesn't
8947 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8948 getservicebyname()! This works ONLY if all services have been loaded, and
8949 does not copy the found service.
8950 ***************************************************************************/
8952 int lp_servicenumber(const char *pszServiceName)
8954 int iService;
8955 fstring serviceName;
8957 if (!pszServiceName) {
8958 return GLOBAL_SECTION_SNUM;
8961 for (iService = iNumServices - 1; iService >= 0; iService--) {
8962 if (VALID(iService) && ServicePtrs[iService]->szService) {
8964 * The substitution here is used to support %U is
8965 * service names
8967 fstrcpy(serviceName, ServicePtrs[iService]->szService);
8968 standard_sub_basic(get_current_username(),
8969 current_user_info.domain,
8970 serviceName,sizeof(serviceName));
8971 if (strequal(serviceName, pszServiceName)) {
8972 break;
8977 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
8978 time_t last_mod;
8980 if (!usershare_exists(iService, &last_mod)) {
8981 /* Remove the share security tdb entry for it. */
8982 delete_share_security(lp_servicename(iService));
8983 /* Remove it from the array. */
8984 free_service_byindex(iService);
8985 /* Doesn't exist anymore. */
8986 return GLOBAL_SECTION_SNUM;
8989 /* Has it been modified ? If so delete and reload. */
8990 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
8991 /* Remove it from the array. */
8992 free_service_byindex(iService);
8993 /* and now reload it. */
8994 iService = load_usershare_service(pszServiceName);
8998 if (iService < 0) {
8999 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9000 return GLOBAL_SECTION_SNUM;
9003 return (iService);
9006 bool share_defined(const char *service_name)
9008 return (lp_servicenumber(service_name) != -1);
9011 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9012 const char *sharename)
9014 struct share_params *result;
9015 char *sname;
9016 int snum;
9018 if (!(sname = SMB_STRDUP(sharename))) {
9019 return NULL;
9022 snum = find_service(sname);
9023 SAFE_FREE(sname);
9025 if (snum < 0) {
9026 return NULL;
9029 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9030 DEBUG(0, ("talloc failed\n"));
9031 return NULL;
9034 result->service = snum;
9035 return result;
9038 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9040 struct share_iterator *result;
9042 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9043 DEBUG(0, ("talloc failed\n"));
9044 return NULL;
9047 result->next_id = 0;
9048 return result;
9051 struct share_params *next_share(struct share_iterator *list)
9053 struct share_params *result;
9055 while (!lp_snum_ok(list->next_id) &&
9056 (list->next_id < lp_numservices())) {
9057 list->next_id += 1;
9060 if (list->next_id >= lp_numservices()) {
9061 return NULL;
9064 if (!(result = TALLOC_P(list, struct share_params))) {
9065 DEBUG(0, ("talloc failed\n"));
9066 return NULL;
9069 result->service = list->next_id;
9070 list->next_id += 1;
9071 return result;
9074 struct share_params *next_printer(struct share_iterator *list)
9076 struct share_params *result;
9078 while ((result = next_share(list)) != NULL) {
9079 if (lp_print_ok(result->service)) {
9080 break;
9083 return result;
9087 * This is a hack for a transition period until we transformed all code from
9088 * service numbers to struct share_params.
9091 struct share_params *snum2params_static(int snum)
9093 static struct share_params result;
9094 result.service = snum;
9095 return &result;
9098 /*******************************************************************
9099 A useful volume label function.
9100 ********************************************************************/
9102 const char *volume_label(int snum)
9104 char *ret;
9105 const char *label = lp_volume(snum);
9106 if (!*label) {
9107 label = lp_servicename(snum);
9110 /* This returns a 33 byte guarenteed null terminated string. */
9111 ret = talloc_strndup(talloc_tos(), label, 32);
9112 if (!ret) {
9113 return "";
9115 return ret;
9118 /*******************************************************************
9119 Set the server type we will announce as via nmbd.
9120 ********************************************************************/
9122 static void set_default_server_announce_type(void)
9124 default_server_announce = 0;
9125 default_server_announce |= SV_TYPE_WORKSTATION;
9126 default_server_announce |= SV_TYPE_SERVER;
9127 default_server_announce |= SV_TYPE_SERVER_UNIX;
9129 /* note that the flag should be set only if we have a
9130 printer service but nmbd doesn't actually load the
9131 services so we can't tell --jerry */
9133 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9135 switch (lp_announce_as()) {
9136 case ANNOUNCE_AS_NT_SERVER:
9137 default_server_announce |= SV_TYPE_SERVER_NT;
9138 /* fall through... */
9139 case ANNOUNCE_AS_NT_WORKSTATION:
9140 default_server_announce |= SV_TYPE_NT;
9141 break;
9142 case ANNOUNCE_AS_WIN95:
9143 default_server_announce |= SV_TYPE_WIN95_PLUS;
9144 break;
9145 case ANNOUNCE_AS_WFW:
9146 default_server_announce |= SV_TYPE_WFW;
9147 break;
9148 default:
9149 break;
9152 switch (lp_server_role()) {
9153 case ROLE_DOMAIN_MEMBER:
9154 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9155 break;
9156 case ROLE_DOMAIN_PDC:
9157 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9158 break;
9159 case ROLE_DOMAIN_BDC:
9160 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9161 break;
9162 case ROLE_STANDALONE:
9163 default:
9164 break;
9166 if (lp_time_server())
9167 default_server_announce |= SV_TYPE_TIME_SOURCE;
9169 if (lp_host_msdfs())
9170 default_server_announce |= SV_TYPE_DFS_SERVER;
9173 /***********************************************************
9174 returns role of Samba server
9175 ************************************************************/
9177 int lp_server_role(void)
9179 return server_role;
9182 /***********************************************************
9183 If we are PDC then prefer us as DMB
9184 ************************************************************/
9186 bool lp_domain_master(void)
9188 if (Globals.iDomainMaster == Auto)
9189 return (lp_server_role() == ROLE_DOMAIN_PDC);
9191 return (bool)Globals.iDomainMaster;
9194 /***********************************************************
9195 If we are DMB then prefer us as LMB
9196 ************************************************************/
9198 bool lp_preferred_master(void)
9200 if (Globals.iPreferredMaster == Auto)
9201 return (lp_local_master() && lp_domain_master());
9203 return (bool)Globals.iPreferredMaster;
9206 /*******************************************************************
9207 Remove a service.
9208 ********************************************************************/
9210 void lp_remove_service(int snum)
9212 ServicePtrs[snum]->valid = False;
9213 invalid_services[num_invalid_services++] = snum;
9216 /*******************************************************************
9217 Copy a service.
9218 ********************************************************************/
9220 void lp_copy_service(int snum, const char *new_name)
9222 do_section(new_name, NULL);
9223 if (snum >= 0) {
9224 snum = lp_servicenumber(new_name);
9225 if (snum >= 0)
9226 lp_do_parameter(snum, "copy", lp_servicename(snum));
9231 /*******************************************************************
9232 Get the default server type we will announce as via nmbd.
9233 ********************************************************************/
9235 int lp_default_server_announce(void)
9237 return default_server_announce;
9240 /*******************************************************************
9241 Split the announce version into major and minor numbers.
9242 ********************************************************************/
9244 int lp_major_announce_version(void)
9246 static bool got_major = False;
9247 static int major_version = DEFAULT_MAJOR_VERSION;
9248 char *vers;
9249 char *p;
9251 if (got_major)
9252 return major_version;
9254 got_major = True;
9255 if ((vers = lp_announce_version()) == NULL)
9256 return major_version;
9258 if ((p = strchr_m(vers, '.')) == 0)
9259 return major_version;
9261 *p = '\0';
9262 major_version = atoi(vers);
9263 return major_version;
9266 int lp_minor_announce_version(void)
9268 static bool got_minor = False;
9269 static int minor_version = DEFAULT_MINOR_VERSION;
9270 char *vers;
9271 char *p;
9273 if (got_minor)
9274 return minor_version;
9276 got_minor = True;
9277 if ((vers = lp_announce_version()) == NULL)
9278 return minor_version;
9280 if ((p = strchr_m(vers, '.')) == 0)
9281 return minor_version;
9283 p++;
9284 minor_version = atoi(p);
9285 return minor_version;
9288 /***********************************************************
9289 Set the global name resolution order (used in smbclient).
9290 ************************************************************/
9292 void lp_set_name_resolve_order(const char *new_order)
9294 string_set(&Globals.szNameResolveOrder, new_order);
9297 const char *lp_printername(int snum)
9299 const char *ret = _lp_printername(snum);
9300 if (ret == NULL || (ret != NULL && *ret == '\0'))
9301 ret = lp_const_servicename(snum);
9303 return ret;
9307 /***********************************************************
9308 Allow daemons such as winbindd to fix their logfile name.
9309 ************************************************************/
9311 void lp_set_logfile(const char *name)
9313 string_set(&Globals.szLogFile, name);
9314 debug_set_logfile(name);
9317 /*******************************************************************
9318 Return the max print jobs per queue.
9319 ********************************************************************/
9321 int lp_maxprintjobs(int snum)
9323 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9324 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9325 maxjobs = PRINT_MAX_JOBID - 1;
9327 return maxjobs;
9330 const char *lp_printcapname(void)
9332 if ((Globals.szPrintcapname != NULL) &&
9333 (Globals.szPrintcapname[0] != '\0'))
9334 return Globals.szPrintcapname;
9336 if (sDefault.iPrinting == PRINT_CUPS) {
9337 #ifdef HAVE_CUPS
9338 return "cups";
9339 #else
9340 return "lpstat";
9341 #endif
9344 if (sDefault.iPrinting == PRINT_BSD)
9345 return "/etc/printcap";
9347 return PRINTCAP_NAME;
9350 /*******************************************************************
9351 Ensure we don't use sendfile if server smb signing is active.
9352 ********************************************************************/
9354 static uint32 spoolss_state;
9356 bool lp_disable_spoolss( void )
9358 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9359 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9361 return spoolss_state == SVCCTL_STOPPED ? True : False;
9364 void lp_set_spoolss_state( uint32 state )
9366 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9368 spoolss_state = state;
9371 uint32 lp_get_spoolss_state( void )
9373 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9376 /*******************************************************************
9377 Ensure we don't use sendfile if server smb signing is active.
9378 ********************************************************************/
9380 bool lp_use_sendfile(int snum)
9382 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9383 if (Protocol < PROTOCOL_NT1) {
9384 return False;
9386 return (_lp_use_sendfile(snum) &&
9387 (get_remote_arch() != RA_WIN95) &&
9388 !srv_is_signing_active());
9391 /*******************************************************************
9392 Turn off sendfile if we find the underlying OS doesn't support it.
9393 ********************************************************************/
9395 void set_use_sendfile(int snum, bool val)
9397 if (LP_SNUM_OK(snum))
9398 ServicePtrs[snum]->bUseSendfile = val;
9399 else
9400 sDefault.bUseSendfile = val;
9403 /*******************************************************************
9404 Turn off storing DOS attributes if this share doesn't support it.
9405 ********************************************************************/
9407 void set_store_dos_attributes(int snum, bool val)
9409 if (!LP_SNUM_OK(snum))
9410 return;
9411 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9414 void lp_set_mangling_method(const char *new_method)
9416 string_set(&Globals.szManglingMethod, new_method);
9419 /*******************************************************************
9420 Global state for POSIX pathname processing.
9421 ********************************************************************/
9423 static bool posix_pathnames;
9425 bool lp_posix_pathnames(void)
9427 return posix_pathnames;
9430 /*******************************************************************
9431 Change everything needed to ensure POSIX pathname processing (currently
9432 not much).
9433 ********************************************************************/
9435 void lp_set_posix_pathnames(void)
9437 posix_pathnames = True;
9440 /*******************************************************************
9441 Global state for POSIX lock processing - CIFS unix extensions.
9442 ********************************************************************/
9444 bool posix_default_lock_was_set;
9445 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9447 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9449 if (posix_default_lock_was_set) {
9450 return posix_cifsx_locktype;
9451 } else {
9452 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9456 /*******************************************************************
9457 ********************************************************************/
9459 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9461 posix_default_lock_was_set = True;
9462 posix_cifsx_locktype = val;
9465 int lp_min_receive_file_size(void)
9467 if (Globals.iminreceivefile < 0) {
9468 return 0;
9470 return MIN(Globals.iminreceivefile, BUFFER_SIZE);