Home | History | Annotate | Line # | Download | only in overlays
      1 /*	$NetBSD: rwmdn.c,v 1.4 2025/09/05 21:16:32 christos Exp $	*/
      2 
      3 /* rwmdn.c - massages dns */
      4 /* $OpenLDAP$ */
      5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      6  *
      7  * Copyright 1999-2024 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 Howard Chu for inclusion
     22  * in OpenLDAP Software and subsequently enhanced by Pierangelo
     23  * Masarati.
     24  */
     25 
     26 
     27 #include <sys/cdefs.h>
     28 __RCSID("$NetBSD: rwmdn.c,v 1.4 2025/09/05 21:16:32 christos Exp $");
     29 
     30 #include "portable.h"
     31 
     32 #ifdef SLAPD_OVER_RWM
     33 
     34 #include <stdio.h>
     35 
     36 #include <ac/string.h>
     37 #include <ac/socket.h>
     38 
     39 #include "slap.h"
     40 #include "rwm.h"
     41 
     42 /* FIXME: after rewriting, we should also remap attributes ...  */
     43 
     44 /*
     45  * massages "in" and normalizes it into "ndn"
     46  *
     47  * "ndn" may be untouched if no massaging occurred and its value was not null
     48  */
     49 int
     50 rwm_dn_massage_normalize(
     51 	dncookie *dc,
     52 	struct berval *in,
     53 	struct berval *ndn )
     54 {
     55 	int		rc;
     56 	struct berval	mdn = BER_BVNULL;
     57 
     58 	/* massage and normalize a DN */
     59 	rc = rwm_dn_massage( dc, in, &mdn );
     60 	if ( rc != LDAP_SUCCESS ) {
     61 		return rc;
     62 	}
     63 
     64 	if ( mdn.bv_val == in->bv_val && !BER_BVISNULL( ndn ) ) {
     65 		return rc;
     66 	}
     67 
     68 	rc = dnNormalize( 0, NULL, NULL, &mdn, ndn, NULL );
     69 
     70 	if ( mdn.bv_val != in->bv_val ) {
     71 		ch_free( mdn.bv_val );
     72 	}
     73 
     74 	return rc;
     75 }
     76 
     77 /*
     78  * massages "in" and prettifies it into "pdn"
     79  *
     80  * "pdn" may be untouched if no massaging occurred and its value was not null
     81  */
     82 int
     83 rwm_dn_massage_pretty(
     84 	dncookie *dc,
     85 	struct berval *in,
     86 	struct berval *pdn )
     87 {
     88 	int		rc;
     89 	struct berval	mdn = BER_BVNULL;
     90 
     91 	/* massage and pretty a DN */
     92 	rc = rwm_dn_massage( dc, in, &mdn );
     93 	if ( rc != LDAP_SUCCESS ) {
     94 		return rc;
     95 	}
     96 
     97 	if ( mdn.bv_val == in->bv_val && !BER_BVISNULL( pdn ) ) {
     98 		return rc;
     99 	}
    100 
    101 	rc = dnPretty( NULL, &mdn, pdn, NULL );
    102 
    103 	if ( mdn.bv_val != in->bv_val ) {
    104 		ch_free( mdn.bv_val );
    105 	}
    106 
    107 	return rc;
    108 }
    109 
    110 /*
    111  * massages "in" and prettifies and normalizes it into "pdn" and "ndn"
    112  *
    113  * "pdn" may be untouched if no massaging occurred and its value was not null;
    114  * "ndn" may be untouched if no massaging occurred and its value was not null;
    115  * if no massage occurred and "ndn" value was not null, it is filled
    116  * with the normalized value of "pdn", much like ndn = dnNormalize( pdn )
    117  */
    118 int
    119 rwm_dn_massage_pretty_normalize(
    120 	dncookie *dc,
    121 	struct berval *in,
    122 	struct berval *pdn,
    123 	struct berval *ndn )
    124 {
    125 	int		rc;
    126 	struct berval	mdn = BER_BVNULL;
    127 
    128 	/* massage, pretty and normalize a DN */
    129 	rc = rwm_dn_massage( dc, in, &mdn );
    130 	if ( rc != LDAP_SUCCESS ) {
    131 		return rc;
    132 	}
    133 
    134 	if ( mdn.bv_val == in->bv_val && !BER_BVISNULL( pdn ) ) {
    135 		if ( BER_BVISNULL( ndn ) ) {
    136 			rc = dnNormalize( 0, NULL, NULL, &mdn, ndn, NULL );
    137 		}
    138 		return rc;
    139 	}
    140 
    141 	rc = dnPrettyNormal( NULL, &mdn, pdn, ndn, NULL );
    142 
    143 	if ( mdn.bv_val != in->bv_val ) {
    144 		ch_free( mdn.bv_val );
    145 	}
    146 
    147 	return rc;
    148 }
    149 
    150 /*
    151  * massages "in" into "dn"
    152  *
    153  * "dn" may contain the value of "in" if no massage occurred
    154  */
    155 int
    156 rwm_dn_massage(
    157 	dncookie *dc,
    158 	struct berval *in,
    159 	struct berval *dn
    160 )
    161 {
    162 	int		rc = 0;
    163 	struct berval	mdn;
    164 	static char	*dmy = "";
    165 	char *in_val;
    166 
    167 	assert( dc != NULL );
    168 	assert( in != NULL );
    169 	assert( dn != NULL );
    170 
    171 	/* protect from NULL berval */
    172 	in_val = in->bv_val ? in->bv_val : dmy;
    173 
    174 	rc = rewrite_session( dc->rwmap->rwm_rw, dc->ctx,
    175 			in_val, dc->conn, &mdn.bv_val );
    176 	switch ( rc ) {
    177 	case REWRITE_REGEXEC_OK:
    178 		if ( !BER_BVISNULL( &mdn ) && mdn.bv_val != in_val ) {
    179 			mdn.bv_len = strlen( mdn.bv_val );
    180 			*dn = mdn;
    181 		} else {
    182 			dn->bv_len = in->bv_len;
    183 			dn->bv_val = in_val;
    184 		}
    185 		rc = LDAP_SUCCESS;
    186 
    187 		Debug( LDAP_DEBUG_ARGS,
    188 			"[rw] %s: \"%s\" -> \"%s\"\n",
    189 			dc->ctx, in_val, dn->bv_val );
    190 		break;
    191 
    192  	case REWRITE_REGEXEC_UNWILLING:
    193 		if ( dc->rs ) {
    194 			dc->rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
    195 			dc->rs->sr_text = "Operation not allowed";
    196 		}
    197 		rc = LDAP_UNWILLING_TO_PERFORM;
    198 		break;
    199 
    200 	case REWRITE_REGEXEC_ERR:
    201 		if ( dc->rs ) {
    202 			dc->rs->sr_err = LDAP_OTHER;
    203 			dc->rs->sr_text = "Rewrite error";
    204 		}
    205 		rc = LDAP_OTHER;
    206 		break;
    207 	}
    208 
    209 	if ( mdn.bv_val == dmy ) {
    210 		BER_BVZERO( &mdn );
    211 	}
    212 
    213 	if ( dn->bv_val == dmy ) {
    214 		BER_BVZERO( dn );
    215 	}
    216 
    217 	return rc;
    218 }
    219 
    220 #endif /* SLAPD_OVER_RWM */
    221