~ubuntu-branches/ubuntu/precise/openldap/precise

« back to all changes in this revision

Viewing changes to servers/slapd/back-ldap/bind.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-01-23 10:01:13 UTC
  • mfrom: (1.1.9) (0.3.17 sid)
  • Revision ID: package-import@ubuntu.com-20120123100113-gntssa0aqxn4dfui
Tags: 2.4.28-1.1ubuntu1
* Merge from Debian testing.  Remaining changes:
  - Install a default DIT (LP: #442498).
  - Document cn=config in README file (LP: #370784).
  - remaining changes:
    + AppArmor support:
      - debian/apparmor-profile: add AppArmor profile
      - use dh_apparmor:
        - debian/rules: use dh_apparmor
        - debian/control: Build-Depends on debhelper 7.4.20ubuntu5
      - updated debian/slapd.README.Debian for note on AppArmor
      - debian/slapd.dirs: add etc/apparmor.d/force-complain
    + Enable GSSAPI support (LP: #495418):
      - debian/patches/gssapi.diff, thanks to Jerry Carter (Likewise):
        - Add --with-gssapi support
        - Make guess_service_principal() more robust when determining
          principal
      - debian/patches/series: apply gssapi.diff patch.
      - debian/configure.options: Configure with --with-gssapi
      - debian/control: Added libkrb5-dev as a build depend
    + debian/rules: Enable -DLDAP_CONNECTIONLESS to build CLDAP (UDP) support
      in the openldap library, as required by Likewise-Open (LP: #390579)
   + Don't build smbk5pwd overlay since it uses heimdal instead of krb5:
      - debian/control: 
        - remove build-dependency on heimdal-dev.
        - remove slapd-smbk5pwd binary package.
      - debian/rules: don't build smbk5pwd slapd module.
    + debian/{control,rules}: enable PIE hardening
    + ufw support (LP: #423246):
      - debian/control: suggest ufw.
      - debian/rules: install ufw profile.
      - debian/slapd.ufw.profile: add ufw profile.
    + Enable nssoverlay:
      - debian/patches/nssov-build, debian/series, debian/rules: 
        Apply, build and package the nss overlay.
      - debian/schema/extra/misc.ldif: add ldif file for the misc schema
        which defines rfc822MailMember (required by the nss overlay).
    + debian/rules, debian/schema/extra/: 
      Fix configure rule to supports extra schemas shipped as part
      of the debian/schema/ directory.
    + debian/rules, debian/slapd.py: Add apport hook. (LP: #610544)
    + debian/slapd.init.ldif: don't set olcRootDN since it's not defined in
     neither the default DIT nor via an Authn mapping.
    + debian/slapd.scripts-common: adjust minimum version that triggers a
      database upgrade. Upgrade from maverick shouldn't trigger database
      upgrade (which would happen with the version used in Debian).
    + debian/slapd.scripts-common: add slapcat_opts to local variables.
      Remove unused variable new_conf.
    + debian/slapd.script-common: Fix package reconfiguration.
      - Fix backup directory naming for multiple reconfiguration.
    + debian/slapd.default, debian/slapd.README.Debian: 
      use the new configuration style.
    + Install nss overlay (LP: #675391):
      - debian/rules: run install target for nssov module.
      - debian/patches/nssov-build: fix patch to install schema in /etc/ldap/schema
    + debian/patches/gssapi.diff:
      - Update patch so that likewise-open is usuable again. (LP: #661547)
    + debian/patches/service-operational-before-detach: New patch replacing old one
      of the same name as previous could cause database corruption based on upstream commits.
      (LP: #727973)
    + debian/patches/CVE-2011-4079: fix off by one error in postalAddressNormalize()
      (CVE-2011-4079)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* bind.c - ldap backend bind function */
2
 
/* $OpenLDAP: pkg/ldap/servers/slapd/back-ldap/bind.c,v 1.162.2.33 2011/01/26 18:32:52 quanah Exp $ */
 
2
/* $OpenLDAP$ */
3
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
4
 *
5
5
 * Copyright 1999-2011 The OpenLDAP Foundation.
37
37
 
38
38
#define LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ       "2.16.840.1.113730.3.4.12"
39
39
 
 
40
#ifdef LDAP_DEVEL
 
41
#define SLAP_AUTH_DN 1
 
42
#endif
 
43
 
40
44
#if LDAP_BACK_PRINT_CONNTREE > 0
41
45
 
42
46
static const struct {
710
714
 
711
715
#ifdef HAVE_TLS
712
716
        if ( LDAP_BACK_CONN_ISPRIV( lc ) ) {
713
 
                sb = &li->li_acl;
 
717
                /* See "rationale" comment in ldap_back_getconn() */
 
718
                if ( li->li_acl_authmethod == LDAP_AUTH_NONE &&
 
719
                         li->li_idassert_authmethod != LDAP_AUTH_NONE )
 
720
                        sb = &li->li_idassert.si_bc;
 
721
                else
 
722
                        sb = &li->li_acl;
714
723
 
715
724
        } else if ( LDAP_BACK_CONN_ISIDASSERT( lc ) ) {
716
725
                sb = &li->li_idassert.si_bc;
976
985
 
977
986
                /*
978
987
                 * the rationale is: connections as the rootdn are privileged,
979
 
                 * so acl_authcDN is to be used; however, in some cases
 
988
                 * so li_acl is to be used; however, in some cases
980
989
                 * one already configured identity assertion with a highly
981
 
                 * privileged idassert_authcDN, so if acl_authcDN is NULL
982
 
                 * and idassert_authcDN is not, use the second instead.
 
990
                 * privileged idassert_authcDN, so if li_acl is not configured
 
991
                 * and idassert is, use idassert instead.
983
992
                 *
984
993
                 * might change in the future, because it's preferable
985
994
                 * to make clear what identity is being used, since
987
996
                 * the same identity twice...
988
997
                 */
989
998
                if ( LDAP_BACK_CONN_ISPRIV( &lc_curr ) ) {
990
 
                        if ( BER_BVISNULL( &li->li_acl_authcDN ) && !BER_BVISNULL( &li->li_idassert_authcDN ) ) {
 
999
                        if ( li->li_acl_authmethod == LDAP_AUTH_NONE &&
 
1000
                                 li->li_idassert_authmethod != LDAP_AUTH_NONE ) {
991
1001
                                ber_dupbv( &lc->lc_bound_ndn, &li->li_idassert_authcDN );
992
1002
                                ber_dupbv( &lc->lc_cred, &li->li_idassert_passwd );
993
1003
 
1398
1408
        }
1399
1409
 
1400
1410
#ifdef HAVE_CYRUS_SASL
1401
 
        if ( LDAP_BACK_CONN_ISPRIV( lc )
1402
 
                && li->li_acl_authmethod == LDAP_AUTH_SASL )
1403
 
        {
 
1411
        if ( LDAP_BACK_CONN_ISPRIV( lc )) {
 
1412
        slap_bindconf *sb;
 
1413
        if ( li->li_acl_authmethod != LDAP_AUTH_NONE )
 
1414
                sb = &li->li_acl;
 
1415
        else
 
1416
                sb = &li->li_idassert.si_bc;
 
1417
 
 
1418
        if ( sb->sb_method == LDAP_AUTH_SASL ) {
1404
1419
                void            *defaults = NULL;
1405
1420
 
1406
 
                if ( li->li_acl_secprops != NULL ) {
 
1421
                if ( sb->sb_secprops != NULL ) {
1407
1422
                        rc = ldap_set_option( lc->lc_ld,
1408
 
                                LDAP_OPT_X_SASL_SECPROPS, li->li_acl_secprops );
 
1423
                                LDAP_OPT_X_SASL_SECPROPS, sb->sb_secprops );
1409
1424
 
1410
1425
                        if ( rc != LDAP_OPT_SUCCESS ) {
1411
1426
                                Debug( LDAP_DEBUG_ANY, "Error: ldap_set_option "
1412
1427
                                        "(SECPROPS,\"%s\") failed!\n",
1413
 
                                        li->li_acl_secprops, 0, 0 );
 
1428
                                        sb->sb_secprops, 0, 0 );
1414
1429
                                goto done;
1415
1430
                        }
1416
1431
                }
1417
1432
 
1418
1433
                defaults = lutil_sasl_defaults( lc->lc_ld,
1419
 
                                li->li_acl_sasl_mech.bv_val,
1420
 
                                li->li_acl_sasl_realm.bv_val,
1421
 
                                li->li_acl_authcID.bv_val,
1422
 
                                li->li_acl_passwd.bv_val,
 
1434
                                sb->sb_saslmech.bv_val,
 
1435
                                sb->sb_realm.bv_val,
 
1436
                                sb->sb_authcId.bv_val,
 
1437
                                sb->sb_cred.bv_val,
1423
1438
                                NULL );
1424
1439
                if ( defaults == NULL ) {
1425
1440
                        rs->sr_err = LDAP_OTHER;
1431
1446
                }
1432
1447
 
1433
1448
                rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld,
1434
 
                                li->li_acl_authcDN.bv_val,
1435
 
                                li->li_acl_sasl_mech.bv_val, NULL, NULL,
 
1449
                                sb->sb_binddn.bv_val,
 
1450
                                sb->sb_saslmech.bv_val, NULL, NULL,
1436
1451
                                LDAP_SASL_QUIET, lutil_sasl_interact,
1437
1452
                                defaults );
1438
1453
 
1466
1481
 
1467
1482
                goto done;
1468
1483
        }
 
1484
        }
1469
1485
#endif /* HAVE_CYRUS_SASL */
1470
1486
 
1471
1487
retry:;
2193
2209
                void            *defaults = NULL;
2194
2210
                struct berval   authzID = BER_BVNULL;
2195
2211
                int             freeauthz = 0;
 
2212
                LDAPControl **ctrlsp = NULL;
 
2213
                LDAPMessage *result = NULL;
 
2214
                const char *rmech = NULL;
 
2215
                const char *save_text = rs->sr_text;
 
2216
 
 
2217
#ifdef SLAP_AUTH_DN
 
2218
                LDAPControl ctrl, *ctrls[2];
 
2219
                int msgid;
 
2220
#endif /* SLAP_AUTH_DN */
2196
2221
 
2197
2222
                /* if SASL supports native authz, prepare for it */
2198
2223
                if ( ( !op->o_do_not_cache || !op->o_is_auth_check ) &&
2257
2282
                        goto done;
2258
2283
                }
2259
2284
 
2260
 
                rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld, binddn->bv_val,
2261
 
                                li->li_idassert_sasl_mech.bv_val, NULL, NULL,
2262
 
                                LDAP_SASL_QUIET, lutil_sasl_interact,
2263
 
                                defaults );
 
2285
#ifdef SLAP_AUTH_DN
 
2286
                if ( li->li_idassert_flags & LDAP_BACK_AUTH_DN_AUTHZID ) {
 
2287
                        assert( BER_BVISNULL( binddn ) );
 
2288
 
 
2289
                        ctrl.ldctl_oid = LDAP_CONTROL_AUTHZID_REQUEST;
 
2290
                        ctrl.ldctl_iscritical = 0;
 
2291
                        BER_BVZERO( &ctrl.ldctl_value );
 
2292
                        ctrls[0] = &ctrl;
 
2293
                        ctrls[1] = NULL;
 
2294
                        ctrlsp = ctrls;
 
2295
                }
 
2296
#endif /* SLAP_AUTH_DN */
 
2297
 
 
2298
                do {
 
2299
                        rs->sr_err = ldap_sasl_interactive_bind( lc->lc_ld, binddn->bv_val,
 
2300
                                li->li_idassert_sasl_mech.bv_val, 
 
2301
                                ctrlsp, NULL, LDAP_SASL_QUIET, lutil_sasl_interact, defaults,
 
2302
                                result, &rmech, &msgid );
 
2303
 
 
2304
                        if ( rs->sr_err != LDAP_SASL_BIND_IN_PROGRESS )
 
2305
                                break;
 
2306
 
 
2307
                        ldap_msgfree( result );
 
2308
 
 
2309
                        if ( ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, NULL, &result ) == -1 || !result ) {
 
2310
                                ldap_get_option( lc->lc_ld, LDAP_OPT_RESULT_CODE, (void*)&rs->sr_err );
 
2311
                                ldap_get_option( lc->lc_ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*)&rs->sr_text );
 
2312
                                break;
 
2313
                        }
 
2314
                } while ( rs->sr_err == LDAP_SASL_BIND_IN_PROGRESS );
2264
2315
 
2265
2316
                switch ( rs->sr_err ) {
2266
2317
                case LDAP_SUCCESS:
 
2318
#ifdef SLAP_AUTH_DN
 
2319
                        /* FIXME: right now, the only reason to check
 
2320
                         * response controls is RFC 3829 authzid */
 
2321
                        if ( li->li_idassert_flags & LDAP_BACK_AUTH_DN_AUTHZID ) {
 
2322
                                ctrlsp = NULL;
 
2323
                                rc = ldap_parse_result( lc->lc_ld, result, NULL, NULL, NULL, NULL,
 
2324
                                        &ctrlsp, 0 );
 
2325
                                if ( rc == LDAP_SUCCESS && ctrlsp ) {
 
2326
                                        LDAPControl *ctrl;
 
2327
                
 
2328
                                        ctrl = ldap_control_find( LDAP_CONTROL_AUTHZID_RESPONSE,
 
2329
                                                ctrlsp, NULL );
 
2330
                                        if ( ctrl ) {
 
2331
                                                Debug( LDAP_DEBUG_TRACE, "%s: ldap_back_proxy_authz_bind: authzID=\"%s\" (authzid)\n",
 
2332
                                                        op->o_log_prefix, ctrl->ldctl_value.bv_val, 0 );
 
2333
                                                if ( ctrl->ldctl_value.bv_len > STRLENOF("dn:") &&
 
2334
                                                        strncasecmp( ctrl->ldctl_value.bv_val, "dn:", STRLENOF("dn:") ) == 0 )
 
2335
                                                {
 
2336
                                                        struct berval bv;
 
2337
                                                        bv.bv_val = &ctrl->ldctl_value.bv_val[STRLENOF("dn:")];
 
2338
                                                        bv.bv_len = ctrl->ldctl_value.bv_len - STRLENOF("dn:");
 
2339
                                                        ber_bvreplace( &lc->lc_bound_ndn, &bv );
 
2340
                                                }
 
2341
                                        }
 
2342
                                }
 
2343
 
 
2344
                                ldap_controls_free( ctrlsp );
 
2345
 
 
2346
                        } else if ( li->li_idassert_flags & LDAP_BACK_AUTH_DN_WHOAMI ) {
 
2347
                                struct berval *val = NULL;
 
2348
                                rc = ldap_whoami_s( lc->lc_ld, &val, NULL, NULL );
 
2349
                                if ( rc == LDAP_SUCCESS && val != NULL ) {
 
2350
                                        Debug( LDAP_DEBUG_TRACE, "%s: ldap_back_proxy_authz_bind: authzID=\"%s\" (whoami)\n",
 
2351
                                                op->o_log_prefix, val->bv_val, 0 );
 
2352
                                        if ( val->bv_len > STRLENOF("dn:") &&
 
2353
                                                strncasecmp( val->bv_val, "dn:", STRLENOF("dn:") ) == 0 )
 
2354
                                        {
 
2355
                                                struct berval bv;
 
2356
                                                bv.bv_val = &val->bv_val[STRLENOF("dn:")];
 
2357
                                                bv.bv_len = val->bv_len - STRLENOF("dn:");
 
2358
                                                ber_bvreplace( &lc->lc_bound_ndn, &bv );
 
2359
                                        }
 
2360
                                        ber_bvfree( val );
 
2361
                                }
 
2362
                        }
 
2363
 
 
2364
                        if ( ( li->li_idassert_flags & LDAP_BACK_AUTH_DN_MASK ) &&
 
2365
                                BER_BVISNULL( &lc->lc_bound_ndn ) )
 
2366
                        {
 
2367
                                /* all in all, we only need it to be non-null */
 
2368
                                /* FIXME: should this be configurable? */
 
2369
                                static struct berval bv = BER_BVC("cn=authzdn");
 
2370
                                ber_bvreplace( &lc->lc_bound_ndn, &bv );
 
2371
                        }
 
2372
#endif /* SLAP_AUTH_DN */
 
2373
                        op->o_conn->c_authz_cookie = op->o_bd->be_private;
2267
2374
                        LDAP_BACK_CONN_ISBOUND_SET( lc );
2268
2375
                        break;
2269
2376
 
2284
2391
                        break;
2285
2392
                }
2286
2393
 
 
2394
                if ( save_text != rs->sr_text ) {
 
2395
                        ldap_memfree( (char *)rs->sr_text );
 
2396
                        rs->sr_text = save_text;
 
2397
                }
 
2398
 
 
2399
                ldap_msgfree( result );
 
2400
 
2287
2401
                lutil_sasl_freedefs( defaults );
2288
2402
                if ( freeauthz ) {
2289
2403
                        slap_sl_free( authzID.bv_val, op->o_tmpmemctx );
2343
2457
                        lc->lc_cred.bv_len = 0;
2344
2458
                }
2345
2459
        }
 
2460
 
2346
2461
done:;
2347
2462
        return LDAP_BACK_CONN_ISBOUND( lc );
2348
2463
}