X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fsasl.c;h=649094f713ab664341189de2ed4b707124013f74;hb=3743a5a68e4d608949d5fd04904733ee5c1ac959;hp=e12a82946fad2fbc7ae0c9caa64b128f95ea5692;hpb=d3e7717473503e286f39eef1f5ae7f214f0deb04;p=openldap diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c index e12a82946f..649094f713 100644 --- a/servers/slapd/sasl.c +++ b/servers/slapd/sasl.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2009 The OpenLDAP Foundation. + * Copyright 1998-2012 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -149,6 +149,11 @@ static const char *slap_propnames[] = { "*slapConn", "*slapAuthcDNlen", "*slapAuthcDN", "*slapAuthzDNlen", "*slapAuthzDN", NULL }; +#ifdef SLAP_AUXPROP_DONTUSECOPY +int slap_dontUseCopy_ignore; +BerVarray slap_dontUseCopy_propnames; +#endif /* SLAP_AUXPROP_DONTUSECOPY */ + static Filter generic_filter = { LDAP_FILTER_PRESENT, { 0 }, NULL }; static struct berval generic_filterstr = BER_BVC("(objectclass=*)"); @@ -179,7 +184,10 @@ sasl_ap_lookup( Operation *op, SlapReply *rs ) int rc, i; lookup_info *sl = (lookup_info *)op->o_callback->sc_private; - if (rs->sr_type != REP_SEARCH) return 0; + /* return the actual error code, + * to allow caller to handle specific errors + */ + if (rs->sr_type != REP_SEARCH) return rs->sr_err; for( i = 0; sl->list[i].name; i++ ) { const char *name = sl->list[i].name; @@ -258,7 +266,11 @@ sasl_ap_lookup( Operation *op, SlapReply *rs ) return LDAP_SUCCESS; } +#if SASL_VERSION_FULL >= 0x020118 +static int +#else static void +#endif slap_auxprop_lookup( void *glob_context, sasl_server_params_t *sparams, @@ -266,10 +278,16 @@ slap_auxprop_lookup( const char *user, unsigned ulen) { - Operation op = {0}; + OperationBuffer opbuf = {{ NULL }}; + Operation *op = (Operation *)&opbuf; int i, doit = 0; Connection *conn = NULL; lookup_info sl; + int rc = LDAP_SUCCESS; +#ifdef SLAP_AUXPROP_DONTUSECOPY + int dontUseCopy = 0; + BackendDB *dontUseCopy_bd = NULL; +#endif /* SLAP_AUXPROP_DONTUSECOPY */ sl.list = sparams->utils->prop_get( sparams->propctx ); sl.sparams = sparams; @@ -286,26 +304,39 @@ slap_auxprop_lookup( if ( flags & SASL_AUXPROP_AUTHZID ) { if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHZLEN] )) { if ( sl.list[i].values && sl.list[i].values[0] ) - AC_MEMCPY( &op.o_req_ndn.bv_len, sl.list[i].values[0], - sizeof( op.o_req_ndn.bv_len ) ); + AC_MEMCPY( &op->o_req_ndn.bv_len, sl.list[i].values[0], + sizeof( op->o_req_ndn.bv_len ) ); } else if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHZ] )) { if ( sl.list[i].values ) - op.o_req_ndn.bv_val = (char *)sl.list[i].values[0]; + op->o_req_ndn.bv_val = (char *)sl.list[i].values[0]; break; } } if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHCLEN] )) { if ( sl.list[i].values && sl.list[i].values[0] ) - AC_MEMCPY( &op.o_req_ndn.bv_len, sl.list[i].values[0], - sizeof( op.o_req_ndn.bv_len ) ); + AC_MEMCPY( &op->o_req_ndn.bv_len, sl.list[i].values[0], + sizeof( op->o_req_ndn.bv_len ) ); } else if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHC] ) ) { if ( sl.list[i].values ) { - op.o_req_ndn.bv_val = (char *)sl.list[i].values[0]; + op->o_req_ndn.bv_val = (char *)sl.list[i].values[0]; if ( !(flags & SASL_AUXPROP_AUTHZID) ) break; } } +#ifdef SLAP_AUXPROP_DONTUSECOPY + if ( slap_dontUseCopy_propnames != NULL ) { + int j; + struct berval bv; + ber_str2bv( &sl.list[i].name[1], 0, 1, &bv ); + for ( j = 0; !BER_BVISNULL( &slap_dontUseCopy_propnames[ j ]); j++ ) { + if ( bvmatch( &bv, &slap_dontUseCopy_propnames[ j ] ) ) { + dontUseCopy = 1; + break; + } + } + } +#endif /* SLAP_AUXPROP_DONTUSECOPY */ } } @@ -336,30 +367,30 @@ slap_auxprop_lookup( cb.sc_private = &sl; - op.o_bd = select_backend( &op.o_req_ndn, 1 ); + op->o_bd = select_backend( &op->o_req_ndn, 1 ); - if ( op.o_bd ) { + if ( op->o_bd ) { /* For rootdn, see if we can use the rootpw */ - if ( be_isroot_dn( op.o_bd, &op.o_req_ndn ) && - !BER_BVISEMPTY( &op.o_bd->be_rootpw )) { + if ( be_isroot_dn( op->o_bd, &op->o_req_ndn ) && + !BER_BVISEMPTY( &op->o_bd->be_rootpw )) { struct berval cbv = BER_BVNULL; /* If there's a recognized scheme, see if it's CLEARTEXT */ - if ( lutil_passwd_scheme( op.o_bd->be_rootpw.bv_val )) { - if ( !strncasecmp( op.o_bd->be_rootpw.bv_val, + if ( lutil_passwd_scheme( op->o_bd->be_rootpw.bv_val )) { + if ( !strncasecmp( op->o_bd->be_rootpw.bv_val, sc_cleartext.bv_val, sc_cleartext.bv_len )) { /* If it's CLEARTEXT, skip past scheme spec */ - cbv.bv_len = op.o_bd->be_rootpw.bv_len - + cbv.bv_len = op->o_bd->be_rootpw.bv_len - sc_cleartext.bv_len; if ( cbv.bv_len ) { - cbv.bv_val = op.o_bd->be_rootpw.bv_val + + cbv.bv_val = op->o_bd->be_rootpw.bv_val + sc_cleartext.bv_len; } } /* No scheme, use the whole value */ } else { - cbv = op.o_bd->be_rootpw; + cbv = op->o_bd->be_rootpw; } if ( !BER_BVISEMPTY( &cbv )) { for( i = 0; sl.list[i].name; i++ ) { @@ -380,30 +411,91 @@ slap_auxprop_lookup( } } - if ( op.o_bd->be_search ) { +#ifdef SLAP_AUXPROP_DONTUSECOPY + if ( SLAP_SHADOW( op->o_bd ) && dontUseCopy ) { + dontUseCopy_bd = op->o_bd; + op->o_bd = frontendDB; + } + +retry_dontUseCopy:; +#endif /* SLAP_AUXPROP_DONTUSECOPY */ + + if ( op->o_bd->be_search ) { SlapReply rs = {REP_RESULT}; - op.o_hdr = conn->c_sasl_bindop->o_hdr; - op.o_tag = LDAP_REQ_SEARCH; - op.o_dn = conn->c_ndn; - op.o_ndn = conn->c_ndn; - op.o_callback = &cb; - slap_op_time( &op.o_time, &op.o_tincr ); - op.o_do_not_cache = 1; - op.o_is_auth_check = 1; - op.o_req_dn = op.o_req_ndn; - op.ors_scope = LDAP_SCOPE_BASE; - op.ors_deref = LDAP_DEREF_NEVER; - op.ors_tlimit = SLAP_NO_LIMIT; - op.ors_slimit = 1; - op.ors_filter = &generic_filter; - op.ors_filterstr = generic_filterstr; +#ifdef SLAP_AUXPROP_DONTUSECOPY + LDAPControl **save_ctrls = NULL, c; + int save_dontUseCopy; +#endif /* SLAP_AUXPROP_DONTUSECOPY */ + + op->o_hdr = conn->c_sasl_bindop->o_hdr; + op->o_controls = opbuf.ob_controls; + op->o_tag = LDAP_REQ_SEARCH; + op->o_dn = conn->c_ndn; + op->o_ndn = conn->c_ndn; + op->o_callback = &cb; + slap_op_time( &op->o_time, &op->o_tincr ); + op->o_do_not_cache = 1; + op->o_is_auth_check = 1; + op->o_req_dn = op->o_req_ndn; + op->ors_scope = LDAP_SCOPE_BASE; + op->ors_deref = LDAP_DEREF_NEVER; + op->ors_tlimit = SLAP_NO_LIMIT; + op->ors_slimit = 1; + op->ors_filter = &generic_filter; + op->ors_filterstr = generic_filterstr; + op->o_authz = conn->c_authz; /* FIXME: we want all attributes, right? */ - op.ors_attrs = NULL; + op->ors_attrs = NULL; + +#ifdef SLAP_AUXPROP_DONTUSECOPY + if ( dontUseCopy ) { + save_dontUseCopy = op->o_dontUseCopy; + if ( !op->o_dontUseCopy ) { + int cnt = 0; + save_ctrls = op->o_ctrls; + if ( op->o_ctrls ) { + for ( ; op->o_ctrls[ cnt ]; cnt++ ) + ; + } + op->o_ctrls = op->o_tmpcalloc( sizeof(LDAPControl *), cnt + 2, op->o_tmpmemctx ); + if ( cnt ) { + for ( cnt = 0; save_ctrls[ cnt ]; cnt++ ) { + op->o_ctrls[ cnt ] = save_ctrls[ cnt ]; + } + } + c.ldctl_oid = LDAP_CONTROL_DONTUSECOPY; + c.ldctl_iscritical = 1; + BER_BVZERO( &c.ldctl_value ); + op->o_ctrls[ cnt ] = &c; + } + op->o_dontUseCopy = SLAP_CONTROL_CRITICAL; + } +#endif /* SLAP_AUXPROP_DONTUSECOPY */ - op.o_bd->be_search( &op, &rs ); + rc = op->o_bd->be_search( op, &rs ); + +#ifdef SLAP_AUXPROP_DONTUSECOPY + if ( dontUseCopy ) { + if ( save_ctrls != op->o_ctrls ) { + op->o_tmpfree( op->o_ctrls, op->o_tmpmemctx ); + op->o_ctrls = save_ctrls; + op->o_dontUseCopy = save_dontUseCopy; + } + + if ( rs.sr_err == LDAP_UNAVAILABLE && slap_dontUseCopy_ignore ) + { + op->o_bd = dontUseCopy_bd; + dontUseCopy = 0; + goto retry_dontUseCopy; + } + } +#endif /* SLAP_AUXPROP_DONTUSECOPY */ } } } +#if SASL_VERSION_FULL >= 0x020118 + return rc != LDAP_SUCCESS ? SASL_FAIL : SASL_OK; +#endif } #if SASL_VERSION_FULL >= 0x020110 @@ -417,7 +509,6 @@ slap_auxprop_store( { Operation op = {0}; Opheader oph; - SlapReply rs = {REP_RESULT}; int rc, i; unsigned j; Connection *conn = NULL; @@ -427,6 +518,10 @@ slap_auxprop_store( char textbuf[SLAP_TEXT_BUFLEN]; const char *text; size_t textlen = sizeof(textbuf); +#ifdef SLAP_AUXPROP_DONTUSECOPY + int dontUseCopy = 0; + BackendDB *dontUseCopy_bd = NULL; +#endif /* SLAP_AUXPROP_DONTUSECOPY */ /* just checking if we are enabled */ if (!prctx) return SASL_OK; @@ -451,6 +546,18 @@ slap_auxprop_store( if ( pr[i].values ) op.o_req_ndn.bv_val = (char *)pr[i].values[0]; } +#ifdef SLAP_AUXPROP_DONTUSECOPY + if ( slap_dontUseCopy_propnames != NULL ) { + struct berval bv; + ber_str2bv( &pr[i].name[1], 0, 1, &bv ); + for ( j = 0; !BER_BVISNULL( &slap_dontUseCopy_propnames[ j ] ); j++ ) { + if ( bvmatch( &bv, &slap_dontUseCopy_propnames[ j ] ) ) { + dontUseCopy = 1; + break; + } + } + } +#endif /* SLAP_AUXPROP_DONTUSECOPY */ } } if (!conn || !op.o_req_ndn.bv_val) return SASL_BADPARAM; @@ -458,7 +565,15 @@ slap_auxprop_store( op.o_bd = select_backend( &op.o_req_ndn, 1 ); if ( !op.o_bd || !op.o_bd->be_modify ) return SASL_FAIL; - + +#ifdef SLAP_AUXPROP_DONTUSECOPY + if ( SLAP_SHADOW( op.o_bd ) && dontUseCopy ) { + dontUseCopy_bd = op.o_bd; + op.o_bd = frontendDB; + op.o_dontUseCopy = SLAP_CONTROL_CRITICAL; + } +#endif /* SLAP_AUXPROP_DONTUSECOPY */ + pr = sparams->utils->prop_get( prctx ); if (!pr) return SASL_BADPARAM; @@ -507,7 +622,23 @@ slap_auxprop_store( op.o_req_dn = op.o_req_ndn; op.orm_modlist = modlist; - rc = op.o_bd->be_modify( &op, &rs ); + for (;;) { + SlapReply rs = {REP_RESULT}; + rc = op.o_bd->be_modify( &op, &rs ); + +#ifdef SLAP_AUXPROP_DONTUSECOPY + if ( dontUseCopy && + rs.sr_err == LDAP_UNAVAILABLE && + slap_dontUseCopy_ignore ) + { + op.o_bd = dontUseCopy_bd; + op.o_dontUseCopy = SLAP_CONTROL_NONE; + dontUseCopy = 0; + continue; + } +#endif /* SLAP_AUXPROP_DONTUSECOPY */ + break; + } } } slap_mods_free( modlist, 1 ); @@ -1177,6 +1308,13 @@ int slap_sasl_destroy( void ) { #ifdef HAVE_CYRUS_SASL sasl_done(); + +#ifdef SLAP_AUXPROP_DONTUSECOPY + if ( slap_dontUseCopy_propnames ) { + ber_bvarray_free( slap_dontUseCopy_propnames ); + slap_dontUseCopy_propnames = NULL; + } +#endif /* SLAP_AUXPROP_DONTUSECOPY */ #endif free( sasl_host ); sasl_host = NULL; @@ -1579,7 +1717,7 @@ int slap_sasl_bind( Operation *op, SlapReply *rs ) /* EXTERNAL */ if( op->orb_cred.bv_len ) { - rs->sr_text = "proxy authorization not support"; + rs->sr_text = "proxy authorization not supported"; rs->sr_err = LDAP_UNWILLING_TO_PERFORM; send_ldap_result( op, rs );