Exemple #1
0
static int
do_check( Connection *c, Operation *op, struct berval *id )
{
    struct berval	authcdn;
    int		rc;

    rc = slap_sasl_getdn( c, op, id, realm, &authcdn, SLAP_GETDN_AUTHCID );
    if ( rc != LDAP_SUCCESS ) {
        fprintf( stderr, "ID: <%s> check failed %d (%s)\n",
                 id->bv_val, rc,
                 ldap_err2string( rc ) );
        rc = 1;

    } else {
        if ( !BER_BVISNULL( &authzID ) ) {
            rc = slap_sasl_authorized( op, &authcdn, &authzID );

            fprintf( stderr,
                     "ID:      <%s>\n"
                     "authcDN: <%s>\n"
                     "authzDN: <%s>\n"
                     "authorization %s\n",
                     id->bv_val,
                     authcdn.bv_val,
                     authzID.bv_val,
                     rc == LDAP_SUCCESS ? "OK" : "failed" );

        } else {
            fprintf( stderr, "ID: <%s> check succeeded\n"
                     "authcID:     <%s>\n",
                     id->bv_val,
                     authcdn.bv_val );
            op->o_tmpfree( authcdn.bv_val, op->o_tmpmemctx );
        }
        rc = 0;
    }

    return rc;
}
Exemple #2
0
int
slapauth( int argc, char **argv )
{
    int			rc = EXIT_SUCCESS;
    const char		*progname = "slapauth";
    Connection		conn = {0};
    OperationBuffer	opbuf;
    Operation		*op;

    slap_tool_init( progname, SLAPAUTH, argc, argv );

    argv = &argv[ optind ];
    argc -= optind;

    connection_fake_init( &conn, &opbuf, &conn );
    op = &opbuf.ob_op;

    conn.c_sasl_bind_mech = mech;

    if ( !BER_BVISNULL( &authzID ) ) {
        struct berval	authzdn;

        rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn,
                              SLAP_GETDN_AUTHZID );
        if ( rc != LDAP_SUCCESS ) {
            fprintf( stderr, "authzID: <%s> check failed %d (%s)\n",
                     authzID.bv_val, rc,
                     ldap_err2string( rc ) );
            rc = 1;
            BER_BVZERO( &authzID );
            goto destroy;
        }

        authzID = authzdn;
    }


    if ( !BER_BVISNULL( &authcID ) ) {
        if ( !BER_BVISNULL( &authzID ) || argc == 0 ) {
            rc = do_check( &conn, op, &authcID );
            goto destroy;
        }

        for ( ; argc--; argv++ ) {
            struct berval	authzdn;

            ber_str2bv( argv[ 0 ], 0, 0, &authzID );

            rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn,
                                  SLAP_GETDN_AUTHZID );
            if ( rc != LDAP_SUCCESS ) {
                fprintf( stderr, "authzID: <%s> check failed %d (%s)\n",
                         authzID.bv_val, rc,
                         ldap_err2string( rc ) );
                rc = -1;
                BER_BVZERO( &authzID );
                if ( !continuemode ) {
                    goto destroy;
                }
            }

            authzID = authzdn;

            rc = do_check( &conn, op, &authcID );

            op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx );
            BER_BVZERO( &authzID );

            if ( rc && !continuemode ) {
                goto destroy;
            }
        }

        goto destroy;
    }

    for ( ; argc--; argv++ ) {
        struct berval	id;

        ber_str2bv( argv[ 0 ], 0, 0, &id );

        rc = do_check( &conn, op, &id );

        if ( rc && !continuemode ) {
            goto destroy;
        }
    }

destroy:
    ;
    if ( !BER_BVISNULL( &authzID ) ) {
        op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx );
    }
    if ( slap_tool_destroy())
        rc = EXIT_FAILURE;

    return rc;
}
Exemple #3
0
/* Convert a SASL authcid or authzid into a DN. Store the DN in an
 * auxiliary property, so that we can refer to it in sasl_authorize
 * without interfering with anything else. Also, the SASL username
 * buffer is constrained to 256 characters, and our DNs could be
 * much longer (SLAP_LDAPDN_MAXLEN, currently set to 8192)
 */
static int
slap_sasl_canonicalize(
	sasl_conn_t *sconn,
	void *context,
	const char *in,
	unsigned inlen,
	unsigned flags,
	const char *user_realm,
	char *out,
	unsigned out_max,
	unsigned *out_len)
{
	Connection *conn = (Connection *)context;
	struct propctx *props = sasl_auxprop_getctx( sconn );
	struct propval auxvals[ SLAP_SASL_PROP_COUNT ] = { { 0 } };
	struct berval dn;
	int rc, which;
	const char *names[2];
	struct berval	bvin;

	*out_len = 0;

	Debug( LDAP_DEBUG_ARGS, "SASL Canonicalize [conn=%ld]: %s=\"%s\"\n",
		conn ? (long) conn->c_connid : -1L,
		(flags & SASL_CU_AUTHID) ? "authcid" : "authzid",
		in ? in : "<empty>");

	/* If name is too big, just truncate. We don't care, we're
	 * using DNs, not the usernames.
	 */
	if ( inlen > out_max )
		inlen = out_max-1;

	/* This is a Simple Bind using SPASSWD. That means the in-directory
	 * userPassword of the Binding user already points at SASL, so it
	 * cannot be used to actually satisfy a password comparison. Just
	 * ignore it, some other mech will process it.
	 */
	if ( !conn->c_sasl_bindop ||
		conn->c_sasl_bindop->orb_method != LDAP_AUTH_SASL ) goto done;

	/* See if we need to add request, can only do it once */
	prop_getnames( props, slap_propnames, auxvals );
	if ( !auxvals[0].name )
		prop_request( props, slap_propnames );

	if ( flags & SASL_CU_AUTHID )
		which = SLAP_SASL_PROP_AUTHCLEN;
	else
		which = SLAP_SASL_PROP_AUTHZLEN;

	/* Need to store the Connection for auxprop_lookup */
	if ( !auxvals[SLAP_SASL_PROP_CONN].values ) {
		names[0] = slap_propnames[SLAP_SASL_PROP_CONN];
		names[1] = NULL;
		prop_set( props, names[0], (char *)&conn, sizeof( conn ) );
	}
		
	/* Already been here? */
	if ( auxvals[which].values )
		goto done;

	/* Normally we require an authzID to have a u: or dn: prefix.
	 * However, SASL frequently gives us an authzID that is just
	 * an exact copy of the authcID, without a prefix. We need to
	 * detect and allow this condition. If SASL calls canonicalize
	 * with SASL_CU_AUTHID|SASL_CU_AUTHZID this is a no-brainer.
	 * But if it's broken into two calls, we need to remember the
	 * authcID so that we can compare the authzID later. We store
	 * the authcID temporarily in conn->c_sasl_dn. We necessarily
	 * finish Canonicalizing before Authorizing, so there is no
	 * conflict with slap_sasl_authorize's use of this temp var.
	 *
	 * The SASL EXTERNAL mech is backwards from all the other mechs,
	 * it does authzID before the authcID. If we see that authzID
	 * has already been done, don't do anything special with authcID.
	 */
	if ( flags == SASL_CU_AUTHID && !auxvals[SLAP_SASL_PROP_AUTHZ].values ) {
		conn->c_sasl_dn.bv_val = (char *) in;
		conn->c_sasl_dn.bv_len = 0;
	} else if ( flags == SASL_CU_AUTHZID && conn->c_sasl_dn.bv_val ) {
		rc = strcmp( in, conn->c_sasl_dn.bv_val );
		conn->c_sasl_dn.bv_val = NULL;
		/* They were equal, no work needed */
		if ( !rc ) goto done;
	}

	bvin.bv_val = (char *)in;
	bvin.bv_len = inlen;
	rc = slap_sasl_getdn( conn, NULL, &bvin, (char *)user_realm, &dn,
		(flags & SASL_CU_AUTHID) ? SLAP_GETDN_AUTHCID : SLAP_GETDN_AUTHZID );
	if ( rc != LDAP_SUCCESS ) {
		sasl_seterror( sconn, 0, ldap_err2string( rc ) );
		return SASL_NOAUTHZ;
	}

	names[0] = slap_propnames[which];
	names[1] = NULL;
	prop_set( props, names[0], (char *)&dn.bv_len, sizeof( dn.bv_len ) );

	which++;
	names[0] = slap_propnames[which];
	prop_set( props, names[0], dn.bv_val, dn.bv_len );

	Debug( LDAP_DEBUG_ARGS, "SASL Canonicalize [conn=%ld]: %s=\"%s\"\n",
		conn ? (long) conn->c_connid : -1L, names[0]+1,
		dn.bv_val ? dn.bv_val : "<EMPTY>" );

	/* Not needed any more, SASL has copied it */
	if ( conn && conn->c_sasl_bindop )
		conn->c_sasl_bindop->o_tmpfree( dn.bv_val, conn->c_sasl_bindop->o_tmpmemctx );

done:
	AC_MEMCPY( out, in, inlen );
	out[inlen] = '\0';

	*out_len = inlen;

	return SASL_OK;
}