1 /* 2 * The contents of this file are subject to the Netscape Public 3 * License Version 1.1 (the "License"); you may not use this file 4 * except in compliance with the License. You may obtain a copy of 5 * the License at http://www.mozilla.org/NPL/ 6 * 7 * Software distributed under the License is distributed on an "AS 8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 9 * implied. See the License for the specific language governing 10 * rights and limitations under the License. 11 * 12 * The Original Code is Mozilla Communicator client code, released 13 * March 31, 1998. 14 * 15 * The Initial Developer of the Original Code is Netscape 16 * Communications Corporation. Portions created by Netscape are 17 * Copyright (C) 1998-1999 Netscape Communications Corporation. All 18 * Rights Reserved. 19 * 20 * Contributor(s): 21 */ 22 /* 23 * Copyright (c) 1990 Regents of the University of Michigan. 24 * All rights reserved. 25 */ 26 /* 27 * rename.c 28 */ 29 30 #if 0 31 #ifndef lint 32 static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n"; 33 #endif 34 #endif 35 36 #include "ldap-int.h" 37 38 /* 39 * ldap_rename - initiate an ldap modifyDN operation. Parameters: 40 * 41 * ld LDAP descriptor 42 * dn DN of the object to modify 43 * newrdn RDN that will form leftmost component of entry's new name 44 * newparent if present, this is the Distinguished Name of the entry 45 * which becomes the immediate parent of the existing entry 46 * deleteoldrdn nonzero means to delete old rdn values from the entry 47 * while zero means to retain them as attributes of the entry 48 * serverctrls list of LDAP server controls 49 * clientctrls list of client controls 50 * msgidp this result parameter will be set to the message id of the 51 * request if the ldap_rename() call succeeds 52 * 53 * Example: 54 * int rc; 55 * rc = ldap_rename( ld, dn, newrdn, newparent, deleteoldrdn, serverctrls, clientctrls, &msgid ); 56 */ 57 int 58 LDAP_CALL 59 ldap_rename( 60 LDAP *ld, 61 const char *dn, 62 const char *newrdn, 63 const char *newparent, 64 int deleteoldrdn, 65 LDAPControl **serverctrls, 66 LDAPControl **clientctrls, /* not used for anything yet */ 67 int *msgidp 68 ) 69 { 70 BerElement *ber; 71 int rc, err; 72 73 /* 74 * A modify dn request looks like this: 75 * ModifyDNRequest ::= SEQUENCE { 76 * entry LDAPDN, 77 * newrdn RelativeLDAPDN, 78 * newparent [0] LDAPDN OPTIONAL, 79 * deleteoldrdn BOOLEAN 80 * } 81 */ 82 83 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_rename\n", 0, 0, 0 ); 84 85 if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { 86 return( LDAP_PARAM_ERROR ); 87 } 88 if ( NULL == newrdn) { 89 LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); 90 return( LDAP_PARAM_ERROR ); 91 } 92 93 /* only ldapv3 or higher can do a proper rename 94 * (i.e. with non-NULL newparent and/or controls) 95 */ 96 97 if (( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) 98 && ((newparent != NULL) || (serverctrls != NULL) 99 || (clientctrls != NULL))) { 100 LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL ); 101 return( LDAP_NOT_SUPPORTED ); 102 } 103 104 if ( msgidp == NULL ) { 105 LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); 106 return( LDAP_PARAM_ERROR ); 107 } 108 109 LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK ); 110 *msgidp = ++ld->ld_msgid; 111 LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK ); 112 113 /* see if modRDN or modDN is handled by the cache */ 114 if ( ld->ld_cache_on ) { 115 if ( newparent == NULL && ld->ld_cache_modrdn != NULL ) { 116 LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK ); 117 if ( (rc = (ld->ld_cache_modrdn)( ld, *msgidp, 118 LDAP_REQ_MODRDN, dn, newrdn, deleteoldrdn )) 119 != 0 ) { 120 *msgidp = rc; 121 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); 122 return( LDAP_SUCCESS ); 123 } 124 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); 125 #if 0 126 } else if ( ld->ld_cache_rename != NULL ) { 127 LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK ); 128 if ( (rc = (ld->ld_cache_rename)( ld, *msgidp, 129 LDAP_REQ_MODDN, dn, newrdn, newparent, 130 deleteoldrdn )) != 0 ) { 131 *msgidp = rc; 132 return( LDAP_SUCCESS ); 133 } 134 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); 135 #endif 136 } 137 } 138 139 /* create a message to send */ 140 if (( err = nsldapi_alloc_ber_with_options( ld, &ber )) 141 != LDAP_SUCCESS ) { 142 return( err ); 143 } 144 145 /* fill it in */ 146 if ( ber_printf( ber, "{it{ssb", *msgidp, LDAP_REQ_MODDN, dn, 147 newrdn, deleteoldrdn ) == -1 ) { 148 LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL ); 149 ber_free( ber, 1 ); 150 return( LDAP_ENCODING_ERROR ); 151 } 152 153 if ( newparent == NULL ) { 154 if ( ber_printf( ber, "}" ) == -1 ) { 155 LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL ); 156 ber_free( ber, 1 ); 157 return( LDAP_ENCODING_ERROR ); 158 } 159 } else { 160 if ( ber_printf( ber, "ts}", LDAP_TAG_NEWSUPERIOR, newparent ) 161 == -1 ) { 162 LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL ); 163 ber_free( ber, 1 ); 164 return( LDAP_ENCODING_ERROR ); 165 } 166 } 167 168 if (( rc = nsldapi_put_controls( ld, serverctrls, 1, ber )) 169 != LDAP_SUCCESS ) { 170 ber_free( ber, 1 ); 171 return( rc ); 172 } 173 174 /* send the message */ 175 rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_MODDN, 176 (char *) dn, ber ); 177 *msgidp = rc; 178 return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS ); 179 } 180 181 int 182 LDAP_CALL 183 ldap_modrdn2( LDAP *ld, const char *dn, const char *newrdn, int deleteoldrdn ) 184 { 185 int msgid; 186 187 if ( ldap_rename( ld, dn, newrdn, NULL, deleteoldrdn, NULL, NULL, &msgid ) == LDAP_SUCCESS ) { 188 return( msgid ); 189 } else { 190 return( -1 ); /* error is in ld handle */ 191 } 192 } 193 194 int 195 LDAP_CALL 196 ldap_modrdn( LDAP *ld, const char *dn, const char *newrdn ) 197 { 198 return( ldap_modrdn2( ld, dn, newrdn, 1 ) ); 199 } 200 201 int 202 LDAP_CALL 203 ldap_rename_s( 204 LDAP *ld, 205 const char *dn, 206 const char *newrdn, 207 const char *newparent, 208 int deleteoldrdn, 209 LDAPControl **serverctrls, 210 LDAPControl **clientctrls /* not used for anything yet */ 211 ) 212 { 213 int msgid; 214 LDAPMessage *res; 215 216 if ( ldap_rename( ld, dn, newrdn, newparent, deleteoldrdn, serverctrls, clientctrls, &msgid ) != LDAP_SUCCESS ) { 217 return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); 218 } 219 220 if ( msgid == -1 ) 221 return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); 222 223 if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) 224 return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); 225 226 return( ldap_result2error( ld, res, 1 ) ); 227 } 228 229 int 230 LDAP_CALL 231 ldap_modrdn2_s( LDAP *ld, const char *dn, const char *newrdn, int deleteoldrdn ) 232 { 233 int msgid; 234 LDAPMessage *res; 235 236 if ( (msgid = ldap_modrdn2( ld, dn, newrdn, deleteoldrdn )) == -1 ) 237 return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); 238 239 if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) 240 return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); 241 242 return( ldap_result2error( ld, res, 1 ) ); 243 } 244 245 int 246 LDAP_CALL 247 ldap_modrdn_s( LDAP *ld, const char *dn, const char *newrdn ) 248 { 249 return( ldap_modrdn2_s( ld, dn, newrdn, 1 ) ); 250 } 251