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