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