1 #pragma ident "%Z%%M% %I% %E% SMI" 2 3 /* 4 * The contents of this file are subject to the Netscape Public 5 * License Version 1.1 (the "License"); you may not use this file 6 * except in compliance with the License. You may obtain a copy of 7 * the License at http://www.mozilla.org/NPL/ 8 * 9 * Software distributed under the License is distributed on an "AS 10 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 11 * implied. See the License for the specific language governing 12 * rights and limitations under the License. 13 * 14 * The Original Code is Mozilla Communicator client code, released 15 * March 31, 1998. 16 * 17 * The Initial Developer of the Original Code is Netscape 18 * Communications Corporation. Portions created by Netscape are 19 * Copyright (C) 1998-1999 Netscape Communications Corporation. All 20 * Rights Reserved. 21 * 22 * Contributor(s): 23 */ 24 /* 25 * Copyright (c) 1990 Regents of the University of Michigan. 26 * All rights reserved. 27 */ 28 /* 29 * modify.c 30 */ 31 32 #if 0 33 #ifndef lint 34 static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n"; 35 #endif 36 #endif 37 38 #include "ldap-int.h" 39 40 /* 41 * ldap_modify - initiate an ldap modify operation. Parameters: 42 * 43 * ld LDAP descriptor 44 * dn DN of the object to modify 45 * mods List of modifications to make. This is null-terminated 46 * array of struct ldapmod's, specifying the modifications 47 * to perform. 48 * 49 * Example: 50 * LDAPMod *mods[] = { 51 * { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } }, 52 * { LDAP_MOD_REPLACE, "sn", { "jensen", 0 } }, 53 * 0 54 * } 55 * msgid = ldap_modify( ld, dn, mods ); 56 */ 57 int 58 LDAP_CALL 59 ldap_modify( LDAP *ld, const char *dn, LDAPMod **mods ) 60 { 61 int msgid; 62 63 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_modify\n", 0, 0, 0 ); 64 65 if ( ldap_modify_ext( ld, dn, mods, NULL, NULL, &msgid ) 66 == LDAP_SUCCESS ) { 67 return( msgid ); 68 } else { 69 return( -1 ); /* error is in ld handle */ 70 } 71 } 72 73 int 74 LDAP_CALL 75 ldap_modify_ext( LDAP *ld, const char *dn, LDAPMod **mods, 76 LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp ) 77 { 78 BerElement *ber; 79 int i, rc, lderr; 80 81 /* 82 * A modify request looks like this: 83 * ModifyRequet ::= SEQUENCE { 84 * object DistinguishedName, 85 * modifications SEQUENCE OF SEQUENCE { 86 * operation ENUMERATED { 87 * add (0), 88 * delete (1), 89 * replace (2) 90 * }, 91 * modification SEQUENCE { 92 * type AttributeType, 93 * values SET OF AttributeValue 94 * } 95 * } 96 * } 97 */ 98 99 LDAPDebug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 ); 100 101 if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { 102 return( LDAP_PARAM_ERROR ); 103 } 104 if ( !NSLDAPI_VALID_LDAPMESSAGE_POINTER( msgidp )) 105 { 106 LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); 107 return( LDAP_PARAM_ERROR ); 108 } 109 110 if ( !NSLDAPI_VALID_NONEMPTY_LDAPMOD_ARRAY( mods )) { 111 lderr = LDAP_PARAM_ERROR; 112 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL ); 113 return( lderr ); 114 } 115 if ( dn == NULL ) { 116 dn = ""; 117 } 118 119 LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK ); 120 *msgidp = ++ld->ld_msgid; 121 LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK ); 122 123 /* see if we should add to the cache */ 124 if ( ld->ld_cache_on && ld->ld_cache_modify != NULL ) { 125 LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK ); 126 if ( (rc = (ld->ld_cache_modify)( ld, *msgidp, LDAP_REQ_MODIFY, 127 dn, mods )) != 0 ) { 128 *msgidp = rc; 129 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); 130 return( LDAP_SUCCESS ); 131 } 132 LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK ); 133 } 134 135 /* create a message to send */ 136 if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber )) 137 != LDAP_SUCCESS ) { 138 return( lderr ); 139 } 140 141 if ( ber_printf( ber, "{it{s{", *msgidp, LDAP_REQ_MODIFY, dn ) 142 == -1 ) { 143 lderr = LDAP_ENCODING_ERROR; 144 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL ); 145 ber_free( ber, 1 ); 146 return( lderr ); 147 } 148 149 /* for each modification to be performed... */ 150 for ( i = 0; mods[i] != NULL; i++ ) { 151 if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) { 152 rc = ber_printf( ber, "{e{s[V]}}", 153 mods[i]->mod_op & ~LDAP_MOD_BVALUES, 154 mods[i]->mod_type, mods[i]->mod_bvalues ); 155 } else { 156 rc = ber_printf( ber, "{e{s[v]}}", mods[i]->mod_op, 157 mods[i]->mod_type, mods[i]->mod_values ); 158 } 159 160 if ( rc == -1 ) { 161 lderr = LDAP_ENCODING_ERROR; 162 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL ); 163 ber_free( ber, 1 ); 164 return( lderr ); 165 } 166 } 167 168 if ( ber_printf( ber, "}}" ) == -1 ) { 169 lderr = LDAP_ENCODING_ERROR; 170 LDAP_SET_LDERRNO( ld, lderr, NULL, NULL ); 171 ber_free( ber, 1 ); 172 return( lderr ); 173 } 174 175 if (( lderr = nsldapi_put_controls( ld, serverctrls, 1, ber )) 176 != LDAP_SUCCESS ) { 177 ber_free( ber, 1 ); 178 return( lderr ); 179 } 180 181 /* send the message */ 182 rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_MODIFY, 183 (char *)dn, ber ); 184 *msgidp = rc; 185 return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS ); 186 } 187 188 int 189 LDAP_CALL 190 ldap_modify_s( LDAP *ld, const char *dn, LDAPMod **mods ) 191 { 192 return( ldap_modify_ext_s( ld, dn, mods, NULL, NULL )); 193 } 194 195 int 196 LDAP_CALL 197 ldap_modify_ext_s( LDAP *ld, const char *dn, LDAPMod **mods, 198 LDAPControl **serverctrls, LDAPControl **clientctrls ) 199 { 200 int msgid, err; 201 LDAPMessage *res; 202 203 if (( err = ldap_modify_ext( ld, dn, mods, serverctrls, clientctrls, 204 &msgid )) != LDAP_SUCCESS ) { 205 return( err ); 206 } 207 208 if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res ) == -1 ) { 209 return( LDAP_GET_LDERRNO( ld, NULL, NULL ) ); 210 } 211 212 return( ldap_result2error( ld, res, 1 ) ); 213 } 214