1 /* $NetBSD: rwmdn.c,v 1.3 2021/08/14 16:15:02 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-2021 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.3 2021/08/14 16:15:02 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