1 /* suffixmassage.c - massages ldap backend dns */ 2 /* $OpenLDAP: pkg/ldap/servers/slapd/back-meta/suffixmassage.c,v 1.7.2.3 2008/02/11 23:26:47 kurt Exp $ */ 3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 4 * 5 * Copyright 2003-2008 The OpenLDAP Foundation. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted only as authorized by the OpenLDAP 10 * Public License. 11 * 12 * A copy of this license is available in the file LICENSE in the 13 * top-level directory of the distribution or, alternatively, at 14 * <http://www.OpenLDAP.org/license.html>. 15 */ 16 /* ACKNOWLEDGEMENTS: 17 * This work was initially developed by the Howard Chu for inclusion 18 * in OpenLDAP Software and subsequently enhanced by Pierangelo 19 * Masarati. 20 */ 21 /* This is an altered version */ 22 23 /* 24 * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com> 25 * Copyright 2000, Pierangelo Masarati, All rights reserved. <ando@sys-net.it> 26 * 27 * Module back-ldap, originally developed by Howard Chu 28 * 29 * has been modified by Pierangelo Masarati. The original copyright 30 * notice has been maintained. 31 * 32 * Permission is granted to anyone to use this software for any purpose 33 * on any computer system, and to alter it and redistribute it, subject 34 * to the following restrictions: 35 * 36 * 1. The author is not responsible for the consequences of use of this 37 * software, no matter how awful, even if they arise from flaws in it. 38 * 39 * 2. The origin of this software must not be misrepresented, either by 40 * explicit claim or by omission. Since few users ever read sources, 41 * credits should appear in the documentation. 42 * 43 * 3. Altered versions must be plainly marked as such, and must not be 44 * misrepresented as being the original software. Since few users 45 * ever read sources, credits should appear in the documentation. 46 * 47 * 4. This notice may not be removed or altered. 48 */ 49 50 #include "portable.h" 51 52 #include <stdio.h> 53 54 #include <ac/string.h> 55 #include <ac/socket.h> 56 57 #include "slap.h" 58 #include "../back-ldap/back-ldap.h" 59 #include "back-meta.h" 60 61 #ifdef ENABLE_REWRITE 62 int 63 ldap_back_dn_massage( 64 dncookie *dc, 65 struct berval *dn, 66 struct berval *res ) 67 { 68 int rc = 0; 69 static char *dmy = ""; 70 71 switch ( rewrite_session( dc->target->mt_rwmap.rwm_rw, dc->ctx, 72 ( dn->bv_val ? dn->bv_val : dmy ), 73 dc->conn, &res->bv_val ) ) 74 { 75 case REWRITE_REGEXEC_OK: 76 if ( res->bv_val != NULL ) { 77 res->bv_len = strlen( res->bv_val ); 78 } else { 79 *res = *dn; 80 } 81 Debug( LDAP_DEBUG_ARGS, 82 "[rw] %s: \"%s\" -> \"%s\"\n", 83 dc->ctx, 84 BER_BVISNULL( dn ) ? "" : dn->bv_val, 85 BER_BVISNULL( res ) ? "" : res->bv_val ); 86 rc = LDAP_SUCCESS; 87 break; 88 89 case REWRITE_REGEXEC_UNWILLING: 90 if ( dc->rs ) { 91 dc->rs->sr_err = LDAP_UNWILLING_TO_PERFORM; 92 dc->rs->sr_text = "Operation not allowed"; 93 } 94 rc = LDAP_UNWILLING_TO_PERFORM; 95 break; 96 97 case REWRITE_REGEXEC_ERR: 98 if ( dc->rs ) { 99 dc->rs->sr_err = LDAP_OTHER; 100 dc->rs->sr_text = "Rewrite error"; 101 } 102 rc = LDAP_OTHER; 103 break; 104 } 105 106 if ( res->bv_val == dmy ) { 107 BER_BVZERO( res ); 108 } 109 110 return rc; 111 } 112 113 #else 114 /* 115 * ldap_back_dn_massage 116 * 117 * Aliases the suffix; based on suffix_alias (servers/slapd/suffixalias.c). 118 */ 119 int 120 ldap_back_dn_massage( 121 dncookie *dc, 122 struct berval *odn, 123 struct berval *res 124 ) 125 { 126 int i, src, dst; 127 struct berval pretty = {0,NULL}, *dn = odn; 128 129 assert( res != NULL ); 130 131 if ( dn == NULL ) { 132 res->bv_val = NULL; 133 res->bv_len = 0; 134 return 0; 135 } 136 if ( dc->target->mt_rwmap.rwm_suffix_massage == NULL ) { 137 *res = *dn; 138 return 0; 139 } 140 141 if ( dc->tofrom ) { 142 src = 0 + dc->normalized; 143 dst = 2 + dc->normalized; 144 } else { 145 src = 2 + dc->normalized; 146 dst = 0 + dc->normalized; 147 /* DN from remote server may be in arbitrary form. 148 * Pretty it so we can parse reliably. 149 */ 150 dnPretty( NULL, dn, &pretty, NULL ); 151 if (pretty.bv_val) dn = &pretty; 152 } 153 154 for ( i = 0; 155 dc->target->mt_rwmap.rwm_suffix_massage[i].bv_val != NULL; 156 i += 4 ) { 157 int aliasLength = dc->target->mt_rwmap.rwm_suffix_massage[i+src].bv_len; 158 int diff = dn->bv_len - aliasLength; 159 160 if ( diff < 0 ) { 161 /* alias is longer than dn */ 162 continue; 163 } else if ( diff > 0 && ( !DN_SEPARATOR(dn->bv_val[diff-1]))) { 164 /* boundary is not at a DN separator */ 165 continue; 166 /* At a DN Separator */ 167 } 168 169 if ( !strcmp( dc->target->mt_rwmap.rwm_suffix_massage[i+src].bv_val, &dn->bv_val[diff] ) ) { 170 res->bv_len = diff + dc->target->mt_rwmap.rwm_suffix_massage[i+dst].bv_len; 171 res->bv_val = ch_malloc( res->bv_len + 1 ); 172 strncpy( res->bv_val, dn->bv_val, diff ); 173 strcpy( &res->bv_val[diff], dc->target->mt_rwmap.rwm_suffix_massage[i+dst].bv_val ); 174 Debug( LDAP_DEBUG_ARGS, 175 "ldap_back_dn_massage:" 176 " converted \"%s\" to \"%s\"\n", 177 BER_BVISNULL( dn ) ? "" : dn->bv_val, 178 BER_BVISNULL( res ) ? "" : res->bv_val, 0 ); 179 break; 180 } 181 } 182 if (pretty.bv_val) { 183 ch_free(pretty.bv_val); 184 dn = odn; 185 } 186 /* Nothing matched, just return the original DN */ 187 if (res->bv_val == NULL) { 188 *res = *dn; 189 } 190 191 return 0; 192 } 193 #endif /* !ENABLE_REWRITE */ 194