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