1 /* $NetBSD: modrdn.c,v 1.3 2021/08/14 16:14:56 christos Exp $ */
2
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 *
6 * Copyright 1998-2021 The OpenLDAP Foundation.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
11 * Public License.
12 *
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
16 */
17 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
18 * All rights reserved.
19 */
20 /* Copyright 1999, Juan C. Gomez, All rights reserved.
21 * This software is not subject to any license of Silicon Graphics
22 * Inc. or Purdue University.
23 *
24 * Redistribution and use in source and binary forms are permitted
25 * without restriction or fee of any kind as long as this notice
26 * is preserved.
27 */
28
29 /* ACKNOWLEDGEMENTS:
30 * Juan C. Gomez
31 */
32
33 #include <sys/cdefs.h>
34 __RCSID("$NetBSD: modrdn.c,v 1.3 2021/08/14 16:14:56 christos Exp $");
35
36 #include "portable.h"
37
38 #include <stdio.h>
39
40 #include <ac/socket.h>
41 #include <ac/string.h>
42 #include <ac/time.h>
43
44 #include "ldap-int.h"
45
46 /*
47 * A modify rdn request looks like this:
48 * ModifyRDNRequest ::= SEQUENCE {
49 * entry DistinguishedName,
50 * newrdn RelativeDistinguishedName,
51 * deleteoldrdn BOOLEAN
52 * newSuperior [0] DistinguishedName [v3 only]
53 * }
54 */
55
56 BerElement *
ldap_build_moddn_req(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * newrdn,LDAP_CONST char * newSuperior,int deleteoldrdn,LDAPControl ** sctrls,LDAPControl ** cctrls,ber_int_t * msgidp)57 ldap_build_moddn_req(
58 LDAP *ld,
59 LDAP_CONST char *dn,
60 LDAP_CONST char *newrdn,
61 LDAP_CONST char *newSuperior,
62 int deleteoldrdn,
63 LDAPControl **sctrls,
64 LDAPControl **cctrls,
65 ber_int_t *msgidp )
66 {
67 BerElement *ber;
68 int rc;
69
70 /* create a message to send */
71 if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
72 return( NULL );
73 }
74
75 LDAP_NEXT_MSGID( ld, *msgidp );
76 if( newSuperior != NULL ) {
77 /* must be version 3 (or greater) */
78 if ( ld->ld_version < LDAP_VERSION3 ) {
79 ld->ld_errno = LDAP_NOT_SUPPORTED;
80 ber_free( ber, 1 );
81 return( NULL );
82 }
83 rc = ber_printf( ber, "{it{ssbtsN}", /* '}' */
84 *msgidp, LDAP_REQ_MODDN,
85 dn, newrdn, (ber_int_t) deleteoldrdn,
86 LDAP_TAG_NEWSUPERIOR, newSuperior );
87
88 } else {
89 rc = ber_printf( ber, "{it{ssbN}", /* '}' */
90 *msgidp, LDAP_REQ_MODDN,
91 dn, newrdn, (ber_int_t) deleteoldrdn );
92 }
93
94 if ( rc < 0 ) {
95 ld->ld_errno = LDAP_ENCODING_ERROR;
96 ber_free( ber, 1 );
97 return( NULL );
98 }
99
100 /* Put Server Controls */
101 if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
102 ber_free( ber, 1 );
103 return( NULL );
104 }
105
106 rc = ber_printf( ber, /*{*/ "N}" );
107 if ( rc < 0 ) {
108 ld->ld_errno = LDAP_ENCODING_ERROR;
109 ber_free( ber, 1 );
110 return( NULL );
111 }
112
113 return( ber );
114 }
115
116 /*
117 * ldap_rename - initiate an ldap extended modifyDN operation.
118 *
119 * Parameters:
120 * ld LDAP descriptor
121 * dn DN of the object to modify
122 * newrdn RDN to give the object
123 * deleteoldrdn nonzero means to delete old rdn values from the entry
124 * newSuperior DN of the new parent if applicable
125 *
126 * Returns the LDAP error code.
127 */
128
129 int
ldap_rename(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * newrdn,LDAP_CONST char * newSuperior,int deleteoldrdn,LDAPControl ** sctrls,LDAPControl ** cctrls,int * msgidp)130 ldap_rename(
131 LDAP *ld,
132 LDAP_CONST char *dn,
133 LDAP_CONST char *newrdn,
134 LDAP_CONST char *newSuperior,
135 int deleteoldrdn,
136 LDAPControl **sctrls,
137 LDAPControl **cctrls,
138 int *msgidp )
139 {
140 BerElement *ber;
141 int rc;
142 ber_int_t id;
143
144 Debug0( LDAP_DEBUG_TRACE, "ldap_rename\n" );
145
146 /* check client controls */
147 rc = ldap_int_client_controls( ld, cctrls );
148 if( rc != LDAP_SUCCESS ) return rc;
149
150 ber = ldap_build_moddn_req( ld, dn, newrdn, newSuperior,
151 deleteoldrdn, sctrls, cctrls, &id );
152 if( !ber )
153 return ld->ld_errno;
154
155 /* send the message */
156 *msgidp = ldap_send_initial_request( ld, LDAP_REQ_MODRDN, dn, ber, id );
157
158 if( *msgidp < 0 ) {
159 return( ld->ld_errno );
160 }
161
162 return LDAP_SUCCESS;
163 }
164
165
166 /*
167 * ldap_rename2 - initiate an ldap (and X.500) modifyDN operation. Parameters:
168 * (LDAP V3 MODIFYDN REQUEST)
169 * ld LDAP descriptor
170 * dn DN of the object to modify
171 * newrdn RDN to give the object
172 * deleteoldrdn nonzero means to delete old rdn values from the entry
173 * newSuperior DN of the new parent if applicable
174 *
175 * ldap_rename2 uses a U-Mich Style API. It returns the msgid.
176 */
177
178 int
ldap_rename2(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * newrdn,LDAP_CONST char * newSuperior,int deleteoldrdn)179 ldap_rename2(
180 LDAP *ld,
181 LDAP_CONST char *dn,
182 LDAP_CONST char *newrdn,
183 LDAP_CONST char *newSuperior,
184 int deleteoldrdn )
185 {
186 int msgid;
187 int rc;
188
189 Debug0( LDAP_DEBUG_TRACE, "ldap_rename2\n" );
190
191 rc = ldap_rename( ld, dn, newrdn, newSuperior,
192 deleteoldrdn, NULL, NULL, &msgid );
193
194 return rc == LDAP_SUCCESS ? msgid : -1;
195 }
196
197
198 /*
199 * ldap_modrdn2 - initiate an ldap modifyRDN operation. Parameters:
200 *
201 * ld LDAP descriptor
202 * dn DN of the object to modify
203 * newrdn RDN to give the object
204 * deleteoldrdn nonzero means to delete old rdn values from the entry
205 *
206 * Example:
207 * msgid = ldap_modrdn( ld, dn, newrdn );
208 */
209 int
ldap_modrdn2(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * newrdn,int deleteoldrdn)210 ldap_modrdn2( LDAP *ld,
211 LDAP_CONST char *dn,
212 LDAP_CONST char *newrdn,
213 int deleteoldrdn )
214 {
215 return ldap_rename2( ld, dn, newrdn, NULL, deleteoldrdn );
216 }
217
218 int
ldap_modrdn(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * newrdn)219 ldap_modrdn( LDAP *ld, LDAP_CONST char *dn, LDAP_CONST char *newrdn )
220 {
221 return( ldap_rename2( ld, dn, newrdn, NULL, 1 ) );
222 }
223
224
225 int
ldap_rename_s(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * newrdn,LDAP_CONST char * newSuperior,int deleteoldrdn,LDAPControl ** sctrls,LDAPControl ** cctrls)226 ldap_rename_s(
227 LDAP *ld,
228 LDAP_CONST char *dn,
229 LDAP_CONST char *newrdn,
230 LDAP_CONST char *newSuperior,
231 int deleteoldrdn,
232 LDAPControl **sctrls,
233 LDAPControl **cctrls )
234 {
235 int rc;
236 int msgid;
237 LDAPMessage *res;
238
239 rc = ldap_rename( ld, dn, newrdn, newSuperior,
240 deleteoldrdn, sctrls, cctrls, &msgid );
241
242 if( rc != LDAP_SUCCESS ) {
243 return rc;
244 }
245
246 rc = ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &res );
247
248 if( rc == -1 || !res ) {
249 return ld->ld_errno;
250 }
251
252 return ldap_result2error( ld, res, 1 );
253 }
254
255 int
ldap_rename2_s(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * newrdn,LDAP_CONST char * newSuperior,int deleteoldrdn)256 ldap_rename2_s(
257 LDAP *ld,
258 LDAP_CONST char *dn,
259 LDAP_CONST char *newrdn,
260 LDAP_CONST char *newSuperior,
261 int deleteoldrdn )
262 {
263 return ldap_rename_s( ld, dn, newrdn, newSuperior,
264 deleteoldrdn, NULL, NULL );
265 }
266
267 int
ldap_modrdn2_s(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * newrdn,int deleteoldrdn)268 ldap_modrdn2_s( LDAP *ld, LDAP_CONST char *dn, LDAP_CONST char *newrdn, int deleteoldrdn )
269 {
270 return ldap_rename_s( ld, dn, newrdn, NULL, deleteoldrdn, NULL, NULL );
271 }
272
273 int
ldap_modrdn_s(LDAP * ld,LDAP_CONST char * dn,LDAP_CONST char * newrdn)274 ldap_modrdn_s( LDAP *ld, LDAP_CONST char *dn, LDAP_CONST char *newrdn )
275 {
276 return ldap_rename_s( ld, dn, newrdn, NULL, 1, NULL, NULL );
277 }
278
279