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