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 * modify.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_modify - initiate an ldap modify operation. Parameters: 40 * 41 * ld LDAP descriptor 42 * dn DN of the object to modify 43 * mods List of modifications to make. This is null-terminated 44 * array of struct ldapmod's, specifying the modifications 45 * to perform. 46 * 47 * Example: 48 * LDAPMod *mods[] = { 49 * { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } }, 50 * { LDAP_MOD_REPLACE, "sn", { "jensen", 0 } }, 51 * 0 52 * } 53 * msgid = ldap_modify( ld, dn, mods ); 54 */ 55 int 56 LDAP_CALL 57 ldap_modify( LDAP *ld, const char *dn, LDAPMod **mods ) 58 { 59 int msgid; 60 61 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_modify\n", 0, 0, 0 ); 62 63 if ( ldap_modify_ext( ld, dn, mods, NULL, NULL, &msgid ) 64 == LDAP_SUCCESS ) { 65 return( msgid ); 66 } else { 67 return( -1 ); /* error is in ld handle */ 68 } 69 } 70 71 int 72 LDAP_CALL 73 ldap_modify_ext( LDAP *ld, const char *dn, LDAPMod **mods, 74 LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp ) 75 { 76 BerElement *ber; 77 int i, rc, lderr; 78 79 /* 80 * A modify request looks like this: 81 * ModifyRequet ::= SEQUENCE { 82 * object DistinguishedName, 83 * modifications SEQUENCE OF SEQUENCE { 84 * operation ENUMERATED { 85 * add (0), 86 * delete (1), 87 * replace (2) 88 * }, 89 * modification SEQUENCE { 90 * type AttributeType, 91 * values SET OF AttributeValue 92 * } 93 * } 94 * } 95 */ 96 97 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 ); 98 99 if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { 100 return( LDAP_PARAM_ERROR ); 101 } 102 if ( !NSLDAPI_VALID_LDAPMESSAGE_POINTER( msgidp )) 103 { 104 LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); 105 return( LDAP_PARAM_ERROR ); 106 } 107 108 if ( !NSLDAPI_VALID_NONEMPTY_LDAPMOD_ARRAY( mods )) { 109 lderr = LDAP_PARAM_ERROR; 110 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL ); 111 return( lderr ); 112 } 113 if ( dn == NULL ) { 114 dn = ""; 115 } 116 117 LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK ); 118 *msgidp = ++ld->ld_msgid; 119 LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK ); 120 121 /* see if we should add to the cache */ 122 if ( ld->ld_cache_on && ld->ld_cache_modify != NULL ) { 123 LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK ); 124 if ( (rc = (ld->ld_cache_modify)( ld, *msgidp, LDAP_REQ_MODIFY, 125 dn, mods )) != 0 ) { 126 *msgidp = rc; 127 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); 128 return( LDAP_SUCCESS ); 129 } 130 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); 131 } 132 133 /* create a message to send */ 134 if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber )) 135 != LDAP_SUCCESS ) { 136 return( lderr ); 137 } 138 139 if ( ber_printf( ber, "{it{s{", *msgidp, LDAP_REQ_MODIFY, dn ) 140 == -1 ) { 141 lderr = LDAP_ENCODING_ERROR; 142 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL ); 143 ber_free( ber, 1 ); 144 return( lderr ); 145 } 146 147 /* for each modification to be performed... */ 148 for ( i = 0; mods[i] != NULL; i++ ) { 149 if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) { 150 rc = ber_printf( ber, "{e{s[V]}}", 151 mods[i]->mod_op & ~LDAP_MOD_BVALUES, 152 mods[i]->mod_type, mods[i]->mod_bvalues ); 153 } else { 154 rc = ber_printf( ber, "{e{s[v]}}", mods[i]->mod_op, 155 mods[i]->mod_type, mods[i]->mod_values ); 156 } 157 158 if ( rc == -1 ) { 159 lderr = LDAP_ENCODING_ERROR; 160 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL ); 161 ber_free( ber, 1 ); 162 return( lderr ); 163 } 164 } 165 166 if ( ber_printf( ber, "}}" ) == -1 ) { 167 lderr = LDAP_ENCODING_ERROR; 168 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL ); 169 ber_free( ber, 1 ); 170 return( lderr ); 171 } 172 173 if (( lderr = nsldapi_put_controls( ld, serverctrls, 1, ber )) 174 != LDAP_SUCCESS ) { 175 ber_free( ber, 1 ); 176 return( lderr ); 177 } 178 179 /* send the message */ 180 rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_MODIFY, 181 (char *)dn, ber ); 182 *msgidp = rc; 183 return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS ); 184 } 185 186 int 187 LDAP_CALL 188 ldap_modify_s( LDAP *ld, const char *dn, LDAPMod **mods ) 189 { 190 return( ldap_modify_ext_s( ld, dn, mods, NULL, NULL )); 191 } 192 193 int 194 LDAP_CALL 195 ldap_modify_ext_s( LDAP *ld, const char *dn, LDAPMod **mods, 196 LDAPControl **serverctrls, LDAPControl **clientctrls ) 197 { 198 int msgid, err; 199 LDAPMessage *res; 200 201 if (( err = ldap_modify_ext( ld, dn, mods, serverctrls, clientctrls, 202 &msgid )) != LDAP_SUCCESS ) { 203 return( err ); 204 } 205 206 if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res ) == -1 ) { 207 return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); 208 } 209 210 return( ldap_result2error( ld, res, 1 ) ); 211 } 212