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