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 56BerElement * 57ldap_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 129int 130ldap_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 178int 179ldap_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 */ 209int 210ldap_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 218int 219ldap_modrdn( LDAP *ld, LDAP_CONST char *dn, LDAP_CONST char *newrdn ) 220{ 221 return( ldap_rename2( ld, dn, newrdn, NULL, 1 ) ); 222} 223 224 225int 226ldap_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 255int 256ldap_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 267int 268ldap_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 273int 274ldap_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