1 /* $NetBSD: config.c,v 1.2 2020/08/11 13:15:40 christos Exp $ */ 2 3 /* config.c - ldap backend configuration file routine */ 4 /* $OpenLDAP$ */ 5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 2003-2020 The OpenLDAP Foundation. 8 * Portions Copyright 1999-2003 Howard Chu. 9 * Portions Copyright 2000-2003 Pierangelo Masarati. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted only as authorized by the OpenLDAP 14 * Public License. 15 * 16 * A copy of this license is available in the file LICENSE in the 17 * top-level directory of the distribution or, alternatively, at 18 * <http://www.OpenLDAP.org/license.html>. 19 */ 20 /* ACKNOWLEDGEMENTS: 21 * This work was initially developed by the Howard Chu for inclusion 22 * in OpenLDAP Software and subsequently enhanced by Pierangelo 23 * Masarati. 24 */ 25 26 #include <sys/cdefs.h> 27 __RCSID("$NetBSD: config.c,v 1.2 2020/08/11 13:15:40 christos Exp $"); 28 29 #include "portable.h" 30 31 #include <stdio.h> 32 33 #include <ac/string.h> 34 #include <ac/ctype.h> 35 #include <ac/socket.h> 36 37 #include "slap.h" 38 #include "config.h" 39 #include "back-ldap.h" 40 #include "lutil.h" 41 #include "ldif.h" 42 43 static SLAP_EXTOP_MAIN_FN ldap_back_exop_whoami; 44 45 static ConfigDriver ldap_back_cf_gen; 46 static ConfigDriver ldap_pbind_cf_gen; 47 48 enum { 49 LDAP_BACK_CFG_URI = 1, 50 LDAP_BACK_CFG_TLS, 51 LDAP_BACK_CFG_ACL_AUTHCDN, 52 LDAP_BACK_CFG_ACL_PASSWD, 53 LDAP_BACK_CFG_ACL_METHOD, 54 LDAP_BACK_CFG_ACL_BIND, 55 LDAP_BACK_CFG_IDASSERT_MODE, 56 LDAP_BACK_CFG_IDASSERT_AUTHCDN, 57 LDAP_BACK_CFG_IDASSERT_PASSWD, 58 LDAP_BACK_CFG_IDASSERT_AUTHZFROM, 59 LDAP_BACK_CFG_IDASSERT_PASSTHRU, 60 LDAP_BACK_CFG_IDASSERT_METHOD, 61 LDAP_BACK_CFG_IDASSERT_BIND, 62 LDAP_BACK_CFG_REBIND, 63 LDAP_BACK_CFG_CHASE, 64 LDAP_BACK_CFG_T_F, 65 LDAP_BACK_CFG_WHOAMI, 66 LDAP_BACK_CFG_TIMEOUT, 67 LDAP_BACK_CFG_IDLE_TIMEOUT, 68 LDAP_BACK_CFG_CONN_TTL, 69 LDAP_BACK_CFG_NETWORK_TIMEOUT, 70 LDAP_BACK_CFG_VERSION, 71 LDAP_BACK_CFG_SINGLECONN, 72 LDAP_BACK_CFG_USETEMP, 73 LDAP_BACK_CFG_CONNPOOLMAX, 74 LDAP_BACK_CFG_CANCEL, 75 LDAP_BACK_CFG_QUARANTINE, 76 LDAP_BACK_CFG_ST_REQUEST, 77 LDAP_BACK_CFG_NOREFS, 78 LDAP_BACK_CFG_NOUNDEFFILTER, 79 LDAP_BACK_CFG_ONERR, 80 81 LDAP_BACK_CFG_REWRITE, 82 LDAP_BACK_CFG_KEEPALIVE, 83 84 LDAP_BACK_CFG_OMIT_UNKNOWN_SCHEMA, 85 86 LDAP_BACK_CFG_LAST 87 }; 88 89 static ConfigTable ldapcfg[] = { 90 { "uri", "uri", 2, 2, 0, 91 ARG_MAGIC|LDAP_BACK_CFG_URI, 92 ldap_back_cf_gen, "( OLcfgDbAt:0.14 " 93 "NAME 'olcDbURI' " 94 "DESC 'URI (list) for remote DSA' " 95 "SYNTAX OMsDirectoryString " 96 "SINGLE-VALUE )", 97 NULL, NULL }, 98 { "tls", "what", 2, 0, 0, 99 ARG_MAGIC|LDAP_BACK_CFG_TLS, 100 ldap_back_cf_gen, "( OLcfgDbAt:3.1 " 101 "NAME 'olcDbStartTLS' " 102 "DESC 'StartTLS' " 103 "SYNTAX OMsDirectoryString " 104 "SINGLE-VALUE )", 105 NULL, NULL }, 106 { "acl-authcDN", "DN", 2, 2, 0, 107 ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_ACL_AUTHCDN, 108 ldap_back_cf_gen, "( OLcfgDbAt:3.2 " 109 "NAME 'olcDbACLAuthcDn' " 110 "DESC 'Remote ACL administrative identity' " 111 "OBSOLETE " 112 "SYNTAX OMsDN " 113 "SINGLE-VALUE )", 114 NULL, NULL }, 115 /* deprecated, will be removed; aliases "acl-authcDN" */ 116 { "binddn", "DN", 2, 2, 0, 117 ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_ACL_AUTHCDN, 118 ldap_back_cf_gen, NULL, NULL, NULL }, 119 { "acl-passwd", "cred", 2, 2, 0, 120 ARG_MAGIC|LDAP_BACK_CFG_ACL_PASSWD, 121 ldap_back_cf_gen, "( OLcfgDbAt:3.3 " 122 "NAME 'olcDbACLPasswd' " 123 "DESC 'Remote ACL administrative identity credentials' " 124 "OBSOLETE " 125 "SYNTAX OMsDirectoryString " 126 "SINGLE-VALUE )", 127 NULL, NULL }, 128 /* deprecated, will be removed; aliases "acl-passwd" */ 129 { "bindpw", "cred", 2, 2, 0, 130 ARG_MAGIC|LDAP_BACK_CFG_ACL_PASSWD, 131 ldap_back_cf_gen, NULL, NULL, NULL }, 132 /* deprecated, will be removed; aliases "acl-bind" */ 133 { "acl-method", "args", 2, 0, 0, 134 ARG_MAGIC|LDAP_BACK_CFG_ACL_METHOD, 135 ldap_back_cf_gen, NULL, NULL, NULL }, 136 { "acl-bind", "args", 2, 0, 0, 137 ARG_MAGIC|LDAP_BACK_CFG_ACL_BIND, 138 ldap_back_cf_gen, "( OLcfgDbAt:3.4 " 139 "NAME 'olcDbACLBind' " 140 "DESC 'Remote ACL administrative identity auth bind configuration' " 141 "SYNTAX OMsDirectoryString " 142 "SINGLE-VALUE )", 143 NULL, NULL }, 144 { "idassert-authcDN", "DN", 2, 2, 0, 145 ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_AUTHCDN, 146 ldap_back_cf_gen, "( OLcfgDbAt:3.5 " 147 "NAME 'olcDbIDAssertAuthcDn' " 148 "DESC 'Remote Identity Assertion administrative identity' " 149 "OBSOLETE " 150 "SYNTAX OMsDN " 151 "SINGLE-VALUE )", 152 NULL, NULL }, 153 /* deprecated, will be removed; partially aliases "idassert-authcDN" */ 154 { "proxyauthzdn", "DN", 2, 2, 0, 155 ARG_DN|ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_AUTHCDN, 156 ldap_back_cf_gen, NULL, NULL, NULL }, 157 { "idassert-passwd", "cred", 2, 2, 0, 158 ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_PASSWD, 159 ldap_back_cf_gen, "( OLcfgDbAt:3.6 " 160 "NAME 'olcDbIDAssertPasswd' " 161 "DESC 'Remote Identity Assertion administrative identity credentials' " 162 "OBSOLETE " 163 "SYNTAX OMsDirectoryString " 164 "SINGLE-VALUE )", 165 NULL, NULL }, 166 /* deprecated, will be removed; partially aliases "idassert-passwd" */ 167 { "proxyauthzpw", "cred", 2, 2, 0, 168 ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_PASSWD, 169 ldap_back_cf_gen, NULL, NULL, NULL }, 170 { "idassert-bind", "args", 2, 0, 0, 171 ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_BIND, 172 ldap_back_cf_gen, "( OLcfgDbAt:3.7 " 173 "NAME 'olcDbIDAssertBind' " 174 "DESC 'Remote Identity Assertion administrative identity auth bind configuration' " 175 "SYNTAX OMsDirectoryString " 176 "SINGLE-VALUE )", 177 NULL, NULL }, 178 { "idassert-method", "args", 2, 0, 0, 179 ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_METHOD, 180 ldap_back_cf_gen, NULL, NULL, NULL }, 181 { "idassert-mode", "mode>|u:<user>|[dn:]<DN", 2, 0, 0, 182 ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_MODE, 183 ldap_back_cf_gen, "( OLcfgDbAt:3.8 " 184 "NAME 'olcDbIDAssertMode' " 185 "DESC 'Remote Identity Assertion mode' " 186 "OBSOLETE " 187 "SYNTAX OMsDirectoryString " 188 "SINGLE-VALUE)", 189 NULL, NULL }, 190 { "idassert-authzFrom", "authzRule", 2, 2, 0, 191 ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_AUTHZFROM, 192 ldap_back_cf_gen, "( OLcfgDbAt:3.9 " 193 "NAME 'olcDbIDAssertAuthzFrom' " 194 "DESC 'Remote Identity Assertion authz rules' " 195 "EQUALITY caseIgnoreMatch " 196 "SYNTAX OMsDirectoryString " 197 "X-ORDERED 'VALUES' )", 198 NULL, NULL }, 199 { "rebind-as-user", "true|FALSE", 1, 2, 0, 200 ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_REBIND, 201 ldap_back_cf_gen, "( OLcfgDbAt:3.10 " 202 "NAME 'olcDbRebindAsUser' " 203 "DESC 'Rebind as user' " 204 "SYNTAX OMsBoolean " 205 "SINGLE-VALUE )", 206 NULL, NULL }, 207 { "chase-referrals", "true|FALSE", 2, 2, 0, 208 ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_CHASE, 209 ldap_back_cf_gen, "( OLcfgDbAt:3.11 " 210 "NAME 'olcDbChaseReferrals' " 211 "DESC 'Chase referrals' " 212 "SYNTAX OMsBoolean " 213 "SINGLE-VALUE )", 214 NULL, NULL }, 215 { "t-f-support", "true|FALSE|discover", 2, 2, 0, 216 ARG_MAGIC|LDAP_BACK_CFG_T_F, 217 ldap_back_cf_gen, "( OLcfgDbAt:3.12 " 218 "NAME 'olcDbTFSupport' " 219 "DESC 'Absolute filters support' " 220 "SYNTAX OMsDirectoryString " 221 "SINGLE-VALUE )", 222 NULL, NULL }, 223 { "proxy-whoami", "true|FALSE", 1, 2, 0, 224 ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_WHOAMI, 225 ldap_back_cf_gen, "( OLcfgDbAt:3.13 " 226 "NAME 'olcDbProxyWhoAmI' " 227 "DESC 'Proxy whoAmI exop' " 228 "SYNTAX OMsBoolean " 229 "SINGLE-VALUE )", 230 NULL, NULL }, 231 { "timeout", "timeout(list)", 2, 0, 0, 232 ARG_MAGIC|LDAP_BACK_CFG_TIMEOUT, 233 ldap_back_cf_gen, "( OLcfgDbAt:3.14 " 234 "NAME 'olcDbTimeout' " 235 "DESC 'Per-operation timeouts' " 236 "SYNTAX OMsDirectoryString " 237 "SINGLE-VALUE )", 238 NULL, NULL }, 239 { "idle-timeout", "timeout", 2, 2, 0, 240 ARG_MAGIC|LDAP_BACK_CFG_IDLE_TIMEOUT, 241 ldap_back_cf_gen, "( OLcfgDbAt:3.15 " 242 "NAME 'olcDbIdleTimeout' " 243 "DESC 'connection idle timeout' " 244 "SYNTAX OMsDirectoryString " 245 "SINGLE-VALUE )", 246 NULL, NULL }, 247 { "conn-ttl", "ttl", 2, 2, 0, 248 ARG_MAGIC|LDAP_BACK_CFG_CONN_TTL, 249 ldap_back_cf_gen, "( OLcfgDbAt:3.16 " 250 "NAME 'olcDbConnTtl' " 251 "DESC 'connection ttl' " 252 "SYNTAX OMsDirectoryString " 253 "SINGLE-VALUE )", 254 NULL, NULL }, 255 { "network-timeout", "timeout", 2, 2, 0, 256 ARG_MAGIC|LDAP_BACK_CFG_NETWORK_TIMEOUT, 257 ldap_back_cf_gen, "( OLcfgDbAt:3.17 " 258 "NAME 'olcDbNetworkTimeout' " 259 "DESC 'connection network timeout' " 260 "SYNTAX OMsDirectoryString " 261 "SINGLE-VALUE )", 262 NULL, NULL }, 263 { "protocol-version", "version", 2, 2, 0, 264 ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_VERSION, 265 ldap_back_cf_gen, "( OLcfgDbAt:3.18 " 266 "NAME 'olcDbProtocolVersion' " 267 "DESC 'protocol version' " 268 "SYNTAX OMsInteger " 269 "SINGLE-VALUE )", 270 NULL, NULL }, 271 { "single-conn", "true|FALSE", 2, 2, 0, 272 ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_SINGLECONN, 273 ldap_back_cf_gen, "( OLcfgDbAt:3.19 " 274 "NAME 'olcDbSingleConn' " 275 "DESC 'cache a single connection per identity' " 276 "SYNTAX OMsBoolean " 277 "SINGLE-VALUE )", 278 NULL, NULL }, 279 { "cancel", "ABANDON|ignore|exop", 2, 2, 0, 280 ARG_MAGIC|LDAP_BACK_CFG_CANCEL, 281 ldap_back_cf_gen, "( OLcfgDbAt:3.20 " 282 "NAME 'olcDbCancel' " 283 "DESC 'abandon/ignore/exop operations when appropriate' " 284 "SYNTAX OMsDirectoryString " 285 "SINGLE-VALUE )", 286 NULL, NULL }, 287 { "quarantine", "retrylist", 2, 2, 0, 288 ARG_MAGIC|LDAP_BACK_CFG_QUARANTINE, 289 ldap_back_cf_gen, "( OLcfgDbAt:3.21 " 290 "NAME 'olcDbQuarantine' " 291 "DESC 'Quarantine database if connection fails and retry according to rule' " 292 "SYNTAX OMsDirectoryString " 293 "SINGLE-VALUE )", 294 NULL, NULL }, 295 { "use-temporary-conn", "true|FALSE", 2, 2, 0, 296 ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_USETEMP, 297 ldap_back_cf_gen, "( OLcfgDbAt:3.22 " 298 "NAME 'olcDbUseTemporaryConn' " 299 "DESC 'Use temporary connections if the cached one is busy' " 300 "SYNTAX OMsBoolean " 301 "SINGLE-VALUE )", 302 NULL, NULL }, 303 { "conn-pool-max", "<n>", 2, 2, 0, 304 ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_CONNPOOLMAX, 305 ldap_back_cf_gen, "( OLcfgDbAt:3.23 " 306 "NAME 'olcDbConnectionPoolMax' " 307 "DESC 'Max size of privileged connections pool' " 308 "SYNTAX OMsInteger " 309 "SINGLE-VALUE )", 310 NULL, NULL }, 311 #ifdef SLAP_CONTROL_X_SESSION_TRACKING 312 { "session-tracking-request", "true|FALSE", 2, 2, 0, 313 ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_ST_REQUEST, 314 ldap_back_cf_gen, "( OLcfgDbAt:3.24 " 315 "NAME 'olcDbSessionTrackingRequest' " 316 "DESC 'Add session tracking control to proxied requests' " 317 "SYNTAX OMsBoolean " 318 "SINGLE-VALUE )", 319 NULL, NULL }, 320 #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ 321 { "norefs", "true|FALSE", 2, 2, 0, 322 ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_NOREFS, 323 ldap_back_cf_gen, "( OLcfgDbAt:3.25 " 324 "NAME 'olcDbNoRefs' " 325 "DESC 'Do not return search reference responses' " 326 "SYNTAX OMsBoolean " 327 "SINGLE-VALUE )", 328 NULL, NULL }, 329 { "noundeffilter", "true|FALSE", 2, 2, 0, 330 ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_NOUNDEFFILTER, 331 ldap_back_cf_gen, "( OLcfgDbAt:3.26 " 332 "NAME 'olcDbNoUndefFilter' " 333 "DESC 'Do not propagate undefined search filters' " 334 "SYNTAX OMsBoolean " 335 "SINGLE-VALUE )", 336 NULL, NULL }, 337 { "onerr", "CONTINUE|report|stop", 2, 2, 0, 338 ARG_MAGIC|LDAP_BACK_CFG_ONERR, 339 ldap_back_cf_gen, "( OLcfgDbAt:3.108 " 340 "NAME 'olcDbOnErr' " 341 "DESC 'error handling' " 342 "SYNTAX OMsDirectoryString " 343 "SINGLE-VALUE )", 344 NULL, NULL }, 345 { "idassert-passThru", "authzRule", 2, 2, 0, 346 ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_PASSTHRU, 347 ldap_back_cf_gen, "( OLcfgDbAt:3.27 " 348 "NAME 'olcDbIDAssertPassThru' " 349 "DESC 'Remote Identity Assertion passthru rules' " 350 "EQUALITY caseIgnoreMatch " 351 "SYNTAX OMsDirectoryString " 352 "X-ORDERED 'VALUES' )", 353 NULL, NULL }, 354 355 { "suffixmassage", "[virtual]> <real", 2, 3, 0, 356 ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE, 357 ldap_back_cf_gen, NULL, NULL, NULL }, 358 { "map", "attribute|objectClass> [*|<local>] *|<remote", 3, 4, 0, 359 ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE, 360 ldap_back_cf_gen, NULL, NULL, NULL }, 361 { "rewrite", "<arglist>", 2, 4, STRLENOF( "rewrite" ), 362 ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE, 363 ldap_back_cf_gen, NULL, NULL, NULL }, 364 { "omit-unknown-schema", "true|FALSE", 2, 2, 0, 365 ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_OMIT_UNKNOWN_SCHEMA, 366 ldap_back_cf_gen, "( OLcfgDbAt:3.28 " 367 "NAME 'olcDbRemoveUnknownSchema' " 368 "DESC 'Omit unknown schema when returning search results' " 369 "SYNTAX OMsBoolean " 370 "SINGLE-VALUE )", 371 NULL, NULL }, 372 { "keepalive", "keepalive", 2, 2, 0, 373 ARG_MAGIC|LDAP_BACK_CFG_KEEPALIVE, 374 ldap_back_cf_gen, "( OLcfgDbAt:3.29 " 375 "NAME 'olcDbKeepalive' " 376 "DESC 'TCP keepalive' " 377 "SYNTAX OMsDirectoryString " 378 "SINGLE-VALUE )", 379 NULL, NULL }, 380 { NULL, NULL, 0, 0, 0, ARG_IGNORED, 381 NULL, NULL, NULL, NULL } 382 }; 383 384 static ConfigOCs ldapocs[] = { 385 { "( OLcfgDbOc:3.1 " 386 "NAME 'olcLDAPConfig' " 387 "DESC 'LDAP backend configuration' " 388 "SUP olcDatabaseConfig " 389 "MAY ( olcDbURI " 390 "$ olcDbStartTLS " 391 "$ olcDbACLAuthcDn " 392 "$ olcDbACLPasswd " 393 "$ olcDbACLBind " 394 "$ olcDbIDAssertAuthcDn " 395 "$ olcDbIDAssertPasswd " 396 "$ olcDbIDAssertBind " 397 "$ olcDbIDAssertMode " 398 "$ olcDbIDAssertAuthzFrom " 399 "$ olcDbIDAssertPassThru " 400 "$ olcDbRebindAsUser " 401 "$ olcDbChaseReferrals " 402 "$ olcDbTFSupport " 403 "$ olcDbProxyWhoAmI " 404 "$ olcDbTimeout " 405 "$ olcDbIdleTimeout " 406 "$ olcDbConnTtl " 407 "$ olcDbNetworkTimeout " 408 "$ olcDbProtocolVersion " 409 "$ olcDbSingleConn " 410 "$ olcDbCancel " 411 "$ olcDbQuarantine " 412 "$ olcDbUseTemporaryConn " 413 "$ olcDbConnectionPoolMax " 414 #ifdef SLAP_CONTROL_X_SESSION_TRACKING 415 "$ olcDbSessionTrackingRequest " 416 #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ 417 "$ olcDbNoRefs " 418 "$ olcDbNoUndefFilter " 419 "$ olcDbOnErr " 420 "$ olcDbKeepalive " 421 ") )", 422 Cft_Database, ldapcfg}, 423 { NULL, 0, NULL } 424 }; 425 426 static ConfigTable pbindcfg[] = { 427 { "uri", "uri", 2, 2, 0, 428 ARG_MAGIC|LDAP_BACK_CFG_URI, 429 ldap_pbind_cf_gen, "( OLcfgDbAt:0.14 " 430 "NAME 'olcDbURI' " 431 "DESC 'URI (list) for remote DSA' " 432 "SYNTAX OMsDirectoryString " 433 "SINGLE-VALUE )", 434 NULL, NULL }, 435 { "tls", "what", 2, 0, 0, 436 ARG_MAGIC|LDAP_BACK_CFG_TLS, 437 ldap_pbind_cf_gen, "( OLcfgDbAt:3.1 " 438 "NAME 'olcDbStartTLS' " 439 "DESC 'StartTLS' " 440 "SYNTAX OMsDirectoryString " 441 "SINGLE-VALUE )", 442 NULL, NULL }, 443 { "network-timeout", "timeout", 2, 2, 0, 444 ARG_MAGIC|LDAP_BACK_CFG_NETWORK_TIMEOUT, 445 ldap_pbind_cf_gen, "( OLcfgDbAt:3.17 " 446 "NAME 'olcDbNetworkTimeout' " 447 "DESC 'connection network timeout' " 448 "SYNTAX OMsDirectoryString " 449 "SINGLE-VALUE )", 450 NULL, NULL }, 451 { "quarantine", "retrylist", 2, 2, 0, 452 ARG_MAGIC|LDAP_BACK_CFG_QUARANTINE, 453 ldap_pbind_cf_gen, "( OLcfgDbAt:3.21 " 454 "NAME 'olcDbQuarantine' " 455 "DESC 'Quarantine database if connection fails and retry according to rule' " 456 "SYNTAX OMsDirectoryString " 457 "SINGLE-VALUE )", 458 NULL, NULL }, 459 { NULL, NULL, 0, 0, 0, ARG_IGNORED, 460 NULL, NULL, NULL, NULL } 461 }; 462 463 static ConfigOCs pbindocs[] = { 464 { "( OLcfgOvOc:3.3 " 465 "NAME 'olcPBindConfig' " 466 "DESC 'Proxy Bind configuration' " 467 "SUP olcOverlayConfig " 468 "MUST olcDbURI " 469 "MAY ( olcDbStartTLS " 470 "$ olcDbNetworkTimeout " 471 "$ olcDbQuarantine " 472 ") )", 473 Cft_Overlay, pbindcfg}, 474 { NULL, 0, NULL } 475 }; 476 477 static slap_verbmasks idassert_mode[] = { 478 { BER_BVC("self"), LDAP_BACK_IDASSERT_SELF }, 479 { BER_BVC("anonymous"), LDAP_BACK_IDASSERT_ANONYMOUS }, 480 { BER_BVC("none"), LDAP_BACK_IDASSERT_NOASSERT }, 481 { BER_BVC("legacy"), LDAP_BACK_IDASSERT_LEGACY }, 482 { BER_BVNULL, 0 } 483 }; 484 485 static slap_verbmasks tls_mode[] = { 486 { BER_BVC( "propagate" ), LDAP_BACK_F_TLS_PROPAGATE_MASK }, 487 { BER_BVC( "try-propagate" ), LDAP_BACK_F_PROPAGATE_TLS }, 488 { BER_BVC( "start" ), LDAP_BACK_F_TLS_USE_MASK }, 489 { BER_BVC( "try-start" ), LDAP_BACK_F_USE_TLS }, 490 { BER_BVC( "ldaps" ), LDAP_BACK_F_TLS_LDAPS }, 491 { BER_BVC( "none" ), LDAP_BACK_F_NONE }, 492 { BER_BVNULL, 0 } 493 }; 494 495 static slap_verbmasks t_f_mode[] = { 496 { BER_BVC( "yes" ), LDAP_BACK_F_T_F }, 497 { BER_BVC( "discover" ), LDAP_BACK_F_T_F_DISCOVER }, 498 { BER_BVC( "no" ), LDAP_BACK_F_NONE }, 499 { BER_BVNULL, 0 } 500 }; 501 502 static slap_verbmasks cancel_mode[] = { 503 { BER_BVC( "ignore" ), LDAP_BACK_F_CANCEL_IGNORE }, 504 { BER_BVC( "exop" ), LDAP_BACK_F_CANCEL_EXOP }, 505 { BER_BVC( "exop-discover" ), LDAP_BACK_F_CANCEL_EXOP_DISCOVER }, 506 { BER_BVC( "abandon" ), LDAP_BACK_F_CANCEL_ABANDON }, 507 { BER_BVNULL, 0 } 508 }; 509 510 static slap_verbmasks onerr_mode[] = { 511 { BER_BVC( "stop" ), LDAP_BACK_F_ONERR_STOP }, 512 { BER_BVC( "report" ), LDAP_BACK_F_ONERR_STOP }, /* same behavior */ 513 { BER_BVC( "continue" ), LDAP_BACK_F_NONE }, 514 { BER_BVNULL, 0 } 515 }; 516 517 /* see enum in slap.h */ 518 static slap_cf_aux_table timeout_table[] = { 519 { BER_BVC("bind="), SLAP_OP_BIND * sizeof( time_t ), 'u', 0, NULL }, 520 /* unbind makes no sense */ 521 { BER_BVC("add="), SLAP_OP_ADD * sizeof( time_t ), 'u', 0, NULL }, 522 { BER_BVC("delete="), SLAP_OP_DELETE * sizeof( time_t ), 'u', 0, NULL }, 523 { BER_BVC("modrdn="), SLAP_OP_MODRDN * sizeof( time_t ), 'u', 0, NULL }, 524 { BER_BVC("modify="), SLAP_OP_MODIFY * sizeof( time_t ), 'u', 0, NULL }, 525 { BER_BVC("compare="), SLAP_OP_COMPARE * sizeof( time_t ), 'u', 0, NULL }, 526 { BER_BVC("search="), SLAP_OP_SEARCH * sizeof( time_t ), 'u', 0, NULL }, 527 /* abandon makes little sense */ 528 #if 0 /* not implemented yet */ 529 { BER_BVC("extended="), SLAP_OP_EXTENDED * sizeof( time_t ), 'u', 0, NULL }, 530 #endif 531 { BER_BVNULL, 0, 0, 0, NULL } 532 }; 533 534 int 535 slap_retry_info_parse( 536 char *in, 537 slap_retry_info_t *ri, 538 char *buf, 539 ber_len_t buflen ) 540 { 541 char **retrylist = NULL; 542 int rc = 0; 543 int i; 544 545 slap_str2clist( &retrylist, in, " ;" ); 546 if ( retrylist == NULL ) { 547 return 1; 548 } 549 550 for ( i = 0; retrylist[ i ] != NULL; i++ ) 551 /* count */ ; 552 553 ri->ri_interval = ch_calloc( sizeof( time_t ), i + 1 ); 554 ri->ri_num = ch_calloc( sizeof( int ), i + 1 ); 555 556 for ( i = 0; retrylist[ i ] != NULL; i++ ) { 557 unsigned long t; 558 char *sep = strchr( retrylist[ i ], ',' ); 559 560 if ( sep == NULL ) { 561 snprintf( buf, buflen, 562 "missing comma in retry pattern #%d \"%s\"", 563 i, retrylist[ i ] ); 564 rc = 1; 565 goto done; 566 } 567 568 *sep++ = '\0'; 569 570 if ( lutil_parse_time( retrylist[ i ], &t ) ) { 571 snprintf( buf, buflen, 572 "unable to parse interval #%d \"%s\"", 573 i, retrylist[ i ] ); 574 rc = 1; 575 goto done; 576 } 577 ri->ri_interval[ i ] = (time_t)t; 578 579 if ( strcmp( sep, "+" ) == 0 ) { 580 if ( retrylist[ i + 1 ] != NULL ) { 581 snprintf( buf, buflen, 582 "extra cruft after retry pattern " 583 "#%d \"%s,+\" with \"forever\" mark", 584 i, retrylist[ i ] ); 585 rc = 1; 586 goto done; 587 } 588 ri->ri_num[ i ] = SLAP_RETRYNUM_FOREVER; 589 590 } else if ( lutil_atoi( &ri->ri_num[ i ], sep ) ) { 591 snprintf( buf, buflen, 592 "unable to parse retry num #%d \"%s\"", 593 i, sep ); 594 rc = 1; 595 goto done; 596 } 597 } 598 599 ri->ri_num[ i ] = SLAP_RETRYNUM_TAIL; 600 601 ri->ri_idx = 0; 602 ri->ri_count = 0; 603 ri->ri_last = (time_t)(-1); 604 605 done:; 606 ldap_charray_free( retrylist ); 607 608 if ( rc ) { 609 slap_retry_info_destroy( ri ); 610 } 611 612 return rc; 613 } 614 615 int 616 slap_retry_info_unparse( 617 slap_retry_info_t *ri, 618 struct berval *bvout ) 619 { 620 char buf[ BUFSIZ * 2 ], 621 *ptr = buf; 622 int i, len, restlen = (int) sizeof( buf ); 623 struct berval bv; 624 625 assert( ri != NULL ); 626 assert( bvout != NULL ); 627 628 BER_BVZERO( bvout ); 629 630 for ( i = 0; ri->ri_num[ i ] != SLAP_RETRYNUM_TAIL; i++ ) { 631 if ( i > 0 ) { 632 if ( --restlen <= 0 ) { 633 return 1; 634 } 635 *ptr++ = ';'; 636 } 637 638 if ( lutil_unparse_time( ptr, restlen, ri->ri_interval[i] ) < 0 ) { 639 return 1; 640 } 641 len = (int) strlen( ptr ); 642 if ( (restlen -= len + 1) <= 0 ) { 643 return 1; 644 } 645 ptr += len; 646 *ptr++ = ','; 647 648 if ( ri->ri_num[i] == SLAP_RETRYNUM_FOREVER ) { 649 if ( --restlen <= 0 ) { 650 return 1; 651 } 652 *ptr++ = '+'; 653 654 } else { 655 len = snprintf( ptr, restlen, "%d", ri->ri_num[i] ); 656 if ( (restlen -= len) <= 0 || len < 0 ) { 657 return 1; 658 } 659 ptr += len; 660 } 661 } 662 663 bv.bv_val = buf; 664 bv.bv_len = ptr - buf; 665 ber_dupbv( bvout, &bv ); 666 667 return 0; 668 } 669 670 void 671 slap_retry_info_destroy( 672 slap_retry_info_t *ri ) 673 { 674 assert( ri != NULL ); 675 676 assert( ri->ri_interval != NULL ); 677 ch_free( ri->ri_interval ); 678 ri->ri_interval = NULL; 679 680 assert( ri->ri_num != NULL ); 681 ch_free( ri->ri_num ); 682 ri->ri_num = NULL; 683 } 684 685 int 686 slap_idassert_authzfrom_parse( ConfigArgs *c, slap_idassert_t *si ) 687 { 688 struct berval bv; 689 struct berval in; 690 int rc; 691 692 if ( strcmp( c->argv[ 1 ], "*" ) == 0 693 || strcmp( c->argv[ 1 ], "dn:*" ) == 0 694 || strcasecmp( c->argv[ 1 ], "dn.regex:.*" ) == 0 ) 695 { 696 if ( si->si_authz != NULL ) { 697 snprintf( c->cr_msg, sizeof( c->cr_msg ), 698 "\"idassert-authzFrom <authz>\": " 699 "\"%s\" conflicts with existing authz rules", 700 c->argv[ 1 ] ); 701 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 702 return 1; 703 } 704 705 si->si_flags |= LDAP_BACK_AUTH_AUTHZ_ALL; 706 707 return 0; 708 709 } else if ( ( si->si_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) { 710 snprintf( c->cr_msg, sizeof( c->cr_msg ), 711 "\"idassert-authzFrom <authz>\": " 712 "\"<authz>\" conflicts with \"*\"" ); 713 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 714 return 1; 715 } 716 717 ber_str2bv( c->argv[ 1 ], 0, 0, &in ); 718 rc = authzNormalize( 0, NULL, NULL, &in, &bv, NULL ); 719 if ( rc != LDAP_SUCCESS ) { 720 snprintf( c->cr_msg, sizeof( c->cr_msg ), 721 "\"idassert-authzFrom <authz>\": " 722 "invalid syntax" ); 723 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 724 return 1; 725 } 726 727 if ( c->valx == -1 ) { 728 ber_bvarray_add( &si->si_authz, &bv ); 729 730 } else { 731 int i = 0; 732 if ( si->si_authz != NULL ) { 733 for ( ; !BER_BVISNULL( &si->si_authz[ i ] ); i++ ) 734 ; 735 } 736 737 if ( i <= c->valx ) { 738 ber_bvarray_add( &si->si_authz, &bv ); 739 740 } else { 741 BerVarray tmp = ber_memrealloc( si->si_authz, 742 sizeof( struct berval )*( i + 2 ) ); 743 if ( tmp == NULL ) { 744 return -1; 745 } 746 si->si_authz = tmp; 747 for ( ; i > c->valx; i-- ) { 748 si->si_authz[ i ] = si->si_authz[ i - 1 ]; 749 } 750 si->si_authz[ c->valx ] = bv; 751 } 752 } 753 754 return 0; 755 } 756 757 static int 758 slap_idassert_passthru_parse( ConfigArgs *c, slap_idassert_t *si ) 759 { 760 struct berval bv; 761 struct berval in; 762 int rc; 763 764 ber_str2bv( c->argv[ 1 ], 0, 0, &in ); 765 rc = authzNormalize( 0, NULL, NULL, &in, &bv, NULL ); 766 if ( rc != LDAP_SUCCESS ) { 767 snprintf( c->cr_msg, sizeof( c->cr_msg ), 768 "\"idassert-passThru <authz>\": " 769 "invalid syntax" ); 770 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 771 return 1; 772 } 773 774 if ( c->valx == -1 ) { 775 ber_bvarray_add( &si->si_passthru, &bv ); 776 777 } else { 778 int i = 0; 779 if ( si->si_passthru != NULL ) { 780 for ( ; !BER_BVISNULL( &si->si_passthru[ i ] ); i++ ) 781 ; 782 } 783 784 if ( i <= c->valx ) { 785 ber_bvarray_add( &si->si_passthru, &bv ); 786 787 } else { 788 BerVarray tmp = ber_memrealloc( si->si_passthru, 789 sizeof( struct berval )*( i + 2 ) ); 790 if ( tmp == NULL ) { 791 return -1; 792 } 793 si->si_passthru = tmp; 794 for ( ; i > c->valx; i-- ) { 795 si->si_passthru[ i ] = si->si_passthru[ i - 1 ]; 796 } 797 si->si_passthru[ c->valx ] = bv; 798 } 799 } 800 801 return 0; 802 } 803 804 int 805 slap_idassert_parse( ConfigArgs *c, slap_idassert_t *si ) 806 { 807 int i; 808 809 for ( i = 1; i < c->argc; i++ ) { 810 if ( strncasecmp( c->argv[ i ], "mode=", STRLENOF( "mode=" ) ) == 0 ) { 811 char *argvi = c->argv[ i ] + STRLENOF( "mode=" ); 812 int j; 813 814 j = verb_to_mask( argvi, idassert_mode ); 815 if ( BER_BVISNULL( &idassert_mode[ j ].word ) ) { 816 snprintf( c->cr_msg, sizeof( c->cr_msg ), 817 "\"idassert-bind <args>\": " 818 "unknown mode \"%s\"", 819 argvi ); 820 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 821 return 1; 822 } 823 824 si->si_mode = idassert_mode[ j ].mask; 825 826 } else if ( strncasecmp( c->argv[ i ], "authz=", STRLENOF( "authz=" ) ) == 0 ) { 827 char *argvi = c->argv[ i ] + STRLENOF( "authz=" ); 828 829 if ( strcasecmp( argvi, "native" ) == 0 ) { 830 if ( si->si_bc.sb_method != LDAP_AUTH_SASL ) { 831 snprintf( c->cr_msg, sizeof( c->cr_msg ), 832 "\"idassert-bind <args>\": " 833 "authz=\"native\" incompatible " 834 "with auth method" ); 835 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 836 return 1; 837 } 838 si->si_flags |= LDAP_BACK_AUTH_NATIVE_AUTHZ; 839 840 } else if ( strcasecmp( argvi, "proxyAuthz" ) == 0 ) { 841 si->si_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ; 842 843 } else { 844 snprintf( c->cr_msg, sizeof( c->cr_msg ), 845 "\"idassert-bind <args>\": " 846 "unknown authz \"%s\"", 847 argvi ); 848 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 849 return 1; 850 } 851 852 } else if ( strncasecmp( c->argv[ i ], "flags=", STRLENOF( "flags=" ) ) == 0 ) { 853 char *argvi = c->argv[ i ] + STRLENOF( "flags=" ); 854 char **flags = ldap_str2charray( argvi, "," ); 855 int j, err = 0; 856 857 if ( flags == NULL ) { 858 snprintf( c->cr_msg, sizeof( c->cr_msg ), 859 "\"idassert-bind <args>\": " 860 "unable to parse flags \"%s\"", 861 argvi ); 862 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 863 return 1; 864 } 865 866 for ( j = 0; flags[ j ] != NULL; j++ ) { 867 868 if ( strcasecmp( flags[ j ], "override" ) == 0 ) { 869 si->si_flags |= LDAP_BACK_AUTH_OVERRIDE; 870 871 } else if ( strcasecmp( flags[ j ], "prescriptive" ) == 0 ) { 872 si->si_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE; 873 874 } else if ( strcasecmp( flags[ j ], "non-prescriptive" ) == 0 ) { 875 si->si_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE ); 876 877 } else if ( strcasecmp( flags[ j ], "obsolete-proxy-authz" ) == 0 ) { 878 if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) { 879 Debug( LDAP_DEBUG_ANY, 880 "%s: \"obsolete-proxy-authz\" flag " 881 "in \"idassert-mode <args>\" " 882 "incompatible with previously issued \"obsolete-encoding-workaround\" flag.\n", 883 c->log, 0, 0 ); 884 err = 1; 885 break; 886 887 } else { 888 si->si_flags |= LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ; 889 } 890 891 } else if ( strcasecmp( flags[ j ], "obsolete-encoding-workaround" ) == 0 ) { 892 if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) { 893 Debug( LDAP_DEBUG_ANY, 894 "%s: \"obsolete-encoding-workaround\" flag " 895 "in \"idassert-mode <args>\" " 896 "incompatible with previously issued \"obsolete-proxy-authz\" flag.\n", 897 c->log, 0, 0 ); 898 err = 1; 899 break; 900 901 } else { 902 si->si_flags |= LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND; 903 } 904 905 } else if ( strcasecmp( flags[ j ], "proxy-authz-critical" ) == 0 ) { 906 si->si_flags |= LDAP_BACK_AUTH_PROXYAUTHZ_CRITICAL; 907 908 } else if ( strcasecmp( flags[ j ], "proxy-authz-non-critical" ) == 0 ) { 909 si->si_flags &= ~LDAP_BACK_AUTH_PROXYAUTHZ_CRITICAL; 910 911 } else { 912 snprintf( c->cr_msg, sizeof( c->cr_msg ), 913 "\"idassert-bind <args>\": " 914 "unknown flag \"%s\"", 915 flags[ j ] ); 916 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 917 err = 1; 918 break; 919 } 920 } 921 922 ldap_charray_free( flags ); 923 if ( err ) { 924 return 1; 925 } 926 927 } else if ( bindconf_parse( c->argv[ i ], &si->si_bc ) ) { 928 snprintf( c->cr_msg, sizeof( c->cr_msg ), 929 "\"idassert-bind <args>\": " 930 "unable to parse field \"%s\"", 931 c->argv[ i ] ); 932 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 933 return 1; 934 } 935 } 936 937 if ( si->si_bc.sb_method == LDAP_AUTH_SIMPLE ) { 938 if ( BER_BVISNULL( &si->si_bc.sb_binddn ) 939 || BER_BVISNULL( &si->si_bc.sb_cred ) ) 940 { 941 snprintf( c->cr_msg, sizeof( c->cr_msg ), 942 "\"idassert-bind <args>\": " 943 "SIMPLE needs \"binddn\" and \"credentials\"" ); 944 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 945 return 1; 946 } 947 } 948 949 bindconf_tls_defaults( &si->si_bc ); 950 951 return 0; 952 } 953 954 /* NOTE: temporary, until back-meta is ported to back-config */ 955 int 956 slap_idassert_passthru_parse_cf( const char *fname, int lineno, const char *arg, slap_idassert_t *si ) 957 { 958 ConfigArgs c = { 0 }; 959 char *argv[ 3 ]; 960 961 snprintf( c.log, sizeof( c.log ), "%s: line %d", fname, lineno ); 962 c.argc = 2; 963 c.argv = argv; 964 argv[ 0 ] = "idassert-passThru"; 965 argv[ 1 ] = (char *)arg; 966 argv[ 2 ] = NULL; 967 968 return slap_idassert_passthru_parse( &c, si ); 969 } 970 971 static int 972 ldap_back_cf_gen( ConfigArgs *c ) 973 { 974 ldapinfo_t *li = ( ldapinfo_t * )c->be->be_private; 975 int rc = 0; 976 int i; 977 978 if ( c->op == SLAP_CONFIG_EMIT ) { 979 struct berval bv = BER_BVNULL; 980 981 if ( li == NULL ) { 982 return 1; 983 } 984 985 switch( c->type ) { 986 case LDAP_BACK_CFG_URI: 987 if ( li->li_uri != NULL ) { 988 struct berval bv, bv2; 989 990 ber_str2bv( li->li_uri, 0, 0, &bv ); 991 bv2.bv_len = bv.bv_len + STRLENOF( "\"\"" ); 992 bv2.bv_val = ch_malloc( bv2.bv_len + 1 ); 993 snprintf( bv2.bv_val, bv2.bv_len + 1, 994 "\"%s\"", bv.bv_val ); 995 ber_bvarray_add( &c->rvalue_vals, &bv2 ); 996 997 } else { 998 rc = 1; 999 } 1000 break; 1001 1002 case LDAP_BACK_CFG_TLS: { 1003 struct berval bc = BER_BVNULL, bv2; 1004 enum_to_verb( tls_mode, ( li->li_flags & LDAP_BACK_F_TLS_MASK ), &bv ); 1005 assert( !BER_BVISNULL( &bv ) ); 1006 bindconf_tls_unparse( &li->li_tls, &bc ); 1007 1008 if ( !BER_BVISEMPTY( &bc )) { 1009 bv2.bv_len = bv.bv_len + bc.bv_len + 1; 1010 bv2.bv_val = ch_malloc( bv2.bv_len + 1 ); 1011 strcpy( bv2.bv_val, bv.bv_val ); 1012 bv2.bv_val[bv.bv_len] = ' '; 1013 strcpy( &bv2.bv_val[bv.bv_len + 1], bc.bv_val ); 1014 ber_bvarray_add( &c->rvalue_vals, &bv2 ); 1015 1016 } else { 1017 value_add_one( &c->rvalue_vals, &bv ); 1018 } 1019 ber_memfree( bc.bv_val ); 1020 } 1021 break; 1022 1023 case LDAP_BACK_CFG_ACL_AUTHCDN: 1024 case LDAP_BACK_CFG_ACL_PASSWD: 1025 case LDAP_BACK_CFG_ACL_METHOD: 1026 /* handled by LDAP_BACK_CFG_ACL_BIND */ 1027 rc = 1; 1028 break; 1029 1030 case LDAP_BACK_CFG_ACL_BIND: { 1031 int i; 1032 1033 if ( li->li_acl_authmethod == LDAP_AUTH_NONE ) { 1034 return 1; 1035 } 1036 1037 bindconf_unparse( &li->li_acl, &bv ); 1038 1039 for ( i = 0; isspace( (unsigned char) bv.bv_val[ i ] ); i++ ) 1040 /* count spaces */ ; 1041 1042 if ( i ) { 1043 bv.bv_len -= i; 1044 AC_MEMCPY( bv.bv_val, &bv.bv_val[ i ], 1045 bv.bv_len + 1 ); 1046 } 1047 1048 ber_bvarray_add( &c->rvalue_vals, &bv ); 1049 break; 1050 } 1051 1052 case LDAP_BACK_CFG_IDASSERT_MODE: 1053 case LDAP_BACK_CFG_IDASSERT_AUTHCDN: 1054 case LDAP_BACK_CFG_IDASSERT_PASSWD: 1055 case LDAP_BACK_CFG_IDASSERT_METHOD: 1056 /* handled by LDAP_BACK_CFG_IDASSERT_BIND */ 1057 rc = 1; 1058 break; 1059 1060 case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: 1061 case LDAP_BACK_CFG_IDASSERT_PASSTHRU: { 1062 BerVarray *bvp; 1063 int i; 1064 struct berval bv = BER_BVNULL; 1065 char buf[SLAP_TEXT_BUFLEN]; 1066 1067 switch ( c->type ) { 1068 case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: bvp = &li->li_idassert_authz; break; 1069 case LDAP_BACK_CFG_IDASSERT_PASSTHRU: bvp = &li->li_idassert_passthru; break; 1070 default: assert( 0 ); break; 1071 } 1072 1073 if ( *bvp == NULL ) { 1074 if ( bvp == &li->li_idassert_authz 1075 && ( li->li_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) 1076 { 1077 BER_BVSTR( &bv, "*" ); 1078 value_add_one( &c->rvalue_vals, &bv ); 1079 1080 } else { 1081 rc = 1; 1082 } 1083 break; 1084 } 1085 1086 for ( i = 0; !BER_BVISNULL( &((*bvp)[ i ]) ); i++ ) { 1087 char *ptr; 1088 int len = snprintf( buf, sizeof( buf ), SLAP_X_ORDERED_FMT, i ); 1089 bv.bv_len = ((*bvp)[ i ]).bv_len + len; 1090 bv.bv_val = ber_memrealloc( bv.bv_val, bv.bv_len + 1 ); 1091 ptr = bv.bv_val; 1092 ptr = lutil_strcopy( ptr, buf ); 1093 ptr = lutil_strncopy( ptr, ((*bvp)[ i ]).bv_val, ((*bvp)[ i ]).bv_len ); 1094 value_add_one( &c->rvalue_vals, &bv ); 1095 } 1096 if ( bv.bv_val ) { 1097 ber_memfree( bv.bv_val ); 1098 } 1099 break; 1100 } 1101 1102 case LDAP_BACK_CFG_IDASSERT_BIND: { 1103 int i; 1104 struct berval bc = BER_BVNULL; 1105 char *ptr; 1106 1107 if ( li->li_idassert_authmethod == LDAP_AUTH_NONE ) { 1108 return 1; 1109 } 1110 1111 if ( li->li_idassert_authmethod != LDAP_AUTH_NONE ) { 1112 ber_len_t len; 1113 1114 switch ( li->li_idassert_mode ) { 1115 case LDAP_BACK_IDASSERT_OTHERID: 1116 case LDAP_BACK_IDASSERT_OTHERDN: 1117 break; 1118 1119 default: { 1120 struct berval mode = BER_BVNULL; 1121 1122 enum_to_verb( idassert_mode, li->li_idassert_mode, &mode ); 1123 if ( BER_BVISNULL( &mode ) ) { 1124 /* there's something wrong... */ 1125 assert( 0 ); 1126 rc = 1; 1127 1128 } else { 1129 bv.bv_len = STRLENOF( "mode=" ) + mode.bv_len; 1130 bv.bv_val = ch_malloc( bv.bv_len + 1 ); 1131 1132 ptr = lutil_strcopy( bv.bv_val, "mode=" ); 1133 ptr = lutil_strcopy( ptr, mode.bv_val ); 1134 } 1135 break; 1136 } 1137 } 1138 1139 if ( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) { 1140 len = bv.bv_len + STRLENOF( "authz=native" ); 1141 1142 if ( !BER_BVISEMPTY( &bv ) ) { 1143 len += STRLENOF( " " ); 1144 } 1145 1146 bv.bv_val = ch_realloc( bv.bv_val, len + 1 ); 1147 1148 ptr = &bv.bv_val[ bv.bv_len ]; 1149 1150 if ( !BER_BVISEMPTY( &bv ) ) { 1151 ptr = lutil_strcopy( ptr, " " ); 1152 } 1153 1154 (void)lutil_strcopy( ptr, "authz=native" ); 1155 } 1156 1157 len = bv.bv_len + STRLENOF( "flags=non-prescriptive,override,obsolete-encoding-workaround,proxy-authz-non-critical" ); 1158 /* flags */ 1159 if ( !BER_BVISEMPTY( &bv ) ) { 1160 len += STRLENOF( " " ); 1161 } 1162 1163 bv.bv_val = ch_realloc( bv.bv_val, len + 1 ); 1164 1165 ptr = &bv.bv_val[ bv.bv_len ]; 1166 1167 if ( !BER_BVISEMPTY( &bv ) ) { 1168 ptr = lutil_strcopy( ptr, " " ); 1169 } 1170 1171 ptr = lutil_strcopy( ptr, "flags=" ); 1172 1173 if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { 1174 ptr = lutil_strcopy( ptr, "prescriptive" ); 1175 } else { 1176 ptr = lutil_strcopy( ptr, "non-prescriptive" ); 1177 } 1178 1179 if ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) { 1180 ptr = lutil_strcopy( ptr, ",override" ); 1181 } 1182 1183 if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) { 1184 ptr = lutil_strcopy( ptr, ",obsolete-proxy-authz" ); 1185 1186 } else if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) { 1187 ptr = lutil_strcopy( ptr, ",obsolete-encoding-workaround" ); 1188 } 1189 1190 if ( li->li_idassert_flags & LDAP_BACK_AUTH_PROXYAUTHZ_CRITICAL ) { 1191 ptr = lutil_strcopy( ptr, ",proxy-authz-critical" ); 1192 1193 } else { 1194 ptr = lutil_strcopy( ptr, ",proxy-authz-non-critical" ); 1195 } 1196 1197 bv.bv_len = ( ptr - bv.bv_val ); 1198 /* end-of-flags */ 1199 } 1200 1201 bindconf_unparse( &li->li_idassert.si_bc, &bc ); 1202 1203 if ( !BER_BVISNULL( &bv ) ) { 1204 ber_len_t len = bv.bv_len + bc.bv_len; 1205 1206 bv.bv_val = ch_realloc( bv.bv_val, len + 1 ); 1207 1208 assert( bc.bv_val[ 0 ] == ' ' ); 1209 1210 ptr = lutil_strcopy( &bv.bv_val[ bv.bv_len ], bc.bv_val ); 1211 free( bc.bv_val ); 1212 bv.bv_len = ptr - bv.bv_val; 1213 1214 } else { 1215 for ( i = 0; isspace( (unsigned char) bc.bv_val[ i ] ); i++ ) 1216 /* count spaces */ ; 1217 1218 if ( i ) { 1219 bc.bv_len -= i; 1220 AC_MEMCPY( bc.bv_val, &bc.bv_val[ i ], bc.bv_len + 1 ); 1221 } 1222 1223 bv = bc; 1224 } 1225 1226 ber_bvarray_add( &c->rvalue_vals, &bv ); 1227 1228 break; 1229 } 1230 1231 case LDAP_BACK_CFG_REBIND: 1232 c->value_int = LDAP_BACK_SAVECRED( li ); 1233 break; 1234 1235 case LDAP_BACK_CFG_CHASE: 1236 c->value_int = LDAP_BACK_CHASE_REFERRALS( li ); 1237 break; 1238 1239 case LDAP_BACK_CFG_T_F: 1240 enum_to_verb( t_f_mode, (li->li_flags & LDAP_BACK_F_T_F_MASK2), &bv ); 1241 if ( BER_BVISNULL( &bv ) ) { 1242 /* there's something wrong... */ 1243 assert( 0 ); 1244 rc = 1; 1245 1246 } else { 1247 value_add_one( &c->rvalue_vals, &bv ); 1248 } 1249 break; 1250 1251 case LDAP_BACK_CFG_WHOAMI: 1252 c->value_int = LDAP_BACK_PROXY_WHOAMI( li ); 1253 break; 1254 1255 case LDAP_BACK_CFG_TIMEOUT: 1256 BER_BVZERO( &bv ); 1257 1258 for ( i = 0; i < SLAP_OP_LAST; i++ ) { 1259 if ( li->li_timeout[ i ] != 0 ) { 1260 break; 1261 } 1262 } 1263 1264 if ( i == SLAP_OP_LAST ) { 1265 return 1; 1266 } 1267 1268 slap_cf_aux_table_unparse( li->li_timeout, &bv, timeout_table ); 1269 1270 if ( BER_BVISNULL( &bv ) ) { 1271 return 1; 1272 } 1273 1274 for ( i = 0; isspace( (unsigned char) bv.bv_val[ i ] ); i++ ) 1275 /* count spaces */ ; 1276 1277 if ( i ) { 1278 bv.bv_len -= i; 1279 AC_MEMCPY( bv.bv_val, &bv.bv_val[ i ], 1280 bv.bv_len + 1 ); 1281 } 1282 1283 ber_bvarray_add( &c->rvalue_vals, &bv ); 1284 break; 1285 1286 case LDAP_BACK_CFG_IDLE_TIMEOUT: { 1287 char buf[ SLAP_TEXT_BUFLEN ]; 1288 1289 if ( li->li_idle_timeout == 0 ) { 1290 return 1; 1291 } 1292 1293 lutil_unparse_time( buf, sizeof( buf ), li->li_idle_timeout ); 1294 ber_str2bv( buf, 0, 0, &bv ); 1295 value_add_one( &c->rvalue_vals, &bv ); 1296 } break; 1297 1298 case LDAP_BACK_CFG_CONN_TTL: { 1299 char buf[ SLAP_TEXT_BUFLEN ]; 1300 1301 if ( li->li_conn_ttl == 0 ) { 1302 return 1; 1303 } 1304 1305 lutil_unparse_time( buf, sizeof( buf ), li->li_conn_ttl ); 1306 ber_str2bv( buf, 0, 0, &bv ); 1307 value_add_one( &c->rvalue_vals, &bv ); 1308 } break; 1309 1310 case LDAP_BACK_CFG_NETWORK_TIMEOUT: { 1311 char buf[ SLAP_TEXT_BUFLEN ]; 1312 1313 if ( li->li_network_timeout == 0 ) { 1314 return 1; 1315 } 1316 1317 snprintf( buf, sizeof( buf ), "%ld", 1318 (long)li->li_network_timeout ); 1319 ber_str2bv( buf, 0, 0, &bv ); 1320 value_add_one( &c->rvalue_vals, &bv ); 1321 } break; 1322 1323 case LDAP_BACK_CFG_VERSION: 1324 if ( li->li_version == 0 ) { 1325 return 1; 1326 } 1327 1328 c->value_int = li->li_version; 1329 break; 1330 1331 case LDAP_BACK_CFG_SINGLECONN: 1332 c->value_int = LDAP_BACK_SINGLECONN( li ); 1333 break; 1334 1335 case LDAP_BACK_CFG_USETEMP: 1336 c->value_int = LDAP_BACK_USE_TEMPORARIES( li ); 1337 break; 1338 1339 case LDAP_BACK_CFG_CONNPOOLMAX: 1340 c->value_int = li->li_conn_priv_max; 1341 break; 1342 1343 case LDAP_BACK_CFG_CANCEL: { 1344 slap_mask_t mask = LDAP_BACK_F_CANCEL_MASK2; 1345 1346 if ( LDAP_BACK_CANCEL_DISCOVER( li ) ) { 1347 mask &= ~LDAP_BACK_F_CANCEL_EXOP; 1348 } 1349 enum_to_verb( cancel_mode, (li->li_flags & mask), &bv ); 1350 if ( BER_BVISNULL( &bv ) ) { 1351 /* there's something wrong... */ 1352 assert( 0 ); 1353 rc = 1; 1354 1355 } else { 1356 value_add_one( &c->rvalue_vals, &bv ); 1357 } 1358 } break; 1359 1360 case LDAP_BACK_CFG_QUARANTINE: 1361 if ( !LDAP_BACK_QUARANTINE( li ) ) { 1362 rc = 1; 1363 break; 1364 } 1365 1366 rc = slap_retry_info_unparse( &li->li_quarantine, &bv ); 1367 if ( rc == 0 ) { 1368 ber_bvarray_add( &c->rvalue_vals, &bv ); 1369 } 1370 break; 1371 1372 #ifdef SLAP_CONTROL_X_SESSION_TRACKING 1373 case LDAP_BACK_CFG_ST_REQUEST: 1374 c->value_int = LDAP_BACK_ST_REQUEST( li ); 1375 break; 1376 #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ 1377 1378 case LDAP_BACK_CFG_NOREFS: 1379 c->value_int = LDAP_BACK_NOREFS( li ); 1380 break; 1381 1382 case LDAP_BACK_CFG_NOUNDEFFILTER: 1383 c->value_int = LDAP_BACK_NOUNDEFFILTER( li ); 1384 break; 1385 1386 case LDAP_BACK_CFG_OMIT_UNKNOWN_SCHEMA: 1387 c->value_int = LDAP_BACK_OMIT_UNKNOWN_SCHEMA( li ); 1388 break; 1389 1390 case LDAP_BACK_CFG_ONERR: 1391 enum_to_verb( onerr_mode, li->li_flags & LDAP_BACK_F_ONERR_STOP, &bv ); 1392 if ( BER_BVISNULL( &bv )) { 1393 rc = 1; 1394 } else { 1395 value_add_one( &c->rvalue_vals, &bv ); 1396 } 1397 break; 1398 1399 case LDAP_BACK_CFG_KEEPALIVE: { 1400 struct berval bv; 1401 char buf[AC_LINE_MAX]; 1402 bv.bv_len = AC_LINE_MAX; 1403 bv.bv_val = &buf[0]; 1404 slap_keepalive_parse(&bv, &li->li_tls.sb_keepalive, 0, 0, 1); 1405 value_add_one( &c->rvalue_vals, &bv ); 1406 break; 1407 } 1408 1409 default: 1410 /* FIXME: we need to handle all... */ 1411 assert( 0 ); 1412 break; 1413 } 1414 return rc; 1415 1416 } else if ( c->op == LDAP_MOD_DELETE ) { 1417 switch( c->type ) { 1418 case LDAP_BACK_CFG_URI: 1419 if ( li->li_uri != NULL ) { 1420 ch_free( li->li_uri ); 1421 li->li_uri = NULL; 1422 1423 assert( li->li_bvuri != NULL ); 1424 ber_bvarray_free( li->li_bvuri ); 1425 li->li_bvuri = NULL; 1426 } 1427 1428 /* better cleanup the cached connections... */ 1429 /* NOTE: don't worry about locking: if we got here, 1430 * other threads are suspended. */ 1431 if ( li->li_conninfo.lai_tree != NULL ) { 1432 avl_free( li->li_conninfo.lai_tree, ldap_back_conn_free ); 1433 li->li_conninfo.lai_tree = NULL; 1434 } 1435 1436 break; 1437 1438 case LDAP_BACK_CFG_TLS: 1439 rc = 1; 1440 break; 1441 1442 case LDAP_BACK_CFG_ACL_AUTHCDN: 1443 case LDAP_BACK_CFG_ACL_PASSWD: 1444 case LDAP_BACK_CFG_ACL_METHOD: 1445 /* handled by LDAP_BACK_CFG_ACL_BIND */ 1446 rc = 1; 1447 break; 1448 1449 case LDAP_BACK_CFG_ACL_BIND: 1450 bindconf_free( &li->li_acl ); 1451 break; 1452 1453 case LDAP_BACK_CFG_IDASSERT_MODE: 1454 case LDAP_BACK_CFG_IDASSERT_AUTHCDN: 1455 case LDAP_BACK_CFG_IDASSERT_PASSWD: 1456 case LDAP_BACK_CFG_IDASSERT_METHOD: 1457 /* handled by LDAP_BACK_CFG_IDASSERT_BIND */ 1458 rc = 1; 1459 break; 1460 1461 case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: 1462 case LDAP_BACK_CFG_IDASSERT_PASSTHRU: { 1463 BerVarray *bvp; 1464 1465 switch ( c->type ) { 1466 case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: bvp = &li->li_idassert_authz; break; 1467 case LDAP_BACK_CFG_IDASSERT_PASSTHRU: bvp = &li->li_idassert_passthru; break; 1468 default: assert( 0 ); break; 1469 } 1470 1471 if ( c->valx < 0 ) { 1472 if ( *bvp != NULL ) { 1473 ber_bvarray_free( *bvp ); 1474 *bvp = NULL; 1475 } 1476 1477 } else { 1478 int i; 1479 1480 if ( *bvp == NULL ) { 1481 rc = 1; 1482 break; 1483 } 1484 1485 for ( i = 0; !BER_BVISNULL( &((*bvp)[ i ]) ); i++ ) 1486 ; 1487 1488 if ( i >= c->valx ) { 1489 rc = 1; 1490 break; 1491 } 1492 ber_memfree( ((*bvp)[ c->valx ]).bv_val ); 1493 for ( i = c->valx; !BER_BVISNULL( &((*bvp)[ i + 1 ]) ); i++ ) { 1494 (*bvp)[ i ] = (*bvp)[ i + 1 ]; 1495 } 1496 BER_BVZERO( &((*bvp)[ i ]) ); 1497 } 1498 } break; 1499 1500 case LDAP_BACK_CFG_IDASSERT_BIND: 1501 bindconf_free( &li->li_idassert.si_bc ); 1502 memset( &li->li_idassert, 0, sizeof( slap_idassert_t ) ); 1503 break; 1504 1505 case LDAP_BACK_CFG_REBIND: 1506 case LDAP_BACK_CFG_CHASE: 1507 case LDAP_BACK_CFG_T_F: 1508 case LDAP_BACK_CFG_WHOAMI: 1509 case LDAP_BACK_CFG_CANCEL: 1510 rc = 1; 1511 break; 1512 1513 case LDAP_BACK_CFG_TIMEOUT: 1514 for ( i = 0; i < SLAP_OP_LAST; i++ ) { 1515 li->li_timeout[ i ] = 0; 1516 } 1517 break; 1518 1519 case LDAP_BACK_CFG_IDLE_TIMEOUT: 1520 li->li_idle_timeout = 0; 1521 break; 1522 1523 case LDAP_BACK_CFG_CONN_TTL: 1524 li->li_conn_ttl = 0; 1525 break; 1526 1527 case LDAP_BACK_CFG_NETWORK_TIMEOUT: 1528 li->li_network_timeout = 0; 1529 break; 1530 1531 case LDAP_BACK_CFG_VERSION: 1532 li->li_version = 0; 1533 break; 1534 1535 case LDAP_BACK_CFG_SINGLECONN: 1536 li->li_flags &= ~LDAP_BACK_F_SINGLECONN; 1537 break; 1538 1539 case LDAP_BACK_CFG_USETEMP: 1540 li->li_flags &= ~LDAP_BACK_F_USE_TEMPORARIES; 1541 break; 1542 1543 case LDAP_BACK_CFG_CONNPOOLMAX: 1544 li->li_conn_priv_max = LDAP_BACK_CONN_PRIV_MIN; 1545 break; 1546 1547 case LDAP_BACK_CFG_QUARANTINE: 1548 if ( !LDAP_BACK_QUARANTINE( li ) ) { 1549 break; 1550 } 1551 1552 slap_retry_info_destroy( &li->li_quarantine ); 1553 ldap_pvt_thread_mutex_destroy( &li->li_quarantine_mutex ); 1554 li->li_isquarantined = 0; 1555 li->li_flags &= ~LDAP_BACK_F_QUARANTINE; 1556 break; 1557 1558 #ifdef SLAP_CONTROL_X_SESSION_TRACKING 1559 case LDAP_BACK_CFG_ST_REQUEST: 1560 li->li_flags &= ~LDAP_BACK_F_ST_REQUEST; 1561 break; 1562 #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ 1563 1564 case LDAP_BACK_CFG_NOREFS: 1565 li->li_flags &= ~LDAP_BACK_F_NOREFS; 1566 break; 1567 1568 case LDAP_BACK_CFG_NOUNDEFFILTER: 1569 li->li_flags &= ~LDAP_BACK_F_NOUNDEFFILTER; 1570 break; 1571 1572 case LDAP_BACK_CFG_OMIT_UNKNOWN_SCHEMA: 1573 li->li_flags &= ~LDAP_BACK_F_OMIT_UNKNOWN_SCHEMA; 1574 break; 1575 1576 case LDAP_BACK_CFG_ONERR: 1577 li->li_flags &= ~LDAP_BACK_F_ONERR_STOP; 1578 break; 1579 1580 case LDAP_BACK_CFG_KEEPALIVE: 1581 li->li_tls.sb_keepalive.sk_idle = 0; 1582 li->li_tls.sb_keepalive.sk_probes = 0; 1583 li->li_tls.sb_keepalive.sk_interval = 0; 1584 break; 1585 1586 default: 1587 /* FIXME: we need to handle all... */ 1588 assert( 0 ); 1589 break; 1590 } 1591 return rc; 1592 1593 } 1594 1595 switch( c->type ) { 1596 case LDAP_BACK_CFG_URI: { 1597 LDAPURLDesc *tmpludp, *lud; 1598 char **urllist = NULL; 1599 int urlrc = LDAP_URL_SUCCESS, i; 1600 1601 if ( li->li_uri != NULL ) { 1602 ch_free( li->li_uri ); 1603 li->li_uri = NULL; 1604 1605 assert( li->li_bvuri != NULL ); 1606 ber_bvarray_free( li->li_bvuri ); 1607 li->li_bvuri = NULL; 1608 } 1609 1610 /* PARANOID: DN and more are not required nor allowed */ 1611 urlrc = ldap_url_parselist_ext( &lud, c->argv[ 1 ], ", \t", LDAP_PVT_URL_PARSE_NONE ); 1612 if ( urlrc != LDAP_URL_SUCCESS ) { 1613 char *why; 1614 1615 switch ( urlrc ) { 1616 case LDAP_URL_ERR_MEM: 1617 why = "no memory"; 1618 break; 1619 case LDAP_URL_ERR_PARAM: 1620 why = "parameter is bad"; 1621 break; 1622 case LDAP_URL_ERR_BADSCHEME: 1623 why = "URL doesn't begin with \"[c]ldap[si]://\""; 1624 break; 1625 case LDAP_URL_ERR_BADENCLOSURE: 1626 why = "URL is missing trailing \">\""; 1627 break; 1628 case LDAP_URL_ERR_BADURL: 1629 why = "URL is bad"; 1630 break; 1631 case LDAP_URL_ERR_BADHOST: 1632 why = "host/port is bad"; 1633 break; 1634 case LDAP_URL_ERR_BADATTRS: 1635 why = "bad (or missing) attributes"; 1636 break; 1637 case LDAP_URL_ERR_BADSCOPE: 1638 why = "scope string is invalid (or missing)"; 1639 break; 1640 case LDAP_URL_ERR_BADFILTER: 1641 why = "bad or missing filter"; 1642 break; 1643 case LDAP_URL_ERR_BADEXTS: 1644 why = "bad or missing extensions"; 1645 break; 1646 default: 1647 why = "unknown reason"; 1648 break; 1649 } 1650 snprintf( c->cr_msg, sizeof( c->cr_msg), 1651 "unable to parse uri \"%s\" " 1652 "in \"uri <uri>\" line: %s", 1653 c->value_string, why ); 1654 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 1655 urlrc = 1; 1656 goto done_url; 1657 } 1658 1659 for ( i = 0, tmpludp = lud; 1660 tmpludp; 1661 i++, tmpludp = tmpludp->lud_next ) 1662 { 1663 if ( ( tmpludp->lud_dn != NULL 1664 && tmpludp->lud_dn[0] != '\0' ) 1665 || tmpludp->lud_attrs != NULL 1666 /* || tmpludp->lud_scope != LDAP_SCOPE_DEFAULT */ 1667 || tmpludp->lud_filter != NULL 1668 || tmpludp->lud_exts != NULL ) 1669 { 1670 snprintf( c->cr_msg, sizeof( c->cr_msg ), 1671 "warning, only protocol, " 1672 "host and port allowed " 1673 "in \"uri <uri>\" statement " 1674 "for uri #%d of \"%s\"", 1675 i, c->argv[ 1 ] ); 1676 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 1677 } 1678 } 1679 1680 for ( i = 0, tmpludp = lud; 1681 tmpludp; 1682 i++, tmpludp = tmpludp->lud_next ) 1683 /* just count */ 1684 ; 1685 urllist = ch_calloc( sizeof( char * ), i + 1 ); 1686 1687 for ( i = 0, tmpludp = lud; 1688 tmpludp; 1689 i++, tmpludp = tmpludp->lud_next ) 1690 { 1691 LDAPURLDesc tmplud; 1692 1693 tmplud = *tmpludp; 1694 tmplud.lud_dn = ""; 1695 tmplud.lud_attrs = NULL; 1696 tmplud.lud_filter = NULL; 1697 if ( !ldap_is_ldapi_url( tmplud.lud_scheme ) ) { 1698 tmplud.lud_exts = NULL; 1699 tmplud.lud_crit_exts = 0; 1700 } 1701 1702 urllist[ i ] = ldap_url_desc2str( &tmplud ); 1703 1704 if ( urllist[ i ] == NULL ) { 1705 snprintf( c->cr_msg, sizeof( c->cr_msg), 1706 "unable to rebuild uri " 1707 "in \"uri <uri>\" statement " 1708 "for \"%s\"", 1709 c->argv[ 1 ] ); 1710 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 1711 urlrc = 1; 1712 goto done_url; 1713 } 1714 } 1715 1716 li->li_uri = ldap_charray2str( urllist, " " ); 1717 for ( i = 0; urllist[ i ] != NULL; i++ ) { 1718 struct berval bv; 1719 1720 ber_str2bv( urllist[ i ], 0, 0, &bv ); 1721 ber_bvarray_add( &li->li_bvuri, &bv ); 1722 urllist[ i ] = NULL; 1723 } 1724 ldap_memfree( urllist ); 1725 urllist = NULL; 1726 1727 done_url:; 1728 if ( urllist ) { 1729 ldap_charray_free( urllist ); 1730 } 1731 if ( lud ) { 1732 ldap_free_urllist( lud ); 1733 } 1734 if ( urlrc != LDAP_URL_SUCCESS ) { 1735 return 1; 1736 } 1737 break; 1738 } 1739 1740 case LDAP_BACK_CFG_TLS: 1741 i = verb_to_mask( c->argv[1], tls_mode ); 1742 if ( BER_BVISNULL( &tls_mode[i].word ) ) { 1743 return 1; 1744 } 1745 li->li_flags &= ~LDAP_BACK_F_TLS_MASK; 1746 li->li_flags |= tls_mode[i].mask; 1747 if ( c->argc > 2 ) { 1748 for ( i=2; i<c->argc; i++ ) { 1749 if ( bindconf_tls_parse( c->argv[i], &li->li_tls )) 1750 return 1; 1751 } 1752 bindconf_tls_defaults( &li->li_tls ); 1753 } 1754 break; 1755 1756 case LDAP_BACK_CFG_ACL_AUTHCDN: 1757 switch ( li->li_acl_authmethod ) { 1758 case LDAP_AUTH_NONE: 1759 li->li_acl_authmethod = LDAP_AUTH_SIMPLE; 1760 break; 1761 1762 case LDAP_AUTH_SIMPLE: 1763 break; 1764 1765 default: 1766 snprintf( c->cr_msg, sizeof( c->cr_msg), 1767 "\"acl-authcDN <DN>\" incompatible " 1768 "with auth method %d", 1769 li->li_acl_authmethod ); 1770 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 1771 return 1; 1772 } 1773 if ( !BER_BVISNULL( &li->li_acl_authcDN ) ) { 1774 free( li->li_acl_authcDN.bv_val ); 1775 } 1776 ber_memfree_x( c->value_dn.bv_val, NULL ); 1777 li->li_acl_authcDN = c->value_ndn; 1778 BER_BVZERO( &c->value_dn ); 1779 BER_BVZERO( &c->value_ndn ); 1780 break; 1781 1782 case LDAP_BACK_CFG_ACL_PASSWD: 1783 switch ( li->li_acl_authmethod ) { 1784 case LDAP_AUTH_NONE: 1785 li->li_acl_authmethod = LDAP_AUTH_SIMPLE; 1786 break; 1787 1788 case LDAP_AUTH_SIMPLE: 1789 break; 1790 1791 default: 1792 snprintf( c->cr_msg, sizeof( c->cr_msg ), 1793 "\"acl-passwd <cred>\" incompatible " 1794 "with auth method %d", 1795 li->li_acl_authmethod ); 1796 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 1797 return 1; 1798 } 1799 if ( !BER_BVISNULL( &li->li_acl_passwd ) ) { 1800 free( li->li_acl_passwd.bv_val ); 1801 } 1802 ber_str2bv( c->argv[ 1 ], 0, 1, &li->li_acl_passwd ); 1803 break; 1804 1805 case LDAP_BACK_CFG_ACL_METHOD: 1806 case LDAP_BACK_CFG_ACL_BIND: 1807 for ( i = 1; i < c->argc; i++ ) { 1808 if ( bindconf_parse( c->argv[ i ], &li->li_acl ) ) { 1809 return 1; 1810 } 1811 } 1812 bindconf_tls_defaults( &li->li_acl ); 1813 break; 1814 1815 case LDAP_BACK_CFG_IDASSERT_MODE: 1816 i = verb_to_mask( c->argv[1], idassert_mode ); 1817 if ( BER_BVISNULL( &idassert_mode[i].word ) ) { 1818 if ( strncasecmp( c->argv[1], "u:", STRLENOF( "u:" ) ) == 0 ) { 1819 li->li_idassert_mode = LDAP_BACK_IDASSERT_OTHERID; 1820 ber_str2bv( c->argv[1], 0, 1, &li->li_idassert_authzID ); 1821 li->li_idassert_authzID.bv_val[ 0 ] = 'u'; 1822 1823 } else { 1824 struct berval id, ndn; 1825 1826 ber_str2bv( c->argv[1], 0, 0, &id ); 1827 1828 if ( strncasecmp( c->argv[1], "dn:", STRLENOF( "dn:" ) ) == 0 ) { 1829 id.bv_val += STRLENOF( "dn:" ); 1830 id.bv_len -= STRLENOF( "dn:" ); 1831 } 1832 1833 rc = dnNormalize( 0, NULL, NULL, &id, &ndn, NULL ); 1834 if ( rc != LDAP_SUCCESS ) { 1835 Debug( LDAP_DEBUG_ANY, 1836 "%s: line %d: idassert ID \"%s\" is not a valid DN\n", 1837 c->fname, c->lineno, c->argv[1] ); 1838 return 1; 1839 } 1840 1841 li->li_idassert_authzID.bv_len = STRLENOF( "dn:" ) + ndn.bv_len; 1842 li->li_idassert_authzID.bv_val = ch_malloc( li->li_idassert_authzID.bv_len + 1 ); 1843 AC_MEMCPY( li->li_idassert_authzID.bv_val, "dn:", STRLENOF( "dn:" ) ); 1844 AC_MEMCPY( &li->li_idassert_authzID.bv_val[ STRLENOF( "dn:" ) ], ndn.bv_val, ndn.bv_len + 1 ); 1845 ch_free( ndn.bv_val ); 1846 1847 li->li_idassert_mode = LDAP_BACK_IDASSERT_OTHERDN; 1848 } 1849 1850 } else { 1851 li->li_idassert_mode = idassert_mode[i].mask; 1852 } 1853 1854 if ( c->argc > 2 ) { 1855 int i; 1856 1857 for ( i = 2; i < c->argc; i++ ) { 1858 if ( strcasecmp( c->argv[ i ], "override" ) == 0 ) { 1859 li->li_idassert_flags |= LDAP_BACK_AUTH_OVERRIDE; 1860 1861 } else if ( strcasecmp( c->argv[ i ], "prescriptive" ) == 0 ) { 1862 li->li_idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE; 1863 1864 } else if ( strcasecmp( c->argv[ i ], "non-prescriptive" ) == 0 ) { 1865 li->li_idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE ); 1866 1867 } else if ( strcasecmp( c->argv[ i ], "obsolete-proxy-authz" ) == 0 ) { 1868 if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) { 1869 Debug( LDAP_DEBUG_ANY, 1870 "%s: line %d: \"obsolete-proxy-authz\" flag " 1871 "in \"idassert-mode <args>\" " 1872 "incompatible with previously issued \"obsolete-encoding-workaround\" flag.\n", 1873 c->fname, c->lineno, 0 ); 1874 return 1; 1875 } 1876 li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ; 1877 1878 } else if ( strcasecmp( c->argv[ i ], "obsolete-encoding-workaround" ) == 0 ) { 1879 if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) { 1880 Debug( LDAP_DEBUG_ANY, 1881 "%s: line %d: \"obsolete-encoding-workaround\" flag " 1882 "in \"idassert-mode <args>\" " 1883 "incompatible with previously issued \"obsolete-proxy-authz\" flag.\n", 1884 c->fname, c->lineno, 0 ); 1885 return 1; 1886 } 1887 li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND; 1888 1889 } else { 1890 Debug( LDAP_DEBUG_ANY, 1891 "%s: line %d: unknown flag #%d " 1892 "in \"idassert-mode <args> " 1893 "[<flags>]\" line.\n", 1894 c->fname, c->lineno, i - 2 ); 1895 return 1; 1896 } 1897 } 1898 } 1899 break; 1900 1901 case LDAP_BACK_CFG_IDASSERT_AUTHCDN: 1902 switch ( li->li_idassert_authmethod ) { 1903 case LDAP_AUTH_NONE: 1904 li->li_idassert_authmethod = LDAP_AUTH_SIMPLE; 1905 break; 1906 1907 case LDAP_AUTH_SIMPLE: 1908 break; 1909 1910 default: 1911 snprintf( c->cr_msg, sizeof( c->cr_msg ), 1912 "\"idassert-authcDN <DN>\" incompatible " 1913 "with auth method %d", 1914 li->li_idassert_authmethod ); 1915 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 1916 return 1; 1917 } 1918 if ( !BER_BVISNULL( &li->li_idassert_authcDN ) ) { 1919 free( li->li_idassert_authcDN.bv_val ); 1920 } 1921 ber_memfree_x( c->value_dn.bv_val, NULL ); 1922 li->li_idassert_authcDN = c->value_ndn; 1923 BER_BVZERO( &c->value_dn ); 1924 BER_BVZERO( &c->value_ndn ); 1925 break; 1926 1927 case LDAP_BACK_CFG_IDASSERT_PASSWD: 1928 switch ( li->li_idassert_authmethod ) { 1929 case LDAP_AUTH_NONE: 1930 li->li_idassert_authmethod = LDAP_AUTH_SIMPLE; 1931 break; 1932 1933 case LDAP_AUTH_SIMPLE: 1934 break; 1935 1936 default: 1937 snprintf( c->cr_msg, sizeof( c->cr_msg ), 1938 "\"idassert-passwd <cred>\" incompatible " 1939 "with auth method %d", 1940 li->li_idassert_authmethod ); 1941 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 1942 return 1; 1943 } 1944 if ( !BER_BVISNULL( &li->li_idassert_passwd ) ) { 1945 free( li->li_idassert_passwd.bv_val ); 1946 } 1947 ber_str2bv( c->argv[ 1 ], 0, 1, &li->li_idassert_passwd ); 1948 break; 1949 1950 case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: 1951 rc = slap_idassert_authzfrom_parse( c, &li->li_idassert ); 1952 break; 1953 1954 case LDAP_BACK_CFG_IDASSERT_PASSTHRU: 1955 rc = slap_idassert_passthru_parse( c, &li->li_idassert ); 1956 break; 1957 1958 case LDAP_BACK_CFG_IDASSERT_METHOD: 1959 /* no longer supported */ 1960 snprintf( c->cr_msg, sizeof( c->cr_msg ), 1961 "\"idassert-method <args>\": " 1962 "no longer supported; use \"idassert-bind\"" ); 1963 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 1964 return 1; 1965 1966 case LDAP_BACK_CFG_IDASSERT_BIND: 1967 rc = slap_idassert_parse( c, &li->li_idassert ); 1968 break; 1969 1970 case LDAP_BACK_CFG_REBIND: 1971 if ( c->argc == 1 || c->value_int ) { 1972 li->li_flags |= LDAP_BACK_F_SAVECRED; 1973 1974 } else { 1975 li->li_flags &= ~LDAP_BACK_F_SAVECRED; 1976 } 1977 break; 1978 1979 case LDAP_BACK_CFG_CHASE: 1980 if ( c->argc == 1 || c->value_int ) { 1981 li->li_flags |= LDAP_BACK_F_CHASE_REFERRALS; 1982 1983 } else { 1984 li->li_flags &= ~LDAP_BACK_F_CHASE_REFERRALS; 1985 } 1986 break; 1987 1988 case LDAP_BACK_CFG_T_F: { 1989 slap_mask_t mask; 1990 1991 i = verb_to_mask( c->argv[1], t_f_mode ); 1992 if ( BER_BVISNULL( &t_f_mode[i].word ) ) { 1993 return 1; 1994 } 1995 1996 mask = t_f_mode[i].mask; 1997 1998 if ( LDAP_BACK_ISOPEN( li ) 1999 && mask == LDAP_BACK_F_T_F_DISCOVER 2000 && !LDAP_BACK_T_F( li ) ) 2001 { 2002 slap_bindconf sb = { BER_BVNULL }; 2003 int rc; 2004 2005 if ( li->li_uri == NULL ) { 2006 snprintf( c->cr_msg, sizeof( c->cr_msg ), 2007 "need URI to discover absolute filters support " 2008 "in \"t-f-support discover\"" ); 2009 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 2010 return 1; 2011 } 2012 2013 ber_str2bv( li->li_uri, 0, 0, &sb.sb_uri ); 2014 sb.sb_version = li->li_version; 2015 sb.sb_method = LDAP_AUTH_SIMPLE; 2016 BER_BVSTR( &sb.sb_binddn, "" ); 2017 2018 rc = slap_discover_feature( &sb, 2019 slap_schema.si_ad_supportedFeatures->ad_cname.bv_val, 2020 LDAP_FEATURE_ABSOLUTE_FILTERS ); 2021 if ( rc == LDAP_COMPARE_TRUE ) { 2022 mask |= LDAP_BACK_F_T_F; 2023 } 2024 } 2025 2026 li->li_flags &= ~LDAP_BACK_F_T_F_MASK2; 2027 li->li_flags |= mask; 2028 } break; 2029 2030 case LDAP_BACK_CFG_WHOAMI: 2031 if ( c->argc == 1 || c->value_int ) { 2032 li->li_flags |= LDAP_BACK_F_PROXY_WHOAMI; 2033 load_extop( (struct berval *)&slap_EXOP_WHOAMI, 2034 0, ldap_back_exop_whoami ); 2035 2036 } else { 2037 li->li_flags &= ~LDAP_BACK_F_PROXY_WHOAMI; 2038 } 2039 break; 2040 2041 case LDAP_BACK_CFG_TIMEOUT: 2042 for ( i = 1; i < c->argc; i++ ) { 2043 if ( isdigit( (unsigned char) c->argv[ i ][ 0 ] ) ) { 2044 int j; 2045 unsigned u; 2046 2047 if ( lutil_atoux( &u, c->argv[ i ], 0 ) != 0 ) { 2048 snprintf( c->cr_msg, sizeof( c->cr_msg), 2049 "unable to parse timeout \"%s\"", 2050 c->argv[ i ] ); 2051 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 2052 return 1; 2053 } 2054 2055 for ( j = 0; j < SLAP_OP_LAST; j++ ) { 2056 li->li_timeout[ j ] = u; 2057 } 2058 2059 continue; 2060 } 2061 2062 if ( slap_cf_aux_table_parse( c->argv[ i ], li->li_timeout, timeout_table, "slapd-ldap timeout" ) ) { 2063 snprintf( c->cr_msg, sizeof( c->cr_msg), 2064 "unable to parse timeout \"%s\"", 2065 c->argv[ i ] ); 2066 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 2067 return 1; 2068 } 2069 } 2070 break; 2071 2072 case LDAP_BACK_CFG_IDLE_TIMEOUT: { 2073 unsigned long t; 2074 2075 if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) { 2076 snprintf( c->cr_msg, sizeof( c->cr_msg), 2077 "unable to parse idle timeout \"%s\"", 2078 c->argv[ 1 ] ); 2079 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 2080 return 1; 2081 } 2082 li->li_idle_timeout = (time_t)t; 2083 } break; 2084 2085 case LDAP_BACK_CFG_CONN_TTL: { 2086 unsigned long t; 2087 2088 if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) { 2089 snprintf( c->cr_msg, sizeof( c->cr_msg), 2090 "unable to parse conn ttl\"%s\"", 2091 c->argv[ 1 ] ); 2092 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 2093 return 1; 2094 } 2095 li->li_conn_ttl = (time_t)t; 2096 } break; 2097 2098 case LDAP_BACK_CFG_NETWORK_TIMEOUT: { 2099 unsigned long t; 2100 2101 if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) { 2102 snprintf( c->cr_msg, sizeof( c->cr_msg), 2103 "unable to parse network timeout \"%s\"", 2104 c->argv[ 1 ] ); 2105 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 2106 return 1; 2107 } 2108 li->li_network_timeout = (time_t)t; 2109 } break; 2110 2111 case LDAP_BACK_CFG_VERSION: 2112 if ( c->value_int != 0 && ( c->value_int < LDAP_VERSION_MIN || c->value_int > LDAP_VERSION_MAX ) ) { 2113 snprintf( c->cr_msg, sizeof( c->cr_msg ), 2114 "unsupported version \"%s\" " 2115 "in \"protocol-version <version>\"", 2116 c->argv[ 1 ] ); 2117 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 2118 return 1; 2119 } 2120 2121 li->li_version = c->value_int; 2122 break; 2123 2124 case LDAP_BACK_CFG_SINGLECONN: 2125 if ( c->value_int ) { 2126 li->li_flags |= LDAP_BACK_F_SINGLECONN; 2127 2128 } else { 2129 li->li_flags &= ~LDAP_BACK_F_SINGLECONN; 2130 } 2131 break; 2132 2133 case LDAP_BACK_CFG_USETEMP: 2134 if ( c->value_int ) { 2135 li->li_flags |= LDAP_BACK_F_USE_TEMPORARIES; 2136 2137 } else { 2138 li->li_flags &= ~LDAP_BACK_F_USE_TEMPORARIES; 2139 } 2140 break; 2141 2142 case LDAP_BACK_CFG_CONNPOOLMAX: 2143 if ( c->value_int < LDAP_BACK_CONN_PRIV_MIN 2144 || c->value_int > LDAP_BACK_CONN_PRIV_MAX ) 2145 { 2146 snprintf( c->cr_msg, sizeof( c->cr_msg ), 2147 "invalid max size " "of privileged " 2148 "connections pool \"%s\" " 2149 "in \"conn-pool-max <n> " 2150 "(must be between %d and %d)\"", 2151 c->argv[ 1 ], 2152 LDAP_BACK_CONN_PRIV_MIN, 2153 LDAP_BACK_CONN_PRIV_MAX ); 2154 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 2155 return 1; 2156 } 2157 li->li_conn_priv_max = c->value_int; 2158 break; 2159 2160 case LDAP_BACK_CFG_CANCEL: { 2161 slap_mask_t mask; 2162 2163 i = verb_to_mask( c->argv[1], cancel_mode ); 2164 if ( BER_BVISNULL( &cancel_mode[i].word ) ) { 2165 return 1; 2166 } 2167 2168 mask = cancel_mode[i].mask; 2169 2170 if ( LDAP_BACK_ISOPEN( li ) 2171 && mask == LDAP_BACK_F_CANCEL_EXOP_DISCOVER 2172 && !LDAP_BACK_CANCEL( li ) ) 2173 { 2174 slap_bindconf sb = { BER_BVNULL }; 2175 int rc; 2176 2177 if ( li->li_uri == NULL ) { 2178 snprintf( c->cr_msg, sizeof( c->cr_msg ), 2179 "need URI to discover \"cancel\" support " 2180 "in \"cancel exop-discover\"" ); 2181 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 2182 return 1; 2183 } 2184 2185 ber_str2bv( li->li_uri, 0, 0, &sb.sb_uri ); 2186 sb.sb_version = li->li_version; 2187 sb.sb_method = LDAP_AUTH_SIMPLE; 2188 BER_BVSTR( &sb.sb_binddn, "" ); 2189 2190 rc = slap_discover_feature( &sb, 2191 slap_schema.si_ad_supportedExtension->ad_cname.bv_val, 2192 LDAP_EXOP_CANCEL ); 2193 if ( rc == LDAP_COMPARE_TRUE ) { 2194 mask |= LDAP_BACK_F_CANCEL_EXOP; 2195 } 2196 } 2197 2198 li->li_flags &= ~LDAP_BACK_F_CANCEL_MASK2; 2199 li->li_flags |= mask; 2200 } break; 2201 2202 case LDAP_BACK_CFG_QUARANTINE: 2203 if ( LDAP_BACK_QUARANTINE( li ) ) { 2204 snprintf( c->cr_msg, sizeof( c->cr_msg ), 2205 "quarantine already defined" ); 2206 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 2207 return 1; 2208 } 2209 rc = slap_retry_info_parse( c->argv[1], &li->li_quarantine, 2210 c->cr_msg, sizeof( c->cr_msg ) ); 2211 if ( rc ) { 2212 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 2213 2214 } else { 2215 ldap_pvt_thread_mutex_init( &li->li_quarantine_mutex ); 2216 /* give it a chance to retry if the pattern gets reset 2217 * via back-config */ 2218 li->li_isquarantined = 0; 2219 li->li_flags |= LDAP_BACK_F_QUARANTINE; 2220 } 2221 break; 2222 2223 #ifdef SLAP_CONTROL_X_SESSION_TRACKING 2224 case LDAP_BACK_CFG_ST_REQUEST: 2225 if ( c->value_int ) { 2226 li->li_flags |= LDAP_BACK_F_ST_REQUEST; 2227 2228 } else { 2229 li->li_flags &= ~LDAP_BACK_F_ST_REQUEST; 2230 } 2231 break; 2232 #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ 2233 2234 case LDAP_BACK_CFG_NOREFS: 2235 if ( c->value_int ) { 2236 li->li_flags |= LDAP_BACK_F_NOREFS; 2237 2238 } else { 2239 li->li_flags &= ~LDAP_BACK_F_NOREFS; 2240 } 2241 break; 2242 2243 case LDAP_BACK_CFG_NOUNDEFFILTER: 2244 if ( c->value_int ) { 2245 li->li_flags |= LDAP_BACK_F_NOUNDEFFILTER; 2246 2247 } else { 2248 li->li_flags &= ~LDAP_BACK_F_NOUNDEFFILTER; 2249 } 2250 break; 2251 2252 case LDAP_BACK_CFG_ONERR: 2253 /* onerr? */ 2254 i = verb_to_mask( c->argv[1], onerr_mode ); 2255 if ( BER_BVISNULL( &onerr_mode[i].word ) ) { 2256 snprintf( c->cr_msg, sizeof( c->cr_msg ), 2257 "%s unknown argument \"%s\"", 2258 c->argv[0], c->argv[1] ); 2259 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 2260 return 1; 2261 } 2262 li->li_flags &= ~LDAP_BACK_F_ONERR_STOP; 2263 li->li_flags |= onerr_mode[i].mask; 2264 break; 2265 2266 case LDAP_BACK_CFG_REWRITE: 2267 snprintf( c->cr_msg, sizeof( c->cr_msg ), 2268 "rewrite/remap capabilities have been moved " 2269 "to the \"rwm\" overlay; see slapo-rwm(5) " 2270 "for details (hint: add \"overlay rwm\" " 2271 "and prefix all directives with \"rwm-\")" ); 2272 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); 2273 return 1; 2274 2275 case LDAP_BACK_CFG_OMIT_UNKNOWN_SCHEMA: 2276 if ( c->value_int ) { 2277 li->li_flags |= LDAP_BACK_F_OMIT_UNKNOWN_SCHEMA; 2278 2279 } else { 2280 li->li_flags &= ~LDAP_BACK_F_OMIT_UNKNOWN_SCHEMA; 2281 } 2282 break; 2283 2284 case LDAP_BACK_CFG_KEEPALIVE: 2285 slap_keepalive_parse( ber_bvstrdup(c->argv[1]), 2286 &li->li_tls.sb_keepalive, 0, 0, 0); 2287 break; 2288 2289 default: 2290 /* FIXME: try to catch inconsistencies */ 2291 assert( 0 ); 2292 break; 2293 } 2294 2295 return rc; 2296 } 2297 2298 int 2299 ldap_back_init_cf( BackendInfo *bi ) 2300 { 2301 int rc; 2302 AttributeDescription *ad = NULL; 2303 const char *text; 2304 2305 /* Make sure we don't exceed the bits reserved for userland */ 2306 config_check_userland( LDAP_BACK_CFG_LAST ); 2307 2308 bi->bi_cf_ocs = ldapocs; 2309 2310 rc = config_register_schema( ldapcfg, ldapocs ); 2311 if ( rc ) { 2312 return rc; 2313 } 2314 2315 /* setup olcDbAclPasswd and olcDbIDAssertPasswd 2316 * to be base64-encoded when written in LDIF form; 2317 * basically, we don't care if it fails */ 2318 rc = slap_str2ad( "olcDbACLPasswd", &ad, &text ); 2319 if ( rc ) { 2320 Debug( LDAP_DEBUG_ANY, "config_back_initialize: " 2321 "warning, unable to get \"olcDbACLPasswd\" " 2322 "attribute description: %d: %s\n", 2323 rc, text, 0 ); 2324 } else { 2325 (void)ldif_must_b64_encode_register( ad->ad_cname.bv_val, 2326 ad->ad_type->sat_oid ); 2327 } 2328 2329 ad = NULL; 2330 rc = slap_str2ad( "olcDbIDAssertPasswd", &ad, &text ); 2331 if ( rc ) { 2332 Debug( LDAP_DEBUG_ANY, "config_back_initialize: " 2333 "warning, unable to get \"olcDbIDAssertPasswd\" " 2334 "attribute description: %d: %s\n", 2335 rc, text, 0 ); 2336 } else { 2337 (void)ldif_must_b64_encode_register( ad->ad_cname.bv_val, 2338 ad->ad_type->sat_oid ); 2339 } 2340 2341 return 0; 2342 } 2343 2344 static int 2345 ldap_pbind_cf_gen( ConfigArgs *c ) 2346 { 2347 slap_overinst *on = (slap_overinst *)c->bi; 2348 void *private = c->be->be_private; 2349 int rc; 2350 2351 c->be->be_private = on->on_bi.bi_private; 2352 rc = ldap_back_cf_gen( c ); 2353 c->be->be_private = private; 2354 return rc; 2355 } 2356 2357 int 2358 ldap_pbind_init_cf( BackendInfo *bi ) 2359 { 2360 bi->bi_cf_ocs = pbindocs; 2361 2362 return config_register_schema( pbindcfg, pbindocs ); 2363 } 2364 2365 static int 2366 ldap_back_exop_whoami( 2367 Operation *op, 2368 SlapReply *rs ) 2369 { 2370 struct berval *bv = NULL; 2371 2372 if ( op->oq_extended.rs_reqdata != NULL ) { 2373 /* no request data should be provided */ 2374 rs->sr_text = "no request data expected"; 2375 return rs->sr_err = LDAP_PROTOCOL_ERROR; 2376 } 2377 2378 Statslog( LDAP_DEBUG_STATS, "%s WHOAMI\n", 2379 op->o_log_prefix, 0, 0, 0, 0 ); 2380 2381 rs->sr_err = backend_check_restrictions( op, rs, 2382 (struct berval *)&slap_EXOP_WHOAMI ); 2383 if( rs->sr_err != LDAP_SUCCESS ) return rs->sr_err; 2384 2385 /* if auth'd by back-ldap and request is proxied, forward it */ 2386 if ( op->o_conn->c_authz_backend 2387 && !strcmp( op->o_conn->c_authz_backend->be_type, "ldap" ) 2388 && !dn_match( &op->o_ndn, &op->o_conn->c_ndn ) ) 2389 { 2390 ldapconn_t *lc = NULL; 2391 LDAPControl c, *ctrls[2] = {NULL, NULL}; 2392 LDAPMessage *res; 2393 Operation op2 = *op; 2394 ber_int_t msgid; 2395 int doretry = 1; 2396 char *ptr; 2397 2398 ctrls[0] = &c; 2399 op2.o_ndn = op->o_conn->c_ndn; 2400 if ( !ldap_back_dobind( &lc, &op2, rs, LDAP_BACK_SENDERR ) ) { 2401 return -1; 2402 } 2403 c.ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ; 2404 c.ldctl_iscritical = 1; 2405 c.ldctl_value.bv_val = op->o_tmpalloc( 2406 op->o_ndn.bv_len + STRLENOF( "dn:" ) + 1, 2407 op->o_tmpmemctx ); 2408 c.ldctl_value.bv_len = op->o_ndn.bv_len + 3; 2409 ptr = c.ldctl_value.bv_val; 2410 ptr = lutil_strcopy( ptr, "dn:" ); 2411 ptr = lutil_strncopy( ptr, op->o_ndn.bv_val, op->o_ndn.bv_len ); 2412 ptr[ 0 ] = '\0'; 2413 2414 retry: 2415 rs->sr_err = ldap_whoami( lc->lc_ld, ctrls, NULL, &msgid ); 2416 if ( rs->sr_err == LDAP_SUCCESS ) { 2417 /* by now, make sure no timeout is used (ITS#6282) */ 2418 struct timeval tv = { -1, 0 }; 2419 if ( ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, &tv, &res ) == -1 ) { 2420 ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, 2421 &rs->sr_err ); 2422 if ( rs->sr_err == LDAP_SERVER_DOWN && doretry ) { 2423 doretry = 0; 2424 if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) { 2425 goto retry; 2426 } 2427 } 2428 2429 } else { 2430 /* NOTE: are we sure "bv" will be malloc'ed 2431 * with the appropriate memory? */ 2432 rs->sr_err = ldap_parse_whoami( lc->lc_ld, res, &bv ); 2433 ldap_msgfree(res); 2434 } 2435 } 2436 op->o_tmpfree( c.ldctl_value.bv_val, op->o_tmpmemctx ); 2437 if ( rs->sr_err != LDAP_SUCCESS ) { 2438 rs->sr_err = slap_map_api2result( rs ); 2439 } 2440 2441 if ( lc != NULL ) { 2442 ldap_back_release_conn( (ldapinfo_t *)op2.o_bd->be_private, lc ); 2443 } 2444 2445 } else { 2446 /* else just do the same as before */ 2447 bv = (struct berval *) ch_malloc( sizeof( struct berval ) ); 2448 if ( !BER_BVISEMPTY( &op->o_dn ) ) { 2449 bv->bv_len = op->o_dn.bv_len + STRLENOF( "dn:" ); 2450 bv->bv_val = ch_malloc( bv->bv_len + 1 ); 2451 AC_MEMCPY( bv->bv_val, "dn:", STRLENOF( "dn:" ) ); 2452 AC_MEMCPY( &bv->bv_val[ STRLENOF( "dn:" ) ], op->o_dn.bv_val, 2453 op->o_dn.bv_len ); 2454 bv->bv_val[ bv->bv_len ] = '\0'; 2455 2456 } else { 2457 bv->bv_len = 0; 2458 bv->bv_val = NULL; 2459 } 2460 } 2461 2462 rs->sr_rspdata = bv; 2463 return rs->sr_err; 2464 } 2465 2466 2467