--- servers/slapd/saslauthz.c 2003/12/29 18:41:56 1.88.2.7 +++ servers/slapd/saslauthz.c 2004/04/13 22:35:20 1.88.2.13 @@ -1,7 +1,7 @@ -/* $OpenLDAP: pkg/ldap/servers/slapd/saslauthz.c,v 1.110 2003/12/18 17:32:45 ando Exp $ */ +/* $OpenLDAP: pkg/ldap/servers/slapd/saslauthz.c,v 1.88.2.12 2004/04/12 18:20:12 kurt Exp $ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2003 The OpenLDAP Foundation. + * Copyright 1998-2004 The OpenLDAP Foundation. * Portions Copyright 2000 Mark Adamson, Carnegie Mellon. * All rights reserved. * @@ -33,6 +33,7 @@ #define LDAP_X_SCOPE_REGEX ((ber_int_t) 0x0020) #define LDAP_X_SCOPE_CHILDREN ((ber_int_t) 0x0030) #define LDAP_X_SCOPE_SUBTREE ((ber_int_t) 0x0040) +#define LDAP_X_SCOPE_ONELEVEL ((ber_int_t) 0x0050) /* * IDs in DNauthzid form can now have a type specifier, that @@ -225,6 +226,10 @@ static int slap_parseURI( Operation *op, bv.bv_val += sizeof( "subtree" ) - 1; *scope = LDAP_X_SCOPE_SUBTREE; + } else if ( !strncasecmp( bv.bv_val, "onelevel:", sizeof( "onelevel:" ) - 1 ) ) { + bv.bv_val += sizeof( "onelevel" ) - 1; + *scope = LDAP_X_SCOPE_ONELEVEL; + } else { return LDAP_PROTOCOL_ERROR; } @@ -244,6 +249,7 @@ is_dn: bv.bv_len = uri->bv_len - (bv.bv case LDAP_X_SCOPE_EXACT: case LDAP_X_SCOPE_CHILDREN: case LDAP_X_SCOPE_SUBTREE: + case LDAP_X_SCOPE_ONELEVEL: rc = dnNormalize( 0, NULL, NULL, &bv, nbase, op->o_tmpmemctx ); if( rc != LDAP_SUCCESS ) { *scope = -1; @@ -270,9 +276,9 @@ is_dn: bv.bv_len = uri->bv_len - (bv.bv Connection c = *op->o_conn; char buf[ SLAP_LDAPDN_MAXLEN ]; struct berval id, - user = { 0, NULL }, - realm = { 0, NULL }, - mech = { 0, NULL }; + user = BER_BVNULL, + realm = BER_BVNULL, + mech = BER_BVNULL; if ( sizeof( buf ) <= uri->bv_len ) { return LDAP_INVALID_SYNTAX; @@ -555,6 +561,7 @@ static int sasl_sc_sasl2dn( Operation *o if( ndn->bv_val ) { o->o_tmpfree(ndn->bv_val, o->o_tmpmemctx); ndn->bv_val = NULL; + ndn->bv_len = 0; #ifdef NEW_LOGGING LDAP_LOG( TRANSPORT, DETAIL1, @@ -639,6 +646,7 @@ exact_match: case LDAP_X_SCOPE_CHILDREN: case LDAP_X_SCOPE_SUBTREE: + case LDAP_X_SCOPE_ONELEVEL: { int d = assertDN->bv_len - op.o_req_ndn.bv_len; @@ -654,7 +662,30 @@ exact_match: bv.bv_val = assertDN->bv_val + d; if ( bv.bv_val[ -1 ] == ',' && dn_match( &op.o_req_ndn, &bv ) ) { - rc = LDAP_SUCCESS; + switch ( op.oq_search.rs_scope ) { + case LDAP_X_SCOPE_SUBTREE: + case LDAP_X_SCOPE_CHILDREN: + rc = LDAP_SUCCESS; + break; + + case LDAP_X_SCOPE_ONELEVEL: + { + struct berval pdn; + + dnParent( assertDN, &pdn ); + /* the common portion of the DN + * already matches, so only check + * if parent DN of assertedDN + * is all the pattern */ + if ( pdn.bv_len == op.o_req_ndn.bv_len ) { + rc = LDAP_SUCCESS; + } + break; + } + default: + /* at present, impossible */ + assert( 0 ); + } } } goto CONCLUDED; @@ -720,6 +751,8 @@ exact_match: op.o_conn = opx->o_conn; op.o_connid = opx->o_connid; op.o_req_dn = op.o_req_ndn; + op.oq_search.rs_slimit = 1; + op.oq_search.rs_tlimit = -1; op.o_bd->be_search( &op, &rs ); @@ -819,7 +852,7 @@ void slap_sasl2dn( Operation *opx, slap_callback cb = { NULL, sasl_sc_sasl2dn, NULL, NULL }; Operation op = {0}; SlapReply rs = {REP_RESULT}; - struct berval regout = { 0, NULL }; + struct berval regout = BER_BVNULL; #ifdef NEW_LOGGING LDAP_LOG( TRANSPORT, ENTRY, @@ -863,11 +896,15 @@ void slap_sasl2dn( Operation *opx, case LDAP_X_SCOPE_REGEX: case LDAP_X_SCOPE_SUBTREE: case LDAP_X_SCOPE_CHILDREN: + case LDAP_X_SCOPE_ONELEVEL: /* correctly parsed, but illegal */ goto FINISHED; case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_SUBTREE: +#ifdef LDAP_SCOPE_SUBORDINATE + case LDAP_SCOPE_SUBORDINATE: +#endif /* do a search */ break; @@ -907,6 +944,7 @@ void slap_sasl2dn( Operation *opx, #endif op.oq_search.rs_deref = LDAP_DEREF_NEVER; op.oq_search.rs_slimit = 1; + op.oq_search.rs_tlimit = -1; op.oq_search.rs_attrsonly = 1; op.o_req_dn = op.o_req_ndn; @@ -966,7 +1004,9 @@ int slap_sasl_authorized( Operation *op, } /* Allow the manager to authorize as any DN. */ - if( op->o_conn->c_authz_backend && be_isroot( op->o_conn->c_authz_backend, authcDN )) { + if( op->o_conn->c_authz_backend && + be_isroot_dn( op->o_conn->c_authz_backend, authcDN )) + { rc = LDAP_SUCCESS; goto DONE; }