1/* 2 Unix SMB/CIFS implementation. 3 Parameter loading functions 4 Copyright (C) Karl Auer 1993-1998 5 6 Largely re-written by Andrew Tridgell, September 1994 7 8 Copyright (C) Simo Sorce 2001 9 Copyright (C) Alexander Bokovoy 2002 10 Copyright (C) Stefan (metze) Metzmacher 2002 11 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003. 12 Copyright (C) James Myers 2003 <myersjj@samba.org> 13 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007 14 15 This program is free software; you can redistribute it and/or modify 16 it under the terms of the GNU General Public License as published by 17 the Free Software Foundation; either version 3 of the License, or 18 (at your option) any later version. 19 20 This program is distributed in the hope that it will be useful, 21 but WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 GNU General Public License for more details. 24 25 You should have received a copy of the GNU General Public License 26 along with this program. If not, see <http://www.gnu.org/licenses/>. 27*/ 28 29/* 30 * Load parameters. 31 * 32 * This module provides suitable callback functions for the params 33 * module. It builds the internal table of service details which is 34 * then used by the rest of the server. 35 * 36 * To add a parameter: 37 * 38 * 1) add it to the global or service structure definition 39 * 2) add it to the parm_table 40 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING()) 41 * 4) If it's a global then initialise it in init_globals. If a local 42 * (ie. service) parameter then initialise it in the sDefault structure 43 * 44 * 45 * Notes: 46 * The configuration file is processed sequentially for speed. It is NOT 47 * accessed randomly as happens in 'real' Windows. For this reason, there 48 * is a fair bit of sequence-dependent code here - ie., code which assumes 49 * that certain things happen before others. In particular, the code which 50 * happens at the boundary between sections is delicately poised, so be 51 * careful! 52 * 53 */ 54 55#include "includes.h" 56#include "version.h" 57#include "dynconfig/dynconfig.h" 58#include "system/time.h" 59#include "system/locale.h" 60#include "system/network.h" /* needed for TCP_NODELAY */ 61#include "smb_server/smb_server.h" 62#include "libcli/raw/signing.h" 63#include "../lib/util/dlinklist.h" 64#include "param/param.h" 65#include "param/loadparm.h" 66#include "libcli/raw/libcliraw.h" 67#include "rpc_server/common/common.h" 68#include "lib/socket/socket.h" 69#include "auth/gensec/gensec.h" 70 71#define standard_sub_basic talloc_strdup 72 73static bool do_parameter(const char *, const char *, void *); 74static bool defaults_saved = false; 75 76/** 77 * This structure describes global (ie., server-wide) parameters. 78 */ 79struct loadparm_global 80{ 81 enum server_role server_role; 82 83 const char **smb_ports; 84 char *ncalrpc_dir; 85 char *dos_charset; 86 char *unix_charset; 87 char *display_charset; 88 char *szLockDir; 89 char *szModulesDir; 90 char *szPidDir; 91 char *szSetupDir; 92 char *szServerString; 93 char *szAutoServices; 94 char *szPasswdChat; 95 char *szShareBackend; 96 char *szSAM_URL; 97 char *szIDMAP_URL; 98 char *szSECRETS_URL; 99 char *szSPOOLSS_URL; 100 char *szWINS_CONFIG_URL; 101 char *szWINS_URL; 102 char *szPrivateDir; 103 const char **szPasswordServers; 104 char *szSocketOptions; 105 char *szRealm; 106 const char **szWINSservers; 107 const char **szInterfaces; 108 char *szSocketAddress; 109 char *szAnnounceVersion; /* This is initialised in init_globals */ 110 char *szWorkgroup; 111 char *szNetbiosName; 112 const char **szNetbiosAliases; 113 char *szNetbiosScope; 114 char *szDomainOtherSIDs; 115 const char **szNameResolveOrder; 116 const char **dcerpc_ep_servers; 117 const char **server_services; 118 char *ntptr_providor; 119 char *szWinbindSeparator; 120 char *szWinbinddPrivilegedSocketDirectory; 121 char *szWinbinddSocketDirectory; 122 char *szTemplateShell; 123 char *szTemplateHomedir; 124 int bWinbindSealedPipes; 125 int bIdmapTrustedOnly; 126 char *swat_directory; 127 int tls_enabled; 128 char *tls_keyfile; 129 char *tls_certfile; 130 char *tls_cafile; 131 char *tls_crlfile; 132 char *tls_dhpfile; 133 char *logfile; 134 char *panic_action; 135 int max_mux; 136 int debuglevel; 137 int max_xmit; 138 int pwordlevel; 139 int srv_maxprotocol; 140 int srv_minprotocol; 141 int cli_maxprotocol; 142 int cli_minprotocol; 143 int security; 144 int paranoid_server_security; 145 int max_wins_ttl; 146 int min_wins_ttl; 147 int announce_as; /* This is initialised in init_globals */ 148 int nbt_port; 149 int dgram_port; 150 int cldap_port; 151 int krb5_port; 152 int kpasswd_port; 153 int web_port; 154 char *socket_options; 155 int bWINSsupport; 156 int bWINSdnsProxy; 157 char *szWINSHook; 158 int bLocalMaster; 159 int bPreferredMaster; 160 int bEncryptPasswords; 161 int bNullPasswords; 162 int bObeyPamRestrictions; 163 int bLargeReadwrite; 164 int bReadRaw; 165 int bWriteRaw; 166 int bTimeServer; 167 int bBindInterfacesOnly; 168 int bNTSmbSupport; 169 int bNTStatusSupport; 170 int bLanmanAuth; 171 int bNTLMAuth; 172 int bUseSpnego; 173 int server_signing; 174 int client_signing; 175 int bClientPlaintextAuth; 176 int bClientLanManAuth; 177 int bClientNTLMv2Auth; 178 int client_use_spnego_principal; 179 int bHostMSDfs; 180 int bUnicode; 181 int bUnixExtensions; 182 int bDisableNetbios; 183 int bRpcBigEndian; 184 char *szNTPSignDSocketDirectory; 185 struct parmlist_entry *param_opt; 186}; 187 188 189/** 190 * This structure describes a single service. 191 */ 192struct loadparm_service 193{ 194 char *szService; 195 char *szPath; 196 char *szCopy; 197 char *szInclude; 198 char *szPrintername; 199 char **szHostsallow; 200 char **szHostsdeny; 201 char *comment; 202 char *volume; 203 char *fstype; 204 char **ntvfs_handler; 205 int iMaxPrintJobs; 206 int iMaxConnections; 207 int iCSCPolicy; 208 int bAvailable; 209 int bBrowseable; 210 int bRead_only; 211 int bPrint_ok; 212 int bMap_system; 213 int bMap_hidden; 214 int bMap_archive; 215 int bStrictLocking; 216 int bOplocks; 217 int iCreate_mask; 218 int iCreate_force_mode; 219 int iDir_mask; 220 int iDir_force_mode; 221 int *copymap; 222 int bMSDfsRoot; 223 int bStrictSync; 224 int bCIFileSystem; 225 struct parmlist_entry *param_opt; 226 227 char dummy[3]; /* for alignment */ 228}; 229 230 231#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct)) 232 233 234/* prototypes for the special type handlers */ 235static bool handle_include(struct loadparm_context *lp_ctx, 236 const char *pszParmValue, char **ptr); 237static bool handle_copy(struct loadparm_context *lp_ctx, 238 const char *pszParmValue, char **ptr); 239static bool handle_debuglevel(struct loadparm_context *lp_ctx, 240 const char *pszParmValue, char **ptr); 241static bool handle_logfile(struct loadparm_context *lp_ctx, 242 const char *pszParmValue, char **ptr); 243 244static const struct enum_list enum_protocol[] = { 245 {PROTOCOL_SMB2, "SMB2"}, 246 {PROTOCOL_NT1, "NT1"}, 247 {PROTOCOL_LANMAN2, "LANMAN2"}, 248 {PROTOCOL_LANMAN1, "LANMAN1"}, 249 {PROTOCOL_CORE, "CORE"}, 250 {PROTOCOL_COREPLUS, "COREPLUS"}, 251 {PROTOCOL_COREPLUS, "CORE+"}, 252 {-1, NULL} 253}; 254 255static const struct enum_list enum_security[] = { 256 {SEC_SHARE, "SHARE"}, 257 {SEC_USER, "USER"}, 258 {-1, NULL} 259}; 260 261static const struct enum_list enum_announce_as[] = { 262 {ANNOUNCE_AS_NT_SERVER, "NT"}, 263 {ANNOUNCE_AS_NT_SERVER, "NT Server"}, 264 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"}, 265 {ANNOUNCE_AS_WIN95, "win95"}, 266 {ANNOUNCE_AS_WFW, "WfW"}, 267 {-1, NULL} 268}; 269 270static const struct enum_list enum_bool_auto[] = { 271 {false, "No"}, 272 {false, "False"}, 273 {false, "0"}, 274 {true, "Yes"}, 275 {true, "True"}, 276 {true, "1"}, 277 {Auto, "Auto"}, 278 {-1, NULL} 279}; 280 281/* Client-side offline caching policy types */ 282enum csc_policy { 283 CSC_POLICY_MANUAL=0, 284 CSC_POLICY_DOCUMENTS=1, 285 CSC_POLICY_PROGRAMS=2, 286 CSC_POLICY_DISABLE=3 287}; 288 289static const struct enum_list enum_csc_policy[] = { 290 {CSC_POLICY_MANUAL, "manual"}, 291 {CSC_POLICY_DOCUMENTS, "documents"}, 292 {CSC_POLICY_PROGRAMS, "programs"}, 293 {CSC_POLICY_DISABLE, "disable"}, 294 {-1, NULL} 295}; 296 297/* SMB signing types. */ 298static const struct enum_list enum_smb_signing_vals[] = { 299 {SMB_SIGNING_OFF, "No"}, 300 {SMB_SIGNING_OFF, "False"}, 301 {SMB_SIGNING_OFF, "0"}, 302 {SMB_SIGNING_OFF, "Off"}, 303 {SMB_SIGNING_OFF, "disabled"}, 304 {SMB_SIGNING_SUPPORTED, "Yes"}, 305 {SMB_SIGNING_SUPPORTED, "True"}, 306 {SMB_SIGNING_SUPPORTED, "1"}, 307 {SMB_SIGNING_SUPPORTED, "On"}, 308 {SMB_SIGNING_SUPPORTED, "enabled"}, 309 {SMB_SIGNING_REQUIRED, "required"}, 310 {SMB_SIGNING_REQUIRED, "mandatory"}, 311 {SMB_SIGNING_REQUIRED, "force"}, 312 {SMB_SIGNING_REQUIRED, "forced"}, 313 {SMB_SIGNING_REQUIRED, "enforced"}, 314 {SMB_SIGNING_AUTO, "auto"}, 315 {-1, NULL} 316}; 317 318static const struct enum_list enum_server_role[] = { 319 {ROLE_STANDALONE, "standalone"}, 320 {ROLE_DOMAIN_MEMBER, "member server"}, 321 {ROLE_DOMAIN_MEMBER, "member"}, 322 {ROLE_DOMAIN_CONTROLLER, "domain controller"}, 323 {ROLE_DOMAIN_CONTROLLER, "dc"}, 324 {-1, NULL} 325}; 326 327 328#define GLOBAL_VAR(name) offsetof(struct loadparm_global, name) 329#define LOCAL_VAR(name) offsetof(struct loadparm_service, name) 330 331static struct parm_struct parm_table[] = { 332 {"server role", P_ENUM, P_GLOBAL, GLOBAL_VAR(server_role), NULL, enum_server_role}, 333 334 {"dos charset", P_STRING, P_GLOBAL, GLOBAL_VAR(dos_charset), NULL, NULL}, 335 {"unix charset", P_STRING, P_GLOBAL, GLOBAL_VAR(unix_charset), NULL, NULL}, 336 {"ncalrpc dir", P_STRING, P_GLOBAL, GLOBAL_VAR(ncalrpc_dir), NULL, NULL}, 337 {"display charset", P_STRING, P_GLOBAL, GLOBAL_VAR(display_charset), NULL, NULL}, 338 {"comment", P_STRING, P_LOCAL, LOCAL_VAR(comment), NULL, NULL}, 339 {"path", P_STRING, P_LOCAL, LOCAL_VAR(szPath), NULL, NULL}, 340 {"directory", P_STRING, P_LOCAL, LOCAL_VAR(szPath), NULL, NULL}, 341 {"workgroup", P_USTRING, P_GLOBAL, GLOBAL_VAR(szWorkgroup), NULL, NULL}, 342 {"realm", P_STRING, P_GLOBAL, GLOBAL_VAR(szRealm), NULL, NULL}, 343 {"netbios name", P_USTRING, P_GLOBAL, GLOBAL_VAR(szNetbiosName), NULL, NULL}, 344 {"netbios aliases", P_LIST, P_GLOBAL, GLOBAL_VAR(szNetbiosAliases), NULL, NULL}, 345 {"netbios scope", P_USTRING, P_GLOBAL, GLOBAL_VAR(szNetbiosScope), NULL, NULL}, 346 {"server string", P_STRING, P_GLOBAL, GLOBAL_VAR(szServerString), NULL, NULL}, 347 {"interfaces", P_LIST, P_GLOBAL, GLOBAL_VAR(szInterfaces), NULL, NULL}, 348 {"bind interfaces only", P_BOOL, P_GLOBAL, GLOBAL_VAR(bBindInterfacesOnly), NULL, NULL}, 349 {"ntvfs handler", P_LIST, P_LOCAL, LOCAL_VAR(ntvfs_handler), NULL, NULL}, 350 {"ntptr providor", P_STRING, P_GLOBAL, GLOBAL_VAR(ntptr_providor), NULL, NULL}, 351 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, GLOBAL_VAR(dcerpc_ep_servers), NULL, NULL}, 352 {"server services", P_LIST, P_GLOBAL, GLOBAL_VAR(server_services), NULL, NULL}, 353 354 {"security", P_ENUM, P_GLOBAL, GLOBAL_VAR(security), NULL, enum_security}, 355 {"encrypt passwords", P_BOOL, P_GLOBAL, GLOBAL_VAR(bEncryptPasswords), NULL, NULL}, 356 {"null passwords", P_BOOL, P_GLOBAL, GLOBAL_VAR(bNullPasswords), NULL, NULL}, 357 {"obey pam restrictions", P_BOOL, P_GLOBAL, GLOBAL_VAR(bObeyPamRestrictions), NULL, NULL}, 358 {"password server", P_LIST, P_GLOBAL, GLOBAL_VAR(szPasswordServers), NULL, NULL}, 359 {"sam database", P_STRING, P_GLOBAL, GLOBAL_VAR(szSAM_URL), NULL, NULL}, 360 {"idmap database", P_STRING, P_GLOBAL, GLOBAL_VAR(szIDMAP_URL), NULL, NULL}, 361 {"secrets database", P_STRING, P_GLOBAL, GLOBAL_VAR(szSECRETS_URL), NULL, NULL}, 362 {"spoolss database", P_STRING, P_GLOBAL, GLOBAL_VAR(szSPOOLSS_URL), NULL, NULL}, 363 {"wins config database", P_STRING, P_GLOBAL, GLOBAL_VAR(szWINS_CONFIG_URL), NULL, NULL}, 364 {"wins database", P_STRING, P_GLOBAL, GLOBAL_VAR(szWINS_URL), NULL, NULL}, 365 {"private dir", P_STRING, P_GLOBAL, GLOBAL_VAR(szPrivateDir), NULL, NULL}, 366 {"passwd chat", P_STRING, P_GLOBAL, GLOBAL_VAR(szPasswdChat), NULL, NULL}, 367 {"password level", P_INTEGER, P_GLOBAL, GLOBAL_VAR(pwordlevel), NULL, NULL}, 368 {"lanman auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bLanmanAuth), NULL, NULL}, 369 {"ntlm auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bNTLMAuth), NULL, NULL}, 370 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bClientNTLMv2Auth), NULL, NULL}, 371 {"client lanman auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bClientLanManAuth), NULL, NULL}, 372 {"client plaintext auth", P_BOOL, P_GLOBAL, GLOBAL_VAR(bClientPlaintextAuth), NULL, NULL}, 373 {"client use spnego principal", P_BOOL, P_GLOBAL, GLOBAL_VAR(client_use_spnego_principal), NULL, NULL}, 374 375 {"read only", P_BOOL, P_LOCAL, LOCAL_VAR(bRead_only), NULL, NULL}, 376 377 {"create mask", P_OCTAL, P_LOCAL, LOCAL_VAR(iCreate_mask), NULL, NULL}, 378 {"force create mode", P_OCTAL, P_LOCAL, LOCAL_VAR(iCreate_force_mode), NULL, NULL}, 379 {"directory mask", P_OCTAL, P_LOCAL, LOCAL_VAR(iDir_mask), NULL, NULL}, 380 {"force directory mode", P_OCTAL, P_LOCAL, LOCAL_VAR(iDir_force_mode), NULL, NULL}, 381 382 {"hosts allow", P_LIST, P_LOCAL, LOCAL_VAR(szHostsallow), NULL, NULL}, 383 {"hosts deny", P_LIST, P_LOCAL, LOCAL_VAR(szHostsdeny), NULL, NULL}, 384 385 {"log level", P_INTEGER, P_GLOBAL, GLOBAL_VAR(debuglevel), handle_debuglevel, NULL}, 386 {"debuglevel", P_INTEGER, P_GLOBAL, GLOBAL_VAR(debuglevel), handle_debuglevel, NULL}, 387 {"log file", P_STRING, P_GLOBAL, GLOBAL_VAR(logfile), handle_logfile, NULL}, 388 389 {"smb ports", P_LIST, P_GLOBAL, GLOBAL_VAR(smb_ports), NULL, NULL}, 390 {"nbt port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(nbt_port), NULL, NULL}, 391 {"dgram port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(dgram_port), NULL, NULL}, 392 {"cldap port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(cldap_port), NULL, NULL}, 393 {"krb5 port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(krb5_port), NULL, NULL}, 394 {"kpasswd port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(kpasswd_port), NULL, NULL}, 395 {"web port", P_INTEGER, P_GLOBAL, GLOBAL_VAR(web_port), NULL, NULL}, 396 {"tls enabled", P_BOOL, P_GLOBAL, GLOBAL_VAR(tls_enabled), NULL, NULL}, 397 {"tls keyfile", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_keyfile), NULL, NULL}, 398 {"tls certfile", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_certfile), NULL, NULL}, 399 {"tls cafile", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_cafile), NULL, NULL}, 400 {"tls crlfile", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_crlfile), NULL, NULL}, 401 {"tls dh params file", P_STRING, P_GLOBAL, GLOBAL_VAR(tls_dhpfile), NULL, NULL}, 402 {"swat directory", P_STRING, P_GLOBAL, GLOBAL_VAR(swat_directory), NULL, NULL}, 403 {"large readwrite", P_BOOL, P_GLOBAL, GLOBAL_VAR(bLargeReadwrite), NULL, NULL}, 404 {"server max protocol", P_ENUM, P_GLOBAL, GLOBAL_VAR(srv_maxprotocol), NULL, enum_protocol}, 405 {"server min protocol", P_ENUM, P_GLOBAL, GLOBAL_VAR(srv_minprotocol), NULL, enum_protocol}, 406 {"client max protocol", P_ENUM, P_GLOBAL, GLOBAL_VAR(cli_maxprotocol), NULL, enum_protocol}, 407 {"client min protocol", P_ENUM, P_GLOBAL, GLOBAL_VAR(cli_minprotocol), NULL, enum_protocol}, 408 {"unicode", P_BOOL, P_GLOBAL, GLOBAL_VAR(bUnicode), NULL, NULL}, 409 {"read raw", P_BOOL, P_GLOBAL, GLOBAL_VAR(bReadRaw), NULL, NULL}, 410 {"write raw", P_BOOL, P_GLOBAL, GLOBAL_VAR(bWriteRaw), NULL, NULL}, 411 {"disable netbios", P_BOOL, P_GLOBAL, GLOBAL_VAR(bDisableNetbios), NULL, NULL}, 412 413 {"nt status support", P_BOOL, P_GLOBAL, GLOBAL_VAR(bNTStatusSupport), NULL, NULL}, 414 415 {"announce version", P_STRING, P_GLOBAL, GLOBAL_VAR(szAnnounceVersion), NULL, NULL}, 416 {"announce as", P_ENUM, P_GLOBAL, GLOBAL_VAR(announce_as), NULL, enum_announce_as}, 417 {"max mux", P_INTEGER, P_GLOBAL, GLOBAL_VAR(max_mux), NULL, NULL}, 418 {"max xmit", P_BYTES, P_GLOBAL, GLOBAL_VAR(max_xmit), NULL, NULL}, 419 420 {"name resolve order", P_LIST, P_GLOBAL, GLOBAL_VAR(szNameResolveOrder), NULL, NULL}, 421 {"max wins ttl", P_INTEGER, P_GLOBAL, GLOBAL_VAR(max_wins_ttl), NULL, NULL}, 422 {"min wins ttl", P_INTEGER, P_GLOBAL, GLOBAL_VAR(min_wins_ttl), NULL, NULL}, 423 {"time server", P_BOOL, P_GLOBAL, GLOBAL_VAR(bTimeServer), NULL, NULL}, 424 {"unix extensions", P_BOOL, P_GLOBAL, GLOBAL_VAR(bUnixExtensions), NULL, NULL}, 425 {"use spnego", P_BOOL, P_GLOBAL, GLOBAL_VAR(bUseSpnego), NULL, NULL}, 426 {"server signing", P_ENUM, P_GLOBAL, GLOBAL_VAR(server_signing), NULL, enum_smb_signing_vals}, 427 {"client signing", P_ENUM, P_GLOBAL, GLOBAL_VAR(client_signing), NULL, enum_smb_signing_vals}, 428 {"rpc big endian", P_BOOL, P_GLOBAL, GLOBAL_VAR(bRpcBigEndian), NULL, NULL}, 429 430 {"max connections", P_INTEGER, P_LOCAL, LOCAL_VAR(iMaxConnections), NULL, NULL}, 431 {"paranoid server security", P_BOOL, P_GLOBAL, GLOBAL_VAR(paranoid_server_security), NULL, NULL}, 432 {"socket options", P_STRING, P_GLOBAL, GLOBAL_VAR(socket_options), NULL, NULL}, 433 434 {"strict sync", P_BOOL, P_LOCAL, LOCAL_VAR(bStrictSync), NULL, NULL}, 435 {"case insensitive filesystem", P_BOOL, P_LOCAL, LOCAL_VAR(bCIFileSystem), NULL, NULL}, 436 437 {"max print jobs", P_INTEGER, P_LOCAL, LOCAL_VAR(iMaxPrintJobs), NULL, NULL}, 438 {"printable", P_BOOL, P_LOCAL, LOCAL_VAR(bPrint_ok), NULL, NULL}, 439 {"print ok", P_BOOL, P_LOCAL, LOCAL_VAR(bPrint_ok), NULL, NULL}, 440 441 {"printer name", P_STRING, P_LOCAL, LOCAL_VAR(szPrintername), NULL, NULL}, 442 {"printer", P_STRING, P_LOCAL, LOCAL_VAR(szPrintername), NULL, NULL}, 443 444 {"map system", P_BOOL, P_LOCAL, LOCAL_VAR(bMap_system), NULL, NULL}, 445 {"map hidden", P_BOOL, P_LOCAL, LOCAL_VAR(bMap_hidden), NULL, NULL}, 446 {"map archive", P_BOOL, P_LOCAL, LOCAL_VAR(bMap_archive), NULL, NULL}, 447 448 {"preferred master", P_ENUM, P_GLOBAL, GLOBAL_VAR(bPreferredMaster), NULL, enum_bool_auto}, 449 {"prefered master", P_ENUM, P_GLOBAL, GLOBAL_VAR(bPreferredMaster), NULL, enum_bool_auto}, 450 {"local master", P_BOOL, P_GLOBAL, GLOBAL_VAR(bLocalMaster), NULL, NULL}, 451 {"browseable", P_BOOL, P_LOCAL, LOCAL_VAR(bBrowseable), NULL, NULL}, 452 {"browsable", P_BOOL, P_LOCAL, LOCAL_VAR(bBrowseable), NULL, NULL}, 453 454 {"wins server", P_LIST, P_GLOBAL, GLOBAL_VAR(szWINSservers), NULL, NULL}, 455 {"wins support", P_BOOL, P_GLOBAL, GLOBAL_VAR(bWINSsupport), NULL, NULL}, 456 {"dns proxy", P_BOOL, P_GLOBAL, GLOBAL_VAR(bWINSdnsProxy), NULL, NULL}, 457 {"wins hook", P_STRING, P_GLOBAL, GLOBAL_VAR(szWINSHook), NULL, NULL}, 458 459 {"csc policy", P_ENUM, P_LOCAL, LOCAL_VAR(iCSCPolicy), NULL, enum_csc_policy}, 460 461 {"strict locking", P_BOOL, P_LOCAL, LOCAL_VAR(bStrictLocking), NULL, NULL}, 462 {"oplocks", P_BOOL, P_LOCAL, LOCAL_VAR(bOplocks), NULL, NULL}, 463 464 {"share backend", P_STRING, P_GLOBAL, GLOBAL_VAR(szShareBackend), NULL, NULL}, 465 {"preload", P_STRING, P_GLOBAL, GLOBAL_VAR(szAutoServices), NULL, NULL}, 466 {"auto services", P_STRING, P_GLOBAL, GLOBAL_VAR(szAutoServices), NULL, NULL}, 467 {"lock dir", P_STRING, P_GLOBAL, GLOBAL_VAR(szLockDir), NULL, NULL}, 468 {"lock directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szLockDir), NULL, NULL}, 469 {"modules dir", P_STRING, P_GLOBAL, GLOBAL_VAR(szModulesDir), NULL, NULL}, 470 {"pid directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szPidDir), NULL, NULL}, 471 {"setup directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szSetupDir), NULL, NULL}, 472 473 {"socket address", P_STRING, P_GLOBAL, GLOBAL_VAR(szSocketAddress), NULL, NULL}, 474 {"copy", P_STRING, P_LOCAL, LOCAL_VAR(szCopy), handle_copy, NULL}, 475 {"include", P_STRING, P_LOCAL, LOCAL_VAR(szInclude), handle_include, NULL}, 476 477 {"available", P_BOOL, P_LOCAL, LOCAL_VAR(bAvailable), NULL, NULL}, 478 {"volume", P_STRING, P_LOCAL, LOCAL_VAR(volume), NULL, NULL }, 479 {"fstype", P_STRING, P_LOCAL, LOCAL_VAR(fstype), NULL, NULL}, 480 481 {"panic action", P_STRING, P_GLOBAL, GLOBAL_VAR(panic_action), NULL, NULL}, 482 483 {"msdfs root", P_BOOL, P_LOCAL, LOCAL_VAR(bMSDfsRoot), NULL, NULL}, 484 {"host msdfs", P_BOOL, P_GLOBAL, GLOBAL_VAR(bHostMSDfs), NULL, NULL}, 485 {"winbind separator", P_STRING, P_GLOBAL, GLOBAL_VAR(szWinbindSeparator), NULL, NULL }, 486 {"winbindd socket directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szWinbinddSocketDirectory), NULL, NULL }, 487 {"winbindd privileged socket directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szWinbinddPrivilegedSocketDirectory), NULL, NULL }, 488 {"winbind sealed pipes", P_BOOL, P_GLOBAL, GLOBAL_VAR(bWinbindSealedPipes), NULL, NULL }, 489 {"template shell", P_STRING, P_GLOBAL, GLOBAL_VAR(szTemplateShell), NULL, NULL }, 490 {"template homedir", P_STRING, P_GLOBAL, GLOBAL_VAR(szTemplateHomedir), NULL, NULL }, 491 {"idmap trusted only", P_BOOL, P_GLOBAL, GLOBAL_VAR(bIdmapTrustedOnly), NULL, NULL}, 492 493 {"ntp signd socket directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szNTPSignDSocketDirectory), NULL, NULL }, 494 495 {NULL, P_BOOL, P_NONE, 0, NULL, NULL} 496}; 497 498 499/* local variables */ 500struct loadparm_context { 501 const char *szConfigFile; 502 struct loadparm_global *globals; 503 struct loadparm_service **services; 504 struct loadparm_service *sDefault; 505 int iNumServices; 506 struct loadparm_service *currentService; 507 bool bInGlobalSection; 508 struct file_lists { 509 struct file_lists *next; 510 char *name; 511 char *subfname; 512 time_t modtime; 513 } *file_lists; 514 unsigned int flags[NUMPARAMETERS]; 515 struct smb_iconv_convenience *iconv_convenience; 516}; 517 518 519struct loadparm_service *lp_default_service(struct loadparm_context *lp_ctx) 520{ 521 return lp_ctx->sDefault; 522} 523 524/* 525 return the parameter table 526*/ 527struct parm_struct *lp_parm_table(void) 528{ 529 return parm_table; 530} 531 532/** 533 * Convenience routine to grab string parameters into temporary memory 534 * and run standard_sub_basic on them. 535 * 536 * The buffers can be written to by 537 * callers without affecting the source string. 538 */ 539 540static const char *lp_string(const char *s) 541{ 542#if 0 /* until REWRITE done to make thread-safe */ 543 size_t len = s ? strlen(s) : 0; 544 char *ret; 545#endif 546 547 /* The follow debug is useful for tracking down memory problems 548 especially if you have an inner loop that is calling a lp_*() 549 function that returns a string. Perhaps this debug should be 550 present all the time? */ 551 552#if 0 553 DEBUG(10, ("lp_string(%s)\n", s)); 554#endif 555 556#if 0 /* until REWRITE done to make thread-safe */ 557 if (!lp_talloc) 558 lp_talloc = talloc_init("lp_talloc"); 559 560 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */ 561 562 if (!ret) 563 return NULL; 564 565 if (!s) 566 *ret = 0; 567 else 568 strlcpy(ret, s, len); 569 570 if (trim_string(ret, "\"", "\"")) { 571 if (strchr(ret,'"') != NULL) 572 strlcpy(ret, s, len); 573 } 574 575 standard_sub_basic(ret,len+100); 576 return (ret); 577#endif 578 return s; 579} 580 581/* 582 In this section all the functions that are used to access the 583 parameters from the rest of the program are defined 584*/ 585 586#define FN_GLOBAL_STRING(fn_name,var_name) \ 587 const char *fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return NULL; return lp_ctx->globals->var_name ? lp_string(lp_ctx->globals->var_name) : "";} 588#define FN_GLOBAL_CONST_STRING(fn_name,var_name) \ 589 const char *fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return NULL; return lp_ctx->globals->var_name ? lp_ctx->globals->var_name : "";} 590#define FN_GLOBAL_LIST(fn_name,var_name) \ 591 const char **fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return NULL; return lp_ctx->globals->var_name;} 592#define FN_GLOBAL_BOOL(fn_name,var_name) \ 593 bool fn_name(struct loadparm_context *lp_ctx) {if (lp_ctx == NULL) return false; return lp_ctx->globals->var_name;} 594#if 0 /* unused */ 595#define FN_GLOBAL_CHAR(fn_name,ptr) \ 596 char fn_name(void) {return(*(char *)(ptr));} 597#endif 598#define FN_GLOBAL_INTEGER(fn_name,var_name) \ 599 int fn_name(struct loadparm_context *lp_ctx) {return lp_ctx->globals->var_name;} 600 601#define FN_LOCAL_STRING(fn_name,val) \ 602 const char *fn_name(struct loadparm_service *service, struct loadparm_service *sDefault) {return(lp_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val)));} 603#define FN_LOCAL_LIST(fn_name,val) \ 604 const char **fn_name(struct loadparm_service *service, struct loadparm_service *sDefault) {return(const char **)(service != NULL && service->val != NULL? service->val : sDefault->val);} 605#define FN_LOCAL_BOOL(fn_name,val) \ 606 bool fn_name(struct loadparm_service *service, struct loadparm_service *sDefault) {return((service != NULL)? service->val : sDefault->val);} 607#define FN_LOCAL_INTEGER(fn_name,val) \ 608 int fn_name(struct loadparm_service *service, struct loadparm_service *sDefault) {return((service != NULL)? service->val : sDefault->val);} 609 610_PUBLIC_ FN_GLOBAL_INTEGER(lp_server_role, server_role) 611_PUBLIC_ FN_GLOBAL_LIST(lp_smb_ports, smb_ports) 612_PUBLIC_ FN_GLOBAL_INTEGER(lp_nbt_port, nbt_port) 613_PUBLIC_ FN_GLOBAL_INTEGER(lp_dgram_port, dgram_port) 614_PUBLIC_ FN_GLOBAL_INTEGER(lp_cldap_port, cldap_port) 615_PUBLIC_ FN_GLOBAL_INTEGER(lp_krb5_port, krb5_port) 616_PUBLIC_ FN_GLOBAL_INTEGER(lp_kpasswd_port, kpasswd_port) 617_PUBLIC_ FN_GLOBAL_INTEGER(lp_web_port, web_port) 618_PUBLIC_ FN_GLOBAL_STRING(lp_swat_directory, swat_directory) 619_PUBLIC_ FN_GLOBAL_BOOL(lp_tls_enabled, tls_enabled) 620_PUBLIC_ FN_GLOBAL_STRING(lp_share_backend, szShareBackend) 621_PUBLIC_ FN_GLOBAL_STRING(lp_sam_url, szSAM_URL) 622_PUBLIC_ FN_GLOBAL_STRING(lp_idmap_url, szIDMAP_URL) 623_PUBLIC_ FN_GLOBAL_STRING(lp_secrets_url, szSECRETS_URL) 624_PUBLIC_ FN_GLOBAL_STRING(lp_spoolss_url, szSPOOLSS_URL) 625_PUBLIC_ FN_GLOBAL_STRING(lp_wins_config_url, szWINS_CONFIG_URL) 626_PUBLIC_ FN_GLOBAL_STRING(lp_wins_url, szWINS_URL) 627_PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbind_separator, szWinbindSeparator) 628_PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbindd_socket_directory, szWinbinddSocketDirectory) 629_PUBLIC_ FN_GLOBAL_CONST_STRING(lp_winbindd_privileged_socket_directory, szWinbinddPrivilegedSocketDirectory) 630_PUBLIC_ FN_GLOBAL_CONST_STRING(lp_template_shell, szTemplateShell) 631_PUBLIC_ FN_GLOBAL_CONST_STRING(lp_template_homedir, szTemplateHomedir) 632_PUBLIC_ FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, bWinbindSealedPipes) 633_PUBLIC_ FN_GLOBAL_BOOL(lp_idmap_trusted_only, bIdmapTrustedOnly) 634_PUBLIC_ FN_GLOBAL_STRING(lp_private_dir, szPrivateDir) 635_PUBLIC_ FN_GLOBAL_STRING(lp_serverstring, szServerString) 636_PUBLIC_ FN_GLOBAL_STRING(lp_lockdir, szLockDir) 637_PUBLIC_ FN_GLOBAL_STRING(lp_modulesdir, szModulesDir) 638_PUBLIC_ FN_GLOBAL_STRING(lp_setupdir, szSetupDir) 639_PUBLIC_ FN_GLOBAL_STRING(lp_ncalrpc_dir, ncalrpc_dir) 640_PUBLIC_ FN_GLOBAL_STRING(lp_dos_charset, dos_charset) 641_PUBLIC_ FN_GLOBAL_STRING(lp_unix_charset, unix_charset) 642_PUBLIC_ FN_GLOBAL_STRING(lp_display_charset, display_charset) 643_PUBLIC_ FN_GLOBAL_STRING(lp_piddir, szPidDir) 644_PUBLIC_ FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, dcerpc_ep_servers) 645_PUBLIC_ FN_GLOBAL_LIST(lp_server_services, server_services) 646_PUBLIC_ FN_GLOBAL_STRING(lp_ntptr_providor, ntptr_providor) 647_PUBLIC_ FN_GLOBAL_STRING(lp_auto_services, szAutoServices) 648_PUBLIC_ FN_GLOBAL_STRING(lp_passwd_chat, szPasswdChat) 649_PUBLIC_ FN_GLOBAL_LIST(lp_passwordserver, szPasswordServers) 650_PUBLIC_ FN_GLOBAL_LIST(lp_name_resolve_order, szNameResolveOrder) 651_PUBLIC_ FN_GLOBAL_STRING(lp_realm, szRealm) 652_PUBLIC_ FN_GLOBAL_STRING(lp_socket_options, socket_options) 653_PUBLIC_ FN_GLOBAL_STRING(lp_workgroup, szWorkgroup) 654_PUBLIC_ FN_GLOBAL_STRING(lp_netbios_name, szNetbiosName) 655_PUBLIC_ FN_GLOBAL_STRING(lp_netbios_scope, szNetbiosScope) 656_PUBLIC_ FN_GLOBAL_LIST(lp_wins_server_list, szWINSservers) 657_PUBLIC_ FN_GLOBAL_LIST(lp_interfaces, szInterfaces) 658_PUBLIC_ FN_GLOBAL_STRING(lp_socket_address, szSocketAddress) 659_PUBLIC_ FN_GLOBAL_LIST(lp_netbios_aliases, szNetbiosAliases) 660 661_PUBLIC_ FN_GLOBAL_BOOL(lp_disable_netbios, bDisableNetbios) 662_PUBLIC_ FN_GLOBAL_BOOL(lp_wins_support, bWINSsupport) 663_PUBLIC_ FN_GLOBAL_BOOL(lp_wins_dns_proxy, bWINSdnsProxy) 664_PUBLIC_ FN_GLOBAL_STRING(lp_wins_hook, szWINSHook) 665_PUBLIC_ FN_GLOBAL_BOOL(lp_local_master, bLocalMaster) 666_PUBLIC_ FN_GLOBAL_BOOL(lp_readraw, bReadRaw) 667_PUBLIC_ FN_GLOBAL_BOOL(lp_large_readwrite, bLargeReadwrite) 668_PUBLIC_ FN_GLOBAL_BOOL(lp_writeraw, bWriteRaw) 669_PUBLIC_ FN_GLOBAL_BOOL(lp_null_passwords, bNullPasswords) 670_PUBLIC_ FN_GLOBAL_BOOL(lp_obey_pam_restrictions, bObeyPamRestrictions) 671_PUBLIC_ FN_GLOBAL_BOOL(lp_encrypted_passwords, bEncryptPasswords) 672_PUBLIC_ FN_GLOBAL_BOOL(lp_time_server, bTimeServer) 673_PUBLIC_ FN_GLOBAL_BOOL(lp_bind_interfaces_only, bBindInterfacesOnly) 674_PUBLIC_ FN_GLOBAL_BOOL(lp_unicode, bUnicode) 675_PUBLIC_ FN_GLOBAL_BOOL(lp_nt_status_support, bNTStatusSupport) 676_PUBLIC_ FN_GLOBAL_BOOL(lp_lanman_auth, bLanmanAuth) 677_PUBLIC_ FN_GLOBAL_BOOL(lp_ntlm_auth, bNTLMAuth) 678_PUBLIC_ FN_GLOBAL_BOOL(lp_client_plaintext_auth, bClientPlaintextAuth) 679_PUBLIC_ FN_GLOBAL_BOOL(lp_client_lanman_auth, bClientLanManAuth) 680_PUBLIC_ FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, bClientNTLMv2Auth) 681_PUBLIC_ FN_GLOBAL_BOOL(lp_client_use_spnego_principal, client_use_spnego_principal) 682_PUBLIC_ FN_GLOBAL_BOOL(lp_host_msdfs, bHostMSDfs) 683_PUBLIC_ FN_GLOBAL_BOOL(lp_unix_extensions, bUnixExtensions) 684_PUBLIC_ FN_GLOBAL_BOOL(lp_use_spnego, bUseSpnego) 685_PUBLIC_ FN_GLOBAL_BOOL(lp_rpc_big_endian, bRpcBigEndian) 686_PUBLIC_ FN_GLOBAL_INTEGER(lp_max_wins_ttl, max_wins_ttl) 687_PUBLIC_ FN_GLOBAL_INTEGER(lp_min_wins_ttl, min_wins_ttl) 688_PUBLIC_ FN_GLOBAL_INTEGER(lp_maxmux, max_mux) 689_PUBLIC_ FN_GLOBAL_INTEGER(lp_max_xmit, max_xmit) 690_PUBLIC_ FN_GLOBAL_INTEGER(lp_passwordlevel, pwordlevel) 691_PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_maxprotocol, srv_maxprotocol) 692_PUBLIC_ FN_GLOBAL_INTEGER(lp_srv_minprotocol, srv_minprotocol) 693_PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_maxprotocol, cli_maxprotocol) 694_PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_minprotocol, cli_minprotocol) 695_PUBLIC_ FN_GLOBAL_INTEGER(lp_security, security) 696_PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, paranoid_server_security) 697_PUBLIC_ FN_GLOBAL_INTEGER(lp_announce_as, announce_as) 698const char *lp_servicename(const struct loadparm_service *service) 699{ 700 return lp_string((const char *)service->szService); 701} 702 703_PUBLIC_ FN_LOCAL_STRING(lp_pathname, szPath) 704static FN_LOCAL_STRING(_lp_printername, szPrintername) 705_PUBLIC_ FN_LOCAL_LIST(lp_hostsallow, szHostsallow) 706_PUBLIC_ FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny) 707_PUBLIC_ FN_LOCAL_STRING(lp_comment, comment) 708_PUBLIC_ FN_LOCAL_STRING(lp_fstype, fstype) 709static FN_LOCAL_STRING(lp_volume, volume) 710_PUBLIC_ FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler) 711_PUBLIC_ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot) 712_PUBLIC_ FN_LOCAL_BOOL(lp_browseable, bBrowseable) 713_PUBLIC_ FN_LOCAL_BOOL(lp_readonly, bRead_only) 714_PUBLIC_ FN_LOCAL_BOOL(lp_print_ok, bPrint_ok) 715_PUBLIC_ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden) 716_PUBLIC_ FN_LOCAL_BOOL(lp_map_archive, bMap_archive) 717_PUBLIC_ FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking) 718_PUBLIC_ FN_LOCAL_BOOL(lp_oplocks, bOplocks) 719_PUBLIC_ FN_LOCAL_BOOL(lp_strict_sync, bStrictSync) 720_PUBLIC_ FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem) 721_PUBLIC_ FN_LOCAL_BOOL(lp_map_system, bMap_system) 722_PUBLIC_ FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections) 723_PUBLIC_ FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy) 724_PUBLIC_ FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask) 725_PUBLIC_ FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode) 726_PUBLIC_ FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask) 727_PUBLIC_ FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode) 728_PUBLIC_ FN_GLOBAL_INTEGER(lp_server_signing, server_signing) 729_PUBLIC_ FN_GLOBAL_INTEGER(lp_client_signing, client_signing) 730 731_PUBLIC_ FN_GLOBAL_CONST_STRING(lp_ntp_signd_socket_directory, szNTPSignDSocketDirectory) 732 733/* local prototypes */ 734static int map_parameter(const char *pszParmName); 735static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx, 736 const char *pszServiceName); 737static void copy_service(struct loadparm_service *pserviceDest, 738 struct loadparm_service *pserviceSource, 739 int *pcopymapDest); 740static bool service_ok(struct loadparm_service *service); 741static bool do_section(const char *pszSectionName, void *); 742static void init_copymap(struct loadparm_service *pservice); 743 744/* This is a helper function for parametrical options support. */ 745/* It returns a pointer to parametrical option value if it exists or NULL otherwise */ 746/* Actual parametrical functions are quite simple */ 747const char *lp_get_parametric(struct loadparm_context *lp_ctx, 748 struct loadparm_service *service, 749 const char *type, const char *option) 750{ 751 char *vfskey; 752 struct parmlist_entry *data; 753 754 if (lp_ctx == NULL) 755 return NULL; 756 757 data = (service == NULL ? lp_ctx->globals->param_opt : service->param_opt); 758 759 asprintf(&vfskey, "%s:%s", type, option); 760 strlower(vfskey); 761 762 while (data) { 763 if (strcmp(data->key, vfskey) == 0) { 764 free(vfskey); 765 return data->value; 766 } 767 data = data->next; 768 } 769 770 if (service != NULL) { 771 /* Try to fetch the same option but from globals */ 772 /* but only if we are not already working with globals */ 773 for (data = lp_ctx->globals->param_opt; data; 774 data = data->next) { 775 if (strcmp(data->key, vfskey) == 0) { 776 free(vfskey); 777 return data->value; 778 } 779 } 780 } 781 782 free(vfskey); 783 784 return NULL; 785} 786 787 788/** 789 * convenience routine to return int parameters. 790 */ 791static int lp_int(const char *s) 792{ 793 794 if (!s) { 795 DEBUG(0,("lp_int(%s): is called with NULL!\n",s)); 796 return -1; 797 } 798 799 return strtol(s, NULL, 0); 800} 801 802/** 803 * convenience routine to return unsigned long parameters. 804 */ 805static int lp_ulong(const char *s) 806{ 807 808 if (!s) { 809 DEBUG(0,("lp_int(%s): is called with NULL!\n",s)); 810 return -1; 811 } 812 813 return strtoul(s, NULL, 0); 814} 815 816/** 817 * convenience routine to return unsigned long parameters. 818 */ 819static double lp_double(const char *s) 820{ 821 822 if (!s) { 823 DEBUG(0,("lp_double(%s): is called with NULL!\n",s)); 824 return -1; 825 } 826 827 return strtod(s, NULL); 828} 829 830/** 831 * convenience routine to return boolean parameters. 832 */ 833static bool lp_bool(const char *s) 834{ 835 bool ret = false; 836 837 if (!s) { 838 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s)); 839 return false; 840 } 841 842 if (!set_boolean(s, &ret)) { 843 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s)); 844 return false; 845 } 846 847 return ret; 848} 849 850 851/** 852 * Return parametric option from a given service. Type is a part of option before ':' 853 * Parametric option has following syntax: 'Type: option = value' 854 * Returned value is allocated in 'lp_talloc' context 855 */ 856 857const char *lp_parm_string(struct loadparm_context *lp_ctx, 858 struct loadparm_service *service, const char *type, 859 const char *option) 860{ 861 const char *value = lp_get_parametric(lp_ctx, service, type, option); 862 863 if (value) 864 return lp_string(value); 865 866 return NULL; 867} 868 869/** 870 * Return parametric option from a given service. Type is a part of option before ':' 871 * Parametric option has following syntax: 'Type: option = value' 872 * Returned value is allocated in 'lp_talloc' context 873 */ 874 875const char **lp_parm_string_list(TALLOC_CTX *mem_ctx, 876 struct loadparm_context *lp_ctx, 877 struct loadparm_service *service, 878 const char *type, 879 const char *option, const char *separator) 880{ 881 const char *value = lp_get_parametric(lp_ctx, service, type, option); 882 883 if (value != NULL) 884 return (const char **)str_list_make(mem_ctx, value, separator); 885 886 return NULL; 887} 888 889/** 890 * Return parametric option from a given service. Type is a part of option before ':' 891 * Parametric option has following syntax: 'Type: option = value' 892 */ 893 894int lp_parm_int(struct loadparm_context *lp_ctx, 895 struct loadparm_service *service, const char *type, 896 const char *option, int default_v) 897{ 898 const char *value = lp_get_parametric(lp_ctx, service, type, option); 899 900 if (value) 901 return lp_int(value); 902 903 return default_v; 904} 905 906/** 907 * Return parametric option from a given service. Type is a part of 908 * option before ':'. 909 * Parametric option has following syntax: 'Type: option = value'. 910 */ 911 912int lp_parm_bytes(struct loadparm_context *lp_ctx, 913 struct loadparm_service *service, const char *type, 914 const char *option, int default_v) 915{ 916 uint64_t bval; 917 918 const char *value = lp_get_parametric(lp_ctx, service, type, option); 919 920 if (value && conv_str_size(value, &bval)) { 921 if (bval <= INT_MAX) { 922 return (int)bval; 923 } 924 } 925 926 return default_v; 927} 928 929/** 930 * Return parametric option from a given service. 931 * Type is a part of option before ':' 932 * Parametric option has following syntax: 'Type: option = value' 933 */ 934unsigned long lp_parm_ulong(struct loadparm_context *lp_ctx, 935 struct loadparm_service *service, const char *type, 936 const char *option, unsigned long default_v) 937{ 938 const char *value = lp_get_parametric(lp_ctx, service, type, option); 939 940 if (value) 941 return lp_ulong(value); 942 943 return default_v; 944} 945 946 947double lp_parm_double(struct loadparm_context *lp_ctx, 948 struct loadparm_service *service, const char *type, 949 const char *option, double default_v) 950{ 951 const char *value = lp_get_parametric(lp_ctx, service, type, option); 952 953 if (value != NULL) 954 return lp_double(value); 955 956 return default_v; 957} 958 959/** 960 * Return parametric option from a given service. Type is a part of option before ':' 961 * Parametric option has following syntax: 'Type: option = value' 962 */ 963 964bool lp_parm_bool(struct loadparm_context *lp_ctx, 965 struct loadparm_service *service, const char *type, 966 const char *option, bool default_v) 967{ 968 const char *value = lp_get_parametric(lp_ctx, service, type, option); 969 970 if (value != NULL) 971 return lp_bool(value); 972 973 return default_v; 974} 975 976 977/** 978 * Initialise a service to the defaults. 979 */ 980 981static struct loadparm_service *init_service(TALLOC_CTX *mem_ctx, struct loadparm_service *sDefault) 982{ 983 struct loadparm_service *pservice = 984 talloc_zero(mem_ctx, struct loadparm_service); 985 copy_service(pservice, sDefault, NULL); 986 return pservice; 987} 988 989/** 990 * Set a string value, deallocating any existing space, and allocing the space 991 * for the string 992 */ 993static bool string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src) 994{ 995 talloc_free(*dest); 996 997 if (src == NULL) 998 src = ""; 999 1000 *dest = talloc_strdup(mem_ctx, src); 1001 if ((*dest) == NULL) { 1002 DEBUG(0,("Out of memory in string_init\n")); 1003 return false; 1004 } 1005 1006 return true; 1007} 1008 1009 1010 1011/** 1012 * Add a new service to the services array initialising it with the given 1013 * service. 1014 */ 1015 1016struct loadparm_service *lp_add_service(struct loadparm_context *lp_ctx, 1017 const struct loadparm_service *pservice, 1018 const char *name) 1019{ 1020 int i; 1021 struct loadparm_service tservice; 1022 int num_to_alloc = lp_ctx->iNumServices + 1; 1023 struct parmlist_entry *data, *pdata; 1024 1025 tservice = *pservice; 1026 1027 /* it might already exist */ 1028 if (name) { 1029 struct loadparm_service *service = getservicebyname(lp_ctx, 1030 name); 1031 if (service != NULL) { 1032 /* Clean all parametric options for service */ 1033 /* They will be added during parsing again */ 1034 data = service->param_opt; 1035 while (data) { 1036 pdata = data->next; 1037 talloc_free(data); 1038 data = pdata; 1039 } 1040 service->param_opt = NULL; 1041 return service; 1042 } 1043 } 1044 1045 /* find an invalid one */ 1046 for (i = 0; i < lp_ctx->iNumServices; i++) 1047 if (lp_ctx->services[i] == NULL) 1048 break; 1049 1050 /* if not, then create one */ 1051 if (i == lp_ctx->iNumServices) { 1052 struct loadparm_service **tsp; 1053 1054 tsp = talloc_realloc(lp_ctx, lp_ctx->services, struct loadparm_service *, num_to_alloc); 1055 1056 if (!tsp) { 1057 DEBUG(0,("lp_add_service: failed to enlarge services!\n")); 1058 return NULL; 1059 } else { 1060 lp_ctx->services = tsp; 1061 lp_ctx->services[lp_ctx->iNumServices] = NULL; 1062 } 1063 1064 lp_ctx->iNumServices++; 1065 } 1066 1067 lp_ctx->services[i] = init_service(lp_ctx->services, lp_ctx->sDefault); 1068 if (lp_ctx->services[i] == NULL) { 1069 DEBUG(0,("lp_add_service: out of memory!\n")); 1070 return NULL; 1071 } 1072 copy_service(lp_ctx->services[i], &tservice, NULL); 1073 if (name != NULL) 1074 string_set(lp_ctx->services[i], &lp_ctx->services[i]->szService, name); 1075 return lp_ctx->services[i]; 1076} 1077 1078/** 1079 * Add a new home service, with the specified home directory, defaults coming 1080 * from service ifrom. 1081 */ 1082 1083bool lp_add_home(struct loadparm_context *lp_ctx, 1084 const char *pszHomename, 1085 struct loadparm_service *default_service, 1086 const char *user, const char *pszHomedir) 1087{ 1088 struct loadparm_service *service; 1089 1090 service = lp_add_service(lp_ctx, default_service, pszHomename); 1091 1092 if (service == NULL) 1093 return false; 1094 1095 if (!(*(default_service->szPath)) 1096 || strequal(default_service->szPath, lp_ctx->sDefault->szPath)) { 1097 service->szPath = talloc_strdup(service, pszHomedir); 1098 } else { 1099 service->szPath = string_sub_talloc(service, lp_pathname(default_service, lp_ctx->sDefault), "%H", pszHomedir); 1100 } 1101 1102 if (!(*(service->comment))) { 1103 service->comment = talloc_asprintf(service, "Home directory of %s", user); 1104 } 1105 service->bAvailable = default_service->bAvailable; 1106 service->bBrowseable = default_service->bBrowseable; 1107 1108 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", 1109 pszHomename, user, service->szPath)); 1110 1111 return true; 1112} 1113 1114/** 1115 * Add the IPC service. 1116 */ 1117 1118static bool lp_add_hidden(struct loadparm_context *lp_ctx, const char *name, 1119 const char *fstype) 1120{ 1121 struct loadparm_service *service = lp_add_service(lp_ctx, lp_ctx->sDefault, name); 1122 1123 if (service == NULL) 1124 return false; 1125 1126 string_set(service, &service->szPath, tmpdir()); 1127 1128 service->comment = talloc_asprintf(service, "%s Service (%s)", 1129 fstype, lp_ctx->globals->szServerString); 1130 string_set(service, &service->fstype, fstype); 1131 service->iMaxConnections = -1; 1132 service->bAvailable = true; 1133 service->bRead_only = true; 1134 service->bPrint_ok = false; 1135 service->bBrowseable = false; 1136 1137 if (strcasecmp(fstype, "IPC") == 0) { 1138 lp_do_service_parameter(lp_ctx, service, "ntvfs handler", 1139 "default"); 1140 } 1141 1142 DEBUG(3, ("adding hidden service %s\n", name)); 1143 1144 return true; 1145} 1146 1147/** 1148 * Add a new printer service, with defaults coming from service iFrom. 1149 */ 1150 1151bool lp_add_printer(struct loadparm_context *lp_ctx, 1152 const char *pszPrintername, 1153 struct loadparm_service *default_service) 1154{ 1155 const char *comment = "From Printcap"; 1156 struct loadparm_service *service; 1157 service = lp_add_service(lp_ctx, default_service, pszPrintername); 1158 1159 if (service == NULL) 1160 return false; 1161 1162 /* note that we do NOT default the availability flag to True - */ 1163 /* we take it from the default service passed. This allows all */ 1164 /* dynamic printers to be disabled by disabling the [printers] */ 1165 /* entry (if/when the 'available' keyword is implemented!). */ 1166 1167 /* the printer name is set to the service name. */ 1168 string_set(service, &service->szPrintername, pszPrintername); 1169 string_set(service, &service->comment, comment); 1170 service->bBrowseable = default_service->bBrowseable; 1171 /* Printers cannot be read_only. */ 1172 service->bRead_only = false; 1173 /* Printer services must be printable. */ 1174 service->bPrint_ok = true; 1175 1176 DEBUG(3, ("adding printer service %s\n", pszPrintername)); 1177 1178 return true; 1179} 1180 1181/** 1182 * Map a parameter's string representation to something we can use. 1183 * Returns False if the parameter string is not recognised, else TRUE. 1184 */ 1185 1186static int map_parameter(const char *pszParmName) 1187{ 1188 int iIndex; 1189 1190 if (*pszParmName == '-') 1191 return -1; 1192 1193 for (iIndex = 0; parm_table[iIndex].label; iIndex++) 1194 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0) 1195 return iIndex; 1196 1197 /* Warn only if it isn't parametric option */ 1198 if (strchr(pszParmName, ':') == NULL) 1199 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName)); 1200 /* We do return 'fail' for parametric options as well because they are 1201 stored in different storage 1202 */ 1203 return -1; 1204} 1205 1206 1207/** 1208 return the parameter structure for a parameter 1209*/ 1210struct parm_struct *lp_parm_struct(const char *name) 1211{ 1212 int parmnum = map_parameter(name); 1213 if (parmnum == -1) return NULL; 1214 return &parm_table[parmnum]; 1215} 1216 1217/** 1218 return the parameter pointer for a parameter 1219*/ 1220void *lp_parm_ptr(struct loadparm_context *lp_ctx, 1221 struct loadparm_service *service, struct parm_struct *parm) 1222{ 1223 if (service == NULL) { 1224 if (parm->pclass == P_LOCAL) 1225 return ((char *)lp_ctx->sDefault)+parm->offset; 1226 else if (parm->pclass == P_GLOBAL) 1227 return ((char *)lp_ctx->globals)+parm->offset; 1228 else return NULL; 1229 } else { 1230 return ((char *)service) + parm->offset; 1231 } 1232} 1233 1234/** 1235 * Find a service by name. Otherwise works like get_service. 1236 */ 1237 1238static struct loadparm_service *getservicebyname(struct loadparm_context *lp_ctx, 1239 const char *pszServiceName) 1240{ 1241 int iService; 1242 1243 for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--) 1244 if (lp_ctx->services[iService] != NULL && 1245 strwicmp(lp_ctx->services[iService]->szService, pszServiceName) == 0) { 1246 return lp_ctx->services[iService]; 1247 } 1248 1249 return NULL; 1250} 1251 1252/** 1253 * Copy a service structure to another. 1254 * If pcopymapDest is NULL then copy all fields 1255 */ 1256 1257static void copy_service(struct loadparm_service *pserviceDest, 1258 struct loadparm_service *pserviceSource, 1259 int *pcopymapDest) 1260{ 1261 int i; 1262 bool bcopyall = (pcopymapDest == NULL); 1263 struct parmlist_entry *data, *pdata, *paramo; 1264 bool not_added; 1265 1266 for (i = 0; parm_table[i].label; i++) 1267 if (parm_table[i].offset != -1 && parm_table[i].pclass == P_LOCAL && 1268 (bcopyall || pcopymapDest[i])) { 1269 void *src_ptr = 1270 ((char *)pserviceSource) + parm_table[i].offset; 1271 void *dest_ptr = 1272 ((char *)pserviceDest) + parm_table[i].offset; 1273 1274 switch (parm_table[i].type) { 1275 case P_BOOL: 1276 *(int *)dest_ptr = *(int *)src_ptr; 1277 break; 1278 1279 case P_INTEGER: 1280 case P_OCTAL: 1281 case P_ENUM: 1282 *(int *)dest_ptr = *(int *)src_ptr; 1283 break; 1284 1285 case P_STRING: 1286 string_set(pserviceDest, 1287 (char **)dest_ptr, 1288 *(char **)src_ptr); 1289 break; 1290 1291 case P_USTRING: 1292 string_set(pserviceDest, 1293 (char **)dest_ptr, 1294 *(char **)src_ptr); 1295 strupper(*(char **)dest_ptr); 1296 break; 1297 case P_LIST: 1298 *(const char ***)dest_ptr = (const char **)str_list_copy(pserviceDest, 1299 *(const char ***)src_ptr); 1300 break; 1301 default: 1302 break; 1303 } 1304 } 1305 1306 if (bcopyall) { 1307 init_copymap(pserviceDest); 1308 if (pserviceSource->copymap) 1309 memcpy((void *)pserviceDest->copymap, 1310 (void *)pserviceSource->copymap, 1311 sizeof(int) * NUMPARAMETERS); 1312 } 1313 1314 data = pserviceSource->param_opt; 1315 while (data) { 1316 not_added = true; 1317 pdata = pserviceDest->param_opt; 1318 /* Traverse destination */ 1319 while (pdata) { 1320 /* If we already have same option, override it */ 1321 if (strcmp(pdata->key, data->key) == 0) { 1322 talloc_free(pdata->value); 1323 pdata->value = talloc_reference(pdata, 1324 data->value); 1325 not_added = false; 1326 break; 1327 } 1328 pdata = pdata->next; 1329 } 1330 if (not_added) { 1331 paramo = talloc(pserviceDest, struct parmlist_entry); 1332 if (paramo == NULL) 1333 smb_panic("OOM"); 1334 paramo->key = talloc_reference(paramo, data->key); 1335 paramo->value = talloc_reference(paramo, data->value); 1336 DLIST_ADD(pserviceDest->param_opt, paramo); 1337 } 1338 data = data->next; 1339 } 1340} 1341 1342/** 1343 * Check a service for consistency. Return False if the service is in any way 1344 * incomplete or faulty, else True. 1345 */ 1346static bool service_ok(struct loadparm_service *service) 1347{ 1348 bool bRetval; 1349 1350 bRetval = true; 1351 if (service->szService[0] == '\0') { 1352 DEBUG(0, ("The following message indicates an internal error:\n")); 1353 DEBUG(0, ("No service name in service entry.\n")); 1354 bRetval = false; 1355 } 1356 1357 /* The [printers] entry MUST be printable. I'm all for flexibility, but */ 1358 /* I can't see why you'd want a non-printable printer service... */ 1359 if (strwicmp(service->szService, PRINTERS_NAME) == 0) { 1360 if (!service->bPrint_ok) { 1361 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n", 1362 service->szService)); 1363 service->bPrint_ok = true; 1364 } 1365 /* [printers] service must also be non-browsable. */ 1366 if (service->bBrowseable) 1367 service->bBrowseable = false; 1368 } 1369 1370 /* If a service is flagged unavailable, log the fact at level 0. */ 1371 if (!service->bAvailable) 1372 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n", 1373 service->szService)); 1374 1375 return bRetval; 1376} 1377 1378 1379/******************************************************************* 1380 Keep a linked list of all config files so we know when one has changed 1381 it's date and needs to be reloaded. 1382********************************************************************/ 1383 1384static void add_to_file_list(struct loadparm_context *lp_ctx, 1385 const char *fname, const char *subfname) 1386{ 1387 struct file_lists *f = lp_ctx->file_lists; 1388 1389 while (f) { 1390 if (f->name && !strcmp(f->name, fname)) 1391 break; 1392 f = f->next; 1393 } 1394 1395 if (!f) { 1396 f = talloc(lp_ctx, struct file_lists); 1397 if (!f) 1398 return; 1399 f->next = lp_ctx->file_lists; 1400 f->name = talloc_strdup(f, fname); 1401 if (!f->name) { 1402 talloc_free(f); 1403 return; 1404 } 1405 f->subfname = talloc_strdup(f, subfname); 1406 if (!f->subfname) { 1407 talloc_free(f); 1408 return; 1409 } 1410 lp_ctx->file_lists = f; 1411 f->modtime = file_modtime(subfname); 1412 } else { 1413 time_t t = file_modtime(subfname); 1414 if (t) 1415 f->modtime = t; 1416 } 1417} 1418 1419/******************************************************************* 1420 Check if a config file has changed date. 1421********************************************************************/ 1422bool lp_file_list_changed(struct loadparm_context *lp_ctx) 1423{ 1424 struct file_lists *f; 1425 DEBUG(6, ("lp_file_list_changed()\n")); 1426 1427 for (f = lp_ctx->file_lists; f != NULL; f = f->next) { 1428 char *n2; 1429 time_t mod_time; 1430 1431 n2 = standard_sub_basic(lp_ctx, f->name); 1432 1433 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n", 1434 f->name, n2, ctime(&f->modtime))); 1435 1436 mod_time = file_modtime(n2); 1437 1438 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) { 1439 DEBUGADD(6, ("file %s modified: %s\n", n2, 1440 ctime(&mod_time))); 1441 f->modtime = mod_time; 1442 talloc_free(f->subfname); 1443 f->subfname = talloc_strdup(f, n2); 1444 return true; 1445 } 1446 } 1447 return false; 1448} 1449 1450/*************************************************************************** 1451 Handle the include operation. 1452***************************************************************************/ 1453 1454static bool handle_include(struct loadparm_context *lp_ctx, 1455 const char *pszParmValue, char **ptr) 1456{ 1457 char *fname = standard_sub_basic(lp_ctx, pszParmValue); 1458 1459 add_to_file_list(lp_ctx, pszParmValue, fname); 1460 1461 string_set(lp_ctx, ptr, fname); 1462 1463 if (file_exist(fname)) 1464 return pm_process(fname, do_section, do_parameter, lp_ctx); 1465 1466 DEBUG(2, ("Can't find include file %s\n", fname)); 1467 1468 return false; 1469} 1470 1471/*************************************************************************** 1472 Handle the interpretation of the copy parameter. 1473***************************************************************************/ 1474 1475static bool handle_copy(struct loadparm_context *lp_ctx, 1476 const char *pszParmValue, char **ptr) 1477{ 1478 bool bRetval; 1479 struct loadparm_service *serviceTemp; 1480 1481 string_set(lp_ctx, ptr, pszParmValue); 1482 1483 bRetval = false; 1484 1485 DEBUG(3, ("Copying service from service %s\n", pszParmValue)); 1486 1487 if ((serviceTemp = getservicebyname(lp_ctx, pszParmValue)) != NULL) { 1488 if (serviceTemp == lp_ctx->currentService) { 1489 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue)); 1490 } else { 1491 copy_service(lp_ctx->currentService, 1492 serviceTemp, 1493 lp_ctx->currentService->copymap); 1494 bRetval = true; 1495 } 1496 } else { 1497 DEBUG(0, ("Unable to copy service - source not found: %s\n", 1498 pszParmValue)); 1499 bRetval = false; 1500 } 1501 1502 return bRetval; 1503} 1504 1505static bool handle_debuglevel(struct loadparm_context *lp_ctx, 1506 const char *pszParmValue, char **ptr) 1507{ 1508 DEBUGLEVEL = atoi(pszParmValue); 1509 1510 return true; 1511} 1512 1513static bool handle_logfile(struct loadparm_context *lp_ctx, 1514 const char *pszParmValue, char **ptr) 1515{ 1516 logfile = pszParmValue; 1517 return true; 1518} 1519 1520/*************************************************************************** 1521 Initialise a copymap. 1522***************************************************************************/ 1523 1524static void init_copymap(struct loadparm_service *pservice) 1525{ 1526 int i; 1527 talloc_free(pservice->copymap); 1528 pservice->copymap = talloc_array(pservice, int, NUMPARAMETERS); 1529 if (pservice->copymap == NULL) { 1530 DEBUG(0, 1531 ("Couldn't allocate copymap!! (size %d)\n", 1532 (int)NUMPARAMETERS)); 1533 return; 1534 } 1535 for (i = 0; i < NUMPARAMETERS; i++) 1536 pservice->copymap[i] = true; 1537} 1538 1539/** 1540 * Process a parametric option 1541 */ 1542static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx, 1543 struct loadparm_service *service, 1544 const char *pszParmName, 1545 const char *pszParmValue, int flags) 1546{ 1547 struct parmlist_entry *paramo, *data; 1548 char *name; 1549 TALLOC_CTX *mem_ctx; 1550 1551 while (isspace((unsigned char)*pszParmName)) { 1552 pszParmName++; 1553 } 1554 1555 name = strdup(pszParmName); 1556 if (!name) return false; 1557 1558 strlower(name); 1559 1560 if (service == NULL) { 1561 data = lp_ctx->globals->param_opt; 1562 mem_ctx = lp_ctx->globals; 1563 } else { 1564 data = service->param_opt; 1565 mem_ctx = service; 1566 } 1567 1568 /* Traverse destination */ 1569 for (paramo=data; paramo; paramo=paramo->next) { 1570 /* If we already have the option set, override it unless 1571 it was a command line option and the new one isn't */ 1572 if (strcmp(paramo->key, name) == 0) { 1573 if ((paramo->priority & FLAG_CMDLINE) && 1574 !(flags & FLAG_CMDLINE)) { 1575 return true; 1576 } 1577 1578 talloc_free(paramo->value); 1579 paramo->value = talloc_strdup(paramo, pszParmValue); 1580 paramo->priority = flags; 1581 free(name); 1582 return true; 1583 } 1584 } 1585 1586 paramo = talloc(mem_ctx, struct parmlist_entry); 1587 if (!paramo) 1588 smb_panic("OOM"); 1589 paramo->key = talloc_strdup(paramo, name); 1590 paramo->value = talloc_strdup(paramo, pszParmValue); 1591 paramo->priority = flags; 1592 if (service == NULL) { 1593 DLIST_ADD(lp_ctx->globals->param_opt, paramo); 1594 } else { 1595 DLIST_ADD(service->param_opt, paramo); 1596 } 1597 1598 free(name); 1599 1600 return true; 1601} 1602 1603static bool set_variable(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr, 1604 const char *pszParmName, const char *pszParmValue, 1605 struct loadparm_context *lp_ctx) 1606{ 1607 int i; 1608 /* if it is a special case then go ahead */ 1609 if (parm_table[parmnum].special) { 1610 parm_table[parmnum].special(lp_ctx, pszParmValue, 1611 (char **)parm_ptr); 1612 return true; 1613 } 1614 1615 /* now switch on the type of variable it is */ 1616 switch (parm_table[parmnum].type) 1617 { 1618 case P_BOOL: { 1619 bool b; 1620 if (!set_boolean(pszParmValue, &b)) { 1621 DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue)); 1622 return false; 1623 } 1624 *(int *)parm_ptr = b; 1625 } 1626 break; 1627 1628 case P_INTEGER: 1629 *(int *)parm_ptr = atoi(pszParmValue); 1630 break; 1631 1632 case P_OCTAL: 1633 *(int *)parm_ptr = strtol(pszParmValue, NULL, 8); 1634 break; 1635 1636 case P_BYTES: 1637 { 1638 uint64_t val; 1639 if (conv_str_size(pszParmValue, &val)) { 1640 if (val <= INT_MAX) { 1641 *(int *)parm_ptr = (int)val; 1642 break; 1643 } 1644 } 1645 1646 DEBUG(0,("lp_do_parameter(%s): value is not " 1647 "a valid size specifier!\n", pszParmValue)); 1648 return false; 1649 } 1650 1651 case P_LIST: 1652 *(const char ***)parm_ptr = (const char **)str_list_make(mem_ctx, 1653 pszParmValue, NULL); 1654 break; 1655 1656 case P_STRING: 1657 string_set(mem_ctx, (char **)parm_ptr, pszParmValue); 1658 break; 1659 1660 case P_USTRING: 1661 string_set(mem_ctx, (char **)parm_ptr, pszParmValue); 1662 strupper(*(char **)parm_ptr); 1663 break; 1664 1665 case P_ENUM: 1666 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) { 1667 if (strequal 1668 (pszParmValue, 1669 parm_table[parmnum].enum_list[i].name)) { 1670 *(int *)parm_ptr = 1671 parm_table[parmnum]. 1672 enum_list[i].value; 1673 break; 1674 } 1675 } 1676 if (!parm_table[parmnum].enum_list[i].name) { 1677 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n", 1678 pszParmValue, pszParmName)); 1679 return false; 1680 } 1681 break; 1682 } 1683 1684 if (lp_ctx->flags[parmnum] & FLAG_DEFAULT) { 1685 lp_ctx->flags[parmnum] &= ~FLAG_DEFAULT; 1686 /* we have to also unset FLAG_DEFAULT on aliases */ 1687 for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) { 1688 lp_ctx->flags[i] &= ~FLAG_DEFAULT; 1689 } 1690 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset;i++) { 1691 lp_ctx->flags[i] &= ~FLAG_DEFAULT; 1692 } 1693 } 1694 return true; 1695} 1696 1697 1698bool lp_do_global_parameter(struct loadparm_context *lp_ctx, 1699 const char *pszParmName, const char *pszParmValue) 1700{ 1701 int parmnum = map_parameter(pszParmName); 1702 void *parm_ptr; 1703 1704 if (parmnum < 0) { 1705 if (strchr(pszParmName, ':')) { 1706 return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName, pszParmValue, 0); 1707 } 1708 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName)); 1709 return true; 1710 } 1711 1712 /* if the flag has been set on the command line, then don't allow override, 1713 but don't report an error */ 1714 if (lp_ctx->flags[parmnum] & FLAG_CMDLINE) { 1715 return true; 1716 } 1717 1718 parm_ptr = lp_parm_ptr(lp_ctx, NULL, &parm_table[parmnum]); 1719 1720 return set_variable(lp_ctx, parmnum, parm_ptr, 1721 pszParmName, pszParmValue, lp_ctx); 1722} 1723 1724bool lp_do_service_parameter(struct loadparm_context *lp_ctx, 1725 struct loadparm_service *service, 1726 const char *pszParmName, const char *pszParmValue) 1727{ 1728 void *parm_ptr; 1729 int i; 1730 int parmnum = map_parameter(pszParmName); 1731 1732 if (parmnum < 0) { 1733 if (strchr(pszParmName, ':')) { 1734 return lp_do_parameter_parametric(lp_ctx, service, pszParmName, pszParmValue, 0); 1735 } 1736 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName)); 1737 return true; 1738 } 1739 1740 /* if the flag has been set on the command line, then don't allow override, 1741 but don't report an error */ 1742 if (lp_ctx->flags[parmnum] & FLAG_CMDLINE) { 1743 return true; 1744 } 1745 1746 if (parm_table[parmnum].pclass == P_GLOBAL) { 1747 DEBUG(0, 1748 ("Global parameter %s found in service section!\n", 1749 pszParmName)); 1750 return true; 1751 } 1752 parm_ptr = ((char *)service) + parm_table[parmnum].offset; 1753 1754 if (!service->copymap) 1755 init_copymap(service); 1756 1757 /* this handles the aliases - set the copymap for other 1758 * entries with the same data pointer */ 1759 for (i = 0; parm_table[i].label; i++) 1760 if (parm_table[i].offset == parm_table[parmnum].offset && 1761 parm_table[i].pclass == parm_table[parmnum].pclass) 1762 service->copymap[i] = false; 1763 1764 return set_variable(service, parmnum, parm_ptr, pszParmName, 1765 pszParmValue, lp_ctx); 1766} 1767 1768/** 1769 * Process a parameter. 1770 */ 1771 1772static bool do_parameter(const char *pszParmName, const char *pszParmValue, 1773 void *userdata) 1774{ 1775 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata; 1776 1777 if (lp_ctx->bInGlobalSection) 1778 return lp_do_global_parameter(lp_ctx, pszParmName, 1779 pszParmValue); 1780 else 1781 return lp_do_service_parameter(lp_ctx, lp_ctx->currentService, 1782 pszParmName, pszParmValue); 1783} 1784 1785/* 1786 variable argument do parameter 1787*/ 1788bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx, const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); 1789bool lp_do_global_parameter_var(struct loadparm_context *lp_ctx, 1790 const char *pszParmName, const char *fmt, ...) 1791{ 1792 char *s; 1793 bool ret; 1794 va_list ap; 1795 1796 va_start(ap, fmt); 1797 s = talloc_vasprintf(NULL, fmt, ap); 1798 va_end(ap); 1799 ret = lp_do_global_parameter(lp_ctx, pszParmName, s); 1800 talloc_free(s); 1801 return ret; 1802} 1803 1804 1805/* 1806 set a parameter from the commandline - this is called from command line parameter 1807 parsing code. It sets the parameter then marks the parameter as unable to be modified 1808 by smb.conf processing 1809*/ 1810bool lp_set_cmdline(struct loadparm_context *lp_ctx, const char *pszParmName, 1811 const char *pszParmValue) 1812{ 1813 int parmnum = map_parameter(pszParmName); 1814 int i; 1815 1816 while (isspace((unsigned char)*pszParmValue)) pszParmValue++; 1817 1818 1819 if (parmnum < 0 && strchr(pszParmName, ':')) { 1820 /* set a parametric option */ 1821 return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName, 1822 pszParmValue, FLAG_CMDLINE); 1823 } 1824 1825 if (parmnum < 0) { 1826 DEBUG(0,("Unknown option '%s'\n", pszParmName)); 1827 return false; 1828 } 1829 1830 /* reset the CMDLINE flag in case this has been called before */ 1831 lp_ctx->flags[parmnum] &= ~FLAG_CMDLINE; 1832 1833 if (!lp_do_global_parameter(lp_ctx, pszParmName, pszParmValue)) { 1834 return false; 1835 } 1836 1837 lp_ctx->flags[parmnum] |= FLAG_CMDLINE; 1838 1839 /* we have to also set FLAG_CMDLINE on aliases */ 1840 for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) { 1841 lp_ctx->flags[i] |= FLAG_CMDLINE; 1842 } 1843 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset;i++) { 1844 lp_ctx->flags[i] |= FLAG_CMDLINE; 1845 } 1846 1847 return true; 1848} 1849 1850/* 1851 set a option from the commandline in 'a=b' format. Use to support --option 1852*/ 1853bool lp_set_option(struct loadparm_context *lp_ctx, const char *option) 1854{ 1855 char *p, *s; 1856 bool ret; 1857 1858 s = strdup(option); 1859 if (!s) { 1860 return false; 1861 } 1862 1863 p = strchr(s, '='); 1864 if (!p) { 1865 free(s); 1866 return false; 1867 } 1868 1869 *p = 0; 1870 1871 ret = lp_set_cmdline(lp_ctx, s, p+1); 1872 free(s); 1873 return ret; 1874} 1875 1876 1877#define BOOLSTR(b) ((b) ? "Yes" : "No") 1878 1879/** 1880 * Print a parameter of the specified type. 1881 */ 1882 1883static void print_parameter(struct parm_struct *p, void *ptr, FILE * f) 1884{ 1885 int i; 1886 switch (p->type) 1887 { 1888 case P_ENUM: 1889 for (i = 0; p->enum_list[i].name; i++) { 1890 if (*(int *)ptr == p->enum_list[i].value) { 1891 fprintf(f, "%s", 1892 p->enum_list[i].name); 1893 break; 1894 } 1895 } 1896 break; 1897 1898 case P_BOOL: 1899 fprintf(f, "%s", BOOLSTR((bool)*(int *)ptr)); 1900 break; 1901 1902 case P_INTEGER: 1903 case P_BYTES: 1904 fprintf(f, "%d", *(int *)ptr); 1905 break; 1906 1907 case P_OCTAL: 1908 fprintf(f, "0%o", *(int *)ptr); 1909 break; 1910 1911 case P_LIST: 1912 if ((char ***)ptr && *(char ***)ptr) { 1913 char **list = *(char ***)ptr; 1914 1915 for (; *list; list++) 1916 fprintf(f, "%s%s", *list, 1917 ((*(list+1))?", ":"")); 1918 } 1919 break; 1920 1921 case P_STRING: 1922 case P_USTRING: 1923 if (*(char **)ptr) { 1924 fprintf(f, "%s", *(char **)ptr); 1925 } 1926 break; 1927 } 1928} 1929 1930/** 1931 * Check if two parameters are equal. 1932 */ 1933 1934static bool equal_parameter(parm_type type, void *ptr1, void *ptr2) 1935{ 1936 switch (type) { 1937 case P_BOOL: 1938 return (*((int *)ptr1) == *((int *)ptr2)); 1939 1940 case P_INTEGER: 1941 case P_OCTAL: 1942 case P_BYTES: 1943 case P_ENUM: 1944 return (*((int *)ptr1) == *((int *)ptr2)); 1945 1946 case P_LIST: 1947 return str_list_equal((const char **)(*(char ***)ptr1), 1948 (const char **)(*(char ***)ptr2)); 1949 1950 case P_STRING: 1951 case P_USTRING: 1952 { 1953 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2; 1954 if (p1 && !*p1) 1955 p1 = NULL; 1956 if (p2 && !*p2) 1957 p2 = NULL; 1958 return (p1 == p2 || strequal(p1, p2)); 1959 } 1960 } 1961 return false; 1962} 1963 1964/** 1965 * Process a new section (service). 1966 * 1967 * At this stage all sections are services. 1968 * Later we'll have special sections that permit server parameters to be set. 1969 * Returns True on success, False on failure. 1970 */ 1971 1972static bool do_section(const char *pszSectionName, void *userdata) 1973{ 1974 struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata; 1975 bool bRetval; 1976 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) || 1977 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0)); 1978 bRetval = false; 1979 1980 /* if we've just struck a global section, note the fact. */ 1981 lp_ctx->bInGlobalSection = isglobal; 1982 1983 /* check for multiple global sections */ 1984 if (lp_ctx->bInGlobalSection) { 1985 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName)); 1986 return true; 1987 } 1988 1989 /* if we have a current service, tidy it up before moving on */ 1990 bRetval = true; 1991 1992 if (lp_ctx->currentService != NULL) 1993 bRetval = service_ok(lp_ctx->currentService); 1994 1995 /* if all is still well, move to the next record in the services array */ 1996 if (bRetval) { 1997 /* We put this here to avoid an odd message order if messages are */ 1998 /* issued by the post-processing of a previous section. */ 1999 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName)); 2000 2001 if ((lp_ctx->currentService = lp_add_service(lp_ctx, lp_ctx->sDefault, 2002 pszSectionName)) 2003 == NULL) { 2004 DEBUG(0, ("Failed to add a new service\n")); 2005 return false; 2006 } 2007 } 2008 2009 return bRetval; 2010} 2011 2012 2013/** 2014 * Determine if a particular base parameter is currently set to the default value. 2015 */ 2016 2017static bool is_default(struct loadparm_service *sDefault, int i) 2018{ 2019 void *def_ptr = ((char *)sDefault) + parm_table[i].offset; 2020 if (!defaults_saved) 2021 return false; 2022 switch (parm_table[i].type) { 2023 case P_LIST: 2024 return str_list_equal((const char **)parm_table[i].def.lvalue, 2025 (const char **)def_ptr); 2026 case P_STRING: 2027 case P_USTRING: 2028 return strequal(parm_table[i].def.svalue, 2029 *(char **)def_ptr); 2030 case P_BOOL: 2031 return parm_table[i].def.bvalue == 2032 *(int *)def_ptr; 2033 case P_INTEGER: 2034 case P_OCTAL: 2035 case P_BYTES: 2036 case P_ENUM: 2037 return parm_table[i].def.ivalue == 2038 *(int *)def_ptr; 2039 } 2040 return false; 2041} 2042 2043/** 2044 *Display the contents of the global structure. 2045 */ 2046 2047static void dump_globals(struct loadparm_context *lp_ctx, FILE *f, 2048 bool show_defaults) 2049{ 2050 int i; 2051 struct parmlist_entry *data; 2052 2053 fprintf(f, "# Global parameters\n[global]\n"); 2054 2055 for (i = 0; parm_table[i].label; i++) 2056 if (parm_table[i].pclass == P_GLOBAL && 2057 parm_table[i].offset != -1 && 2058 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) { 2059 if (!show_defaults && (lp_ctx->flags[i] & FLAG_DEFAULT)) 2060 continue; 2061 fprintf(f, "\t%s = ", parm_table[i].label); 2062 print_parameter(&parm_table[i], lp_parm_ptr(lp_ctx, NULL, &parm_table[i]), f); 2063 fprintf(f, "\n"); 2064 } 2065 if (lp_ctx->globals->param_opt != NULL) { 2066 for (data = lp_ctx->globals->param_opt; data; 2067 data = data->next) { 2068 fprintf(f, "\t%s = %s\n", data->key, data->value); 2069 } 2070 } 2071 2072} 2073 2074/** 2075 * Display the contents of a single services record. 2076 */ 2077 2078static void dump_a_service(struct loadparm_service * pService, struct loadparm_service *sDefault, FILE * f) 2079{ 2080 int i; 2081 struct parmlist_entry *data; 2082 2083 if (pService != sDefault) 2084 fprintf(f, "\n[%s]\n", pService->szService); 2085 2086 for (i = 0; parm_table[i].label; i++) { 2087 if (parm_table[i].pclass == P_LOCAL && 2088 parm_table[i].offset != -1 && 2089 (*parm_table[i].label != '-') && 2090 (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) 2091 { 2092 if (pService == sDefault) { 2093 if (defaults_saved && is_default(sDefault, i)) 2094 continue; 2095 } else { 2096 if (equal_parameter(parm_table[i].type, 2097 ((char *)pService) + 2098 parm_table[i].offset, 2099 ((char *)sDefault) + 2100 parm_table[i].offset)) 2101 continue; 2102 } 2103 2104 fprintf(f, "\t%s = ", parm_table[i].label); 2105 print_parameter(&parm_table[i], 2106 ((char *)pService) + parm_table[i].offset, f); 2107 fprintf(f, "\n"); 2108 } 2109 } 2110 if (pService->param_opt != NULL) { 2111 for (data = pService->param_opt; data; data = data->next) { 2112 fprintf(f, "\t%s = %s\n", data->key, data->value); 2113 } 2114 } 2115} 2116 2117bool lp_dump_a_parameter(struct loadparm_context *lp_ctx, 2118 struct loadparm_service *service, 2119 const char *parm_name, FILE * f) 2120{ 2121 struct parm_struct *parm; 2122 void *ptr; 2123 2124 parm = lp_parm_struct(parm_name); 2125 if (!parm) { 2126 return false; 2127 } 2128 2129 ptr = lp_parm_ptr(lp_ctx, service,parm); 2130 2131 print_parameter(parm, ptr, f); 2132 fprintf(f, "\n"); 2133 return true; 2134} 2135 2136/** 2137 * Return info about the next parameter in a service. 2138 * snum==-1 gives the globals. 2139 * Return NULL when out of parameters. 2140 */ 2141 2142struct parm_struct *lp_next_parameter(struct loadparm_context *lp_ctx, int snum, int *i, 2143 int allparameters) 2144{ 2145 if (snum == -1) { 2146 /* do the globals */ 2147 for (; parm_table[*i].label; (*i)++) { 2148 if (parm_table[*i].offset == -1 2149 || (*parm_table[*i].label == '-')) 2150 continue; 2151 2152 if ((*i) > 0 2153 && (parm_table[*i].offset == 2154 parm_table[(*i) - 1].offset)) 2155 continue; 2156 2157 return &parm_table[(*i)++]; 2158 } 2159 } else { 2160 struct loadparm_service *pService = lp_ctx->services[snum]; 2161 2162 for (; parm_table[*i].label; (*i)++) { 2163 if (parm_table[*i].pclass == P_LOCAL && 2164 parm_table[*i].offset != -1 && 2165 (*parm_table[*i].label != '-') && 2166 ((*i) == 0 || 2167 (parm_table[*i].offset != 2168 parm_table[(*i) - 1].offset))) 2169 { 2170 if (allparameters || 2171 !equal_parameter(parm_table[*i].type, 2172 ((char *)pService) + 2173 parm_table[*i].offset, 2174 ((char *)lp_ctx->sDefault) + 2175 parm_table[*i].offset)) 2176 { 2177 return &parm_table[(*i)++]; 2178 } 2179 } 2180 } 2181 } 2182 2183 return NULL; 2184} 2185 2186 2187/** 2188 * Auto-load some home services. 2189 */ 2190static void lp_add_auto_services(struct loadparm_context *lp_ctx, 2191 const char *str) 2192{ 2193 return; 2194} 2195 2196 2197/** 2198 * Unload unused services. 2199 */ 2200 2201void lp_killunused(struct loadparm_context *lp_ctx, 2202 struct smbsrv_connection *smb, 2203 bool (*snumused) (struct smbsrv_connection *, int)) 2204{ 2205 int i; 2206 for (i = 0; i < lp_ctx->iNumServices; i++) { 2207 if (lp_ctx->services[i] == NULL) 2208 continue; 2209 2210 if (!snumused || !snumused(smb, i)) { 2211 talloc_free(lp_ctx->services[i]); 2212 lp_ctx->services[i] = NULL; 2213 } 2214 } 2215} 2216 2217 2218static int lp_destructor(struct loadparm_context *lp_ctx) 2219{ 2220 struct parmlist_entry *data; 2221 2222 if (lp_ctx->globals->param_opt != NULL) { 2223 struct parmlist_entry *next; 2224 for (data = lp_ctx->globals->param_opt; data; data=next) { 2225 next = data->next; 2226 if (data->priority & FLAG_CMDLINE) continue; 2227 DLIST_REMOVE(lp_ctx->globals->param_opt, data); 2228 talloc_free(data); 2229 } 2230 } 2231 2232 return 0; 2233} 2234 2235/** 2236 * Initialise the global parameter structure. 2237 */ 2238struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) 2239{ 2240 int i; 2241 char *myname; 2242 struct loadparm_context *lp_ctx; 2243 2244 lp_ctx = talloc_zero(mem_ctx, struct loadparm_context); 2245 if (lp_ctx == NULL) 2246 return NULL; 2247 2248 talloc_set_destructor(lp_ctx, lp_destructor); 2249 lp_ctx->bInGlobalSection = true; 2250 lp_ctx->globals = talloc_zero(lp_ctx, struct loadparm_global); 2251 lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service); 2252 2253 lp_ctx->sDefault->iMaxPrintJobs = 1000; 2254 lp_ctx->sDefault->bAvailable = true; 2255 lp_ctx->sDefault->bBrowseable = true; 2256 lp_ctx->sDefault->bRead_only = true; 2257 lp_ctx->sDefault->bMap_archive = true; 2258 lp_ctx->sDefault->bStrictLocking = true; 2259 lp_ctx->sDefault->bOplocks = true; 2260 lp_ctx->sDefault->iCreate_mask = 0744; 2261 lp_ctx->sDefault->iCreate_force_mode = 0000; 2262 lp_ctx->sDefault->iDir_mask = 0755; 2263 lp_ctx->sDefault->iDir_force_mode = 0000; 2264 2265 DEBUG(3, ("Initialising global parameters\n")); 2266 2267 for (i = 0; parm_table[i].label; i++) { 2268 if ((parm_table[i].type == P_STRING || 2269 parm_table[i].type == P_USTRING) && 2270 parm_table[i].offset != -1 && 2271 !(lp_ctx->flags[i] & FLAG_CMDLINE)) { 2272 char **r; 2273 if (parm_table[i].pclass == P_LOCAL) { 2274 r = (char **)(((char *)lp_ctx->sDefault) + parm_table[i].offset); 2275 } else { 2276 r = (char **)(((char *)lp_ctx->globals) + parm_table[i].offset); 2277 } 2278 *r = talloc_strdup(lp_ctx, ""); 2279 } 2280 } 2281 2282 lp_do_global_parameter(lp_ctx, "share backend", "classic"); 2283 2284 lp_do_global_parameter(lp_ctx, "server role", "standalone"); 2285 2286 /* options that can be set on the command line must be initialised via 2287 the slower lp_do_global_parameter() to ensure that FLAG_CMDLINE is obeyed */ 2288#ifdef TCP_NODELAY 2289 lp_do_global_parameter(lp_ctx, "socket options", "TCP_NODELAY"); 2290#endif 2291 lp_do_global_parameter(lp_ctx, "workgroup", DEFAULT_WORKGROUP); 2292 myname = get_myname(lp_ctx); 2293 lp_do_global_parameter(lp_ctx, "netbios name", myname); 2294 talloc_free(myname); 2295 lp_do_global_parameter(lp_ctx, "name resolve order", "wins host bcast"); 2296 2297 lp_do_global_parameter(lp_ctx, "fstype", "NTFS"); 2298 2299 lp_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default"); 2300 lp_do_global_parameter(lp_ctx, "max connections", "-1"); 2301 2302 lp_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup unixinfo browser"); 2303 lp_do_global_parameter(lp_ctx, "server services", "smb rpc nbt wrepl ldap cldap kdc drepl winbind ntp_signd kcc"); 2304 lp_do_global_parameter(lp_ctx, "ntptr providor", "simple_ldb"); 2305 lp_do_global_parameter(lp_ctx, "auth methods:domain controller", "anonymous sam_ignoredomain"); 2306 lp_do_global_parameter(lp_ctx, "auth methods:member server", "anonymous sam winbind"); 2307 lp_do_global_parameter(lp_ctx, "auth methods:standalone", "anonymous sam_ignoredomain"); 2308 lp_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR); 2309 lp_do_global_parameter(lp_ctx, "sam database", "sam.ldb"); 2310 lp_do_global_parameter(lp_ctx, "idmap database", "idmap.ldb"); 2311 lp_do_global_parameter(lp_ctx, "secrets database", "secrets.ldb"); 2312 lp_do_global_parameter(lp_ctx, "spoolss database", "spoolss.ldb"); 2313 lp_do_global_parameter(lp_ctx, "wins config database", "wins_config.ldb"); 2314 lp_do_global_parameter(lp_ctx, "wins database", "wins.ldb"); 2315 lp_do_global_parameter(lp_ctx, "registry:HKEY_LOCAL_MACHINE", "hklm.ldb"); 2316 2317 /* This hive should be dynamically generated by Samba using 2318 data from the sam, but for the moment leave it in a tdb to 2319 keep regedt32 from popping up an annoying dialog. */ 2320 lp_do_global_parameter(lp_ctx, "registry:HKEY_USERS", "hku.ldb"); 2321 2322 /* using UTF8 by default allows us to support all chars */ 2323 lp_do_global_parameter(lp_ctx, "unix charset", "UTF8"); 2324 2325 /* Use codepage 850 as a default for the dos character set */ 2326 lp_do_global_parameter(lp_ctx, "dos charset", "CP850"); 2327 2328 /* 2329 * Allow the default PASSWD_CHAT to be overridden in local.h. 2330 */ 2331 lp_do_global_parameter(lp_ctx, "passwd chat", DEFAULT_PASSWD_CHAT); 2332 2333 lp_do_global_parameter(lp_ctx, "pid directory", dyn_PIDDIR); 2334 lp_do_global_parameter(lp_ctx, "lock dir", dyn_LOCKDIR); 2335 lp_do_global_parameter(lp_ctx, "modules dir", dyn_MODULESDIR); 2336 lp_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR); 2337 2338 lp_do_global_parameter(lp_ctx, "socket address", "0.0.0.0"); 2339 lp_do_global_parameter_var(lp_ctx, "server string", 2340 "Samba %s", SAMBA_VERSION_STRING); 2341 2342 lp_do_global_parameter_var(lp_ctx, "announce version", "%d.%d", 2343 DEFAULT_MAJOR_VERSION, 2344 DEFAULT_MINOR_VERSION); 2345 2346 lp_do_global_parameter(lp_ctx, "password server", "*"); 2347 2348 lp_do_global_parameter(lp_ctx, "max mux", "50"); 2349 lp_do_global_parameter(lp_ctx, "max xmit", "12288"); 2350 lp_do_global_parameter(lp_ctx, "password level", "0"); 2351 lp_do_global_parameter(lp_ctx, "LargeReadwrite", "True"); 2352 lp_do_global_parameter(lp_ctx, "server min protocol", "CORE"); 2353 lp_do_global_parameter(lp_ctx, "server max protocol", "NT1"); 2354 lp_do_global_parameter(lp_ctx, "client min protocol", "CORE"); 2355 lp_do_global_parameter(lp_ctx, "client max protocol", "NT1"); 2356 lp_do_global_parameter(lp_ctx, "security", "USER"); 2357 lp_do_global_parameter(lp_ctx, "paranoid server security", "True"); 2358 lp_do_global_parameter(lp_ctx, "EncryptPasswords", "True"); 2359 lp_do_global_parameter(lp_ctx, "ReadRaw", "True"); 2360 lp_do_global_parameter(lp_ctx, "WriteRaw", "True"); 2361 lp_do_global_parameter(lp_ctx, "NullPasswords", "False"); 2362 lp_do_global_parameter(lp_ctx, "ObeyPamRestrictions", "False"); 2363 lp_do_global_parameter(lp_ctx, "announce as", "NT SERVER"); 2364 2365 lp_do_global_parameter(lp_ctx, "TimeServer", "False"); 2366 lp_do_global_parameter(lp_ctx, "BindInterfacesOnly", "False"); 2367 lp_do_global_parameter(lp_ctx, "Unicode", "True"); 2368 lp_do_global_parameter(lp_ctx, "ClientLanManAuth", "False"); 2369 lp_do_global_parameter(lp_ctx, "LanmanAuth", "False"); 2370 lp_do_global_parameter(lp_ctx, "NTLMAuth", "True"); 2371 lp_do_global_parameter(lp_ctx, "client use spnego principal", "False"); 2372 2373 lp_do_global_parameter(lp_ctx, "UnixExtensions", "False"); 2374 2375 lp_do_global_parameter(lp_ctx, "PreferredMaster", "Auto"); 2376 lp_do_global_parameter(lp_ctx, "LocalMaster", "True"); 2377 2378 lp_do_global_parameter(lp_ctx, "wins support", "False"); 2379 lp_do_global_parameter(lp_ctx, "dns proxy", "True"); 2380 2381 lp_do_global_parameter(lp_ctx, "winbind separator", "\\"); 2382 lp_do_global_parameter(lp_ctx, "winbind sealed pipes", "True"); 2383 lp_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR); 2384 lp_do_global_parameter(lp_ctx, "winbindd privileged socket directory", dyn_WINBINDD_PRIVILEGED_SOCKET_DIR); 2385 lp_do_global_parameter(lp_ctx, "template shell", "/bin/false"); 2386 lp_do_global_parameter(lp_ctx, "template homedir", "/home/%WORKGROUP%/%ACCOUNTNAME%"); 2387 lp_do_global_parameter(lp_ctx, "idmap trusted only", "False"); 2388 2389 lp_do_global_parameter(lp_ctx, "client signing", "Yes"); 2390 lp_do_global_parameter(lp_ctx, "server signing", "auto"); 2391 2392 lp_do_global_parameter(lp_ctx, "use spnego", "True"); 2393 2394 lp_do_global_parameter(lp_ctx, "smb ports", "445 139"); 2395 lp_do_global_parameter(lp_ctx, "nbt port", "137"); 2396 lp_do_global_parameter(lp_ctx, "dgram port", "138"); 2397 lp_do_global_parameter(lp_ctx, "cldap port", "389"); 2398 lp_do_global_parameter(lp_ctx, "krb5 port", "88"); 2399 lp_do_global_parameter(lp_ctx, "kpasswd port", "464"); 2400 lp_do_global_parameter(lp_ctx, "web port", "901"); 2401 lp_do_global_parameter(lp_ctx, "swat directory", dyn_SWATDIR); 2402 2403 lp_do_global_parameter(lp_ctx, "nt status support", "True"); 2404 2405 lp_do_global_parameter(lp_ctx, "max wins ttl", "518400"); /* 6 days */ 2406 lp_do_global_parameter(lp_ctx, "min wins ttl", "10"); 2407 2408 lp_do_global_parameter(lp_ctx, "tls enabled", "True"); 2409 lp_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem"); 2410 lp_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem"); 2411 lp_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem"); 2412 lp_do_global_parameter_var(lp_ctx, "setup directory", "%s", 2413 dyn_SETUPDIR); 2414 2415 lp_do_global_parameter(lp_ctx, "prefork children:smb", "4"); 2416 2417 lp_do_global_parameter(lp_ctx, "ntp signd socket directory", dyn_NTP_SIGND_SOCKET_DIR); 2418 2419 for (i = 0; parm_table[i].label; i++) { 2420 if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) { 2421 lp_ctx->flags[i] |= FLAG_DEFAULT; 2422 } 2423 } 2424 2425 return lp_ctx; 2426} 2427 2428const char *lp_configfile(struct loadparm_context *lp_ctx) 2429{ 2430 return lp_ctx->szConfigFile; 2431} 2432 2433const char *lp_default_path(void) 2434{ 2435 if (getenv("SMB_CONF_PATH")) 2436 return getenv("SMB_CONF_PATH"); 2437 else 2438 return dyn_CONFIGFILE; 2439} 2440 2441/** 2442 * Update the internal state of a loadparm context after settings 2443 * have changed. 2444 */ 2445static bool lp_update(struct loadparm_context *lp_ctx) 2446{ 2447 lp_add_auto_services(lp_ctx, lp_auto_services(lp_ctx)); 2448 2449 lp_add_hidden(lp_ctx, "IPC$", "IPC"); 2450 lp_add_hidden(lp_ctx, "ADMIN$", "DISK"); 2451 2452 if (!lp_ctx->globals->szWINSservers && lp_ctx->globals->bWINSsupport) { 2453 lp_do_global_parameter(lp_ctx, "wins server", "127.0.0.1"); 2454 } 2455 2456 panic_action = lp_ctx->globals->panic_action; 2457 2458 reload_charcnv(lp_ctx); 2459 2460 /* FIXME: ntstatus_check_dos_mapping = lp_nt_status_support(lp_ctx); */ 2461 2462 /* FIXME: This is a bit of a hack, but we can't use a global, since 2463 * not everything that uses lp also uses the socket library */ 2464 if (lp_parm_bool(lp_ctx, NULL, "socket", "testnonblock", false)) { 2465 setenv("SOCKET_TESTNONBLOCK", "1", 1); 2466 } else { 2467 unsetenv("SOCKET_TESTNONBLOCK"); 2468 } 2469 2470 /* FIXME: Check locale in environment for this: */ 2471 if (strcmp(lp_display_charset(lp_ctx), lp_unix_charset(lp_ctx)) != 0) 2472 d_set_iconv(smb_iconv_open(lp_display_charset(lp_ctx), lp_unix_charset(lp_ctx))); 2473 else 2474 d_set_iconv((smb_iconv_t)-1); 2475 2476 return true; 2477} 2478 2479bool lp_load_default(struct loadparm_context *lp_ctx) 2480{ 2481 const char *path; 2482 2483 path = lp_default_path(); 2484 2485 if (!file_exist(path)) { 2486 /* We allow the default smb.conf file to not exist, 2487 * basically the equivalent of an empty file. */ 2488 return lp_update(lp_ctx); 2489 } 2490 2491 return lp_load(lp_ctx, path); 2492} 2493 2494/** 2495 * Load the services array from the services file. 2496 * 2497 * Return True on success, False on failure. 2498 */ 2499bool lp_load(struct loadparm_context *lp_ctx, const char *filename) 2500{ 2501 char *n2; 2502 bool bRetval; 2503 2504 filename = talloc_strdup(lp_ctx, filename); 2505 2506 lp_ctx->szConfigFile = filename; 2507 2508 lp_ctx->bInGlobalSection = true; 2509 n2 = standard_sub_basic(lp_ctx, lp_ctx->szConfigFile); 2510 DEBUG(2, ("lp_load: refreshing parameters from %s\n", n2)); 2511 2512 add_to_file_list(lp_ctx, lp_ctx->szConfigFile, n2); 2513 2514 /* We get sections first, so have to start 'behind' to make up */ 2515 lp_ctx->currentService = NULL; 2516 bRetval = pm_process(n2, do_section, do_parameter, lp_ctx); 2517 2518 /* finish up the last section */ 2519 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval))); 2520 if (bRetval) 2521 if (lp_ctx->currentService != NULL) 2522 bRetval = service_ok(lp_ctx->currentService); 2523 2524 bRetval = bRetval && lp_update(lp_ctx); 2525 2526 return bRetval; 2527} 2528 2529/** 2530 * Return the max number of services. 2531 */ 2532 2533int lp_numservices(struct loadparm_context *lp_ctx) 2534{ 2535 return lp_ctx->iNumServices; 2536} 2537 2538/** 2539 * Display the contents of the services array in human-readable form. 2540 */ 2541 2542void lp_dump(struct loadparm_context *lp_ctx, FILE *f, bool show_defaults, 2543 int maxtoprint) 2544{ 2545 int iService; 2546 2547 if (show_defaults) 2548 defaults_saved = false; 2549 2550 dump_globals(lp_ctx, f, show_defaults); 2551 2552 dump_a_service(lp_ctx->sDefault, lp_ctx->sDefault, f); 2553 2554 for (iService = 0; iService < maxtoprint; iService++) 2555 lp_dump_one(f, show_defaults, lp_ctx->services[iService], lp_ctx->sDefault); 2556} 2557 2558/** 2559 * Display the contents of one service in human-readable form. 2560 */ 2561void lp_dump_one(FILE *f, bool show_defaults, struct loadparm_service *service, struct loadparm_service *sDefault) 2562{ 2563 if (service != NULL) { 2564 if (service->szService[0] == '\0') 2565 return; 2566 dump_a_service(service, sDefault, f); 2567 } 2568} 2569 2570struct loadparm_service *lp_servicebynum(struct loadparm_context *lp_ctx, 2571 int snum) 2572{ 2573 return lp_ctx->services[snum]; 2574} 2575 2576struct loadparm_service *lp_service(struct loadparm_context *lp_ctx, 2577 const char *service_name) 2578{ 2579 int iService; 2580 char *serviceName; 2581 2582 for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--) { 2583 if (lp_ctx->services[iService] && 2584 lp_ctx->services[iService]->szService) { 2585 /* 2586 * The substitution here is used to support %U is 2587 * service names 2588 */ 2589 serviceName = standard_sub_basic( 2590 lp_ctx->services[iService], 2591 lp_ctx->services[iService]->szService); 2592 if (strequal(serviceName, service_name)) 2593 return lp_ctx->services[iService]; 2594 } 2595 } 2596 2597 DEBUG(7,("lp_servicenumber: couldn't find %s\n", service_name)); 2598 return NULL; 2599} 2600 2601 2602/** 2603 * A useful volume label function. 2604 */ 2605const char *volume_label(struct loadparm_service *service, struct loadparm_service *sDefault) 2606{ 2607 const char *ret = lp_volume(service, sDefault); 2608 if (!*ret) 2609 return lp_servicename(service); 2610 return ret; 2611} 2612 2613 2614/** 2615 * If we are PDC then prefer us as DMB 2616 */ 2617const char *lp_printername(struct loadparm_service *service, struct loadparm_service *sDefault) 2618{ 2619 const char *ret = _lp_printername(service, sDefault); 2620 if (ret == NULL || (ret != NULL && *ret == '\0')) 2621 ret = lp_servicename(service); 2622 2623 return ret; 2624} 2625 2626 2627/** 2628 * Return the max print jobs per queue. 2629 */ 2630int lp_maxprintjobs(struct loadparm_service *service, struct loadparm_service *sDefault) 2631{ 2632 int maxjobs = (service != NULL) ? service->iMaxPrintJobs : sDefault->iMaxPrintJobs; 2633 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID) 2634 maxjobs = PRINT_MAX_JOBID - 1; 2635 2636 return maxjobs; 2637} 2638 2639struct smb_iconv_convenience *lp_iconv_convenience(struct loadparm_context *lp_ctx) 2640{ 2641 if (lp_ctx == NULL) { 2642 static struct smb_iconv_convenience *fallback_ic = NULL; 2643 if (fallback_ic == NULL) 2644 fallback_ic = smb_iconv_convenience_init(talloc_autofree_context(), 2645 "CP850", "UTF8", true); 2646 return fallback_ic; 2647 } 2648 return lp_ctx->iconv_convenience; 2649} 2650 2651_PUBLIC_ void reload_charcnv(struct loadparm_context *lp_ctx) 2652{ 2653 talloc_unlink(lp_ctx, lp_ctx->iconv_convenience); 2654 global_iconv_convenience = lp_ctx->iconv_convenience = smb_iconv_convenience_init_lp(lp_ctx, lp_ctx); 2655} 2656 2657void lp_smbcli_options(struct loadparm_context *lp_ctx, 2658 struct smbcli_options *options) 2659{ 2660 options->max_xmit = lp_max_xmit(lp_ctx); 2661 options->max_mux = lp_maxmux(lp_ctx); 2662 options->use_spnego = lp_nt_status_support(lp_ctx) && lp_use_spnego(lp_ctx); 2663 options->signing = lp_client_signing(lp_ctx); 2664 options->request_timeout = SMB_REQUEST_TIMEOUT; 2665 options->ntstatus_support = lp_nt_status_support(lp_ctx); 2666 options->max_protocol = lp_cli_maxprotocol(lp_ctx); 2667 options->unicode = lp_unicode(lp_ctx); 2668 options->use_oplocks = true; 2669 options->use_level2_oplocks = true; 2670} 2671 2672void lp_smbcli_session_options(struct loadparm_context *lp_ctx, 2673 struct smbcli_session_options *options) 2674{ 2675 options->lanman_auth = lp_client_lanman_auth(lp_ctx); 2676 options->ntlmv2_auth = lp_client_ntlmv2_auth(lp_ctx); 2677 options->plaintext_auth = lp_client_plaintext_auth(lp_ctx); 2678} 2679 2680_PUBLIC_ char *lp_tls_keyfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 2681{ 2682 return private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_keyfile); 2683} 2684 2685_PUBLIC_ char *lp_tls_certfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 2686{ 2687 return private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_certfile); 2688} 2689 2690_PUBLIC_ char *lp_tls_cafile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 2691{ 2692 return private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_cafile); 2693} 2694 2695_PUBLIC_ char *lp_tls_crlfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 2696{ 2697 return private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_crlfile); 2698} 2699 2700_PUBLIC_ char *lp_tls_dhpfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 2701{ 2702 return private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_dhpfile); 2703} 2704 2705_PUBLIC_ struct dcerpc_server_info *lp_dcerpc_server_info(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 2706{ 2707 struct dcerpc_server_info *ret = talloc_zero(mem_ctx, struct dcerpc_server_info); 2708 2709 ret->domain_name = talloc_reference(mem_ctx, lp_workgroup(lp_ctx)); 2710 ret->version_major = lp_parm_int(lp_ctx, NULL, "server_info", "version_major", 5); 2711 ret->version_minor = lp_parm_int(lp_ctx, NULL, "server_info", "version_minor", 2); 2712 ret->version_build = lp_parm_int(lp_ctx, NULL, "server_info", "version_build", 3790); 2713 2714 return ret; 2715} 2716 2717struct gensec_settings *lp_gensec_settings(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 2718{ 2719 struct gensec_settings *settings = talloc(mem_ctx, struct gensec_settings); 2720 if (settings == NULL) 2721 return NULL; 2722 SMB_ASSERT(lp_ctx != NULL); 2723 settings->lp_ctx = talloc_reference(settings, lp_ctx); 2724 settings->iconv_convenience = lp_iconv_convenience(lp_ctx); 2725 settings->target_hostname = lp_parm_string(lp_ctx, NULL, "gensec", "target_hostname"); 2726 return settings; 2727} 2728 2729